@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,266 @@
1
+ class GraphModel {
2
+ nodes;
3
+ edges;
4
+ indices;
5
+ nodesVersion = 0;
6
+ constructor() {
7
+ this.nodes = /* @__PURE__ */ new Map(), this.edges = /* @__PURE__ */ new Map(), this.indices = {
8
+ nodesByLayer: /* @__PURE__ */ new Map(),
9
+ nodesByType: /* @__PURE__ */ new Map(),
10
+ edgesBySource: /* @__PURE__ */ new Map(),
11
+ edgesByDestination: /* @__PURE__ */ new Map(),
12
+ edgesByPredicate: /* @__PURE__ */ new Map()
13
+ };
14
+ }
15
+ /**
16
+ * Get the current version of the nodes (for cache invalidation)
17
+ */
18
+ getNodesVersion() {
19
+ return this.nodesVersion;
20
+ }
21
+ /**
22
+ * Add a node to the graph and update indices
23
+ * If a node with the same ID exists, its old index entries are cleaned up
24
+ */
25
+ addNode(node) {
26
+ const existingNode = this.nodes.get(node.id);
27
+ if (existingNode) {
28
+ const oldLayerSet = this.indices.nodesByLayer.get(existingNode.layer);
29
+ oldLayerSet && (oldLayerSet.delete(node.id), oldLayerSet.size === 0 && this.indices.nodesByLayer.delete(existingNode.layer));
30
+ const oldTypeSet = this.indices.nodesByType.get(existingNode.type);
31
+ oldTypeSet && (oldTypeSet.delete(node.id), oldTypeSet.size === 0 && this.indices.nodesByType.delete(existingNode.type));
32
+ }
33
+ this.nodes.set(node.id, node), this.indices.nodesByLayer.has(node.layer) || this.indices.nodesByLayer.set(node.layer, /* @__PURE__ */ new Set());
34
+ const layerSet = this.indices.nodesByLayer.get(node.layer);
35
+ layerSet && layerSet.add(node.id), this.indices.nodesByType.has(node.type) || this.indices.nodesByType.set(node.type, /* @__PURE__ */ new Set());
36
+ const typeSet = this.indices.nodesByType.get(node.type);
37
+ typeSet && typeSet.add(node.id), this.nodesVersion++;
38
+ }
39
+ /**
40
+ * Remove a node from the graph
41
+ * Also removes all associated edges
42
+ */
43
+ removeNode(nodeId) {
44
+ const node = this.nodes.get(nodeId);
45
+ if (!node)
46
+ return !1;
47
+ this.nodes.delete(nodeId);
48
+ const layerSet = this.indices.nodesByLayer.get(node.layer);
49
+ layerSet && (layerSet.delete(nodeId), layerSet.size === 0 && this.indices.nodesByLayer.delete(node.layer));
50
+ const typeSet = this.indices.nodesByType.get(node.type);
51
+ typeSet && (typeSet.delete(nodeId), typeSet.size === 0 && this.indices.nodesByType.delete(node.type));
52
+ const edgesInvolving = [];
53
+ for (const [edgeId, edge] of this.edges.entries())
54
+ (edge.source === nodeId || edge.destination === nodeId) && edgesInvolving.push(edgeId);
55
+ for (const edgeId of edgesInvolving)
56
+ this.removeEdge(edgeId);
57
+ return this.nodesVersion++, !0;
58
+ }
59
+ /**
60
+ * Update node properties
61
+ */
62
+ updateNode(nodeId, updates) {
63
+ const node = this.nodes.get(nodeId);
64
+ if (!node)
65
+ return !1;
66
+ if (updates.layer && updates.layer !== node.layer) {
67
+ const oldLayerSet = this.indices.nodesByLayer.get(node.layer);
68
+ oldLayerSet && (oldLayerSet.delete(nodeId), oldLayerSet.size === 0 && this.indices.nodesByLayer.delete(node.layer)), this.indices.nodesByLayer.has(updates.layer) || this.indices.nodesByLayer.set(updates.layer, /* @__PURE__ */ new Set());
69
+ const newLayerSet = this.indices.nodesByLayer.get(updates.layer);
70
+ newLayerSet && newLayerSet.add(nodeId);
71
+ }
72
+ if (updates.type && updates.type !== node.type) {
73
+ const oldTypeSet = this.indices.nodesByType.get(node.type);
74
+ oldTypeSet && (oldTypeSet.delete(nodeId), oldTypeSet.size === 0 && this.indices.nodesByType.delete(node.type)), this.indices.nodesByType.has(updates.type) || this.indices.nodesByType.set(updates.type, /* @__PURE__ */ new Set());
75
+ const newTypeSet = this.indices.nodesByType.get(updates.type);
76
+ newTypeSet && newTypeSet.add(nodeId);
77
+ }
78
+ return Object.assign(node, updates), this.nodesVersion++, !0;
79
+ }
80
+ /**
81
+ * Add an edge to the graph and update indices
82
+ * Validates that both source and destination nodes exist
83
+ * @throws Error if source or destination node does not exist
84
+ */
85
+ addEdge(edge) {
86
+ if (!this.nodes.has(edge.source))
87
+ throw new Error(`Cannot add edge: source node "${edge.source}" does not exist`);
88
+ if (!this.nodes.has(edge.destination))
89
+ throw new Error(`Cannot add edge: destination node "${edge.destination}" does not exist`);
90
+ this.edges.set(edge.id, edge), this.indices.edgesBySource.has(edge.source) || this.indices.edgesBySource.set(edge.source, /* @__PURE__ */ new Set());
91
+ const sourceSet = this.indices.edgesBySource.get(edge.source);
92
+ sourceSet && sourceSet.add(edge.id), this.indices.edgesByDestination.has(edge.destination) || this.indices.edgesByDestination.set(edge.destination, /* @__PURE__ */ new Set());
93
+ const destSet = this.indices.edgesByDestination.get(edge.destination);
94
+ destSet && destSet.add(edge.id), this.indices.edgesByPredicate.has(edge.predicate) || this.indices.edgesByPredicate.set(edge.predicate, /* @__PURE__ */ new Set());
95
+ const predicateSet = this.indices.edgesByPredicate.get(edge.predicate);
96
+ predicateSet && predicateSet.add(edge.id);
97
+ }
98
+ /**
99
+ * Remove an edge from the graph
100
+ */
101
+ removeEdge(edgeId) {
102
+ const edge = this.edges.get(edgeId);
103
+ if (!edge)
104
+ return !1;
105
+ this.edges.delete(edgeId);
106
+ const sourceSet = this.indices.edgesBySource.get(edge.source);
107
+ sourceSet && (sourceSet.delete(edgeId), sourceSet.size === 0 && this.indices.edgesBySource.delete(edge.source));
108
+ const destSet = this.indices.edgesByDestination.get(edge.destination);
109
+ destSet && (destSet.delete(edgeId), destSet.size === 0 && this.indices.edgesByDestination.delete(edge.destination));
110
+ const predicateSet = this.indices.edgesByPredicate.get(edge.predicate);
111
+ return predicateSet && (predicateSet.delete(edgeId), predicateSet.size === 0 && this.indices.edgesByPredicate.delete(edge.predicate)), !0;
112
+ }
113
+ /**
114
+ * Update edge properties
115
+ */
116
+ updateEdge(edgeId, updates) {
117
+ const edge = this.edges.get(edgeId);
118
+ if (!edge)
119
+ return !1;
120
+ if (updates.predicate && updates.predicate !== edge.predicate) {
121
+ const oldPredicateSet = this.indices.edgesByPredicate.get(edge.predicate);
122
+ oldPredicateSet && (oldPredicateSet.delete(edgeId), oldPredicateSet.size === 0 && this.indices.edgesByPredicate.delete(edge.predicate)), this.indices.edgesByPredicate.has(updates.predicate) || this.indices.edgesByPredicate.set(updates.predicate, /* @__PURE__ */ new Set());
123
+ const newPredicateSet = this.indices.edgesByPredicate.get(updates.predicate);
124
+ newPredicateSet && newPredicateSet.add(edgeId);
125
+ }
126
+ return Object.assign(edge, updates), !0;
127
+ }
128
+ /**
129
+ * Get a node by its ID
130
+ */
131
+ getNode(id) {
132
+ return this.nodes.get(id);
133
+ }
134
+ /**
135
+ * Get all nodes in a specific layer
136
+ */
137
+ getNodesByLayer(layer) {
138
+ const nodeIds = this.indices.nodesByLayer.get(layer) ?? /* @__PURE__ */ new Set(), result = [];
139
+ for (const id of nodeIds) {
140
+ const node = this.nodes.get(id);
141
+ node && result.push(node);
142
+ }
143
+ return result;
144
+ }
145
+ /**
146
+ * Get all nodes of a specific type
147
+ */
148
+ getNodesByType(type) {
149
+ const nodeIds = this.indices.nodesByType.get(type) ?? /* @__PURE__ */ new Set(), result = [];
150
+ for (const id of nodeIds) {
151
+ const node = this.nodes.get(id);
152
+ node && result.push(node);
153
+ }
154
+ return result;
155
+ }
156
+ /**
157
+ * Get outgoing edges from a node, optionally filtered by predicate
158
+ */
159
+ getEdgesFrom(nodeId, predicate) {
160
+ const edgeIds = this.indices.edgesBySource.get(nodeId) ?? /* @__PURE__ */ new Set(), edges = [];
161
+ for (const id of edgeIds) {
162
+ const edge = this.edges.get(id);
163
+ edge && edges.push(edge);
164
+ }
165
+ return predicate ? edges.filter((e) => e.predicate === predicate) : edges;
166
+ }
167
+ /**
168
+ * Get incoming edges to a node, optionally filtered by predicate
169
+ */
170
+ getEdgesTo(nodeId, predicate) {
171
+ const edgeIds = this.indices.edgesByDestination.get(nodeId) ?? /* @__PURE__ */ new Set(), edges = [];
172
+ for (const id of edgeIds) {
173
+ const edge = this.edges.get(id);
174
+ edge && edges.push(edge);
175
+ }
176
+ return predicate ? edges.filter((e) => e.predicate === predicate) : edges;
177
+ }
178
+ /**
179
+ * Get edges between two specific nodes
180
+ */
181
+ getEdgesBetween(sourceId, destinationId, predicate) {
182
+ return this.getEdgesFrom(sourceId, predicate).filter((e) => e.destination === destinationId);
183
+ }
184
+ /**
185
+ * Get all edges in the graph
186
+ */
187
+ getAllEdges() {
188
+ return Array.from(this.edges.values());
189
+ }
190
+ /**
191
+ * Traverse the graph starting from a node using breadth-first search
192
+ */
193
+ traverse(startNodeId, predicate, maxDepth = 1 / 0) {
194
+ const visited = /* @__PURE__ */ new Set(), result = [], queue = [{ nodeId: startNodeId, depth: 0 }];
195
+ for (; queue.length > 0; ) {
196
+ const { nodeId, depth } = queue.shift();
197
+ if (visited.has(nodeId) || depth > maxDepth)
198
+ continue;
199
+ visited.add(nodeId);
200
+ const node = this.nodes.get(nodeId);
201
+ node && result.push(node);
202
+ const edges = this.getEdgesFrom(nodeId, predicate);
203
+ for (const edge of edges)
204
+ visited.has(edge.destination) || queue.push({ nodeId: edge.destination, depth: depth + 1 });
205
+ }
206
+ return result;
207
+ }
208
+ /**
209
+ * Get total number of nodes
210
+ */
211
+ getNodeCount() {
212
+ return this.nodes.size;
213
+ }
214
+ /**
215
+ * Get total number of edges
216
+ */
217
+ getEdgeCount() {
218
+ return this.edges.size;
219
+ }
220
+ /**
221
+ * Clear all data from the graph
222
+ */
223
+ clear() {
224
+ this.nodes.clear(), this.edges.clear(), this.indices.nodesByLayer.clear(), this.indices.nodesByType.clear(), this.indices.edgesBySource.clear(), this.indices.edgesByDestination.clear(), this.indices.edgesByPredicate.clear();
225
+ }
226
+ /**
227
+ * Convert Element to GraphNode
228
+ * Preserves spec-node fields so they survive graph round-trips
229
+ */
230
+ /** UUID pattern for detecting actual UUIDs vs slug IDs */
231
+ static UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
232
+ static fromElement(element) {
233
+ const graphId = element.path || element.id, isUUID = GraphModel.UUID_PATTERN.test(element.id);
234
+ return {
235
+ id: graphId,
236
+ uuid: isUUID ? element.id : void 0,
237
+ // preserve UUID for round-tripping
238
+ layer: element.layer || "unknown",
239
+ type: element.type,
240
+ name: element.name,
241
+ description: element.description,
242
+ properties: element.attributes || {},
243
+ spec_node_id: element.spec_node_id || void 0,
244
+ layer_id: element.layer_id || void 0,
245
+ attributes: element.attributes && Object.keys(element.attributes).length > 0 ? element.attributes : void 0,
246
+ source_reference: element.source_reference,
247
+ metadata: element.metadata
248
+ };
249
+ }
250
+ /**
251
+ * Convert Relationship to GraphEdge
252
+ */
253
+ static relationshipToEdge(relationship, edgeId) {
254
+ return {
255
+ id: edgeId,
256
+ source: relationship.source,
257
+ destination: relationship.target,
258
+ predicate: relationship.predicate,
259
+ properties: relationship.properties
260
+ };
261
+ }
262
+ }
263
+ export {
264
+ GraphModel
265
+ };
266
+ //# sourceMappingURL=graph-model.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/core/graph-model.ts"],
4
+ "sourcesContent": ["import { Element } from \"./element.js\";\nimport type { ElementMetadata, Relationship, SourceReference } from \"../types/index.js\";\n\n/**\n * Graph node representing a model element\n * Replaces Element class for graph-based storage\n */\nexport interface GraphNode {\n id: string; // Path (slug) used as graph key: {layer}.{type}.{kebab-name}\n uuid?: string; // UUIDv4 preserved for round-tripping (element.id)\n layer: string; // Layer this node belongs to\n type: string; // Element type\n name: string; // Display name\n description?: string; // Optional description\n properties?: Record<string, unknown>; // Custom properties\n // Spec-node aligned fields (preserved through graph round-trip)\n spec_node_id?: string;\n layer_id?: string;\n attributes?: Record<string, unknown>;\n source_reference?: SourceReference;\n metadata?: ElementMetadata;\n}\n\n/**\n * Graph edge representing a relationship between nodes\n */\nexport interface GraphEdge {\n id: string; // Unique identifier\n source: string; // Source node ID\n destination: string; // Destination node ID\n predicate: string; // Relationship type\n properties?: Record<string, unknown>; // Optional properties\n category?: \"structural\" | \"behavioral\";\n}\n\n/**\n * Index structures for efficient querying\n */\ninterface GraphIndices {\n nodesByLayer: Map<string, Set<string>>; // layer -> node IDs\n nodesByType: Map<string, Set<string>>; // type -> node IDs\n edgesBySource: Map<string, Set<string>>; // source node ID -> edge IDs\n edgesByDestination: Map<string, Set<string>>; // destination node ID -> edge IDs\n edgesByPredicate: Map<string, Set<string>>; // predicate -> edge IDs\n}\n\n/**\n * Graph model interface for node/edge storage with query capabilities\n */\nexport interface IGraphModel {\n nodes: Map<string, GraphNode>;\n edges: Map<string, GraphEdge>;\n\n // Query methods\n getNode(id: string): GraphNode | undefined;\n getNodesByLayer(layer: string): GraphNode[];\n getNodesByType(type: string): GraphNode[];\n getEdgesFrom(nodeId: string, predicate?: string): GraphEdge[];\n getEdgesTo(nodeId: string, predicate?: string): GraphEdge[];\n getEdgesBetween(sourceId: string, destinationId: string, predicate?: string): GraphEdge[];\n getAllEdges(): GraphEdge[];\n\n // Mutation methods\n addNode(node: GraphNode): void;\n removeNode(nodeId: string): boolean;\n updateNode(nodeId: string, updates: Partial<GraphNode>): boolean;\n\n addEdge(edge: GraphEdge): void;\n removeEdge(edgeId: string): boolean;\n updateEdge(edgeId: string, updates: Partial<GraphEdge>): boolean;\n\n // Traversal\n traverse(startNodeId: string, predicate?: string, maxDepth?: number): GraphNode[];\n\n // Utility\n getNodeCount(): number;\n getEdgeCount(): number;\n clear(): void;\n}\n\n/**\n * Implementation of graph model with indices for efficient queries\n */\nexport class GraphModel implements IGraphModel {\n nodes: Map<string, GraphNode>;\n edges: Map<string, GraphEdge>;\n private indices: GraphIndices;\n private nodesVersion: number = 0;\n\n constructor() {\n this.nodes = new Map();\n this.edges = new Map();\n this.indices = {\n nodesByLayer: new Map(),\n nodesByType: new Map(),\n edgesBySource: new Map(),\n edgesByDestination: new Map(),\n edgesByPredicate: new Map(),\n };\n }\n\n /**\n * Get the current version of the nodes (for cache invalidation)\n */\n getNodesVersion(): number {\n return this.nodesVersion;\n }\n\n /**\n * Add a node to the graph and update indices\n * If a node with the same ID exists, its old index entries are cleaned up\n */\n addNode(node: GraphNode): void {\n const existingNode = this.nodes.get(node.id);\n\n // Clean up old index entries if node is being replaced\n if (existingNode) {\n // Remove from old layer index\n const oldLayerSet = this.indices.nodesByLayer.get(existingNode.layer);\n if (oldLayerSet) {\n oldLayerSet.delete(node.id);\n if (oldLayerSet.size === 0) {\n this.indices.nodesByLayer.delete(existingNode.layer);\n }\n }\n\n // Remove from old type index\n const oldTypeSet = this.indices.nodesByType.get(existingNode.type);\n if (oldTypeSet) {\n oldTypeSet.delete(node.id);\n if (oldTypeSet.size === 0) {\n this.indices.nodesByType.delete(existingNode.type);\n }\n }\n }\n\n // Add new node\n this.nodes.set(node.id, node);\n\n // Update layer index\n if (!this.indices.nodesByLayer.has(node.layer)) {\n this.indices.nodesByLayer.set(node.layer, new Set());\n }\n const layerSet = this.indices.nodesByLayer.get(node.layer);\n if (layerSet) {\n layerSet.add(node.id);\n }\n\n // Update type index\n if (!this.indices.nodesByType.has(node.type)) {\n this.indices.nodesByType.set(node.type, new Set());\n }\n const typeSet = this.indices.nodesByType.get(node.type);\n if (typeSet) {\n typeSet.add(node.id);\n }\n\n // Increment version to invalidate caches\n this.nodesVersion++;\n }\n\n /**\n * Remove a node from the graph\n * Also removes all associated edges\n */\n removeNode(nodeId: string): boolean {\n const node = this.nodes.get(nodeId);\n if (!node) {\n return false;\n }\n\n // Remove from nodes map\n this.nodes.delete(nodeId);\n\n // Remove from layer index\n const layerSet = this.indices.nodesByLayer.get(node.layer);\n if (layerSet) {\n layerSet.delete(nodeId);\n if (layerSet.size === 0) {\n this.indices.nodesByLayer.delete(node.layer);\n }\n }\n\n // Remove from type index\n const typeSet = this.indices.nodesByType.get(node.type);\n if (typeSet) {\n typeSet.delete(nodeId);\n if (typeSet.size === 0) {\n this.indices.nodesByType.delete(node.type);\n }\n }\n\n // Remove all edges involving this node\n const edgesInvolving: string[] = [];\n for (const [edgeId, edge] of this.edges.entries()) {\n if (edge.source === nodeId || edge.destination === nodeId) {\n edgesInvolving.push(edgeId);\n }\n }\n for (const edgeId of edgesInvolving) {\n this.removeEdge(edgeId);\n }\n\n // Increment version to invalidate caches\n this.nodesVersion++;\n return true;\n }\n\n /**\n * Update node properties\n */\n updateNode(nodeId: string, updates: Partial<GraphNode>): boolean {\n const node = this.nodes.get(nodeId);\n if (!node) {\n return false;\n }\n\n // Handle layer change\n if (updates.layer && updates.layer !== node.layer) {\n const oldLayerSet = this.indices.nodesByLayer.get(node.layer);\n if (oldLayerSet) {\n oldLayerSet.delete(nodeId);\n if (oldLayerSet.size === 0) {\n this.indices.nodesByLayer.delete(node.layer);\n }\n }\n if (!this.indices.nodesByLayer.has(updates.layer)) {\n this.indices.nodesByLayer.set(updates.layer, new Set());\n }\n const newLayerSet = this.indices.nodesByLayer.get(updates.layer);\n if (newLayerSet) {\n newLayerSet.add(nodeId);\n }\n }\n\n // Handle type change\n if (updates.type && updates.type !== node.type) {\n const oldTypeSet = this.indices.nodesByType.get(node.type);\n if (oldTypeSet) {\n oldTypeSet.delete(nodeId);\n if (oldTypeSet.size === 0) {\n this.indices.nodesByType.delete(node.type);\n }\n }\n if (!this.indices.nodesByType.has(updates.type)) {\n this.indices.nodesByType.set(updates.type, new Set());\n }\n const newTypeSet = this.indices.nodesByType.get(updates.type);\n if (newTypeSet) {\n newTypeSet.add(nodeId);\n }\n }\n\n // Apply updates\n Object.assign(node, updates);\n // Increment version to invalidate caches\n this.nodesVersion++;\n return true;\n }\n\n /**\n * Add an edge to the graph and update indices\n * Validates that both source and destination nodes exist\n * @throws Error if source or destination node does not exist\n */\n addEdge(edge: GraphEdge): void {\n // Validate that source node exists\n if (!this.nodes.has(edge.source)) {\n throw new Error(`Cannot add edge: source node \"${edge.source}\" does not exist`);\n }\n\n // Validate that destination node exists\n if (!this.nodes.has(edge.destination)) {\n throw new Error(`Cannot add edge: destination node \"${edge.destination}\" does not exist`);\n }\n\n this.edges.set(edge.id, edge);\n\n // Update source index\n if (!this.indices.edgesBySource.has(edge.source)) {\n this.indices.edgesBySource.set(edge.source, new Set());\n }\n const sourceSet = this.indices.edgesBySource.get(edge.source);\n if (sourceSet) {\n sourceSet.add(edge.id);\n }\n\n // Update destination index\n if (!this.indices.edgesByDestination.has(edge.destination)) {\n this.indices.edgesByDestination.set(edge.destination, new Set());\n }\n const destSet = this.indices.edgesByDestination.get(edge.destination);\n if (destSet) {\n destSet.add(edge.id);\n }\n\n // Update predicate index\n if (!this.indices.edgesByPredicate.has(edge.predicate)) {\n this.indices.edgesByPredicate.set(edge.predicate, new Set());\n }\n const predicateSet = this.indices.edgesByPredicate.get(edge.predicate);\n if (predicateSet) {\n predicateSet.add(edge.id);\n }\n }\n\n /**\n * Remove an edge from the graph\n */\n removeEdge(edgeId: string): boolean {\n const edge = this.edges.get(edgeId);\n if (!edge) {\n return false;\n }\n\n // Remove from edges map\n this.edges.delete(edgeId);\n\n // Remove from source index\n const sourceSet = this.indices.edgesBySource.get(edge.source);\n if (sourceSet) {\n sourceSet.delete(edgeId);\n if (sourceSet.size === 0) {\n this.indices.edgesBySource.delete(edge.source);\n }\n }\n\n // Remove from destination index\n const destSet = this.indices.edgesByDestination.get(edge.destination);\n if (destSet) {\n destSet.delete(edgeId);\n if (destSet.size === 0) {\n this.indices.edgesByDestination.delete(edge.destination);\n }\n }\n\n // Remove from predicate index\n const predicateSet = this.indices.edgesByPredicate.get(edge.predicate);\n if (predicateSet) {\n predicateSet.delete(edgeId);\n if (predicateSet.size === 0) {\n this.indices.edgesByPredicate.delete(edge.predicate);\n }\n }\n\n return true;\n }\n\n /**\n * Update edge properties\n */\n updateEdge(edgeId: string, updates: Partial<GraphEdge>): boolean {\n const edge = this.edges.get(edgeId);\n if (!edge) {\n return false;\n }\n\n // Handle predicate change\n if (updates.predicate && updates.predicate !== edge.predicate) {\n const oldPredicateSet = this.indices.edgesByPredicate.get(edge.predicate);\n if (oldPredicateSet) {\n oldPredicateSet.delete(edgeId);\n if (oldPredicateSet.size === 0) {\n this.indices.edgesByPredicate.delete(edge.predicate);\n }\n }\n if (!this.indices.edgesByPredicate.has(updates.predicate)) {\n this.indices.edgesByPredicate.set(updates.predicate, new Set());\n }\n const newPredicateSet = this.indices.edgesByPredicate.get(updates.predicate);\n if (newPredicateSet) {\n newPredicateSet.add(edgeId);\n }\n }\n\n // Note: Source and destination changes are not supported (use removeEdge + addEdge)\n // Apply updates\n Object.assign(edge, updates);\n return true;\n }\n\n /**\n * Get a node by its ID\n */\n getNode(id: string): GraphNode | undefined {\n return this.nodes.get(id);\n }\n\n /**\n * Get all nodes in a specific layer\n */\n getNodesByLayer(layer: string): GraphNode[] {\n const nodeIds = this.indices.nodesByLayer.get(layer) ?? new Set();\n const result: GraphNode[] = [];\n for (const id of nodeIds) {\n const node = this.nodes.get(id);\n if (node) {\n result.push(node);\n }\n }\n return result;\n }\n\n /**\n * Get all nodes of a specific type\n */\n getNodesByType(type: string): GraphNode[] {\n const nodeIds = this.indices.nodesByType.get(type) ?? new Set();\n const result: GraphNode[] = [];\n for (const id of nodeIds) {\n const node = this.nodes.get(id);\n if (node) {\n result.push(node);\n }\n }\n return result;\n }\n\n /**\n * Get outgoing edges from a node, optionally filtered by predicate\n */\n getEdgesFrom(nodeId: string, predicate?: string): GraphEdge[] {\n const edgeIds = this.indices.edgesBySource.get(nodeId) ?? new Set();\n const edges: GraphEdge[] = [];\n for (const id of edgeIds) {\n const edge = this.edges.get(id);\n if (edge) {\n edges.push(edge);\n }\n }\n\n if (predicate) {\n return edges.filter((e) => e.predicate === predicate);\n }\n return edges;\n }\n\n /**\n * Get incoming edges to a node, optionally filtered by predicate\n */\n getEdgesTo(nodeId: string, predicate?: string): GraphEdge[] {\n const edgeIds = this.indices.edgesByDestination.get(nodeId) ?? new Set();\n const edges: GraphEdge[] = [];\n for (const id of edgeIds) {\n const edge = this.edges.get(id);\n if (edge) {\n edges.push(edge);\n }\n }\n\n if (predicate) {\n return edges.filter((e) => e.predicate === predicate);\n }\n return edges;\n }\n\n /**\n * Get edges between two specific nodes\n */\n getEdgesBetween(sourceId: string, destinationId: string, predicate?: string): GraphEdge[] {\n const outgoing = this.getEdgesFrom(sourceId, predicate);\n return outgoing.filter((e) => e.destination === destinationId);\n }\n\n /**\n * Get all edges in the graph\n */\n getAllEdges(): GraphEdge[] {\n return Array.from(this.edges.values());\n }\n\n /**\n * Traverse the graph starting from a node using breadth-first search\n */\n traverse(startNodeId: string, predicate?: string, maxDepth: number = Infinity): GraphNode[] {\n const visited = new Set<string>();\n const result: GraphNode[] = [];\n const queue: { nodeId: string; depth: number }[] = [{ nodeId: startNodeId, depth: 0 }];\n\n while (queue.length > 0) {\n const { nodeId, depth } = queue.shift()!;\n\n if (visited.has(nodeId) || depth > maxDepth) {\n continue;\n }\n\n visited.add(nodeId);\n const node = this.nodes.get(nodeId);\n if (node) {\n result.push(node);\n }\n\n // Find outgoing edges\n const edges = this.getEdgesFrom(nodeId, predicate);\n for (const edge of edges) {\n if (!visited.has(edge.destination)) {\n queue.push({ nodeId: edge.destination, depth: depth + 1 });\n }\n }\n }\n\n return result;\n }\n\n /**\n * Get total number of nodes\n */\n getNodeCount(): number {\n return this.nodes.size;\n }\n\n /**\n * Get total number of edges\n */\n getEdgeCount(): number {\n return this.edges.size;\n }\n\n /**\n * Clear all data from the graph\n */\n clear(): void {\n this.nodes.clear();\n this.edges.clear();\n this.indices.nodesByLayer.clear();\n this.indices.nodesByType.clear();\n this.indices.edgesBySource.clear();\n this.indices.edgesByDestination.clear();\n this.indices.edgesByPredicate.clear();\n }\n\n /**\n * Convert Element to GraphNode\n * Preserves spec-node fields so they survive graph round-trips\n */\n /** UUID pattern for detecting actual UUIDs vs slug IDs */\n private static readonly UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\n static fromElement(element: Element): GraphNode {\n // path is the graph key; fall back to id for elements without a path\n const graphId = element.path || element.id;\n // Only preserve UUID when the id is actually a UUID (not a slug)\n const isUUID = GraphModel.UUID_PATTERN.test(element.id);\n return {\n id: graphId,\n uuid: isUUID ? element.id : undefined, // preserve UUID for round-tripping\n layer: element.layer || \"unknown\",\n type: element.type,\n name: element.name,\n description: element.description,\n properties: element.attributes || {},\n spec_node_id: element.spec_node_id || undefined,\n layer_id: element.layer_id || undefined,\n attributes: element.attributes && Object.keys(element.attributes).length > 0\n ? element.attributes\n : undefined,\n source_reference: element.source_reference,\n metadata: element.metadata,\n };\n }\n\n /**\n * Convert Relationship to GraphEdge\n */\n static relationshipToEdge(relationship: Relationship, edgeId: string): GraphEdge {\n return {\n id: edgeId,\n source: relationship.source,\n destination: relationship.target,\n predicate: relationship.predicate,\n properties: relationship.properties,\n };\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -1,36 +1,173 @@
1
1
  import { Element } from "./element.js";
2
+ import { GraphModel } from "./graph-model.js";
2
3
  class Layer {
3
4
  name;
4
- elements;
5
+ graph;
5
6
  metadata;
6
7
  dirty = !1;
7
- constructor(name, elements = []) {
8
- this.name = name, this.elements = new Map(elements.map((e) => [e.id, e]));
8
+ cachedElements = null;
9
+ cachedNodesVersion = 0;
10
+ constructor(name, elementsOrGraph, elementsIfGraphPassed) {
11
+ this.name = name;
12
+ let actualGraph, elementsToAdd = [];
13
+ elementsOrGraph instanceof GraphModel ? (actualGraph = elementsOrGraph, Array.isArray(elementsIfGraphPassed) && (elementsToAdd = elementsIfGraphPassed)) : Array.isArray(elementsOrGraph) ? elementsToAdd = elementsOrGraph : elementsOrGraph === void 0 && Array.isArray(elementsIfGraphPassed) && (elementsToAdd = elementsIfGraphPassed), this.graph = actualGraph || new GraphModel();
14
+ for (const element of elementsToAdd) {
15
+ element.layer = this.name, (!element.layer_id || element.layer_id === "") && (element.layer_id = this.name);
16
+ const node = GraphModel.fromElement(element), nodeProperties = node.properties || {};
17
+ node.properties = nodeProperties, element.references && element.references.length > 0 && (nodeProperties.__references__ = element.references), element.relationships && element.relationships.length > 0 && (nodeProperties.__relationships__ = element.relationships), element.semanticId && (nodeProperties.__semanticId__ = element.semanticId), this.graph.addNode(node);
18
+ }
9
19
  }
10
20
  /**
11
- * Add an element to the layer
21
+ * Get all elements in this layer from the graph
22
+ * Converts graph nodes back to Elements for backward compatibility
23
+ * Results are cached and invalidated when the underlying graph changes
24
+ */
25
+ get elements() {
26
+ const currentVersion = this.graph.getNodesVersion();
27
+ if (this.cachedElements !== null && this.cachedNodesVersion === currentVersion)
28
+ return this.cachedElements;
29
+ const result = /* @__PURE__ */ new Map(), nodes = this.graph.getNodesByLayer(this.name);
30
+ for (const node of nodes) {
31
+ const element = new Element({
32
+ id: node.uuid || node.id,
33
+ path: node.id,
34
+ spec_node_id: node.spec_node_id,
35
+ layer_id: node.layer_id,
36
+ type: node.type,
37
+ name: node.name,
38
+ description: node.description,
39
+ attributes: node.attributes,
40
+ source_reference: node.source_reference,
41
+ metadata: node.metadata,
42
+ layer: node.layer,
43
+ references: node.properties?.__references__ ?? [],
44
+ relationships: node.properties?.__relationships__ ?? [],
45
+ semanticId: node.properties?.__semanticId__
46
+ });
47
+ result.set(node.id, element);
48
+ }
49
+ return this.cachedElements = result, this.cachedNodesVersion = currentVersion, result;
50
+ }
51
+ /**
52
+ * Add an element to the layer (stores in graph)
12
53
  */
13
54
  addElement(element) {
14
- this.elements.set(element.id, element), this.dirty = !0;
55
+ element.layer = this.name, (!element.layer_id || element.layer_id === "") && (element.layer_id = this.name);
56
+ const node = GraphModel.fromElement(element), nodeProperties = node.properties || {};
57
+ if (node.properties = nodeProperties, element.references && element.references.length > 0 && (nodeProperties.__references__ = element.references), element.relationships && element.relationships.length > 0 && (nodeProperties.__relationships__ = element.relationships), element.semanticId && (nodeProperties.__semanticId__ = element.semanticId), this.graph.addNode(node), element.references && element.references.length > 0)
58
+ for (const ref of element.references)
59
+ this.graph.nodes.has(ref.source) && this.graph.nodes.has(ref.target) && this.graph.addEdge({
60
+ id: `${ref.source}-${ref.type}-${ref.target}`,
61
+ source: ref.source,
62
+ destination: ref.target,
63
+ predicate: ref.type,
64
+ properties: {}
65
+ });
66
+ if (element.relationships && element.relationships.length > 0)
67
+ for (const rel of element.relationships)
68
+ this.graph.nodes.has(rel.source) && this.graph.nodes.has(rel.target) && this.graph.addEdge({
69
+ id: `${rel.source}-${rel.predicate}-${rel.target}`,
70
+ source: rel.source,
71
+ destination: rel.target,
72
+ predicate: rel.predicate,
73
+ properties: {}
74
+ });
75
+ this.dirty = !0;
15
76
  }
16
77
  /**
17
- * Get an element by ID
78
+ * Get an element by UUID or semantic ID from the graph.
79
+ * Supports direct UUID lookup, and falls back to semantic ID lookup for legacy elements.
80
+ *
81
+ * @param id - UUID or semantic ID of the element to get
82
+ * @returns The element if found, undefined if not found
18
83
  */
19
84
  getElement(id) {
20
- return this.elements.get(id);
85
+ let node = this.graph.nodes.get(id);
86
+ if (!node) {
87
+ for (const candidate of this.graph.nodes.values())
88
+ if (candidate.layer === this.name && (candidate.uuid === id || candidate.properties?.__semanticId__ === id || candidate.id === id)) {
89
+ node = candidate;
90
+ break;
91
+ }
92
+ }
93
+ if (!(!node || node.layer !== this.name))
94
+ return new Element({
95
+ id: node.uuid || node.id,
96
+ path: node.id,
97
+ spec_node_id: node.spec_node_id,
98
+ layer_id: node.layer_id,
99
+ type: node.type,
100
+ name: node.name,
101
+ description: node.description,
102
+ attributes: node.attributes,
103
+ source_reference: node.source_reference,
104
+ metadata: node.metadata,
105
+ layer: node.layer,
106
+ references: node.properties?.__references__ ?? [],
107
+ relationships: node.properties?.__relationships__ ?? []
108
+ });
109
+ }
110
+ /**
111
+ * Update an element in the graph
112
+ */
113
+ updateElement(element) {
114
+ const node = this.graph.nodes.get(element.path || element.id);
115
+ if (!node || node.layer !== this.name)
116
+ return !1;
117
+ const properties = { ...node.properties || {} };
118
+ element.references && element.references.length > 0 ? properties.__references__ = element.references : delete properties.__references__, element.relationships && element.relationships.length > 0 ? properties.__relationships__ = element.relationships : delete properties.__relationships__;
119
+ const updated = this.graph.updateNode(element.path || element.id, {
120
+ type: element.type,
121
+ name: element.name,
122
+ description: element.description,
123
+ properties,
124
+ spec_node_id: element.spec_node_id || void 0,
125
+ layer_id: element.layer_id || void 0,
126
+ attributes: element.attributes,
127
+ source_reference: element.source_reference,
128
+ metadata: element.metadata
129
+ });
130
+ return updated && (this.dirty = !0), updated;
21
131
  }
22
132
  /**
23
- * Delete an element by ID
133
+ * Delete an element by ID from the graph
134
+ *
135
+ * @param id - UUID of the element to delete
136
+ * @returns true if element was deleted, false if not found
24
137
  */
25
138
  deleteElement(id) {
26
- const result = this.elements.delete(id);
139
+ let node = this.graph.nodes.get(id);
140
+ if (!node || node.layer !== this.name) {
141
+ for (const candidate of this.graph.nodes.values())
142
+ if (candidate.layer === this.name && (candidate.uuid === id || candidate.properties?.__semanticId__ === id || candidate.id === id)) {
143
+ node = candidate;
144
+ break;
145
+ }
146
+ }
147
+ if (!node || node.layer !== this.name)
148
+ return !1;
149
+ const result = this.graph.removeNode(node.id);
27
150
  return result && (this.dirty = !0), result;
28
151
  }
29
152
  /**
30
- * List all elements in the layer
153
+ * List all elements in the layer from the graph
31
154
  */
32
155
  listElements() {
33
- return Array.from(this.elements.values());
156
+ return this.graph.getNodesByLayer(this.name).map((node) => new Element({
157
+ id: node.uuid || node.id,
158
+ path: node.id,
159
+ spec_node_id: node.spec_node_id,
160
+ layer_id: node.layer_id,
161
+ type: node.type,
162
+ name: node.name,
163
+ description: node.description,
164
+ attributes: node.attributes,
165
+ source_reference: node.source_reference,
166
+ metadata: node.metadata,
167
+ layer: node.layer,
168
+ references: node.properties?.__references__ ?? [],
169
+ relationships: node.properties?.__relationships__ ?? []
170
+ }));
34
171
  }
35
172
  /**
36
173
  * Check if layer has unsaved changes
@@ -49,23 +186,29 @@ class Layer {
49
186
  */
50
187
  toJSON() {
51
188
  const result = {
52
- elements: Array.from(this.elements.values()).map((e) => e.toJSON())
189
+ elements: this.listElements().map((e) => e.toJSON())
53
190
  };
54
191
  return this.metadata && (result.metadata = this.metadata), result;
55
192
  }
56
193
  /**
57
194
  * Create Layer from JSON data
58
195
  */
59
- static fromJSON(name, data) {
196
+ static fromJSON(name, data, graph) {
60
197
  const elements = data.elements.map((e) => new Element({
61
198
  id: e.id,
199
+ path: e.path,
200
+ spec_node_id: e.spec_node_id,
201
+ layer_id: e.layer_id,
62
202
  type: e.type,
63
203
  name: e.name,
64
204
  description: e.description,
65
- properties: e.properties,
205
+ attributes: e.attributes,
206
+ source_reference: e.source_reference,
207
+ metadata: e.metadata,
66
208
  references: e.references,
67
- relationships: e.relationships
68
- })), layer = new Layer(name, elements);
209
+ relationships: e.relationships,
210
+ layer: name
211
+ })), layer = new Layer(name, graph, elements);
69
212
  return layer.metadata = data.metadata, layer;
70
213
  }
71
214
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/core/layer.ts"],
4
- "sourcesContent": ["import { Element } from \"./element.js\";\nimport type { LayerData } from \"../types/index.js\";\n\n/**\n * Layer class representing a container for elements within a layer\n */\nexport class Layer {\n name: string;\n elements: Map<string, Element>;\n metadata?: { layer: string; version: string };\n private dirty: boolean = false;\n\n constructor(name: string, elements: Element[] = []) {\n this.name = name;\n this.elements = new Map(elements.map((e) => [e.id, e]));\n }\n\n /**\n * Add an element to the layer\n */\n addElement(element: Element): void {\n this.elements.set(element.id, element);\n this.dirty = true;\n }\n\n /**\n * Get an element by ID\n */\n getElement(id: string): Element | undefined {\n return this.elements.get(id);\n }\n\n /**\n * Delete an element by ID\n */\n deleteElement(id: string): boolean {\n const result = this.elements.delete(id);\n if (result) {\n this.dirty = true;\n }\n return result;\n }\n\n /**\n * List all elements in the layer\n */\n listElements(): Element[] {\n return Array.from(this.elements.values());\n }\n\n /**\n * Check if layer has unsaved changes\n */\n isDirty(): boolean {\n return this.dirty;\n }\n\n /**\n * Mark layer as clean (no unsaved changes)\n */\n markClean(): void {\n this.dirty = false;\n }\n\n /**\n * Serialize to JSON representation\n */\n toJSON(): LayerData {\n const result: LayerData = {\n elements: Array.from(this.elements.values()).map((e) => e.toJSON()),\n };\n\n if (this.metadata) {\n result.metadata = this.metadata;\n }\n\n return result;\n }\n\n /**\n * Create Layer from JSON data\n */\n static fromJSON(name: string, data: LayerData): Layer {\n const elements = data.elements.map(\n (e) =>\n new Element({\n id: e.id,\n type: e.type,\n name: e.name,\n description: e.description,\n properties: e.properties,\n references: e.references,\n relationships: e.relationships,\n })\n );\n const layer = new Layer(name, elements);\n layer.metadata = data.metadata;\n return layer;\n }\n}\n"],
5
- "mappings": "AAAA,SAAS,eAAe;AAMlB,MAAO,MAAK;EAChB;EACA;EACA;EACQ,QAAiB;EAEzB,YAAY,MAAc,WAAsB,CAAA,GAAE;AAChD,SAAK,OAAO,MACZ,KAAK,WAAW,IAAI,IAAI,SAAS,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;EACxD;;;;EAKA,WAAW,SAAgB;AACzB,SAAK,SAAS,IAAI,QAAQ,IAAI,OAAO,GACrC,KAAK,QAAQ;EACf;;;;EAKA,WAAW,IAAU;AACnB,WAAO,KAAK,SAAS,IAAI,EAAE;EAC7B;;;;EAKA,cAAc,IAAU;AACtB,UAAM,SAAS,KAAK,SAAS,OAAO,EAAE;AACtC,WAAI,WACF,KAAK,QAAQ,KAER;EACT;;;;EAKA,eAAY;AACV,WAAO,MAAM,KAAK,KAAK,SAAS,OAAM,CAAE;EAC1C;;;;EAKA,UAAO;AACL,WAAO,KAAK;EACd;;;;EAKA,YAAS;AACP,SAAK,QAAQ;EACf;;;;EAKA,SAAM;AACJ,UAAM,SAAoB;MACxB,UAAU,MAAM,KAAK,KAAK,SAAS,OAAM,CAAE,EAAE,IAAI,CAAC,MAAM,EAAE,OAAM,CAAE;;AAGpE,WAAI,KAAK,aACP,OAAO,WAAW,KAAK,WAGlB;EACT;;;;EAKA,OAAO,SAAS,MAAc,MAAe;AAC3C,UAAM,WAAW,KAAK,SAAS,IAC7B,CAAC,MACC,IAAI,QAAQ;MACV,IAAI,EAAE;MACN,MAAM,EAAE;MACR,MAAM,EAAE;MACR,aAAa,EAAE;MACf,YAAY,EAAE;MACd,YAAY,EAAE;MACd,eAAe,EAAE;KAClB,CAAC,GAEA,QAAQ,IAAI,MAAM,MAAM,QAAQ;AACtC,iBAAM,WAAW,KAAK,UACf;EACT;;",
4
+ "sourcesContent": ["import { Element } from \"./element.js\";\nimport { GraphModel } from \"./graph-model.js\";\nimport type { LayerData, Reference, Relationship } from \"../types/index.js\";\n\n/**\n * Layer class - thin wrapper over graph model for backward compatibility\n * Queries the graph for elements in a specific layer\n */\nexport class Layer {\n name: string;\n graph: GraphModel;\n metadata?: { layer: string; version: string };\n private dirty: boolean = false;\n private cachedElements: Map<string, Element> | null = null;\n private cachedNodesVersion: number = 0;\n\n constructor(\n name: string,\n elementsOrGraph?: Element[] | GraphModel,\n elementsIfGraphPassed?: Element[]\n ) {\n this.name = name;\n\n // Handle overloaded constructor:\n // new Layer(name) - create with empty graph\n // new Layer(name, elements) - create with elements array\n // new Layer(name, graph) - create with provided graph\n // new Layer(name, undefined, elements) - create with elements\n // new Layer(name, graph, elements) - create with provided graph and elements\n let actualGraph: GraphModel | undefined;\n let elementsToAdd: Element[] = [];\n\n if (elementsOrGraph instanceof GraphModel) {\n // Called with graph as second parameter\n actualGraph = elementsOrGraph;\n // Elements are in the third parameter if provided\n if (Array.isArray(elementsIfGraphPassed)) {\n elementsToAdd = elementsIfGraphPassed;\n }\n } else if (Array.isArray(elementsOrGraph)) {\n // Called with elements as second parameter\n elementsToAdd = elementsOrGraph;\n } else if (elementsOrGraph === undefined && Array.isArray(elementsIfGraphPassed)) {\n // Called with undefined graph and elements in third parameter\n elementsToAdd = elementsIfGraphPassed;\n }\n\n // Use provided graph or create a new one\n this.graph = actualGraph || new GraphModel();\n\n // Add elements to the graph (without marking as dirty during construction)\n for (const element of elementsToAdd) {\n // Ensure element has the correct layer\n element.layer = this.name;\n // Also set layer_id to maintain consistency with layer name\n if (!element.layer_id || element.layer_id === \"\") {\n element.layer_id = this.name;\n }\n const node = GraphModel.fromElement(element);\n\n // Store references and relationships as node properties for preservation\n // Ensure properties object exists; fromElement always initializes it, but type is optional\n const nodeProperties = node.properties || {};\n node.properties = nodeProperties;\n\n if (element.references && element.references.length > 0) {\n nodeProperties[\"__references__\"] = element.references;\n }\n if (element.relationships && element.relationships.length > 0) {\n nodeProperties[\"__relationships__\"] = element.relationships;\n }\n\n // Store semantic ID if present (for legacy format elements converted to UUID)\n if ((element as any).semanticId) {\n nodeProperties[\"__semanticId__\"] = (element as any).semanticId;\n }\n\n this.graph.addNode(node);\n // Don't mark as dirty during construction - elements added in constructor are initial state\n }\n }\n\n /**\n * Get all elements in this layer from the graph\n * Converts graph nodes back to Elements for backward compatibility\n * Results are cached and invalidated when the underlying graph changes\n */\n get elements(): Map<string, Element> {\n const currentVersion = this.graph.getNodesVersion();\n\n // Return cached result if graph hasn't changed\n if (this.cachedElements !== null && this.cachedNodesVersion === currentVersion) {\n return this.cachedElements;\n }\n\n // Rebuild cache\n const result = new Map<string, Element>();\n const nodes = this.graph.getNodesByLayer(this.name);\n\n for (const node of nodes) {\n const element = new Element({\n id: node.uuid || node.id,\n path: node.id,\n spec_node_id: node.spec_node_id,\n layer_id: node.layer_id,\n type: node.type,\n name: node.name,\n description: node.description,\n attributes: node.attributes,\n source_reference: node.source_reference,\n metadata: node.metadata,\n layer: node.layer,\n references: (node.properties?.[\"__references__\"] ?? []) as Reference[],\n relationships: (node.properties?.[\"__relationships__\"] ?? []) as Relationship[],\n semanticId: node.properties?.[\"__semanticId__\"],\n } as any);\n result.set(node.id, element);\n }\n\n this.cachedElements = result;\n this.cachedNodesVersion = currentVersion;\n return result;\n }\n\n /**\n * Add an element to the layer (stores in graph)\n */\n addElement(element: Element): void {\n // Ensure element has the correct layer\n element.layer = this.name;\n // Also set layer_id to maintain consistency with layer name\n if (!element.layer_id || element.layer_id === \"\") {\n element.layer_id = this.name;\n }\n const node = GraphModel.fromElement(element);\n\n // Store references and relationships as node properties for preservation\n // Ensure properties object exists; fromElement always initializes it, but type is optional\n const nodeProperties = node.properties || {};\n node.properties = nodeProperties;\n\n if (element.references && element.references.length > 0) {\n nodeProperties[\"__references__\"] = element.references;\n }\n if (element.relationships && element.relationships.length > 0) {\n nodeProperties[\"__relationships__\"] = element.relationships;\n }\n\n // Store semantic ID if present (for legacy format elements converted to UUID)\n if ((element as any).semanticId) {\n nodeProperties[\"__semanticId__\"] = (element as any).semanticId;\n }\n\n // Add node to graph first\n this.graph.addNode(node);\n\n // Create graph edges from references for export compatibility\n // Only create edges if both source and destination nodes exist\n if (element.references && element.references.length > 0) {\n for (const ref of element.references) {\n if (this.graph.nodes.has(ref.source) && this.graph.nodes.has(ref.target)) {\n this.graph.addEdge({\n id: `${ref.source}-${ref.type}-${ref.target}`,\n source: ref.source,\n destination: ref.target,\n predicate: ref.type,\n properties: {},\n });\n }\n }\n }\n\n // Create graph edges from relationships for export compatibility\n // Only create edges if both source and destination nodes exist\n if (element.relationships && element.relationships.length > 0) {\n for (const rel of element.relationships) {\n if (this.graph.nodes.has(rel.source) && this.graph.nodes.has(rel.target)) {\n this.graph.addEdge({\n id: `${rel.source}-${rel.predicate}-${rel.target}`,\n source: rel.source,\n destination: rel.target,\n predicate: rel.predicate,\n properties: {},\n });\n }\n }\n }\n\n this.dirty = true;\n }\n\n /**\n * Get an element by UUID or semantic ID from the graph.\n * Supports direct UUID lookup, and falls back to semantic ID lookup for legacy elements.\n *\n * @param id - UUID or semantic ID of the element to get\n * @returns The element if found, undefined if not found\n */\n getElement(id: string): Element | undefined {\n // First try direct lookup by path (graph key) or UUID\n let node = this.graph.nodes.get(id);\n\n if (!node) {\n // Fallback: look up by UUID (node.uuid === id) or legacy semanticId\n for (const candidate of this.graph.nodes.values()) {\n if (\n candidate.layer === this.name &&\n (candidate.uuid === id ||\n candidate.properties?.[\"__semanticId__\"] === id ||\n candidate.id === id)\n ) {\n node = candidate;\n break;\n }\n }\n }\n\n if (!node || node.layer !== this.name) {\n return undefined;\n }\n\n return new Element({\n id: node.uuid || node.id,\n path: node.id,\n spec_node_id: node.spec_node_id,\n layer_id: node.layer_id,\n type: node.type,\n name: node.name,\n description: node.description,\n attributes: node.attributes,\n source_reference: node.source_reference,\n metadata: node.metadata,\n layer: node.layer,\n references: (node.properties?.[\"__references__\"] ?? []) as Reference[],\n relationships: (node.properties?.[\"__relationships__\"] ?? []) as Relationship[],\n });\n }\n\n /**\n * Update an element in the graph\n */\n updateElement(element: Element): boolean {\n const node = this.graph.nodes.get(element.path || element.id);\n if (!node || node.layer !== this.name) {\n return false;\n }\n\n // Prepare properties including references and relationships\n // Start with existing node properties to preserve graph metadata fields like __references__ and __relationships__\n const properties = { ...(node.properties || {}) };\n\n // Persist references and relationships as node properties\n if (element.references && element.references.length > 0) {\n properties[\"__references__\"] = element.references;\n } else {\n delete properties[\"__references__\"];\n }\n\n if (element.relationships && element.relationships.length > 0) {\n properties[\"__relationships__\"] = element.relationships;\n } else {\n delete properties[\"__relationships__\"];\n }\n\n // Convert element to graph node and update in place, including spec-node fields\n // so that source_reference and attributes changes aren't lost on the next save cycle\n const updated = this.graph.updateNode(element.path || element.id, {\n type: element.type,\n name: element.name,\n description: element.description,\n properties,\n spec_node_id: element.spec_node_id || undefined,\n layer_id: element.layer_id || undefined,\n attributes: element.attributes,\n source_reference: element.source_reference,\n metadata: element.metadata,\n });\n\n if (updated) {\n this.dirty = true;\n }\n return updated;\n }\n\n /**\n * Delete an element by ID from the graph\n *\n * @param id - UUID of the element to delete\n * @returns true if element was deleted, false if not found\n */\n deleteElement(id: string): boolean {\n let node = this.graph.nodes.get(id);\n\n if (!node || node.layer !== this.name) {\n // Fallback: search by UUID or semanticId if direct path lookup failed\n for (const candidate of this.graph.nodes.values()) {\n if (\n candidate.layer === this.name &&\n (candidate.uuid === id ||\n candidate.properties?.[\"__semanticId__\"] === id ||\n candidate.id === id)\n ) {\n node = candidate;\n break;\n }\n }\n }\n\n if (!node || node.layer !== this.name) {\n return false;\n }\n\n const result = this.graph.removeNode(node.id);\n if (result) {\n this.dirty = true;\n }\n return result;\n }\n\n /**\n * List all elements in the layer from the graph\n */\n listElements(): Element[] {\n const nodes = this.graph.getNodesByLayer(this.name);\n return nodes.map(\n (node) =>\n new Element({\n id: node.uuid || node.id,\n path: node.id,\n spec_node_id: node.spec_node_id,\n layer_id: node.layer_id,\n type: node.type,\n name: node.name,\n description: node.description,\n attributes: node.attributes,\n source_reference: node.source_reference,\n metadata: node.metadata,\n layer: node.layer,\n references: (node.properties?.[\"__references__\"] ?? []) as Reference[],\n relationships: (node.properties?.[\"__relationships__\"] ?? []) as Relationship[],\n })\n );\n }\n\n /**\n * Check if layer has unsaved changes\n */\n isDirty(): boolean {\n return this.dirty;\n }\n\n /**\n * Mark layer as clean (no unsaved changes)\n */\n markClean(): void {\n this.dirty = false;\n }\n\n /**\n * Serialize to JSON representation\n */\n toJSON(): LayerData {\n const result: LayerData = {\n elements: this.listElements().map((e) => e.toJSON()),\n };\n\n if (this.metadata) {\n result.metadata = this.metadata;\n }\n\n return result;\n }\n\n /**\n * Create Layer from JSON data\n */\n static fromJSON(name: string, data: LayerData, graph?: GraphModel): Layer {\n const elements = data.elements.map(\n (e) =>\n new Element({\n id: e.id,\n path: e.path,\n spec_node_id: e.spec_node_id,\n layer_id: e.layer_id,\n type: e.type,\n name: e.name,\n description: e.description,\n attributes: e.attributes,\n source_reference: e.source_reference,\n metadata: e.metadata,\n references: e.references,\n relationships: e.relationships,\n layer: name,\n })\n );\n const layer = new Layer(name, graph, elements);\n layer.metadata = data.metadata;\n return layer;\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,32 @@
1
+ const CANONICAL_LAYER_NAMES = [
2
+ "motivation",
3
+ "business",
4
+ "security",
5
+ "application",
6
+ "technology",
7
+ "api",
8
+ "data-model",
9
+ "data-store",
10
+ "ux",
11
+ "navigation",
12
+ "apm",
13
+ "testing"
14
+ ];
15
+ function getLayerOrder(layerName) {
16
+ const index = CANONICAL_LAYER_NAMES.indexOf(layerName);
17
+ return index >= 0 ? index + 1 : -1;
18
+ }
19
+ function getLayerByOrder(order) {
20
+ if (!(order < 1 || order > CANONICAL_LAYER_NAMES.length))
21
+ return CANONICAL_LAYER_NAMES[order - 1];
22
+ }
23
+ function isValidLayerName(name) {
24
+ return CANONICAL_LAYER_NAMES.includes(name);
25
+ }
26
+ export {
27
+ CANONICAL_LAYER_NAMES,
28
+ getLayerByOrder,
29
+ getLayerOrder,
30
+ isValidLayerName
31
+ };
32
+ //# sourceMappingURL=layers.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/core/layers.ts"],
4
+ "sourcesContent": ["/**\n * Canonical layer names and ordering for the 12-layer architecture model.\n * This is the source of truth for layer naming and ordering.\n */\n\nexport const CANONICAL_LAYER_NAMES = [\n 'motivation',\n 'business',\n 'security',\n 'application',\n 'technology',\n 'api',\n 'data-model',\n 'data-store',\n 'ux',\n 'navigation',\n 'apm',\n 'testing'\n] as const;\n\nexport type CanonicalLayerName = (typeof CANONICAL_LAYER_NAMES)[number];\n\n/**\n * Get the numeric order of a layer (1-12)\n */\nexport function getLayerOrder(layerName: string): number {\n const index = CANONICAL_LAYER_NAMES.indexOf(layerName as CanonicalLayerName);\n return index >= 0 ? index + 1 : -1;\n}\n\n/**\n * Get layer name by numeric order (1-12)\n */\nexport function getLayerByOrder(order: number): string | undefined {\n if (order < 1 || order > CANONICAL_LAYER_NAMES.length) {\n return undefined;\n }\n return CANONICAL_LAYER_NAMES[order - 1];\n}\n\n/**\n * Check if a layer name is valid (type predicate for compile-time narrowing)\n */\nexport function isValidLayerName(name: string): name is CanonicalLayerName {\n return CANONICAL_LAYER_NAMES.includes(name as CanonicalLayerName);\n}\n"],
5
+ "mappings": "AAKO,MAAM,wBAAwB;EACnC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAQI,SAAU,cAAc,WAAiB;AAC7C,QAAM,QAAQ,sBAAsB,QAAQ,SAA+B;AAC3E,SAAO,SAAS,IAAI,QAAQ,IAAI;AAClC;AAKM,SAAU,gBAAgB,OAAa;AAC3C,MAAI,UAAQ,KAAK,QAAQ,sBAAsB;AAG/C,WAAO,sBAAsB,QAAQ,CAAC;AACxC;AAKM,SAAU,iBAAiB,MAAY;AAC3C,SAAO,sBAAsB,SAAS,IAA0B;AAClE;",
6
+ "names": []
7
+ }