@documentation-robotics/cli 0.1.0 → 0.1.7

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 (510) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +466 -693
  3. package/dist/analysis/data-model-analyzer.js +189 -0
  4. package/dist/analysis/data-model-analyzer.js.map +7 -0
  5. package/dist/analysis/index.js +3 -0
  6. package/dist/analysis/index.js.map +7 -0
  7. package/dist/analysis/relationship-classifier.js +181 -0
  8. package/dist/analysis/relationship-classifier.js.map +7 -0
  9. package/dist/analyzers/base-analyzer.js +1 -0
  10. package/dist/analyzers/base-analyzer.js.map +7 -0
  11. package/dist/analyzers/call-graph-utils.js +39 -0
  12. package/dist/analyzers/call-graph-utils.js.map +7 -0
  13. package/dist/analyzers/cbm-analyzer.js +1205 -0
  14. package/dist/analyzers/cbm-analyzer.js.map +7 -0
  15. package/dist/analyzers/heuristic-utils.js +55 -0
  16. package/dist/analyzers/heuristic-utils.js.map +7 -0
  17. package/dist/analyzers/mapping-loader.js +146 -0
  18. package/dist/analyzers/mapping-loader.js.map +7 -0
  19. package/dist/analyzers/registry.js +124 -0
  20. package/dist/analyzers/registry.js.map +7 -0
  21. package/dist/analyzers/session-state.js +176 -0
  22. package/dist/analyzers/session-state.js.map +7 -0
  23. package/dist/analyzers/stdio-client.js +208 -0
  24. package/dist/analyzers/stdio-client.js.map +7 -0
  25. package/dist/analyzers/types.js +15 -0
  26. package/dist/analyzers/types.js.map +7 -0
  27. package/dist/analyzers/verify-engine.js +209 -0
  28. package/dist/analyzers/verify-engine.js.map +7 -0
  29. package/dist/analyzers/verify-ignore.js +130 -0
  30. package/dist/analyzers/verify-ignore.js.map +7 -0
  31. package/dist/analyzers/version.js +8 -0
  32. package/dist/analyzers/version.js.map +7 -0
  33. package/dist/audit/ai/runner.js +41 -0
  34. package/dist/audit/ai/runner.js.map +7 -0
  35. package/dist/audit/differential-analyzer.js +183 -0
  36. package/dist/audit/differential-analyzer.js.map +7 -0
  37. package/dist/audit/index.js +32 -0
  38. package/dist/audit/index.js.map +7 -0
  39. package/dist/audit/nodes/ai/evaluator.js +49 -0
  40. package/dist/audit/nodes/ai/evaluator.js.map +7 -0
  41. package/dist/audit/nodes/ai/parser.js +55 -0
  42. package/dist/audit/nodes/ai/parser.js.map +7 -0
  43. package/dist/audit/nodes/ai/prompts.js +103 -0
  44. package/dist/audit/nodes/ai/prompts.js.map +7 -0
  45. package/dist/audit/nodes/analysis/node-completeness-checker.js +32 -0
  46. package/dist/audit/nodes/analysis/node-completeness-checker.js.map +7 -0
  47. package/dist/audit/nodes/analysis/node-definition-analyzer.js +47 -0
  48. package/dist/audit/nodes/analysis/node-definition-analyzer.js.map +7 -0
  49. package/dist/audit/nodes/analysis/node-overlap-detector.js +79 -0
  50. package/dist/audit/nodes/analysis/node-overlap-detector.js.map +7 -0
  51. package/dist/audit/nodes/model/orchestrator.js +82 -0
  52. package/dist/audit/nodes/model/orchestrator.js.map +7 -0
  53. package/dist/audit/nodes/spec/loader.js +116 -0
  54. package/dist/audit/nodes/spec/loader.js.map +7 -0
  55. package/dist/audit/nodes/spec/orchestrator.js +68 -0
  56. package/dist/audit/nodes/spec/orchestrator.js.map +7 -0
  57. package/dist/audit/nodes/types.js +1 -0
  58. package/dist/audit/nodes/types.js.map +7 -0
  59. package/dist/audit/pipeline/index.js +5 -0
  60. package/dist/audit/pipeline/index.js.map +7 -0
  61. package/dist/audit/pipeline/pipeline-orchestrator.js +218 -0
  62. package/dist/audit/pipeline/pipeline-orchestrator.js.map +7 -0
  63. package/dist/audit/relationships/ai/evaluator.js +235 -0
  64. package/dist/audit/relationships/ai/evaluator.js.map +7 -0
  65. package/dist/audit/relationships/ai/parser.js +197 -0
  66. package/dist/audit/relationships/ai/parser.js.map +7 -0
  67. package/dist/audit/relationships/ai/prompts.js +274 -0
  68. package/dist/audit/relationships/ai/prompts.js.map +7 -0
  69. package/dist/audit/relationships/analysis/balance-assessor.js +115 -0
  70. package/dist/audit/relationships/analysis/balance-assessor.js.map +7 -0
  71. package/dist/audit/relationships/analysis/coverage-analyzer.js +99 -0
  72. package/dist/audit/relationships/analysis/coverage-analyzer.js.map +7 -0
  73. package/dist/audit/relationships/analysis/duplicate-detector.js +95 -0
  74. package/dist/audit/relationships/analysis/duplicate-detector.js.map +7 -0
  75. package/dist/audit/relationships/analysis/gap-analyzer.js +99 -0
  76. package/dist/audit/relationships/analysis/gap-analyzer.js.map +7 -0
  77. package/dist/audit/relationships/analysis/layer-templates.js +294 -0
  78. package/dist/audit/relationships/analysis/layer-templates.js.map +7 -0
  79. package/dist/audit/relationships/graph/connectivity.js +129 -0
  80. package/dist/audit/relationships/graph/connectivity.js.map +7 -0
  81. package/dist/audit/relationships/graph/relationship-graph.js +179 -0
  82. package/dist/audit/relationships/graph/relationship-graph.js.map +7 -0
  83. package/dist/audit/relationships/model/balance-assessor.js +49 -0
  84. package/dist/audit/relationships/model/balance-assessor.js.map +7 -0
  85. package/dist/audit/relationships/model/coverage-analyzer.js +34 -0
  86. package/dist/audit/relationships/model/coverage-analyzer.js.map +7 -0
  87. package/dist/audit/relationships/model/duplicate-detector.js +68 -0
  88. package/dist/audit/relationships/model/duplicate-detector.js.map +7 -0
  89. package/dist/audit/relationships/model/gap-analyzer.js +41 -0
  90. package/dist/audit/relationships/model/gap-analyzer.js.map +7 -0
  91. package/dist/audit/relationships/model/orchestrator.js +126 -0
  92. package/dist/audit/relationships/model/orchestrator.js.map +7 -0
  93. package/dist/audit/relationships/spec/orchestrator.js +157 -0
  94. package/dist/audit/relationships/spec/orchestrator.js.map +7 -0
  95. package/dist/audit/reports/index.js +5 -0
  96. package/dist/audit/reports/index.js.map +7 -0
  97. package/dist/audit/reports/report-generator.js +118 -0
  98. package/dist/audit/reports/report-generator.js.map +7 -0
  99. package/dist/audit/snapshot-storage.js +163 -0
  100. package/dist/audit/snapshot-storage.js.map +7 -0
  101. package/dist/audit/types.js +21 -0
  102. package/dist/audit/types.js.map +7 -0
  103. package/dist/cli.js +223 -92
  104. package/dist/cli.js.map +3 -3
  105. package/dist/coding-agents/agents/claude-code.js +147 -0
  106. package/dist/coding-agents/agents/claude-code.js.map +7 -0
  107. package/dist/coding-agents/agents/index.js +5 -0
  108. package/dist/coding-agents/agents/index.js.map +7 -0
  109. package/dist/coding-agents/agents/types.js +1 -0
  110. package/dist/coding-agents/agents/types.js.map +7 -0
  111. package/dist/coding-agents/base-chat-client.js +45 -0
  112. package/dist/coding-agents/base-chat-client.js.map +7 -0
  113. package/dist/coding-agents/chat-utils.js +23 -0
  114. package/dist/coding-agents/chat-utils.js.map +7 -0
  115. package/dist/coding-agents/claude-code-client.js +246 -0
  116. package/dist/coding-agents/claude-code-client.js.map +7 -0
  117. package/dist/coding-agents/copilot-client.js +209 -0
  118. package/dist/coding-agents/copilot-client.js.map +7 -0
  119. package/dist/commands/add.js +95 -33
  120. package/dist/commands/add.js.map +2 -2
  121. package/dist/commands/analyzer.js +511 -0
  122. package/dist/commands/analyzer.js.map +7 -0
  123. package/dist/commands/audit-diff.js +49 -0
  124. package/dist/commands/audit-diff.js.map +7 -0
  125. package/dist/commands/audit-snapshots.js +62 -0
  126. package/dist/commands/audit-snapshots.js.map +7 -0
  127. package/dist/commands/audit.js +81 -0
  128. package/dist/commands/audit.js.map +7 -0
  129. package/dist/commands/catalog.js +248 -0
  130. package/dist/commands/catalog.js.map +7 -0
  131. package/dist/commands/changeset.js +577 -66
  132. package/dist/commands/changeset.js.map +2 -2
  133. package/dist/commands/chat.js +106 -83
  134. package/dist/commands/chat.js.map +2 -2
  135. package/dist/commands/claude.js +74 -0
  136. package/dist/commands/claude.js.map +7 -0
  137. package/dist/commands/conformance.js +71 -68
  138. package/dist/commands/conformance.js.map +2 -2
  139. package/dist/commands/copilot.js +75 -0
  140. package/dist/commands/copilot.js.map +7 -0
  141. package/dist/commands/delete.js +125 -11
  142. package/dist/commands/delete.js.map +3 -3
  143. package/dist/commands/discover-logic.js +44 -0
  144. package/dist/commands/discover-logic.js.map +7 -0
  145. package/dist/commands/docs.js +87 -0
  146. package/dist/commands/docs.js.map +7 -0
  147. package/dist/commands/element.js +14 -20
  148. package/dist/commands/element.js.map +2 -2
  149. package/dist/commands/export.js +13 -3
  150. package/dist/commands/export.js.map +2 -2
  151. package/dist/commands/import.js +51 -0
  152. package/dist/commands/import.js.map +7 -0
  153. package/dist/commands/info.js +30 -24
  154. package/dist/commands/info.js.map +2 -2
  155. package/dist/commands/init.js +27 -11
  156. package/dist/commands/init.js.map +2 -2
  157. package/dist/commands/list.js +63 -13
  158. package/dist/commands/list.js.map +3 -3
  159. package/dist/commands/relationship.js +225 -37
  160. package/dist/commands/relationship.js.map +2 -2
  161. package/dist/commands/report.js +54 -0
  162. package/dist/commands/report.js.map +7 -0
  163. package/dist/commands/reports.js +45 -0
  164. package/dist/commands/reports.js.map +7 -0
  165. package/dist/commands/schema.js +135 -0
  166. package/dist/commands/schema.js.map +7 -0
  167. package/dist/commands/search.js +40 -12
  168. package/dist/commands/search.js.map +2 -2
  169. package/dist/commands/show.js +58 -27
  170. package/dist/commands/show.js.map +2 -2
  171. package/dist/commands/stats.js +35 -0
  172. package/dist/commands/stats.js.map +7 -0
  173. package/dist/commands/trace.js +39 -16
  174. package/dist/commands/trace.js.map +2 -2
  175. package/dist/commands/update.js +141 -14
  176. package/dist/commands/update.js.map +2 -2
  177. package/dist/commands/upgrade.js +210 -46
  178. package/dist/commands/upgrade.js.map +3 -3
  179. package/dist/commands/validate.js +142 -23
  180. package/dist/commands/validate.js.map +3 -3
  181. package/dist/commands/version.js +8 -12
  182. package/dist/commands/version.js.map +2 -2
  183. package/dist/commands/visualize.js +162 -25
  184. package/dist/commands/visualize.js.map +2 -2
  185. package/dist/core/base-snapshot-manager.js +84 -0
  186. package/dist/core/base-snapshot-manager.js.map +7 -0
  187. package/dist/core/changeset-exporter.js +305 -0
  188. package/dist/core/changeset-exporter.js.map +7 -0
  189. package/dist/core/changeset-validator.js +41 -0
  190. package/dist/core/changeset-validator.js.map +7 -0
  191. package/dist/core/changeset.js +88 -173
  192. package/dist/core/changeset.js.map +2 -2
  193. package/dist/core/dependency-tracker.js +4 -2
  194. package/dist/core/dependency-tracker.js.map +2 -2
  195. package/dist/core/element.js +98 -27
  196. package/dist/core/element.js.map +2 -2
  197. package/dist/core/golden-copy-cache.js +290 -0
  198. package/dist/core/golden-copy-cache.js.map +7 -0
  199. package/dist/core/graph-model.js +266 -0
  200. package/dist/core/graph-model.js.map +7 -0
  201. package/dist/core/layer.js +159 -16
  202. package/dist/core/layer.js.map +2 -2
  203. package/dist/core/layers.js +32 -0
  204. package/dist/core/layers.js.map +7 -0
  205. package/dist/core/manifest.js +32 -11
  206. package/dist/core/manifest.js.map +2 -2
  207. package/dist/core/migration-registry.js +56 -1
  208. package/dist/core/migration-registry.js.map +2 -2
  209. package/dist/core/model.js +424 -217
  210. package/dist/core/model.js.map +3 -3
  211. package/dist/core/mutation-handler.js +179 -0
  212. package/dist/core/mutation-handler.js.map +7 -0
  213. package/dist/core/reference-registry.js +29 -21
  214. package/dist/core/reference-registry.js.map +2 -2
  215. package/dist/core/relationship-catalog.js +189 -0
  216. package/dist/core/relationship-catalog.js.map +7 -0
  217. package/dist/core/relationship-registry.js.map +2 -2
  218. package/dist/core/relationships.js.map +1 -1
  219. package/dist/core/report-data-model.js +285 -0
  220. package/dist/core/report-data-model.js.map +7 -0
  221. package/dist/core/spec-data-service.js +185 -0
  222. package/dist/core/spec-data-service.js.map +7 -0
  223. package/dist/core/spec-loader-types.js +1 -0
  224. package/dist/core/spec-loader-types.js.map +7 -0
  225. package/dist/core/spec-loader.js +234 -0
  226. package/dist/core/spec-loader.js.map +7 -0
  227. package/dist/core/staged-changeset-storage.js +282 -0
  228. package/dist/core/staged-changeset-storage.js.map +7 -0
  229. package/dist/core/staging-area.js +1002 -0
  230. package/dist/core/staging-area.js.map +7 -0
  231. package/dist/core/stats-collector.js +169 -0
  232. package/dist/core/stats-collector.js.map +7 -0
  233. package/dist/core/virtual-projection.js +443 -0
  234. package/dist/core/virtual-projection.js.map +7 -0
  235. package/dist/export/archimate-exporter.js +99 -60
  236. package/dist/export/archimate-exporter.js.map +2 -2
  237. package/dist/export/audit-formatters.js +479 -0
  238. package/dist/export/audit-formatters.js.map +7 -0
  239. package/dist/export/diff-formatters.js +99 -0
  240. package/dist/export/diff-formatters.js.map +7 -0
  241. package/dist/export/export-manager.js.map +2 -2
  242. package/dist/export/graphml-exporter.js +44 -27
  243. package/dist/export/graphml-exporter.js.map +2 -2
  244. package/dist/export/index.js +4 -0
  245. package/dist/export/index.js.map +2 -2
  246. package/dist/export/json-schema-exporter.js +55 -42
  247. package/dist/export/json-schema-exporter.js.map +2 -2
  248. package/dist/export/markdown-exporter.js +92 -70
  249. package/dist/export/markdown-exporter.js.map +2 -2
  250. package/dist/export/markdown-generator.js +248 -0
  251. package/dist/export/markdown-generator.js.map +7 -0
  252. package/dist/export/markdown-utils.js +30 -0
  253. package/dist/export/markdown-utils.js.map +7 -0
  254. package/dist/export/mermaid-markdown-exporter.js +37 -0
  255. package/dist/export/mermaid-markdown-exporter.js.map +7 -0
  256. package/dist/export/openapi-exporter.js +119 -71
  257. package/dist/export/openapi-exporter.js.map +2 -2
  258. package/dist/export/plantuml-exporter.js +104 -39
  259. package/dist/export/plantuml-exporter.js.map +2 -2
  260. package/dist/export/report-formatters.js +111 -0
  261. package/dist/export/report-formatters.js.map +7 -0
  262. package/dist/export/stats-formatters.js +98 -0
  263. package/dist/export/stats-formatters.js.map +7 -0
  264. package/dist/export/types.js +2 -14
  265. package/dist/export/types.js.map +2 -2
  266. package/dist/export/verify-formatters.js +153 -0
  267. package/dist/export/verify-formatters.js.map +7 -0
  268. package/dist/generated/compiled-validators.js +17 -0
  269. package/dist/generated/compiled-validators.js.map +7 -0
  270. package/dist/generated/index.js +31 -0
  271. package/dist/generated/index.js.map +7 -0
  272. package/dist/generated/layer-registry.js +190 -0
  273. package/dist/generated/layer-registry.js.map +7 -0
  274. package/dist/generated/layer-types.js +7 -0
  275. package/dist/generated/layer-types.js.map +7 -0
  276. package/dist/generated/node-types.js +1719 -0
  277. package/dist/generated/node-types.js.map +7 -0
  278. package/dist/generated/relationship-index.js +14552 -0
  279. package/dist/generated/relationship-index.js.map +7 -0
  280. package/dist/import/archimate-importer.js +166 -0
  281. package/dist/import/archimate-importer.js.map +7 -0
  282. package/dist/import/index.js +47 -0
  283. package/dist/import/index.js.map +7 -0
  284. package/dist/import/openapi-importer.js +143 -0
  285. package/dist/import/openapi-importer.js.map +7 -0
  286. package/dist/import/types.js +1 -0
  287. package/dist/import/types.js.map +7 -0
  288. package/dist/integrations/base-manager.js +311 -0
  289. package/dist/integrations/base-manager.js.map +7 -0
  290. package/dist/integrations/claude-manager.js +360 -0
  291. package/dist/integrations/claude-manager.js.map +7 -0
  292. package/dist/integrations/claude_code/agents/dr-advisor.md +253 -0
  293. package/dist/integrations/claude_code/agents/dr-architect.md +278 -0
  294. package/dist/integrations/claude_code/agents/dr-extractor.md +286 -0
  295. package/dist/integrations/claude_code/commands/dr-changeset.md +657 -0
  296. package/dist/integrations/claude_code/commands/dr-design.md +373 -0
  297. package/dist/integrations/claude_code/commands/dr-info.md +132 -0
  298. package/dist/integrations/claude_code/commands/dr-init.md +251 -0
  299. package/dist/integrations/claude_code/commands/dr-map.md +936 -0
  300. package/dist/integrations/claude_code/commands/dr-model.md +493 -0
  301. package/dist/integrations/claude_code/commands/dr-relate.md +814 -0
  302. package/dist/integrations/claude_code/commands/dr-sync.md +279 -0
  303. package/dist/integrations/claude_code/commands/dr-validate.md +654 -0
  304. package/dist/integrations/claude_code/commands/dr-verify.md +559 -0
  305. package/dist/integrations/claude_code/docs/END_TO_END_WALKTHROUGH.md +903 -0
  306. package/dist/integrations/claude_code/docs/QUICK_START.md +271 -0
  307. package/dist/integrations/claude_code/docs/README.md +347 -0
  308. package/dist/integrations/claude_code/skills/dr_01_motivation_layer/SKILL.md +550 -0
  309. package/dist/integrations/claude_code/skills/dr_02_business_layer/SKILL.md +620 -0
  310. package/dist/integrations/claude_code/skills/dr_03_security_layer/SKILL.md +642 -0
  311. package/dist/integrations/claude_code/skills/dr_04_application_layer/SKILL.md +911 -0
  312. package/dist/integrations/claude_code/skills/dr_05_technology_layer/SKILL.md +836 -0
  313. package/dist/integrations/claude_code/skills/dr_06_api_layer/SKILL.md +933 -0
  314. package/dist/integrations/claude_code/skills/dr_07_data_model_layer/SKILL.md +210 -0
  315. package/dist/integrations/claude_code/skills/dr_08_dataset_layer/SKILL.md +319 -0
  316. package/dist/integrations/claude_code/skills/dr_09_ux_layer/SKILL.md +319 -0
  317. package/dist/integrations/claude_code/skills/dr_10_navigation_layer/SKILL.md +318 -0
  318. package/dist/integrations/claude_code/skills/dr_11_apm_layer/SKILL.md +273 -0
  319. package/dist/integrations/claude_code/skills/dr_12_testing_layer/SKILL.md +273 -0
  320. package/dist/integrations/claude_code/skills/dr_changeset_reviewer/SKILL.md +187 -0
  321. package/dist/integrations/claude_code/skills/dr_codebase_memory/SKILL.md +590 -0
  322. package/dist/integrations/claude_code/skills/dr_engineering_guide/SKILL.md +295 -0
  323. package/dist/integrations/copilot-manager.js +328 -0
  324. package/dist/integrations/copilot-manager.js.map +7 -0
  325. package/dist/integrations/github_copilot/agents/dr-advisor.md +243 -0
  326. package/dist/integrations/github_copilot/agents/dr-architect.md +1567 -0
  327. package/dist/integrations/github_copilot/skills/dr_01_motivation_layer/SKILL.md +491 -0
  328. package/dist/integrations/github_copilot/skills/dr_02_business_layer/SKILL.md +539 -0
  329. package/dist/integrations/github_copilot/skills/dr_03_security_layer/SKILL.md +667 -0
  330. package/dist/integrations/github_copilot/skills/dr_04_application_layer/SKILL.md +670 -0
  331. package/dist/integrations/github_copilot/skills/dr_05_technology_layer/SKILL.md +660 -0
  332. package/dist/integrations/github_copilot/skills/dr_06_api_layer/SKILL.md +855 -0
  333. package/dist/integrations/github_copilot/skills/dr_07_data_model_layer/SKILL.md +171 -0
  334. package/dist/integrations/github_copilot/skills/dr_08_dataset_layer/SKILL.md +216 -0
  335. package/dist/integrations/github_copilot/skills/dr_09_ux_layer/SKILL.md +230 -0
  336. package/dist/integrations/github_copilot/skills/dr_10_navigation_layer/SKILL.md +228 -0
  337. package/dist/integrations/github_copilot/skills/dr_11_apm_layer/SKILL.md +234 -0
  338. package/dist/integrations/github_copilot/skills/dr_12_testing_layer/SKILL.md +230 -0
  339. package/dist/integrations/github_copilot/skills/dr_changeset_reviewer/SKILL.md +187 -0
  340. package/dist/integrations/hash-utils.js +51 -0
  341. package/dist/integrations/hash-utils.js.map +7 -0
  342. package/dist/integrations/types.js +16 -0
  343. package/dist/integrations/types.js.map +7 -0
  344. package/dist/reports/model-layer-report-generator.js +278 -0
  345. package/dist/reports/model-layer-report-generator.js.map +7 -0
  346. package/dist/reports/model-report-data.js +57 -0
  347. package/dist/reports/model-report-data.js.map +7 -0
  348. package/dist/reports/model-report-orchestrator.js +103 -0
  349. package/dist/reports/model-report-orchestrator.js.map +7 -0
  350. package/dist/schemas/bundled/analyzers/cbm.json +595 -0
  351. package/dist/schemas/bundled/analyzers/manifest.json +9 -0
  352. package/dist/schemas/bundled/api.json +3411 -0
  353. package/dist/schemas/bundled/apm.json +2371 -0
  354. package/dist/schemas/bundled/application.json +1253 -0
  355. package/dist/schemas/bundled/base.json +1622 -0
  356. package/dist/schemas/bundled/business.json +1279 -0
  357. package/dist/schemas/bundled/data-model.json +1298 -0
  358. package/dist/schemas/bundled/data-store.json +2025 -0
  359. package/dist/schemas/bundled/manifest.json +93 -0
  360. package/dist/schemas/bundled/motivation.json +1360 -0
  361. package/dist/schemas/bundled/navigation.json +1874 -0
  362. package/dist/schemas/bundled/security.json +3488 -0
  363. package/dist/schemas/bundled/technology.json +2067 -0
  364. package/dist/schemas/bundled/testing.json +3120 -0
  365. package/dist/schemas/bundled/ux.json +3592 -0
  366. package/dist/server/schemas.js +202 -0
  367. package/dist/server/schemas.js.map +7 -0
  368. package/dist/server/server.js +1336 -252
  369. package/dist/server/server.js.map +3 -3
  370. package/dist/server/telemetry-middleware.js +22 -15
  371. package/dist/server/telemetry-middleware.js.map +2 -2
  372. package/dist/server-entry.js +65 -0
  373. package/dist/server-entry.js.map +7 -0
  374. package/dist/telemetry/config.js +89 -0
  375. package/dist/telemetry/config.js.map +7 -0
  376. package/dist/telemetry/console-interceptor.js.map +1 -1
  377. package/dist/telemetry/detect.js +24 -0
  378. package/dist/telemetry/detect.js.map +7 -0
  379. package/dist/telemetry/fetch-otlp-exporter.js +112 -0
  380. package/dist/telemetry/fetch-otlp-exporter.js.map +7 -0
  381. package/dist/telemetry/index.js +153 -3
  382. package/dist/telemetry/index.js.map +2 -2
  383. package/dist/telemetry/resilient-exporter.js +22 -8
  384. package/dist/telemetry/resilient-exporter.js.map +2 -2
  385. package/dist/telemetry/resilient-log-exporter.js +17 -8
  386. package/dist/telemetry/resilient-log-exporter.js.map +2 -2
  387. package/dist/telemetry/test-instrumentation.js.map +2 -2
  388. package/dist/types/index.js +84 -0
  389. package/dist/types/index.js.map +3 -3
  390. package/dist/types/source-reference.js +1 -0
  391. package/dist/types/source-reference.js.map +7 -0
  392. package/dist/utils/chat-logger.js +292 -0
  393. package/dist/utils/chat-logger.js.map +7 -0
  394. package/dist/utils/claude-stream.js +8 -0
  395. package/dist/utils/claude-stream.js.map +7 -0
  396. package/dist/utils/date-utils.js +7 -0
  397. package/dist/utils/date-utils.js.map +7 -0
  398. package/dist/utils/element-utils.js.map +1 -1
  399. package/dist/utils/errors.js +88 -15
  400. package/dist/utils/errors.js.map +3 -3
  401. package/dist/utils/export-python-annotations.js +82 -0
  402. package/dist/utils/export-python-annotations.js.map +7 -0
  403. package/dist/utils/file-io.js +7 -2
  404. package/dist/utils/file-io.js.map +2 -2
  405. package/dist/utils/file-lock.js +156 -0
  406. package/dist/utils/file-lock.js.map +7 -0
  407. package/dist/utils/id-generator.js +18 -0
  408. package/dist/utils/id-generator.js.map +7 -0
  409. package/dist/utils/layer-name-formatter.js +16 -0
  410. package/dist/utils/layer-name-formatter.js.map +7 -0
  411. package/dist/utils/markdown-anchor.js +7 -0
  412. package/dist/utils/markdown-anchor.js.map +7 -0
  413. package/dist/utils/markdown-link.js +12 -0
  414. package/dist/utils/markdown-link.js.map +7 -0
  415. package/dist/utils/markdown-table.js +17 -0
  416. package/dist/utils/markdown-table.js.map +7 -0
  417. package/dist/utils/mermaid-utils.js +11 -0
  418. package/dist/utils/mermaid-utils.js.map +7 -0
  419. package/dist/utils/project-paths.js.map +2 -2
  420. package/dist/utils/source-reference.js +52 -0
  421. package/dist/utils/source-reference.js.map +7 -0
  422. package/dist/utils/spec-installer.js +40 -53
  423. package/dist/utils/spec-installer.js.map +2 -2
  424. package/dist/utils/spec-version.js +5 -1
  425. package/dist/utils/spec-version.js.map +2 -2
  426. package/dist/utils/string-utils.js +12 -0
  427. package/dist/utils/string-utils.js.map +7 -0
  428. package/dist/utils/table-formatting.js +19 -0
  429. package/dist/utils/table-formatting.js.map +7 -0
  430. package/dist/validators/index.js +4 -0
  431. package/dist/validators/index.js.map +2 -2
  432. package/dist/validators/naming-validator.js +20 -23
  433. package/dist/validators/naming-validator.js.map +2 -2
  434. package/dist/validators/reference-validator.js +23 -38
  435. package/dist/validators/reference-validator.js.map +2 -2
  436. package/dist/validators/relationship-schema-validator.js +243 -0
  437. package/dist/validators/relationship-schema-validator.js.map +7 -0
  438. package/dist/validators/schema-validator.js +168 -68
  439. package/dist/validators/schema-validator.js.map +2 -2
  440. package/dist/validators/semantic-validator.js +36 -60
  441. package/dist/validators/semantic-validator.js.map +2 -2
  442. package/dist/validators/types.js.map +2 -2
  443. package/dist/validators/validation-formatter.js +159 -0
  444. package/dist/validators/validation-formatter.js.map +7 -0
  445. package/dist/validators/validator.js +24 -38
  446. package/dist/validators/validator.js.map +2 -2
  447. package/dist/viewer/README.md +139 -0
  448. package/dist/viewer/assets/main-CY0Xufuj.css +1 -0
  449. package/dist/viewer/assets/main-DtgErnwF.js +81 -0
  450. package/dist/viewer/assets/vendor-CxKvDp2x.js +17 -0
  451. package/dist/viewer/favicon.svg +11 -0
  452. package/dist/viewer/fonts/inter/Inter-Black.woff2 +0 -0
  453. package/dist/viewer/fonts/inter/Inter-Bold.woff2 +0 -0
  454. package/dist/viewer/fonts/inter/Inter-ExtraBold.woff2 +0 -0
  455. package/dist/viewer/fonts/inter/Inter-Light.woff2 +0 -0
  456. package/dist/viewer/fonts/inter/Inter-Medium.woff2 +0 -0
  457. package/dist/viewer/fonts/inter/Inter-Regular.woff2 +0 -0
  458. package/dist/viewer/fonts/inter/Inter-SemiBold.woff2 +0 -0
  459. package/dist/viewer/fonts/jetbrains-mono/JetBrainsMono-Medium.woff2 +0 -0
  460. package/dist/viewer/fonts/jetbrains-mono/JetBrainsMono-Regular.woff2 +0 -0
  461. package/dist/viewer/fonts/jetbrains-mono/JetBrainsMono-SemiBold.woff2 +0 -0
  462. package/dist/viewer/index.html +15 -0
  463. package/dist/viewer/manifest.json +99 -0
  464. package/dist/viewer/version.json +1 -0
  465. package/package.json +42 -16
  466. package/PYTHON_CLI_PARITY.md +0 -265
  467. package/PYTHON_CLI_STRUCTURE_UPDATE.md +0 -246
  468. package/biome.json +0 -42
  469. package/bunfig.toml +0 -3
  470. package/dist/ai/claude-client.js +0 -71
  471. package/dist/ai/claude-client.js.map +0 -7
  472. package/dist/ai/context-provider.js +0 -129
  473. package/dist/ai/context-provider.js.map +0 -7
  474. package/dist/ai/tools.js +0 -231
  475. package/dist/ai/tools.js.map +0 -7
  476. package/dist/commands/migrate.js +0 -36
  477. package/dist/commands/migrate.js.map +0 -7
  478. package/dist/commands/project.js +0 -74
  479. package/dist/commands/project.js.map +0 -7
  480. package/dist/core/active-changeset.js +0 -52
  481. package/dist/core/active-changeset.js.map +0 -7
  482. package/dist/core/projection-engine.js +0 -288
  483. package/dist/core/projection-engine.js.map +0 -7
  484. package/dist/schemas/bundled/01-motivation-layer.schema.json +0 -942
  485. package/dist/schemas/bundled/02-business-layer.schema.json +0 -1293
  486. package/dist/schemas/bundled/03-security-layer.schema.json +0 -2177
  487. package/dist/schemas/bundled/04-application-layer.schema.json +0 -1328
  488. package/dist/schemas/bundled/05-technology-layer.schema.json +0 -1465
  489. package/dist/schemas/bundled/06-api-layer.schema.json +0 -1743
  490. package/dist/schemas/bundled/07-data-model-layer.schema.json +0 -1253
  491. package/dist/schemas/bundled/08-datastore-layer.schema.json +0 -892
  492. package/dist/schemas/bundled/09-ux-layer.schema.json +0 -1506
  493. package/dist/schemas/bundled/10-navigation-layer.schema.json +0 -843
  494. package/dist/schemas/bundled/11-apm-observability-layer.schema.json +0 -1430
  495. package/dist/schemas/bundled/12-testing-layer.schema.json +0 -1091
  496. package/dist/schemas/bundled/common/layer-extensions.schema.json +0 -266
  497. package/dist/schemas/bundled/common/predicates.schema.json +0 -493
  498. package/dist/schemas/bundled/common/relationships.schema.json +0 -791
  499. package/dist/schemas/bundled/common/source-references.schema.json +0 -71
  500. package/dist/schemas/bundled/link-registry.json +0 -1839
  501. package/dist/schemas/bundled/link-registry.schema.json +0 -339
  502. package/dist/schemas/bundled/relationship-catalog.json +0 -1302
  503. package/dist/schemas/bundled/relationship-type.schema.json +0 -221
  504. package/dist/utils/model-path.js +0 -22
  505. package/dist/utils/model-path.js.map +0 -7
  506. package/docs/TEST-INSTRUMENTATION.md +0 -405
  507. package/docs/telemetry.md +0 -427
  508. package/test-debug.js +0 -33
  509. package/test-special.mjs +0 -46
  510. package/test_runner.ts +0 -7
@@ -0,0 +1,189 @@
1
+ import path from "node:path";
2
+ import { fileURLToPath } from "url";
3
+ import fs from "node:fs/promises";
4
+ import { glob } from "glob";
5
+ import { getErrorMessage } from "../utils/errors.js";
6
+ class RelationshipCatalog {
7
+ predicatesData = null;
8
+ relationshipTypes = null;
9
+ predicatesPath;
10
+ relationshipSchemasPath;
11
+ constructor(predicatesPath, relationshipSchemasPath) {
12
+ this.predicatesPath = predicatesPath || this.getDefaultPredicatesPath(), this.relationshipSchemasPath = relationshipSchemasPath || this.getDefaultRelationshipSchemasPath();
13
+ }
14
+ /**
15
+ * Get default path to base.json (contains predicates under .predicates key)
16
+ */
17
+ getDefaultPredicatesPath() {
18
+ const currentDir = path.dirname(fileURLToPath(import.meta.url));
19
+ return path.join(currentDir, "../schemas/bundled/base.json");
20
+ }
21
+ /**
22
+ * Get default path to bundled schemas directory (contains manifest.json + per-layer JSON files)
23
+ */
24
+ getDefaultRelationshipSchemasPath() {
25
+ const currentDir = path.dirname(fileURLToPath(import.meta.url));
26
+ return path.join(currentDir, "../schemas/bundled");
27
+ }
28
+ /**
29
+ * Load predicates and compute derived metadata
30
+ */
31
+ async load() {
32
+ try {
33
+ const content = await fs.readFile(this.predicatesPath, "utf-8"), parsed = JSON.parse(content);
34
+ this.predicatesData = parsed.predicates !== void 0 ? { predicates: parsed.predicates } : parsed;
35
+ } catch (error) {
36
+ try {
37
+ const fallbackPath = path.join(path.dirname(fileURLToPath(import.meta.url)), "../../../spec/schemas/base/predicates.json"), content = await fs.readFile(fallbackPath, "utf-8");
38
+ this.predicatesData = JSON.parse(content), this.predicatesPath = fallbackPath, console.debug(`Loaded predicates from fallback path: ${fallbackPath}`);
39
+ } catch {
40
+ throw new Error(`Failed to load predicates from ${this.predicatesPath}: ${getErrorMessage(error)}`);
41
+ }
42
+ }
43
+ const applicableLayersByPredicate = await this.computeApplicableLayers();
44
+ this.relationshipTypes = Object.entries(this.predicatesData.predicates).map(([key, pred]) => ({
45
+ id: key,
46
+ predicate: pred.predicate,
47
+ inversePredicate: pred.inverse,
48
+ category: pred.category,
49
+ archimateAlignment: pred.archimate_alignment,
50
+ description: pred.description,
51
+ semantics: pred.semantics,
52
+ applicableLayers: applicableLayersByPredicate[pred.predicate] || [],
53
+ examples: []
54
+ // Examples are documentation, not stored in predicates
55
+ }));
56
+ }
57
+ /**
58
+ * Compute which layers each predicate is used in by reading compiled layer dist files
59
+ */
60
+ async computeApplicableLayers() {
61
+ const layersByPredicate = {};
62
+ try {
63
+ const manifestPath = path.join(this.relationshipSchemasPath, "manifest.json");
64
+ await fs.access(manifestPath);
65
+ const manifestContent = await fs.readFile(manifestPath, "utf-8"), manifest = JSON.parse(manifestContent);
66
+ for (const { id: layerId } of manifest.layers) {
67
+ const layerPath = path.join(this.relationshipSchemasPath, `${layerId}.json`);
68
+ try {
69
+ await fs.access(layerPath);
70
+ const layerContent = await fs.readFile(layerPath, "utf-8"), layerData = JSON.parse(layerContent);
71
+ for (const relSchema of Object.values(layerData.relationshipSchemas || {})) {
72
+ const { predicate, source_layer } = relSchema;
73
+ predicate && source_layer && (layersByPredicate[predicate] || (layersByPredicate[predicate] = /* @__PURE__ */ new Set()), layersByPredicate[predicate].add(source_layer));
74
+ }
75
+ } catch {
76
+ }
77
+ }
78
+ } catch {
79
+ const fallbackPath = path.join(path.dirname(fileURLToPath(import.meta.url)), "../../../spec/schemas/relationships");
80
+ try {
81
+ await fs.access(fallbackPath);
82
+ const relationshipFiles = await glob(`${fallbackPath}/**/*.relationship.schema.json`);
83
+ for (const file of relationshipFiles)
84
+ try {
85
+ const content = await fs.readFile(file, "utf-8"), schema = JSON.parse(content), predicate = schema.properties?.predicate?.const, sourceLayer = schema.properties?.source_layer?.const;
86
+ predicate && sourceLayer && (layersByPredicate[predicate] || (layersByPredicate[predicate] = /* @__PURE__ */ new Set()), layersByPredicate[predicate].add(sourceLayer));
87
+ } catch {
88
+ continue;
89
+ }
90
+ } catch {
91
+ return {};
92
+ }
93
+ }
94
+ const result = {};
95
+ for (const [predicate, layers] of Object.entries(layersByPredicate))
96
+ result[predicate] = Array.from(layers).sort();
97
+ return result;
98
+ }
99
+ /**
100
+ * Ensure catalog is loaded
101
+ */
102
+ ensureLoaded() {
103
+ if (!this.relationshipTypes)
104
+ throw new Error("Relationship catalog not loaded. Call load() first.");
105
+ }
106
+ /**
107
+ * Get all relationship types
108
+ */
109
+ getAllTypes() {
110
+ return this.ensureLoaded(), this.relationshipTypes;
111
+ }
112
+ /**
113
+ * Get relationship type by ID
114
+ */
115
+ getTypeById(id) {
116
+ return this.ensureLoaded(), this.relationshipTypes.find((t) => t.id === id);
117
+ }
118
+ /**
119
+ * Get relationship type by predicate
120
+ */
121
+ getTypeByPredicate(predicate) {
122
+ return this.ensureLoaded(), this.relationshipTypes.find((t) => t.predicate === predicate || t.inversePredicate === predicate);
123
+ }
124
+ /**
125
+ * Get relationship types by category
126
+ */
127
+ getTypesByCategory(category) {
128
+ return this.ensureLoaded(), this.relationshipTypes.filter((t) => t.category === category);
129
+ }
130
+ /**
131
+ * Get relationship types applicable to a layer
132
+ */
133
+ getTypesForLayer(layer) {
134
+ this.ensureLoaded();
135
+ const normalizedLayer = layer.replace(/^0+/, "");
136
+ return this.relationshipTypes.filter((t) => t.applicableLayers.some((l) => l === layer || l === normalizedLayer || l.replace(/^0+/, "") === normalizedLayer));
137
+ }
138
+ /**
139
+ * Get all categories
140
+ */
141
+ getCategories() {
142
+ this.ensureLoaded();
143
+ const categories = {}, categoryCounts = {};
144
+ for (const type of this.relationshipTypes)
145
+ categoryCounts[type.category] || (categoryCounts[type.category] = 0, categories[type.category] = {
146
+ name: type.category.charAt(0).toUpperCase() + type.category.slice(1),
147
+ description: `${type.category} relationships`
148
+ }), categoryCounts[type.category]++;
149
+ return categories;
150
+ }
151
+ /**
152
+ * Get statistics about the catalog
153
+ */
154
+ getStats() {
155
+ this.ensureLoaded();
156
+ const categoryCounts = {};
157
+ let archimateAligned = 0;
158
+ for (const type of this.relationshipTypes)
159
+ categoryCounts[type.category] = (categoryCounts[type.category] || 0) + 1, type.archimateAlignment && archimateAligned++;
160
+ return {
161
+ totalTypes: this.relationshipTypes.length,
162
+ categoryCounts,
163
+ archimateAligned
164
+ };
165
+ }
166
+ /**
167
+ * Get catalog metadata
168
+ */
169
+ getMetadata() {
170
+ return this.ensureLoaded(), {
171
+ version: "1.0.0",
172
+ generatedBy: "relationship-catalog (predicates.json)",
173
+ lastUpdated: (/* @__PURE__ */ new Date()).toISOString(),
174
+ totalTypes: this.relationshipTypes.length
175
+ };
176
+ }
177
+ /**
178
+ * Search relationship types by keyword
179
+ */
180
+ search(keyword) {
181
+ this.ensureLoaded();
182
+ const lowerKeyword = keyword.toLowerCase();
183
+ return this.relationshipTypes.filter((t) => t.id.toLowerCase().includes(lowerKeyword) || t.predicate.toLowerCase().includes(lowerKeyword) || t.inversePredicate && t.inversePredicate.toLowerCase().includes(lowerKeyword) || t.description.toLowerCase().includes(lowerKeyword) || t.category.toLowerCase().includes(lowerKeyword));
184
+ }
185
+ }
186
+ export {
187
+ RelationshipCatalog
188
+ };
189
+ //# sourceMappingURL=relationship-catalog.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/core/relationship-catalog.ts"],
4
+ "sourcesContent": ["/**\n * Relationship Catalog - Manages catalog of semantic relationship types\n *\n * Loads predicates from spec/schemas/base/predicates.json and computes\n * derived metadata (applicableLayers) by scanning relationship schemas.\n */\n\nimport path from \"node:path\";\nimport { fileURLToPath } from \"url\";\nimport fs from \"node:fs/promises\";\nimport { glob } from \"glob\";\nimport { getErrorMessage } from \"../utils/errors.js\";\n\n/**\n * Directionality of a relationship\n */\nexport type Directionality = \"unidirectional\" | \"bidirectional\";\n\nexport interface RelationshipSemantics {\n directionality: Directionality;\n transitivity: boolean;\n symmetry: boolean;\n reflexivity?: boolean;\n}\n\nexport interface RelationshipExample {\n source: string;\n target: string;\n description: string;\n layer?: string;\n}\n\nexport interface RelationshipType {\n id: string;\n predicate: string;\n inversePredicate: string | null;\n category: string;\n archimateAlignment: string | null;\n description: string;\n semantics: RelationshipSemantics;\n applicableLayers: string[]; // Computed from relationship schemas\n examples: RelationshipExample[]; // Empty for now\n}\n\nexport interface PredicateDefinition {\n predicate: string;\n inverse: string;\n category: string;\n description: string;\n archimate_alignment: string | null;\n semantics: RelationshipSemantics;\n}\n\nexport interface PredicatesData {\n predicates: Record<string, PredicateDefinition>;\n}\n\nexport interface CategoryInfo {\n name: string;\n description: string;\n color?: string;\n}\n\n/**\n * Relationship catalog providing access to semantic relationship type definitions\n */\nexport class RelationshipCatalog {\n private predicatesData: PredicatesData | null = null;\n private relationshipTypes: RelationshipType[] | null = null;\n private predicatesPath: string;\n private relationshipSchemasPath: string;\n\n constructor(predicatesPath?: string, relationshipSchemasPath?: string) {\n this.predicatesPath = predicatesPath || this.getDefaultPredicatesPath();\n this.relationshipSchemasPath = relationshipSchemasPath || this.getDefaultRelationshipSchemasPath();\n }\n\n /**\n * Get default path to base.json (contains predicates under .predicates key)\n */\n private getDefaultPredicatesPath(): string {\n const currentDir = path.dirname(fileURLToPath(import.meta.url));\n return path.join(currentDir, \"../schemas/bundled/base.json\");\n }\n\n /**\n * Get default path to bundled schemas directory (contains manifest.json + per-layer JSON files)\n */\n private getDefaultRelationshipSchemasPath(): string {\n const currentDir = path.dirname(fileURLToPath(import.meta.url));\n return path.join(currentDir, \"../schemas/bundled\");\n }\n\n /**\n * Load predicates and compute derived metadata\n */\n async load(): Promise<void> {\n // Load predicates \u2014 supports both base.json format (has .predicates key) and direct predicates.json\n try {\n const content = await fs.readFile(this.predicatesPath, \"utf-8\");\n const parsed = JSON.parse(content);\n // base.json has { specVersion, schemas, predicates } \u2014 extract .predicates key\n // predicates.json has { predicates } directly\n // In both cases, .predicates is the dict of PredicateDefinition objects\n this.predicatesData = parsed.predicates !== undefined\n ? { predicates: parsed.predicates }\n : parsed;\n } catch (error) {\n // Try fallback path (direct predicates.json in spec source tree)\n try {\n const fallbackPath = path.join(\n path.dirname(fileURLToPath(import.meta.url)),\n \"../../../spec/schemas/base/predicates.json\"\n );\n const content = await fs.readFile(fallbackPath, \"utf-8\");\n this.predicatesData = JSON.parse(content);\n this.predicatesPath = fallbackPath;\n console.debug(`Loaded predicates from fallback path: ${fallbackPath}`);\n } catch {\n throw new Error(\n `Failed to load predicates from ${this.predicatesPath}: ${getErrorMessage(error)}`\n );\n }\n }\n\n // Compute applicableLayers by scanning relationship schemas\n const applicableLayersByPredicate = await this.computeApplicableLayers();\n\n // Convert predicates to RelationshipType format\n this.relationshipTypes = Object.entries(this.predicatesData!.predicates).map(([key, pred]) => ({\n id: key,\n predicate: pred.predicate,\n inversePredicate: pred.inverse,\n category: pred.category,\n archimateAlignment: pred.archimate_alignment,\n description: pred.description,\n semantics: pred.semantics,\n applicableLayers: applicableLayersByPredicate[pred.predicate] || [],\n examples: [], // Examples are documentation, not stored in predicates\n }));\n }\n\n /**\n * Compute which layers each predicate is used in by reading compiled layer dist files\n */\n private async computeApplicableLayers(): Promise<Record<string, string[]>> {\n const layersByPredicate: Record<string, Set<string>> = {};\n\n try {\n // Try compiled bundled format (manifest.json + per-layer JSON files)\n const manifestPath = path.join(this.relationshipSchemasPath, \"manifest.json\");\n await fs.access(manifestPath);\n\n const manifestContent = await fs.readFile(manifestPath, \"utf-8\");\n const manifest = JSON.parse(manifestContent) as { layers: Array<{ id: string }> };\n\n for (const { id: layerId } of manifest.layers) {\n const layerPath = path.join(this.relationshipSchemasPath, `${layerId}.json`);\n try {\n await fs.access(layerPath);\n const layerContent = await fs.readFile(layerPath, \"utf-8\");\n const layerData = JSON.parse(layerContent) as {\n relationshipSchemas: Record<string, { predicate: string; source_layer: string }>;\n };\n\n for (const relSchema of Object.values(layerData.relationshipSchemas || {})) {\n const { predicate, source_layer } = relSchema;\n if (predicate && source_layer) {\n if (!layersByPredicate[predicate]) {\n layersByPredicate[predicate] = new Set();\n }\n layersByPredicate[predicate].add(source_layer);\n }\n }\n } catch {\n // Skip missing or malformed layer files\n }\n }\n } catch {\n // Fall back to spec source tree (development environment)\n const fallbackPath = path.join(\n path.dirname(fileURLToPath(import.meta.url)),\n \"../../../spec/schemas/relationships\"\n );\n try {\n await fs.access(fallbackPath);\n const relationshipFiles = await glob(`${fallbackPath}/**/*.relationship.schema.json`);\n\n for (const file of relationshipFiles) {\n try {\n const content = await fs.readFile(file, \"utf-8\");\n const schema = JSON.parse(content);\n const predicate = schema.properties?.predicate?.const;\n const sourceLayer = schema.properties?.source_layer?.const;\n\n if (predicate && sourceLayer) {\n if (!layersByPredicate[predicate]) {\n layersByPredicate[predicate] = new Set();\n }\n layersByPredicate[predicate].add(sourceLayer);\n }\n } catch {\n continue;\n }\n }\n } catch {\n // No relationship schemas found, return empty\n return {};\n }\n }\n\n // Convert Sets to sorted arrays\n const result: Record<string, string[]> = {};\n for (const [predicate, layers] of Object.entries(layersByPredicate)) {\n result[predicate] = Array.from(layers).sort();\n }\n\n return result;\n }\n\n /**\n * Ensure catalog is loaded\n */\n private ensureLoaded(): void {\n if (!this.relationshipTypes) {\n throw new Error(\"Relationship catalog not loaded. Call load() first.\");\n }\n }\n\n /**\n * Get all relationship types\n */\n getAllTypes(): RelationshipType[] {\n this.ensureLoaded();\n return this.relationshipTypes!;\n }\n\n /**\n * Get relationship type by ID\n */\n getTypeById(id: string): RelationshipType | undefined {\n this.ensureLoaded();\n return this.relationshipTypes!.find((t) => t.id === id);\n }\n\n /**\n * Get relationship type by predicate\n */\n getTypeByPredicate(predicate: string): RelationshipType | undefined {\n this.ensureLoaded();\n return this.relationshipTypes!.find(\n (t) => t.predicate === predicate || t.inversePredicate === predicate\n );\n }\n\n /**\n * Get relationship types by category\n */\n getTypesByCategory(category: string): RelationshipType[] {\n this.ensureLoaded();\n return this.relationshipTypes!.filter((t) => t.category === category);\n }\n\n /**\n * Get relationship types applicable to a layer\n */\n getTypesForLayer(layer: string): RelationshipType[] {\n this.ensureLoaded();\n // Normalize layer format (remove leading zeros if present)\n const normalizedLayer = layer.replace(/^0+/, \"\");\n\n return this.relationshipTypes!.filter((t) =>\n t.applicableLayers.some(\n (l) => l === layer || l === normalizedLayer || l.replace(/^0+/, \"\") === normalizedLayer\n )\n );\n }\n\n /**\n * Get all categories\n */\n getCategories(): Record<string, CategoryInfo> {\n this.ensureLoaded();\n\n // Derive categories from relationship types\n const categories: Record<string, CategoryInfo> = {};\n const categoryCounts: Record<string, number> = {};\n\n for (const type of this.relationshipTypes!) {\n if (!categoryCounts[type.category]) {\n categoryCounts[type.category] = 0;\n categories[type.category] = {\n name: type.category.charAt(0).toUpperCase() + type.category.slice(1),\n description: `${type.category} relationships`,\n };\n }\n categoryCounts[type.category]++;\n }\n\n return categories;\n }\n\n /**\n * Get statistics about the catalog\n */\n getStats(): {\n totalTypes: number;\n categoryCounts: Record<string, number>;\n archimateAligned: number;\n } {\n this.ensureLoaded();\n\n const categoryCounts: Record<string, number> = {};\n let archimateAligned = 0;\n\n for (const type of this.relationshipTypes!) {\n categoryCounts[type.category] = (categoryCounts[type.category] || 0) + 1;\n if (type.archimateAlignment) {\n archimateAligned++;\n }\n }\n\n return {\n totalTypes: this.relationshipTypes!.length,\n categoryCounts,\n archimateAligned,\n };\n }\n\n /**\n * Get catalog metadata\n */\n getMetadata(): {\n version: string;\n generatedBy: string;\n lastUpdated: string;\n totalTypes: number;\n } {\n this.ensureLoaded();\n return {\n version: \"1.0.0\",\n generatedBy: \"relationship-catalog (predicates.json)\",\n lastUpdated: new Date().toISOString(),\n totalTypes: this.relationshipTypes!.length,\n };\n }\n\n /**\n * Search relationship types by keyword\n */\n search(keyword: string): RelationshipType[] {\n this.ensureLoaded();\n const lowerKeyword = keyword.toLowerCase();\n\n return this.relationshipTypes!.filter(\n (t) =>\n t.id.toLowerCase().includes(lowerKeyword) ||\n t.predicate.toLowerCase().includes(lowerKeyword) ||\n (t.inversePredicate && t.inversePredicate.toLowerCase().includes(lowerKeyword)) ||\n t.description.toLowerCase().includes(lowerKeyword) ||\n t.category.toLowerCase().includes(lowerKeyword)\n );\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/core/relationship-registry.ts"],
4
- "sourcesContent": ["import type { Relationship } from \"../types/index.js\";\n\n/**\n * Relationship type metadata\n */\nexport interface RelationshipTypeMetadata {\n id: string;\n predicate: string;\n inversePredicate?: string;\n category: string;\n description?: string;\n applicable_layers?: string[];\n}\n\n/**\n * Relationship registry - manages intra-layer relationships and their catalog\n */\nexport class RelationshipRegistry {\n private relationships: Map<string, Relationship[]>;\n private relationshipTypes: Map<string, RelationshipTypeMetadata>;\n private predicateMap: Map<string, RelationshipTypeMetadata>;\n private layerIndex: Map<string, Relationship[]>;\n\n constructor() {\n this.relationships = new Map();\n this.relationshipTypes = new Map();\n this.predicateMap = new Map();\n this.layerIndex = new Map();\n }\n\n /**\n * Register a relationship type\n */\n registerType(metadata: RelationshipTypeMetadata): void {\n this.relationshipTypes.set(metadata.id, metadata);\n this.predicateMap.set(metadata.predicate, metadata);\n }\n\n /**\n * Get relationship type by ID\n */\n getType(id: string): RelationshipTypeMetadata | undefined {\n return this.relationshipTypes.get(id);\n }\n\n /**\n * Get relationship type by predicate\n */\n getTypeByPredicate(predicate: string): RelationshipTypeMetadata | undefined {\n return this.predicateMap.get(predicate);\n }\n\n /**\n * Add a relationship to the registry\n */\n addRelationship(relationship: Relationship): void {\n // Extract layer from element ID (format: {layer}-{type}-{kebab-case-name})\n const sourceParts = relationship.source.split(\"-\");\n const layerKey = sourceParts[0]; // Get layer prefix\n\n // Add to source index\n if (!this.relationships.has(relationship.source)) {\n this.relationships.set(relationship.source, []);\n }\n this.relationships.get(relationship.source)!.push(relationship);\n\n // Add to layer index\n if (!this.layerIndex.has(layerKey)) {\n this.layerIndex.set(layerKey, []);\n }\n this.layerIndex.get(layerKey)!.push(relationship);\n }\n\n /**\n * Get all relationships from a source element\n */\n getRelationshipsFrom(sourceId: string): Relationship[] {\n return this.relationships.get(sourceId) ?? [];\n }\n\n /**\n * Get all relationships in a layer\n */\n getRelationshipsByLayer(layerPrefix: string): Relationship[] {\n return this.layerIndex.get(layerPrefix) ?? [];\n }\n\n /**\n * Get all relationships with a specific predicate\n */\n getRelationshipsByPredicate(predicate: string): Relationship[] {\n const allRels: Relationship[] = [];\n for (const rels of this.relationships.values()) {\n allRels.push(...rels.filter(rel => rel.predicate === predicate));\n }\n return allRels;\n }\n\n /**\n * Check if a relationship exists\n */\n hasRelationship(sourceId: string, targetId: string, predicate: string): boolean {\n const rels = this.relationships.get(sourceId) ?? [];\n return rels.some(\n rel => rel.target === targetId && rel.predicate === predicate\n );\n }\n\n /**\n * Get all relationships\n */\n getAllRelationships(): Relationship[] {\n const allRels: Relationship[] = [];\n for (const rels of this.relationships.values()) {\n allRels.push(...rels);\n }\n return allRels;\n }\n\n /**\n * Get all relationship types\n */\n getAllTypes(): RelationshipTypeMetadata[] {\n return Array.from(this.relationshipTypes.values());\n }\n\n /**\n * Check if a predicate is valid\n */\n isValidPredicate(predicate: string): boolean {\n return this.predicateMap.has(predicate);\n }\n\n /**\n * Get valid predicates for a layer\n */\n getValidPredicatesForLayer(layer: string): string[] {\n const layerPrefix = layer.split(\"-\")[0];\n return this.getAllTypes()\n .filter(type =>\n !type.applicable_layers || type.applicable_layers.includes(layerPrefix)\n )\n .map(type => type.predicate);\n }\n\n /**\n * Clear all relationships and types\n */\n clear(): void {\n this.relationships.clear();\n this.relationshipTypes.clear();\n this.predicateMap.clear();\n this.layerIndex.clear();\n }\n\n /**\n * Get statistics about registered relationships\n */\n getStats(): {\n totalRelationships: number;\n uniquePredicates: number;\n uniqueLayers: number;\n totalTypes: number;\n } {\n const predicates = new Set<string>();\n for (const rels of this.relationships.values()) {\n for (const rel of rels) {\n predicates.add(rel.predicate);\n }\n }\n\n return {\n totalRelationships: this.getAllRelationships().length,\n uniquePredicates: predicates.size,\n uniqueLayers: this.layerIndex.size,\n totalTypes: this.relationshipTypes.size,\n };\n }\n}\n"],
5
- "mappings": "AAiBM,MAAO,qBAAoB;EACvB;EACA;EACA;EACA;EAER,cAAA;AACE,SAAK,gBAAgB,oBAAI,IAAG,GAC5B,KAAK,oBAAoB,oBAAI,IAAG,GAChC,KAAK,eAAe,oBAAI,IAAG,GAC3B,KAAK,aAAa,oBAAI,IAAG;EAC3B;;;;EAKA,aAAa,UAAkC;AAC7C,SAAK,kBAAkB,IAAI,SAAS,IAAI,QAAQ,GAChD,KAAK,aAAa,IAAI,SAAS,WAAW,QAAQ;EACpD;;;;EAKA,QAAQ,IAAU;AAChB,WAAO,KAAK,kBAAkB,IAAI,EAAE;EACtC;;;;EAKA,mBAAmB,WAAiB;AAClC,WAAO,KAAK,aAAa,IAAI,SAAS;EACxC;;;;EAKA,gBAAgB,cAA0B;AAGxC,UAAM,WADc,aAAa,OAAO,MAAM,GAAG,EACpB,CAAC;AAG9B,IAAK,KAAK,cAAc,IAAI,aAAa,MAAM,KAC7C,KAAK,cAAc,IAAI,aAAa,QAAQ,CAAA,CAAE,GAEhD,KAAK,cAAc,IAAI,aAAa,MAAM,EAAG,KAAK,YAAY,GAGzD,KAAK,WAAW,IAAI,QAAQ,KAC/B,KAAK,WAAW,IAAI,UAAU,CAAA,CAAE,GAElC,KAAK,WAAW,IAAI,QAAQ,EAAG,KAAK,YAAY;EAClD;;;;EAKA,qBAAqB,UAAgB;AACnC,WAAO,KAAK,cAAc,IAAI,QAAQ,KAAK,CAAA;EAC7C;;;;EAKA,wBAAwB,aAAmB;AACzC,WAAO,KAAK,WAAW,IAAI,WAAW,KAAK,CAAA;EAC7C;;;;EAKA,4BAA4B,WAAiB;AAC3C,UAAM,UAA0B,CAAA;AAChC,eAAW,QAAQ,KAAK,cAAc,OAAM;AAC1C,cAAQ,KAAK,GAAG,KAAK,OAAO,SAAO,IAAI,cAAc,SAAS,CAAC;AAEjE,WAAO;EACT;;;;EAKA,gBAAgB,UAAkB,UAAkB,WAAiB;AAEnE,YADa,KAAK,cAAc,IAAI,QAAQ,KAAK,CAAA,GACrC,KACV,SAAO,IAAI,WAAW,YAAY,IAAI,cAAc,SAAS;EAEjE;;;;EAKA,sBAAmB;AACjB,UAAM,UAA0B,CAAA;AAChC,eAAW,QAAQ,KAAK,cAAc,OAAM;AAC1C,cAAQ,KAAK,GAAG,IAAI;AAEtB,WAAO;EACT;;;;EAKA,cAAW;AACT,WAAO,MAAM,KAAK,KAAK,kBAAkB,OAAM,CAAE;EACnD;;;;EAKA,iBAAiB,WAAiB;AAChC,WAAO,KAAK,aAAa,IAAI,SAAS;EACxC;;;;EAKA,2BAA2B,OAAa;AACtC,UAAM,cAAc,MAAM,MAAM,GAAG,EAAE,CAAC;AACtC,WAAO,KAAK,YAAW,EACpB,OAAO,UACN,CAAC,KAAK,qBAAqB,KAAK,kBAAkB,SAAS,WAAW,CAAC,EAExE,IAAI,UAAQ,KAAK,SAAS;EAC/B;;;;EAKA,QAAK;AACH,SAAK,cAAc,MAAK,GACxB,KAAK,kBAAkB,MAAK,GAC5B,KAAK,aAAa,MAAK,GACvB,KAAK,WAAW,MAAK;EACvB;;;;EAKA,WAAQ;AAMN,UAAM,aAAa,oBAAI,IAAG;AAC1B,eAAW,QAAQ,KAAK,cAAc,OAAM;AAC1C,iBAAW,OAAO;AAChB,mBAAW,IAAI,IAAI,SAAS;AAIhC,WAAO;MACL,oBAAoB,KAAK,oBAAmB,EAAG;MAC/C,kBAAkB,WAAW;MAC7B,cAAc,KAAK,WAAW;MAC9B,YAAY,KAAK,kBAAkB;;EAEvC;;",
4
+ "sourcesContent": ["import type { Relationship } from \"../types/index.js\";\n\n/**\n * Relationship type metadata\n */\nexport interface RelationshipTypeMetadata {\n id: string;\n predicate: string;\n inversePredicate?: string;\n category: string;\n description?: string;\n applicable_layers?: string[];\n}\n\n/**\n * Relationship registry - manages intra-layer and cross-layer relationships and their catalog\n *\n * NOTE: Future consolidation - Registry to GraphModel API\n * This registry will be consolidated into the GraphModel query API in a future refactoring.\n * The graph model provides the foundation for relationship tracking via edges.\n * Current approach maintains backward compatibility while the transition occurs.\n *\n * Future approach: Use GraphModel.getEdgesFrom/To with predicate filtering,\n * supporting both intra-layer (source_layer === destination_layer) and\n * cross-layer (source_layer !== destination_layer) relationships per the spec.\n *\n * See: https://github.com/tinkermonkey/documentation_robotics/discussions/317\n */\nexport class RelationshipRegistry {\n private relationships: Map<string, Relationship[]>;\n private relationshipTypes: Map<string, RelationshipTypeMetadata>;\n private predicateMap: Map<string, RelationshipTypeMetadata>;\n private layerIndex: Map<string, Relationship[]>;\n\n constructor() {\n this.relationships = new Map();\n this.relationshipTypes = new Map();\n this.predicateMap = new Map();\n this.layerIndex = new Map();\n }\n\n /**\n * Register a relationship type\n */\n registerType(metadata: RelationshipTypeMetadata): void {\n this.relationshipTypes.set(metadata.id, metadata);\n this.predicateMap.set(metadata.predicate, metadata);\n }\n\n /**\n * Get relationship type by ID\n */\n getType(id: string): RelationshipTypeMetadata | undefined {\n return this.relationshipTypes.get(id);\n }\n\n /**\n * Get relationship type by predicate\n */\n getTypeByPredicate(predicate: string): RelationshipTypeMetadata | undefined {\n return this.predicateMap.get(predicate);\n }\n\n /**\n * Add a relationship to the registry\n */\n addRelationship(relationship: Relationship): void {\n // Extract layer from element ID (format: {layer}-{type}-{kebab-case-name})\n const sourceParts = relationship.source.split(\"-\");\n const layerKey = sourceParts[0]; // Get layer prefix\n\n // Add to source index\n if (!this.relationships.has(relationship.source)) {\n this.relationships.set(relationship.source, []);\n }\n this.relationships.get(relationship.source)!.push(relationship);\n\n // Add to layer index\n if (!this.layerIndex.has(layerKey)) {\n this.layerIndex.set(layerKey, []);\n }\n this.layerIndex.get(layerKey)!.push(relationship);\n }\n\n /**\n * Get all relationships from a source element\n */\n getRelationshipsFrom(sourceId: string): Relationship[] {\n return this.relationships.get(sourceId) ?? [];\n }\n\n /**\n * Get all relationships in a layer\n */\n getRelationshipsByLayer(layerPrefix: string): Relationship[] {\n return this.layerIndex.get(layerPrefix) ?? [];\n }\n\n /**\n * Get all relationships with a specific predicate\n */\n getRelationshipsByPredicate(predicate: string): Relationship[] {\n const allRels: Relationship[] = [];\n for (const rels of this.relationships.values()) {\n allRels.push(...rels.filter((rel) => rel.predicate === predicate));\n }\n return allRels;\n }\n\n /**\n * Check if a relationship exists\n */\n hasRelationship(sourceId: string, targetId: string, predicate: string): boolean {\n const rels = this.relationships.get(sourceId) ?? [];\n return rels.some((rel) => rel.target === targetId && rel.predicate === predicate);\n }\n\n /**\n * Get all relationships\n */\n getAllRelationships(): Relationship[] {\n const allRels: Relationship[] = [];\n for (const rels of this.relationships.values()) {\n allRels.push(...rels);\n }\n return allRels;\n }\n\n /**\n * Get all relationship types\n */\n getAllTypes(): RelationshipTypeMetadata[] {\n return Array.from(this.relationshipTypes.values());\n }\n\n /**\n * Check if a predicate is valid\n */\n isValidPredicate(predicate: string): boolean {\n return this.predicateMap.has(predicate);\n }\n\n /**\n * Get valid predicates for a layer\n */\n getValidPredicatesForLayer(layer: string): string[] {\n const layerPrefix = layer.split(\"-\")[0];\n return this.getAllTypes()\n .filter((type) => !type.applicable_layers || type.applicable_layers.includes(layerPrefix))\n .map((type) => type.predicate);\n }\n\n /**\n * Clear all relationships and types\n */\n clear(): void {\n this.relationships.clear();\n this.relationshipTypes.clear();\n this.predicateMap.clear();\n this.layerIndex.clear();\n }\n\n /**\n * Get statistics about registered relationships\n */\n getStats(): {\n totalRelationships: number;\n uniquePredicates: number;\n uniqueLayers: number;\n totalTypes: number;\n } {\n const predicates = new Set<string>();\n for (const rels of this.relationships.values()) {\n for (const rel of rels) {\n predicates.add(rel.predicate);\n }\n }\n\n return {\n totalRelationships: this.getAllRelationships().length,\n uniquePredicates: predicates.size,\n uniqueLayers: this.layerIndex.size,\n totalTypes: this.relationshipTypes.size,\n };\n }\n}\n"],
5
+ "mappings": "AA4BM,MAAO,qBAAoB;EACvB;EACA;EACA;EACA;EAER,cAAA;AACE,SAAK,gBAAgB,oBAAI,IAAG,GAC5B,KAAK,oBAAoB,oBAAI,IAAG,GAChC,KAAK,eAAe,oBAAI,IAAG,GAC3B,KAAK,aAAa,oBAAI,IAAG;EAC3B;;;;EAKA,aAAa,UAAkC;AAC7C,SAAK,kBAAkB,IAAI,SAAS,IAAI,QAAQ,GAChD,KAAK,aAAa,IAAI,SAAS,WAAW,QAAQ;EACpD;;;;EAKA,QAAQ,IAAU;AAChB,WAAO,KAAK,kBAAkB,IAAI,EAAE;EACtC;;;;EAKA,mBAAmB,WAAiB;AAClC,WAAO,KAAK,aAAa,IAAI,SAAS;EACxC;;;;EAKA,gBAAgB,cAA0B;AAGxC,UAAM,WADc,aAAa,OAAO,MAAM,GAAG,EACpB,CAAC;AAG9B,IAAK,KAAK,cAAc,IAAI,aAAa,MAAM,KAC7C,KAAK,cAAc,IAAI,aAAa,QAAQ,CAAA,CAAE,GAEhD,KAAK,cAAc,IAAI,aAAa,MAAM,EAAG,KAAK,YAAY,GAGzD,KAAK,WAAW,IAAI,QAAQ,KAC/B,KAAK,WAAW,IAAI,UAAU,CAAA,CAAE,GAElC,KAAK,WAAW,IAAI,QAAQ,EAAG,KAAK,YAAY;EAClD;;;;EAKA,qBAAqB,UAAgB;AACnC,WAAO,KAAK,cAAc,IAAI,QAAQ,KAAK,CAAA;EAC7C;;;;EAKA,wBAAwB,aAAmB;AACzC,WAAO,KAAK,WAAW,IAAI,WAAW,KAAK,CAAA;EAC7C;;;;EAKA,4BAA4B,WAAiB;AAC3C,UAAM,UAA0B,CAAA;AAChC,eAAW,QAAQ,KAAK,cAAc,OAAM;AAC1C,cAAQ,KAAK,GAAG,KAAK,OAAO,CAAC,QAAQ,IAAI,cAAc,SAAS,CAAC;AAEnE,WAAO;EACT;;;;EAKA,gBAAgB,UAAkB,UAAkB,WAAiB;AAEnE,YADa,KAAK,cAAc,IAAI,QAAQ,KAAK,CAAA,GACrC,KAAK,CAAC,QAAQ,IAAI,WAAW,YAAY,IAAI,cAAc,SAAS;EAClF;;;;EAKA,sBAAmB;AACjB,UAAM,UAA0B,CAAA;AAChC,eAAW,QAAQ,KAAK,cAAc,OAAM;AAC1C,cAAQ,KAAK,GAAG,IAAI;AAEtB,WAAO;EACT;;;;EAKA,cAAW;AACT,WAAO,MAAM,KAAK,KAAK,kBAAkB,OAAM,CAAE;EACnD;;;;EAKA,iBAAiB,WAAiB;AAChC,WAAO,KAAK,aAAa,IAAI,SAAS;EACxC;;;;EAKA,2BAA2B,OAAa;AACtC,UAAM,cAAc,MAAM,MAAM,GAAG,EAAE,CAAC;AACtC,WAAO,KAAK,YAAW,EACpB,OAAO,CAAC,SAAS,CAAC,KAAK,qBAAqB,KAAK,kBAAkB,SAAS,WAAW,CAAC,EACxF,IAAI,CAAC,SAAS,KAAK,SAAS;EACjC;;;;EAKA,QAAK;AACH,SAAK,cAAc,MAAK,GACxB,KAAK,kBAAkB,MAAK,GAC5B,KAAK,aAAa,MAAK,GACvB,KAAK,WAAW,MAAK;EACvB;;;;EAKA,WAAQ;AAMN,UAAM,aAAa,oBAAI,IAAG;AAC1B,eAAW,QAAQ,KAAK,cAAc,OAAM;AAC1C,iBAAW,OAAO;AAChB,mBAAW,IAAI,IAAI,SAAS;AAIhC,WAAO;MACL,oBAAoB,KAAK,oBAAmB,EAAG;MAC/C,kBAAkB,WAAW;MAC7B,cAAc,KAAK,WAAW;MAC9B,YAAY,KAAK,kBAAkB;;EAEvC;;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/core/relationships.ts"],
4
- "sourcesContent": ["/**\n * Relationships management for intra-layer and cross-layer relationships\n */\n\nexport interface Relationship {\n source: string;\n predicate: string;\n target: string;\n category?: 'structural' | 'behavioral';\n layer: string;\n targetLayer?: string;\n properties?: Record<string, unknown>;\n}\n\n/**\n * Relationships class for managing the central relationships.yaml file\n */\nexport class Relationships {\n private relationships: Relationship[] = [];\n private dirty: boolean = false;\n\n constructor(relationships: Relationship[] = []) {\n this.relationships = relationships;\n }\n\n /**\n * Add a relationship\n */\n add(relationship: Relationship): void {\n this.relationships.push(relationship);\n this.dirty = true;\n }\n\n /**\n * Delete relationships matching criteria\n */\n delete(source: string, target: string, predicate?: string): number {\n const initialLength = this.relationships.length;\n this.relationships = this.relationships.filter(\n (rel) =>\n !(\n rel.source === source &&\n rel.target === target &&\n (!predicate || rel.predicate === predicate)\n )\n );\n const deletedCount = initialLength - this.relationships.length;\n if (deletedCount > 0) {\n this.dirty = true;\n }\n return deletedCount;\n }\n\n /**\n * Delete all relationships involving an element (as source or target)\n */\n deleteForElement(elementId: string): number {\n const initialLength = this.relationships.length;\n this.relationships = this.relationships.filter(\n (rel) => rel.source !== elementId && rel.target !== elementId\n );\n const deletedCount = initialLength - this.relationships.length;\n // Always mark as dirty to ensure file is rewritten (Python CLI behavior)\n this.dirty = true;\n return deletedCount;\n }\n\n /**\n * Get all relationships for an element\n */\n getForElement(elementId: string): {\n outgoing: Relationship[];\n incoming: Relationship[];\n } {\n const outgoing = this.relationships.filter((rel) => rel.source === elementId);\n const incoming = this.relationships.filter((rel) => rel.target === elementId);\n return { outgoing, incoming };\n }\n\n /**\n * Get all relationships\n */\n getAll(): Relationship[] {\n return [...this.relationships];\n }\n\n /**\n * Find relationships between two elements\n */\n find(source: string, target: string, predicate?: string): Relationship[] {\n return this.relationships.filter(\n (rel) =>\n rel.source === source &&\n rel.target === target &&\n (!predicate || rel.predicate === predicate)\n );\n }\n\n /**\n * Check if relationships have unsaved changes\n */\n isDirty(): boolean {\n return this.dirty;\n }\n\n /**\n * Mark relationships as clean (no unsaved changes)\n */\n markClean(): void {\n this.dirty = false;\n }\n\n /**\n * Serialize to array for YAML\n */\n toArray(): Relationship[] {\n return this.relationships;\n }\n\n /**\n * Load from array (from YAML)\n */\n static fromArray(data: Relationship[]): Relationships {\n return new Relationships(data);\n }\n}\n"],
4
+ "sourcesContent": ["/**\n * Relationships management for intra-layer and cross-layer relationships\n */\n\nexport interface Relationship {\n source: string;\n predicate: string;\n target: string;\n category?: \"structural\" | \"behavioral\";\n layer: string;\n targetLayer?: string;\n properties?: Record<string, unknown>;\n}\n\n/**\n * Relationships class for managing the central relationships.yaml file\n */\nexport class Relationships {\n private relationships: Relationship[] = [];\n private dirty: boolean = false;\n\n constructor(relationships: Relationship[] = []) {\n this.relationships = relationships;\n }\n\n /**\n * Add a relationship\n */\n add(relationship: Relationship): void {\n this.relationships.push(relationship);\n this.dirty = true;\n }\n\n /**\n * Delete relationships matching criteria\n */\n delete(source: string, target: string, predicate?: string): number {\n const initialLength = this.relationships.length;\n this.relationships = this.relationships.filter(\n (rel) =>\n !(\n rel.source === source &&\n rel.target === target &&\n (!predicate || rel.predicate === predicate)\n )\n );\n const deletedCount = initialLength - this.relationships.length;\n if (deletedCount > 0) {\n this.dirty = true;\n }\n return deletedCount;\n }\n\n /**\n * Delete all relationships involving an element (as source or target)\n */\n deleteForElement(elementId: string): number {\n const initialLength = this.relationships.length;\n this.relationships = this.relationships.filter(\n (rel) => rel.source !== elementId && rel.target !== elementId\n );\n const deletedCount = initialLength - this.relationships.length;\n // Always mark as dirty to ensure file is rewritten (Python CLI behavior)\n this.dirty = true;\n return deletedCount;\n }\n\n /**\n * Get all relationships for an element\n */\n getForElement(elementId: string): {\n outgoing: Relationship[];\n incoming: Relationship[];\n } {\n const outgoing = this.relationships.filter((rel) => rel.source === elementId);\n const incoming = this.relationships.filter((rel) => rel.target === elementId);\n return { outgoing, incoming };\n }\n\n /**\n * Get all relationships\n */\n getAll(): Relationship[] {\n return [...this.relationships];\n }\n\n /**\n * Find relationships between two elements\n */\n find(source: string, target: string, predicate?: string): Relationship[] {\n return this.relationships.filter(\n (rel) =>\n rel.source === source &&\n rel.target === target &&\n (!predicate || rel.predicate === predicate)\n );\n }\n\n /**\n * Check if relationships have unsaved changes\n */\n isDirty(): boolean {\n return this.dirty;\n }\n\n /**\n * Mark relationships as clean (no unsaved changes)\n */\n markClean(): void {\n this.dirty = false;\n }\n\n /**\n * Serialize to array for YAML\n */\n toArray(): Relationship[] {\n return this.relationships;\n }\n\n /**\n * Load from array (from YAML)\n */\n static fromArray(data: Relationship[]): Relationships {\n return new Relationships(data);\n }\n}\n"],
5
5
  "mappings": "AAiBM,MAAO,cAAa;EAChB,gBAAgC,CAAA;EAChC,QAAiB;EAEzB,YAAY,gBAAgC,CAAA,GAAE;AAC5C,SAAK,gBAAgB;EACvB;;;;EAKA,IAAI,cAA0B;AAC5B,SAAK,cAAc,KAAK,YAAY,GACpC,KAAK,QAAQ;EACf;;;;EAKA,OAAO,QAAgB,QAAgB,WAAkB;AACvD,UAAM,gBAAgB,KAAK,cAAc;AACzC,SAAK,gBAAgB,KAAK,cAAc,OACtC,CAAC,QACC,EACE,IAAI,WAAW,UACf,IAAI,WAAW,WACd,CAAC,aAAa,IAAI,cAAc,WAClC;AAEL,UAAM,eAAe,gBAAgB,KAAK,cAAc;AACxD,WAAI,eAAe,MACjB,KAAK,QAAQ,KAER;EACT;;;;EAKA,iBAAiB,WAAiB;AAChC,UAAM,gBAAgB,KAAK,cAAc;AACzC,SAAK,gBAAgB,KAAK,cAAc,OACtC,CAAC,QAAQ,IAAI,WAAW,aAAa,IAAI,WAAW,SAAS;AAE/D,UAAM,eAAe,gBAAgB,KAAK,cAAc;AAExD,gBAAK,QAAQ,IACN;EACT;;;;EAKA,cAAc,WAAiB;AAI7B,UAAM,WAAW,KAAK,cAAc,OAAO,CAAC,QAAQ,IAAI,WAAW,SAAS,GACtE,WAAW,KAAK,cAAc,OAAO,CAAC,QAAQ,IAAI,WAAW,SAAS;AAC5E,WAAO,EAAE,UAAU,SAAQ;EAC7B;;;;EAKA,SAAM;AACJ,WAAO,CAAC,GAAG,KAAK,aAAa;EAC/B;;;;EAKA,KAAK,QAAgB,QAAgB,WAAkB;AACrD,WAAO,KAAK,cAAc,OACxB,CAAC,QACC,IAAI,WAAW,UACf,IAAI,WAAW,WACd,CAAC,aAAa,IAAI,cAAc,UAAU;EAEjD;;;;EAKA,UAAO;AACL,WAAO,KAAK;EACd;;;;EAKA,YAAS;AACP,SAAK,QAAQ;EACf;;;;EAKA,UAAO;AACL,WAAO,KAAK;EACd;;;;EAKA,OAAO,UAAU,MAAoB;AACnC,WAAO,IAAI,cAAc,IAAI;EAC/B;;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,285 @@
1
+ import { StatsCollector } from "./stats-collector.js";
2
+ import { RelationshipCatalog } from "./relationship-catalog.js";
3
+ import { getLayerOrder } from "./layers.js";
4
+ function createClassifiedRelationship(rel, sourceLayer, targetLayer) {
5
+ return {
6
+ ...rel,
7
+ sourceLayer,
8
+ targetLayer,
9
+ isCrossLayer: sourceLayer !== targetLayer
10
+ };
11
+ }
12
+ class ReportDataModel {
13
+ model;
14
+ statsCollector;
15
+ relationshipCatalog;
16
+ cachedStats = null;
17
+ cachedRelationships = null;
18
+ cachedDataModel = null;
19
+ cachedQuality = null;
20
+ cachedReport = null;
21
+ relationshipTypeMap = /* @__PURE__ */ new Map();
22
+ catalogLoaded = !1;
23
+ constructor(model) {
24
+ this.model = model, this.statsCollector = new StatsCollector(model), this.relationshipCatalog = new RelationshipCatalog();
25
+ }
26
+ /**
27
+ * Load the relationship catalog and build relationship type map
28
+ */
29
+ async loadCatalog() {
30
+ if (this.catalogLoaded)
31
+ return;
32
+ await this.relationshipCatalog.load();
33
+ const types = this.relationshipCatalog.getAllTypes();
34
+ for (const type of types)
35
+ this.relationshipTypeMap.set(type.predicate, type);
36
+ this.catalogLoaded = !0;
37
+ }
38
+ /**
39
+ * Collect all report data (statistics, relationships, data model, quality metrics)
40
+ */
41
+ async collect() {
42
+ if (this.cachedReport)
43
+ return this.cachedReport;
44
+ try {
45
+ await this.loadCatalog();
46
+ const statistics = await this.getStatistics(), relationships = await this.getRelationshipAnalysis(), dataModel = await this.getDataModelInsights(), quality = await this.getQualityMetrics();
47
+ return this.cachedReport = {
48
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
49
+ statistics,
50
+ relationships,
51
+ dataModel,
52
+ quality
53
+ }, this.cachedReport;
54
+ } catch (error) {
55
+ throw new Error(`Failed to collect report data: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
56
+ }
57
+ }
58
+ /**
59
+ * Get model statistics
60
+ */
61
+ async getStatistics() {
62
+ return this.cachedStats ? this.cachedStats : (this.cachedStats = await this.statsCollector.collect(), this.cachedStats);
63
+ }
64
+ /**
65
+ * Get relationship analysis with classification
66
+ */
67
+ async getRelationshipAnalysis() {
68
+ if (this.cachedRelationships)
69
+ return this.cachedRelationships;
70
+ await this.loadCatalog();
71
+ const allRelationships = this.model.relationships.getAll(), classified = [], byCategory = {}, byPredicate = {};
72
+ let crossLayerCount = 0, intraLayerCount = 0;
73
+ for (let i = 0; i < allRelationships.length; i++) {
74
+ const rel = allRelationships[i], relationshipId = `${rel.source}\u2192${rel.predicate}\u2192${rel.target}`, classifiedRel = this.classifyRelationship(rel, relationshipId);
75
+ classified.push(classifiedRel), byCategory[classifiedRel.category] || (byCategory[classifiedRel.category] = 0), byCategory[classifiedRel.category]++, byPredicate[rel.predicate] || (byPredicate[rel.predicate] = 0), byPredicate[rel.predicate]++, classifiedRel.isCrossLayer ? crossLayerCount++ : intraLayerCount++;
76
+ }
77
+ const circularDependencies = this.detectCircularDependencies(classified);
78
+ return this.cachedRelationships = {
79
+ totalRelationships: allRelationships.length,
80
+ classified,
81
+ byCategory,
82
+ byPredicate,
83
+ crossLayerCount,
84
+ intraLayerCount,
85
+ circularDependencies
86
+ }, this.cachedRelationships;
87
+ }
88
+ /**
89
+ * Get relationships filtered by category
90
+ */
91
+ async getRelationshipsByCategory(category) {
92
+ return (await this.getRelationshipAnalysis()).classified.filter((rel) => rel.category === category);
93
+ }
94
+ /**
95
+ * Get data model layer (Layer 7) specific insights
96
+ */
97
+ async getDataModelInsights() {
98
+ if (this.cachedDataModel)
99
+ return this.cachedDataModel;
100
+ const dataModelLayer = await this.model.getLayer("data-model"), entities = [];
101
+ let attributeCount = 0;
102
+ if (dataModelLayer) {
103
+ const elements = dataModelLayer.listElements(), referencesFrom = /* @__PURE__ */ new Set();
104
+ for (const layerName of this.model.getLayerNames()) {
105
+ if (layerName === "data-model")
106
+ continue;
107
+ const layer = await this.model.getLayer(layerName);
108
+ if (layer) {
109
+ for (const element of layer.listElements())
110
+ if (element.references)
111
+ for (const ref of element.references)
112
+ ref.target.startsWith("data-model.") && referencesFrom.add(ref.target);
113
+ }
114
+ }
115
+ for (const element of elements) {
116
+ const attributes = element.attributes ? Object.keys(element.attributes) : [];
117
+ attributeCount += attributes.length, entities.push({
118
+ id: element.path || element.id || "",
119
+ name: element.name,
120
+ layer: "data-model",
121
+ attributes,
122
+ relatedEntities: element.relationships ? element.relationships.map((r) => r.target) : [],
123
+ isReferenced: referencesFrom.has(element.path || element.id || "")
124
+ });
125
+ }
126
+ }
127
+ const entityCount = entities.length, referencedCount = entities.filter((e) => e.isReferenced).length, orphaned = entities.filter((e) => !e.isReferenced && e.relatedEntities.length === 0), entitiesWithAttributes = entities.filter((e) => e.attributes.length > 0).length, attributeCoverage = entityCount > 0 ? entitiesWithAttributes / entityCount * 100 : 0, avgAttrs = entityCount > 0 ? attributeCount / entityCount : 0, maxAttrs = Math.max(0, ...entities.map((e) => e.attributes.length)), avgRels = entityCount > 0 ? entities.reduce((sum, e) => sum + e.relatedEntities.length, 0) / entityCount : 0;
128
+ return this.cachedDataModel = {
129
+ entityCount,
130
+ attributeCount,
131
+ relationshipCount: entities.reduce((sum, e) => sum + e.relatedEntities.length, 0),
132
+ entities,
133
+ entityCoverage: entityCount > 0 ? referencedCount / entityCount * 100 : 0,
134
+ attributeCoverage,
135
+ avgAttributesPerEntity: Math.round(avgAttrs * 10) / 10,
136
+ maxAttributesPerEntity: maxAttrs,
137
+ avgRelationshipsPerEntity: Math.round(avgRels * 10) / 10,
138
+ referencedEntities: referencedCount,
139
+ orphanedEntities: orphaned.map((e) => e.id)
140
+ }, this.cachedDataModel;
141
+ }
142
+ /**
143
+ * Get quality metrics for the model
144
+ */
145
+ async getQualityMetrics() {
146
+ if (this.cachedQuality)
147
+ return this.cachedQuality;
148
+ const stats = await this.getStatistics(), relationships = await this.getRelationshipAnalysis(), elementCoverage = stats.statistics.totalElements > 0 ? 100 : 0, relationshipCoverage = stats.statistics.totalElements > 0 ? stats.statistics.totalRelationships / stats.statistics.totalElements * 100 : 0, documentationCoverage = this.calculateDocumentationCoverage(stats), layerCoverage = stats.statistics.totalLayers > 0 ? stats.statistics.populatedLayers / stats.statistics.totalLayers * 100 : 0, orphanedElements = stats.orphanedElements.length, circularDependencies = relationships.circularDependencies.length, archimateCompliance = this.calculateArchimateCompliance(relationships), specCompliance = this.calculateSpecCompliance(relationships), semanticConsistency = (archimateCompliance + specCompliance) / 2, crossLayerReferenceHealth = relationships.totalRelationships > 0 ? relationships.crossLayerCount / relationships.totalRelationships * 100 : 0, layerComplianceScore = this.calculateLayerComplianceScore(relationships);
149
+ return this.cachedQuality = {
150
+ elementCoverage,
151
+ relationshipCoverage: Math.min(100, relationshipCoverage),
152
+ documentationCoverage: Math.min(100, documentationCoverage),
153
+ layerCoverage: Math.min(100, layerCoverage),
154
+ orphanedElements,
155
+ circularDependencies,
156
+ archimateCompliance,
157
+ specCompliance,
158
+ semanticConsistency,
159
+ crossLayerReferenceHealth: Math.min(100, crossLayerReferenceHealth),
160
+ layerComplianceScore
161
+ }, this.cachedQuality;
162
+ }
163
+ /**
164
+ * Classify a single relationship with semantic metadata
165
+ */
166
+ classifyRelationship(rel, id) {
167
+ const sourceParts = rel.source.split("."), targetParts = rel.target.split("."), sourceLayer = sourceParts[0], targetLayer = targetParts[0];
168
+ (!sourceLayer || !targetLayer) && console.warn(`[REPORT_001] Malformed element ID format in relationship: source="${rel.source}" (${sourceParts.length} parts), target="${rel.target}" (${targetParts.length} parts). Expected format: layer.type.name`);
169
+ const relationshipType = this.relationshipTypeMap.get(rel.predicate), isSpecCompliant = relationshipType !== void 0;
170
+ return createClassifiedRelationship({
171
+ id,
172
+ source: rel.source,
173
+ target: rel.target,
174
+ predicate: rel.predicate,
175
+ category: relationshipType?.category || "unknown",
176
+ archimateAlignment: relationshipType?.archimateAlignment || null,
177
+ directionality: relationshipType?.semantics?.directionality || "unidirectional",
178
+ transitivity: relationshipType?.semantics?.transitivity || !1,
179
+ symmetry: relationshipType?.semantics?.symmetry || !1,
180
+ reflexivity: relationshipType?.semantics?.reflexivity,
181
+ isSpecCompliant
182
+ }, sourceLayer, targetLayer);
183
+ }
184
+ /**
185
+ * Detect circular dependencies in relationships
186
+ * Max depth limit prevents stack overflow on complex graphs
187
+ */
188
+ detectCircularDependencies(relationships) {
189
+ const circularPaths = [], visited = /* @__PURE__ */ new Set(), path = [], predicatePath = [];
190
+ for (const rel of relationships)
191
+ visited.has(rel.source) || this.findCircles(rel.source, relationships, visited, path, predicatePath, circularPaths, 0, 100);
192
+ return circularPaths;
193
+ }
194
+ /**
195
+ * Helper to find circular paths using DFS with depth limit
196
+ */
197
+ findCircles(node, relationships, visited, path, predicatePath, circularPaths, depth, maxDepth) {
198
+ if (!(depth > maxDepth)) {
199
+ if (path.includes(node)) {
200
+ const circleStart = path.indexOf(node), circlePath = path.slice(circleStart), circlePredicates = predicatePath.slice(circleStart), circleKey = [...circlePath].sort().join("\u2192");
201
+ !circularPaths.some((c) => [...c.elements].sort().join("\u2192") === circleKey) && circlePath.length > 1 && circularPaths.push({
202
+ elements: circlePath,
203
+ predicates: circlePredicates,
204
+ pathLength: circlePath.length
205
+ });
206
+ return;
207
+ }
208
+ if (!visited.has(node)) {
209
+ path.push(node), visited.add(node);
210
+ for (const rel of relationships)
211
+ rel.source === node && (predicatePath.push(rel.predicate), this.findCircles(rel.target, relationships, visited, path, predicatePath, circularPaths, depth + 1, maxDepth), predicatePath.pop());
212
+ path.pop(), visited.delete(node);
213
+ }
214
+ }
215
+ }
216
+ /**
217
+ * Calculate documentation coverage percentage
218
+ * Checks what proportion of elements have meaningful descriptions
219
+ */
220
+ calculateDocumentationCoverage(stats) {
221
+ if (stats.statistics.totalElements === 0)
222
+ return 0;
223
+ let documentedCount = 0;
224
+ for (const layerName of this.model.getLayerNames()) {
225
+ const layer = this.model.layers.get(layerName);
226
+ if (layer)
227
+ for (const element of layer.listElements())
228
+ element.description && element.description.trim().length > 0 && documentedCount++;
229
+ }
230
+ return Math.round(documentedCount / stats.statistics.totalElements * 100);
231
+ }
232
+ /**
233
+ * Calculate ArchiMate alignment percentage
234
+ */
235
+ calculateArchimateCompliance(analysis) {
236
+ if (analysis.totalRelationships === 0)
237
+ return 100;
238
+ const archimateAligned = analysis.classified.filter((r) => r.archimateAlignment).length;
239
+ return Math.round(archimateAligned / analysis.totalRelationships * 100);
240
+ }
241
+ /**
242
+ * Calculate spec compliance percentage
243
+ */
244
+ calculateSpecCompliance(analysis) {
245
+ if (analysis.totalRelationships === 0)
246
+ return 100;
247
+ const specCompliant = analysis.classified.filter((r) => r.isSpecCompliant).length;
248
+ return Math.round(specCompliant / analysis.totalRelationships * 100);
249
+ }
250
+ /**
251
+ * Calculate layer compliance score (directional compliance)
252
+ * Measures adherence to the higher -> lower layer reference rule
253
+ */
254
+ calculateLayerComplianceScore(analysis) {
255
+ const validRelationships = analysis.classified.filter((rel) => {
256
+ const sourceOrder = getLayerOrder(rel.sourceLayer), targetOrder = getLayerOrder(rel.targetLayer);
257
+ return sourceOrder > 0 && targetOrder > 0;
258
+ });
259
+ if (validRelationships.length === 0)
260
+ return 100;
261
+ let compliantCount = 0;
262
+ for (const rel of validRelationships) {
263
+ const sourceOrder = getLayerOrder(rel.sourceLayer), targetOrder = getLayerOrder(rel.targetLayer);
264
+ sourceOrder >= targetOrder && compliantCount++;
265
+ }
266
+ return Math.round(compliantCount / validRelationships.length * 100);
267
+ }
268
+ /**
269
+ * Clear all cached data
270
+ */
271
+ clearCache() {
272
+ this.cachedStats = null, this.cachedRelationships = null, this.cachedDataModel = null, this.cachedQuality = null, this.cachedReport = null;
273
+ }
274
+ /**
275
+ * Get the relationship catalog
276
+ */
277
+ getCatalog() {
278
+ return this.relationshipCatalog;
279
+ }
280
+ }
281
+ export {
282
+ ReportDataModel,
283
+ createClassifiedRelationship
284
+ };
285
+ //# sourceMappingURL=report-data-model.js.map