@memoarchitect/tools 0.6.7 → 0.7.2

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 (466) hide show
  1. package/README.md +36 -11
  2. package/package.json +19 -7
  3. package/packages/tools/lib/bin/memo.js +161 -10
  4. package/packages/tools/lib/bin/memo.js.map +1 -1
  5. package/packages/tools/lib/browser/index.d.ts +1 -1
  6. package/packages/tools/lib/browser/index.d.ts.map +1 -1
  7. package/packages/tools/lib/browser/index.js +1 -1
  8. package/packages/tools/lib/browser/index.js.map +1 -1
  9. package/packages/tools/lib/commands/ask.js +1 -1
  10. package/packages/tools/lib/commands/ask.js.map +1 -1
  11. package/packages/tools/lib/commands/check.d.ts.map +1 -1
  12. package/packages/tools/lib/commands/check.js +3 -9
  13. package/packages/tools/lib/commands/check.js.map +1 -1
  14. package/packages/tools/lib/commands/conformance.d.ts +36 -0
  15. package/packages/tools/lib/commands/conformance.d.ts.map +1 -0
  16. package/packages/tools/lib/commands/conformance.js +212 -0
  17. package/packages/tools/lib/commands/conformance.js.map +1 -0
  18. package/packages/tools/lib/commands/convert.d.ts +12 -0
  19. package/packages/tools/lib/commands/convert.d.ts.map +1 -0
  20. package/packages/tools/lib/commands/convert.js +103 -0
  21. package/packages/tools/lib/commands/convert.js.map +1 -0
  22. package/packages/tools/lib/commands/create-package.d.ts +1 -2
  23. package/packages/tools/lib/commands/create-package.d.ts.map +1 -1
  24. package/packages/tools/lib/commands/create-package.js.map +1 -1
  25. package/packages/tools/lib/commands/dev.d.ts +13 -0
  26. package/packages/tools/lib/commands/dev.d.ts.map +1 -1
  27. package/packages/tools/lib/commands/dev.js +208 -74
  28. package/packages/tools/lib/commands/dev.js.map +1 -1
  29. package/packages/tools/lib/commands/dhf-draft.js +1 -1
  30. package/packages/tools/lib/commands/dhf-draft.js.map +1 -1
  31. package/packages/tools/lib/commands/dhf-preview.js +1 -1
  32. package/packages/tools/lib/commands/dhf-preview.js.map +1 -1
  33. package/packages/tools/lib/commands/dhf.js +1 -1
  34. package/packages/tools/lib/commands/dhf.js.map +1 -1
  35. package/packages/tools/lib/commands/element.d.ts +34 -0
  36. package/packages/tools/lib/commands/element.d.ts.map +1 -0
  37. package/packages/tools/lib/commands/element.js +174 -0
  38. package/packages/tools/lib/commands/element.js.map +1 -0
  39. package/packages/tools/lib/commands/export.d.ts.map +1 -1
  40. package/packages/tools/lib/commands/export.js +39 -40
  41. package/packages/tools/lib/commands/export.js.map +1 -1
  42. package/packages/tools/lib/commands/generate.d.ts.map +1 -1
  43. package/packages/tools/lib/commands/generate.js +10 -7
  44. package/packages/tools/lib/commands/generate.js.map +1 -1
  45. package/packages/tools/lib/commands/import.d.ts.map +1 -1
  46. package/packages/tools/lib/commands/import.js +25 -12
  47. package/packages/tools/lib/commands/import.js.map +1 -1
  48. package/packages/tools/lib/commands/init.d.ts.map +1 -1
  49. package/packages/tools/lib/commands/init.js +34 -14
  50. package/packages/tools/lib/commands/init.js.map +1 -1
  51. package/packages/tools/lib/commands/inspect.d.ts +5 -0
  52. package/packages/tools/lib/commands/inspect.d.ts.map +1 -0
  53. package/packages/tools/lib/commands/inspect.js +56 -0
  54. package/packages/tools/lib/commands/inspect.js.map +1 -0
  55. package/packages/tools/lib/commands/lock.d.ts.map +1 -1
  56. package/packages/tools/lib/commands/lock.js +7 -2
  57. package/packages/tools/lib/commands/lock.js.map +1 -1
  58. package/packages/tools/lib/commands/ontology.d.ts.map +1 -1
  59. package/packages/tools/lib/commands/ontology.js +69 -116
  60. package/packages/tools/lib/commands/ontology.js.map +1 -1
  61. package/packages/tools/lib/commands/pack.d.ts +1 -1
  62. package/packages/tools/lib/commands/pack.d.ts.map +1 -1
  63. package/packages/tools/lib/commands/pack.js +20 -78
  64. package/packages/tools/lib/commands/pack.js.map +1 -1
  65. package/packages/tools/lib/commands/package.d.ts +10 -0
  66. package/packages/tools/lib/commands/package.d.ts.map +1 -0
  67. package/packages/tools/lib/commands/package.js +113 -0
  68. package/packages/tools/lib/commands/package.js.map +1 -0
  69. package/packages/tools/lib/commands/plugin.js +1 -1
  70. package/packages/tools/lib/commands/plugin.js.map +1 -1
  71. package/packages/tools/lib/commands/rules.d.ts.map +1 -1
  72. package/packages/tools/lib/commands/rules.js +120 -30
  73. package/packages/tools/lib/commands/rules.js.map +1 -1
  74. package/packages/tools/lib/commands/sysand-publish.d.ts.map +1 -1
  75. package/packages/tools/lib/commands/sysand-publish.js +14 -16
  76. package/packages/tools/lib/commands/sysand-publish.js.map +1 -1
  77. package/packages/tools/lib/commands/toolchain.d.ts +8 -0
  78. package/packages/tools/lib/commands/toolchain.d.ts.map +1 -0
  79. package/packages/tools/lib/commands/toolchain.js +64 -0
  80. package/packages/tools/lib/commands/toolchain.js.map +1 -0
  81. package/packages/tools/lib/commands/validate.d.ts +1 -1
  82. package/packages/tools/lib/commands/validate.d.ts.map +1 -1
  83. package/packages/tools/lib/commands/validate.js +183 -56
  84. package/packages/tools/lib/commands/validate.js.map +1 -1
  85. package/packages/tools/lib/completeness/tracker.d.ts +10 -2
  86. package/packages/tools/lib/completeness/tracker.d.ts.map +1 -1
  87. package/packages/tools/lib/completeness/tracker.js +16 -21
  88. package/packages/tools/lib/completeness/tracker.js.map +1 -1
  89. package/packages/tools/lib/conformance/baseline.d.ts +26 -0
  90. package/packages/tools/lib/conformance/baseline.d.ts.map +1 -0
  91. package/packages/tools/lib/conformance/baseline.js +170 -0
  92. package/packages/tools/lib/conformance/baseline.js.map +1 -0
  93. package/packages/tools/lib/conformance/bnf.d.ts +84 -0
  94. package/packages/tools/lib/conformance/bnf.d.ts.map +1 -0
  95. package/packages/tools/lib/conformance/bnf.js +166 -0
  96. package/packages/tools/lib/conformance/bnf.js.map +1 -0
  97. package/packages/tools/lib/conformance/corpus.d.ts +125 -0
  98. package/packages/tools/lib/conformance/corpus.d.ts.map +1 -0
  99. package/packages/tools/lib/conformance/corpus.js +190 -0
  100. package/packages/tools/lib/conformance/corpus.js.map +1 -0
  101. package/packages/tools/lib/conformance/diff-xmi.d.ts +118 -0
  102. package/packages/tools/lib/conformance/diff-xmi.d.ts.map +1 -0
  103. package/packages/tools/lib/conformance/diff-xmi.js +276 -0
  104. package/packages/tools/lib/conformance/diff-xmi.js.map +1 -0
  105. package/packages/tools/lib/conformance/generated/syside-rules.d.ts +10 -0
  106. package/packages/tools/lib/conformance/generated/syside-rules.d.ts.map +1 -0
  107. package/packages/tools/lib/conformance/generated/syside-rules.js +1142 -0
  108. package/packages/tools/lib/conformance/generated/syside-rules.js.map +1 -0
  109. package/packages/tools/lib/conformance/index.d.ts +7 -0
  110. package/packages/tools/lib/conformance/index.d.ts.map +1 -0
  111. package/packages/tools/lib/conformance/index.js +19 -0
  112. package/packages/tools/lib/conformance/index.js.map +1 -0
  113. package/packages/tools/lib/conformance/run.d.ts +117 -0
  114. package/packages/tools/lib/conformance/run.d.ts.map +1 -0
  115. package/packages/tools/lib/conformance/run.js +0 -0
  116. package/packages/tools/lib/conformance/run.js.map +1 -0
  117. package/packages/tools/lib/conformance/xmi.d.ts +45 -0
  118. package/packages/tools/lib/conformance/xmi.d.ts.map +1 -0
  119. package/packages/tools/lib/conformance/xmi.js +148 -0
  120. package/packages/tools/lib/conformance/xmi.js.map +1 -0
  121. package/packages/tools/lib/dhf/template-resolver.js +1 -1
  122. package/packages/tools/lib/dhf/template-resolver.js.map +1 -1
  123. package/packages/tools/lib/import/column-mapper.d.ts +2 -2
  124. package/packages/tools/lib/import/column-mapper.d.ts.map +1 -1
  125. package/packages/tools/lib/import/column-mapper.js +3 -3
  126. package/packages/tools/lib/import/column-mapper.js.map +1 -1
  127. package/packages/tools/lib/index.d.ts +20 -3
  128. package/packages/tools/lib/index.d.ts.map +1 -1
  129. package/packages/tools/lib/index.js +19 -2
  130. package/packages/tools/lib/index.js.map +1 -1
  131. package/packages/tools/lib/language/generated/ast.d.ts +196 -51
  132. package/packages/tools/lib/language/generated/ast.d.ts.map +1 -1
  133. package/packages/tools/lib/language/generated/ast.js +136 -15
  134. package/packages/tools/lib/language/generated/ast.js.map +1 -1
  135. package/packages/tools/lib/language/generated/grammar.d.ts.map +1 -1
  136. package/packages/tools/lib/language/generated/grammar.js +867 -295
  137. package/packages/tools/lib/language/generated/grammar.js.map +1 -1
  138. package/packages/tools/lib/llm/chat-engine.d.ts +4 -3
  139. package/packages/tools/lib/llm/chat-engine.d.ts.map +1 -1
  140. package/packages/tools/lib/llm/chat-engine.js +15 -12
  141. package/packages/tools/lib/llm/chat-engine.js.map +1 -1
  142. package/packages/tools/lib/llm/generate-engine.d.ts +7 -2
  143. package/packages/tools/lib/llm/generate-engine.d.ts.map +1 -1
  144. package/packages/tools/lib/llm/generate-engine.js +22 -4
  145. package/packages/tools/lib/llm/generate-engine.js.map +1 -1
  146. package/packages/tools/lib/llm/index.d.ts +1 -0
  147. package/packages/tools/lib/llm/index.d.ts.map +1 -1
  148. package/packages/tools/lib/llm/index.js +1 -0
  149. package/packages/tools/lib/llm/index.js.map +1 -1
  150. package/packages/tools/lib/llm/model-context.d.ts +2 -2
  151. package/packages/tools/lib/llm/model-context.d.ts.map +1 -1
  152. package/packages/tools/lib/llm/model-context.js +7 -13
  153. package/packages/tools/lib/llm/model-context.js.map +1 -1
  154. package/packages/tools/lib/llm/sysml-guidance.d.ts +8 -0
  155. package/packages/tools/lib/llm/sysml-guidance.d.ts.map +1 -0
  156. package/packages/tools/lib/llm/sysml-guidance.js +28 -0
  157. package/packages/tools/lib/llm/sysml-guidance.js.map +1 -0
  158. package/packages/tools/lib/lock.d.ts +14 -8
  159. package/packages/tools/lib/lock.d.ts.map +1 -1
  160. package/packages/tools/lib/lock.js +97 -108
  161. package/packages/tools/lib/lock.js.map +1 -1
  162. package/packages/tools/lib/mcp/model-loader.d.ts +3 -0
  163. package/packages/tools/lib/mcp/model-loader.d.ts.map +1 -1
  164. package/packages/tools/lib/mcp/model-loader.js +9 -5
  165. package/packages/tools/lib/mcp/model-loader.js.map +1 -1
  166. package/packages/tools/lib/mcp/tools.d.ts +3 -0
  167. package/packages/tools/lib/mcp/tools.d.ts.map +1 -1
  168. package/packages/tools/lib/mcp/tools.js +8 -9
  169. package/packages/tools/lib/mcp/tools.js.map +1 -1
  170. package/packages/tools/lib/model/activity-notation.d.ts +54 -0
  171. package/packages/tools/lib/model/activity-notation.d.ts.map +1 -0
  172. package/packages/tools/lib/model/activity-notation.js +208 -0
  173. package/packages/tools/lib/model/activity-notation.js.map +1 -0
  174. package/packages/tools/lib/model/builder.d.ts +3 -0
  175. package/packages/tools/lib/model/builder.d.ts.map +1 -1
  176. package/packages/tools/lib/model/builder.js +231 -19
  177. package/packages/tools/lib/model/builder.js.map +1 -1
  178. package/packages/tools/lib/model/config-loader.d.ts +19 -25
  179. package/packages/tools/lib/model/config-loader.d.ts.map +1 -1
  180. package/packages/tools/lib/model/config-loader.js +51 -233
  181. package/packages/tools/lib/model/config-loader.js.map +1 -1
  182. package/packages/tools/lib/model/config.d.ts +42 -213
  183. package/packages/tools/lib/model/config.d.ts.map +1 -1
  184. package/packages/tools/lib/model/config.js +11 -9
  185. package/packages/tools/lib/model/config.js.map +1 -1
  186. package/packages/tools/lib/model/effective-scope.d.ts +74 -0
  187. package/packages/tools/lib/model/effective-scope.d.ts.map +1 -0
  188. package/packages/tools/lib/model/effective-scope.js +133 -0
  189. package/packages/tools/lib/model/effective-scope.js.map +1 -0
  190. package/packages/tools/lib/model/ir-identity.d.ts +94 -0
  191. package/packages/tools/lib/model/ir-identity.d.ts.map +1 -0
  192. package/packages/tools/lib/model/ir-identity.js +178 -0
  193. package/packages/tools/lib/model/ir-identity.js.map +1 -0
  194. package/packages/tools/lib/model/kind-registry.d.ts +114 -1
  195. package/packages/tools/lib/model/kind-registry.d.ts.map +1 -1
  196. package/packages/tools/lib/model/kind-registry.js +148 -4
  197. package/packages/tools/lib/model/kind-registry.js.map +1 -1
  198. package/packages/tools/lib/model/layer-resolver.js +1 -1
  199. package/packages/tools/lib/model/layer-resolver.js.map +1 -1
  200. package/packages/tools/lib/model/methodology-loader.d.ts +19 -24
  201. package/packages/tools/lib/model/methodology-loader.d.ts.map +1 -1
  202. package/packages/tools/lib/model/methodology-loader.js +179 -176
  203. package/packages/tools/lib/model/methodology-loader.js.map +1 -1
  204. package/packages/tools/lib/model/methodology-resolver.d.ts +115 -0
  205. package/packages/tools/lib/model/methodology-resolver.d.ts.map +1 -0
  206. package/packages/tools/lib/model/methodology-resolver.js +317 -0
  207. package/packages/tools/lib/model/methodology-resolver.js.map +1 -0
  208. package/packages/tools/lib/model/native-project.d.ts +130 -0
  209. package/packages/tools/lib/model/native-project.d.ts.map +1 -0
  210. package/packages/tools/lib/model/native-project.js +570 -0
  211. package/packages/tools/lib/model/native-project.js.map +1 -0
  212. package/packages/tools/lib/model/ontology-loader.d.ts +34 -21
  213. package/packages/tools/lib/model/ontology-loader.d.ts.map +1 -1
  214. package/packages/tools/lib/model/ontology-loader.js +340 -614
  215. package/packages/tools/lib/model/ontology-loader.js.map +1 -1
  216. package/packages/tools/lib/model/package-manifest.d.ts +37 -0
  217. package/packages/tools/lib/model/package-manifest.d.ts.map +1 -0
  218. package/packages/tools/lib/model/package-manifest.js +96 -0
  219. package/packages/tools/lib/model/package-manifest.js.map +1 -0
  220. package/packages/tools/lib/model/parser-utils.d.ts +31 -0
  221. package/packages/tools/lib/model/parser-utils.d.ts.map +1 -1
  222. package/packages/tools/lib/model/parser-utils.js +89 -1
  223. package/packages/tools/lib/model/parser-utils.js.map +1 -1
  224. package/packages/tools/lib/model/paths.d.ts +10 -4
  225. package/packages/tools/lib/model/paths.d.ts.map +1 -1
  226. package/packages/tools/lib/model/paths.js +10 -4
  227. package/packages/tools/lib/model/paths.js.map +1 -1
  228. package/packages/tools/lib/model/project-conversion.d.ts +226 -0
  229. package/packages/tools/lib/model/project-conversion.d.ts.map +1 -0
  230. package/packages/tools/lib/model/project-conversion.js +946 -0
  231. package/packages/tools/lib/model/project-conversion.js.map +1 -0
  232. package/packages/tools/lib/model/relationship-legality.d.ts +10 -0
  233. package/packages/tools/lib/model/relationship-legality.d.ts.map +1 -1
  234. package/packages/tools/lib/model/relationship-legality.js.map +1 -1
  235. package/packages/tools/lib/model/relationship-registry.d.ts +16 -1
  236. package/packages/tools/lib/model/relationship-registry.d.ts.map +1 -1
  237. package/packages/tools/lib/model/relationship-registry.js.map +1 -1
  238. package/packages/tools/lib/model/semantic.d.ts +27 -0
  239. package/packages/tools/lib/model/semantic.d.ts.map +1 -1
  240. package/packages/tools/lib/model/semantic.js +3 -0
  241. package/packages/tools/lib/model/semantic.js.map +1 -1
  242. package/packages/tools/lib/model/settings-boundary.d.ts +19 -0
  243. package/packages/tools/lib/model/settings-boundary.d.ts.map +1 -0
  244. package/packages/tools/lib/model/settings-boundary.js +118 -0
  245. package/packages/tools/lib/model/settings-boundary.js.map +1 -0
  246. package/packages/tools/lib/model/short-id.d.ts.map +1 -1
  247. package/packages/tools/lib/model/short-id.js +2 -0
  248. package/packages/tools/lib/model/short-id.js.map +1 -1
  249. package/packages/tools/lib/model/source-graph.d.ts.map +1 -1
  250. package/packages/tools/lib/model/source-graph.js +5 -1
  251. package/packages/tools/lib/model/source-graph.js.map +1 -1
  252. package/packages/tools/lib/model/source-provenance.d.ts +112 -0
  253. package/packages/tools/lib/model/source-provenance.d.ts.map +1 -0
  254. package/packages/tools/lib/model/source-provenance.js +169 -0
  255. package/packages/tools/lib/model/source-provenance.js.map +1 -0
  256. package/packages/tools/lib/model/sysml-ir.d.ts +9 -0
  257. package/packages/tools/lib/model/sysml-ir.d.ts.map +1 -0
  258. package/packages/tools/lib/model/sysml-ir.js +105 -0
  259. package/packages/tools/lib/model/sysml-ir.js.map +1 -0
  260. package/packages/tools/lib/model/view-deriver.d.ts.map +1 -1
  261. package/packages/tools/lib/model/view-deriver.js +36 -6
  262. package/packages/tools/lib/model/view-deriver.js.map +1 -1
  263. package/packages/tools/lib/model/view-kinds.d.ts +2 -0
  264. package/packages/tools/lib/model/view-kinds.d.ts.map +1 -1
  265. package/packages/tools/lib/model/view-kinds.js +11 -0
  266. package/packages/tools/lib/model/view-kinds.js.map +1 -1
  267. package/packages/tools/lib/ontology/owl-exporter.d.ts +2 -2
  268. package/packages/tools/lib/ontology/owl-exporter.d.ts.map +1 -1
  269. package/packages/tools/lib/ontology/owl-exporter.js +12 -12
  270. package/packages/tools/lib/ontology/owl-exporter.js.map +1 -1
  271. package/packages/tools/lib/operations/ai-authoring.d.ts +24 -0
  272. package/packages/tools/lib/operations/ai-authoring.d.ts.map +1 -0
  273. package/packages/tools/lib/operations/ai-authoring.js +77 -0
  274. package/packages/tools/lib/operations/ai-authoring.js.map +1 -0
  275. package/packages/tools/lib/operations/authoring.d.ts +40 -0
  276. package/packages/tools/lib/operations/authoring.d.ts.map +1 -0
  277. package/packages/tools/lib/operations/authoring.js +56 -0
  278. package/packages/tools/lib/operations/authoring.js.map +1 -0
  279. package/packages/tools/lib/operations/index.d.ts +2 -0
  280. package/packages/tools/lib/operations/index.d.ts.map +1 -1
  281. package/packages/tools/lib/operations/index.js +2 -0
  282. package/packages/tools/lib/operations/index.js.map +1 -1
  283. package/packages/tools/lib/operations/project-snapshot.d.ts +28 -3
  284. package/packages/tools/lib/operations/project-snapshot.d.ts.map +1 -1
  285. package/packages/tools/lib/operations/project-snapshot.js +79 -30
  286. package/packages/tools/lib/operations/project-snapshot.js.map +1 -1
  287. package/packages/tools/lib/protocol/messages.d.ts +298 -11
  288. package/packages/tools/lib/protocol/messages.d.ts.map +1 -1
  289. package/packages/tools/lib/serializer/csv-io.d.ts +7 -7
  290. package/packages/tools/lib/serializer/csv-io.d.ts.map +1 -1
  291. package/packages/tools/lib/serializer/csv-io.js +11 -11
  292. package/packages/tools/lib/serializer/csv-io.js.map +1 -1
  293. package/packages/tools/lib/serializer/sysml-generator.d.ts.map +1 -1
  294. package/packages/tools/lib/serializer/sysml-generator.js +34 -2
  295. package/packages/tools/lib/serializer/sysml-generator.js.map +1 -1
  296. package/packages/tools/lib/server/config-resolver.d.ts +8 -4
  297. package/packages/tools/lib/server/config-resolver.d.ts.map +1 -1
  298. package/packages/tools/lib/server/config-resolver.js +25 -44
  299. package/packages/tools/lib/server/config-resolver.js.map +1 -1
  300. package/packages/tools/lib/server/conflict-policy.d.ts +44 -0
  301. package/packages/tools/lib/server/conflict-policy.d.ts.map +1 -0
  302. package/packages/tools/lib/server/conflict-policy.js +94 -0
  303. package/packages/tools/lib/server/conflict-policy.js.map +1 -0
  304. package/packages/tools/lib/server/dev-server.d.ts +32 -2
  305. package/packages/tools/lib/server/dev-server.d.ts.map +1 -1
  306. package/packages/tools/lib/server/dev-server.js +721 -53
  307. package/packages/tools/lib/server/dev-server.js.map +1 -1
  308. package/packages/tools/lib/server/element-writer.d.ts +11 -0
  309. package/packages/tools/lib/server/element-writer.d.ts.map +1 -0
  310. package/packages/tools/lib/server/element-writer.js +123 -0
  311. package/packages/tools/lib/server/element-writer.js.map +1 -0
  312. package/packages/tools/lib/server/file-watcher.d.ts +4 -1
  313. package/packages/tools/lib/server/file-watcher.d.ts.map +1 -1
  314. package/packages/tools/lib/server/file-watcher.js +17 -7
  315. package/packages/tools/lib/server/file-watcher.js.map +1 -1
  316. package/packages/tools/lib/server/mutation-domain.d.ts +22 -0
  317. package/packages/tools/lib/server/mutation-domain.d.ts.map +1 -0
  318. package/packages/tools/lib/server/mutation-domain.js +87 -0
  319. package/packages/tools/lib/server/mutation-domain.js.map +1 -0
  320. package/packages/tools/lib/server/persistor.d.ts +63 -8
  321. package/packages/tools/lib/server/persistor.d.ts.map +1 -1
  322. package/packages/tools/lib/server/persistor.js +152 -44
  323. package/packages/tools/lib/server/persistor.js.map +1 -1
  324. package/packages/tools/lib/server/relationship-writer.d.ts +28 -4
  325. package/packages/tools/lib/server/relationship-writer.d.ts.map +1 -1
  326. package/packages/tools/lib/server/relationship-writer.js +98 -13
  327. package/packages/tools/lib/server/relationship-writer.js.map +1 -1
  328. package/packages/tools/lib/server/rule-policy-writer.d.ts +40 -0
  329. package/packages/tools/lib/server/rule-policy-writer.d.ts.map +1 -0
  330. package/packages/tools/lib/server/rule-policy-writer.js +124 -0
  331. package/packages/tools/lib/server/rule-policy-writer.js.map +1 -0
  332. package/packages/tools/lib/server/runtime-budget.d.ts +14 -0
  333. package/packages/tools/lib/server/runtime-budget.d.ts.map +1 -0
  334. package/packages/tools/lib/server/runtime-budget.js +15 -0
  335. package/packages/tools/lib/server/runtime-budget.js.map +1 -0
  336. package/packages/tools/lib/server/sysml-notation.d.ts +36 -0
  337. package/packages/tools/lib/server/sysml-notation.d.ts.map +1 -0
  338. package/packages/tools/lib/server/sysml-notation.js +87 -0
  339. package/packages/tools/lib/server/sysml-notation.js.map +1 -0
  340. package/packages/tools/lib/sysml-ir/generated/sysml-derivations.d.ts +9 -0
  341. package/packages/tools/lib/sysml-ir/generated/sysml-derivations.d.ts.map +1 -0
  342. package/packages/tools/lib/sysml-ir/generated/sysml-derivations.js +315 -0
  343. package/packages/tools/lib/sysml-ir/generated/sysml-derivations.js.map +1 -0
  344. package/packages/tools/lib/sysml-ir/generated/sysml-metamodel.d.ts +5206 -0
  345. package/packages/tools/lib/sysml-ir/generated/sysml-metamodel.d.ts.map +1 -0
  346. package/packages/tools/lib/sysml-ir/generated/sysml-metamodel.js +1933 -0
  347. package/packages/tools/lib/sysml-ir/generated/sysml-metamodel.js.map +1 -0
  348. package/packages/tools/lib/sysml-ir/index.d.ts +3 -0
  349. package/packages/tools/lib/sysml-ir/index.d.ts.map +1 -0
  350. package/packages/tools/lib/sysml-ir/index.js +3 -0
  351. package/packages/tools/lib/sysml-ir/index.js.map +1 -0
  352. package/packages/tools/lib/sysml-ir/ir.d.ts +50 -0
  353. package/packages/tools/lib/sysml-ir/ir.d.ts.map +1 -0
  354. package/packages/tools/lib/sysml-ir/ir.js +2 -0
  355. package/packages/tools/lib/sysml-ir/ir.js.map +1 -0
  356. package/packages/tools/lib/sysmlc/bin/memo-sysmlc.d.ts +3 -0
  357. package/packages/tools/lib/sysmlc/bin/memo-sysmlc.d.ts.map +1 -0
  358. package/packages/tools/lib/sysmlc/bin/memo-sysmlc.js +97 -0
  359. package/packages/tools/lib/sysmlc/bin/memo-sysmlc.js.map +1 -0
  360. package/packages/tools/lib/sysmlc/index.d.ts +2 -0
  361. package/packages/tools/lib/sysmlc/index.d.ts.map +1 -0
  362. package/packages/tools/lib/sysmlc/index.js +7 -0
  363. package/packages/tools/lib/sysmlc/index.js.map +1 -0
  364. package/packages/tools/lib/sysmlc/server.d.ts +29 -0
  365. package/packages/tools/lib/sysmlc/server.d.ts.map +1 -0
  366. package/packages/tools/lib/sysmlc/server.js +168 -0
  367. package/packages/tools/lib/sysmlc/server.js.map +1 -0
  368. package/packages/tools/lib/toolchain/default-registry.d.ts +12 -0
  369. package/packages/tools/lib/toolchain/default-registry.d.ts.map +1 -0
  370. package/packages/tools/lib/toolchain/default-registry.js +28 -0
  371. package/packages/tools/lib/toolchain/default-registry.js.map +1 -0
  372. package/packages/tools/lib/toolchain/diagnostic.d.ts +57 -0
  373. package/packages/tools/lib/toolchain/diagnostic.d.ts.map +1 -0
  374. package/packages/tools/lib/toolchain/diagnostic.js +69 -0
  375. package/packages/tools/lib/toolchain/diagnostic.js.map +1 -0
  376. package/packages/tools/lib/toolchain/effective.d.ts +36 -0
  377. package/packages/tools/lib/toolchain/effective.d.ts.map +1 -0
  378. package/packages/tools/lib/toolchain/effective.js +91 -0
  379. package/packages/tools/lib/toolchain/effective.js.map +1 -0
  380. package/packages/tools/lib/toolchain/index.d.ts +11 -0
  381. package/packages/tools/lib/toolchain/index.d.ts.map +1 -0
  382. package/packages/tools/lib/toolchain/index.js +21 -0
  383. package/packages/tools/lib/toolchain/index.js.map +1 -0
  384. package/packages/tools/lib/toolchain/lowering.d.ts +63 -0
  385. package/packages/tools/lib/toolchain/lowering.d.ts.map +1 -0
  386. package/packages/tools/lib/toolchain/lowering.js +100 -0
  387. package/packages/tools/lib/toolchain/lowering.js.map +1 -0
  388. package/packages/tools/lib/toolchain/operations.d.ts +87 -0
  389. package/packages/tools/lib/toolchain/operations.d.ts.map +1 -0
  390. package/packages/tools/lib/toolchain/operations.js +111 -0
  391. package/packages/tools/lib/toolchain/operations.js.map +1 -0
  392. package/packages/tools/lib/toolchain/process.d.ts +45 -0
  393. package/packages/tools/lib/toolchain/process.d.ts.map +1 -0
  394. package/packages/tools/lib/toolchain/process.js +125 -0
  395. package/packages/tools/lib/toolchain/process.js.map +1 -0
  396. package/packages/tools/lib/toolchain/protocol.d.ts +122 -0
  397. package/packages/tools/lib/toolchain/protocol.d.ts.map +1 -0
  398. package/packages/tools/lib/toolchain/protocol.js +74 -0
  399. package/packages/tools/lib/toolchain/protocol.js.map +1 -0
  400. package/packages/tools/lib/toolchain/providers/internal-kpar.d.ts +9 -0
  401. package/packages/tools/lib/toolchain/providers/internal-kpar.d.ts.map +1 -0
  402. package/packages/tools/lib/toolchain/providers/internal-kpar.js +84 -0
  403. package/packages/tools/lib/toolchain/providers/internal-kpar.js.map +1 -0
  404. package/packages/tools/lib/toolchain/providers/internal.d.ts +33 -0
  405. package/packages/tools/lib/toolchain/providers/internal.d.ts.map +1 -0
  406. package/packages/tools/lib/toolchain/providers/internal.js +286 -0
  407. package/packages/tools/lib/toolchain/providers/internal.js.map +1 -0
  408. package/packages/tools/lib/toolchain/providers/sysand.d.ts +12 -0
  409. package/packages/tools/lib/toolchain/providers/sysand.d.ts.map +1 -0
  410. package/packages/tools/lib/toolchain/providers/sysand.js +110 -0
  411. package/packages/tools/lib/toolchain/providers/sysand.js.map +1 -0
  412. package/packages/tools/lib/toolchain/providers/syside.d.ts +24 -0
  413. package/packages/tools/lib/toolchain/providers/syside.d.ts.map +1 -0
  414. package/packages/tools/lib/toolchain/providers/syside.js +208 -0
  415. package/packages/tools/lib/toolchain/providers/syside.js.map +1 -0
  416. package/packages/tools/lib/toolchain/registry.d.ts +192 -0
  417. package/packages/tools/lib/toolchain/registry.d.ts.map +1 -0
  418. package/packages/tools/lib/toolchain/registry.js +130 -0
  419. package/packages/tools/lib/toolchain/registry.js.map +1 -0
  420. package/packages/tools/lib/toolchain/schema.d.ts +30 -0
  421. package/packages/tools/lib/toolchain/schema.d.ts.map +1 -0
  422. package/packages/tools/lib/toolchain/schema.js +112 -0
  423. package/packages/tools/lib/toolchain/schema.js.map +1 -0
  424. package/packages/tools/lib/toolchain/sysmlc-client.d.ts +77 -0
  425. package/packages/tools/lib/toolchain/sysmlc-client.d.ts.map +1 -0
  426. package/packages/tools/lib/toolchain/sysmlc-client.js +0 -0
  427. package/packages/tools/lib/toolchain/sysmlc-client.js.map +1 -0
  428. package/packages/tools/lib/validator/architecture-validator.d.ts +8 -1
  429. package/packages/tools/lib/validator/architecture-validator.d.ts.map +1 -1
  430. package/packages/tools/lib/validator/architecture-validator.js +25 -1
  431. package/packages/tools/lib/validator/architecture-validator.js.map +1 -1
  432. package/packages/tools/lib/validator/builtin-rules.d.ts +16 -0
  433. package/packages/tools/lib/validator/builtin-rules.d.ts.map +1 -0
  434. package/packages/tools/lib/validator/builtin-rules.js +62 -0
  435. package/packages/tools/lib/validator/builtin-rules.js.map +1 -0
  436. package/packages/tools/lib/validator/constraint-eval.d.ts +15 -0
  437. package/packages/tools/lib/validator/constraint-eval.d.ts.map +1 -1
  438. package/packages/tools/lib/validator/constraint-eval.js +62 -7
  439. package/packages/tools/lib/validator/constraint-eval.js.map +1 -1
  440. package/packages/tools/lib/validator/constraint-loader.d.ts +22 -4
  441. package/packages/tools/lib/validator/constraint-loader.d.ts.map +1 -1
  442. package/packages/tools/lib/validator/constraint-loader.js +100 -27
  443. package/packages/tools/lib/validator/constraint-loader.js.map +1 -1
  444. package/packages/tools/lib/validator/rule-engine.d.ts +2 -1
  445. package/packages/tools/lib/validator/rule-engine.d.ts.map +1 -1
  446. package/packages/tools/lib/validator/rule-engine.js +56 -5
  447. package/packages/tools/lib/validator/rule-engine.js.map +1 -1
  448. package/packages/tools/lib/validator/sysml-constraints.d.ts +64 -0
  449. package/packages/tools/lib/validator/sysml-constraints.d.ts.map +1 -0
  450. package/packages/tools/lib/validator/sysml-constraints.js +251 -0
  451. package/packages/tools/lib/validator/sysml-constraints.js.map +1 -0
  452. package/packages/tools/lib/validator/types.d.ts +33 -0
  453. package/packages/tools/lib/validator/types.d.ts.map +1 -1
  454. package/packages/tools/lib/version.d.ts +2 -0
  455. package/packages/tools/lib/version.d.ts.map +1 -0
  456. package/packages/tools/lib/version.js +26 -0
  457. package/packages/tools/lib/version.js.map +1 -0
  458. package/packages/tools/src/grammar/memo-sysml.langium +104 -18
  459. package/packages/tools/lib/model/dimension-filter.d.ts +0 -33
  460. package/packages/tools/lib/model/dimension-filter.d.ts.map +0 -1
  461. package/packages/tools/lib/model/dimension-filter.js +0 -57
  462. package/packages/tools/lib/model/dimension-filter.js.map +0 -1
  463. package/packages/tools/lib/model/toolchain.d.ts +0 -12
  464. package/packages/tools/lib/model/toolchain.d.ts.map +0 -1
  465. package/packages/tools/lib/model/toolchain.js +0 -92
  466. package/packages/tools/lib/model/toolchain.js.map +0 -1
@@ -9,14 +9,17 @@
9
9
  // const model = buildMemoModel(documents, config, errors, registries);
10
10
  // ─────────────────────────────────────────────────────────────────────────────
11
11
  import { existsSync, readFileSync, readdirSync } from 'node:fs';
12
- import { resolve, dirname, join, basename } from 'node:path';
12
+ import { resolve, dirname, join, basename, sep } from 'node:path';
13
13
  import { fileURLToPath } from 'node:url';
14
- import { parse as parseYaml } from 'yaml';
14
+ import { isConnectionDefinition, isDocComment, isEndDeclaration, isPackageDeclaration, } from '../language/generated/ast.js';
15
15
  import { KindRegistry } from './kind-registry.js';
16
16
  import { RelationshipRegistry } from './relationship-registry.js';
17
- import { parseFiles } from './parser-utils.js';
17
+ import { parseFileToAstSync } from './parser-utils.js';
18
18
  import { VENDOR_ONTOLOGY_DIR } from './paths.js';
19
19
  import { discoverMemoManifests, findMemoManifests, resolveManifestPath } from './manifest.js';
20
+ import { CONFIG_SEARCH_ORDER, readPackageManifest, } from './package-manifest.js';
21
+ import { ProvenanceTable } from './source-provenance.js';
22
+ import { discoverLibraryRoots, resolveNativeProject } from './native-project.js';
20
23
  /** Layer color palette (mirrors web constants) */
21
24
  const LAYER_COLORS = {
22
25
  // ontology-core layers
@@ -42,48 +45,106 @@ const LAYER_COLORS = {
42
45
  artifacts: '#D97706',
43
46
  };
44
47
  /**
45
- * Parse SysML constructs (part def, requirement def, action def, connection def)
46
- * from a single SysML file, extracting specialization and doc comments.
48
+ * AST node `$type` → the `<construct> def` spelling reported in catalog DTOs.
49
+ *
50
+ * Kept separate from kind-registry's own map because that one deliberately
51
+ * omits connection/metadata definitions (they classify relationships and
52
+ * annotations, not model elements) while the catalog view lists them.
53
+ */
54
+ const CATALOG_CONSTRUCTS = {
55
+ PartDefinition: 'part def',
56
+ RequirementDefinition: 'requirement def',
57
+ VerificationDefinition: 'verification def',
58
+ StateDefinition: 'state def',
59
+ UseCaseDeclaration: 'use case def',
60
+ ActionDefinition: 'action def',
61
+ AttributeDefinition: 'attribute def',
62
+ ItemDefinition: 'item def',
63
+ PortDefinition: 'port def',
64
+ InterfaceDefinition: 'interface def',
65
+ EnumDefinition: 'enum def',
66
+ ConnectionDefinition: 'connection def',
67
+ MetadataDefinition: 'metadata def',
68
+ // ConstraintDefinition is deliberately absent: rules are not catalog kinds,
69
+ // and including them would add 33 entries to the ontology browser that the
70
+ // previous scanner never listed. Session 1 changes no output.
71
+ };
72
+ /**
73
+ * Read the definitions and connection endpoints declared in one SysML file.
74
+ *
75
+ * This walks the parsed AST. The previous implementation pattern-matched the
76
+ * source text, which meant a definition inside a block comment counted, a
77
+ * `connection def` whose body contained a nested brace truncated at the wrong
78
+ * place, and a qualified supertype (`:> memo::core::MemoPart`) was recorded as
79
+ * the bare last segment only by accident of the character class. Reading the
80
+ * tree removes all three failure modes and costs one parse per file.
47
81
  */
48
82
  function parseConstructsInFile(filePath) {
49
83
  const kinds = [];
50
84
  const relationships = [];
51
- try {
52
- const content = readFileSync(filePath, 'utf-8');
53
- // Match kind definitions with optional :> (specializes) and preceding doc comments
54
- // Pattern: [doc /* ... */] <construct> def Name [:> SuperType] { ... }
55
- const kindRegex = /(?:doc\s+\/\*\s*([\s\S]*?)\s*\*\/\s*)?^\s*(?:abstract\s+)?(?:part|requirement|verification|state|use\s+case|action|attribute|item|port|interface|enum|connection|metadata)\s+def\s+(\w+)(?:\s*(?::>|specializes)\s+(\w+))?/gm;
56
- for (const m of content.matchAll(kindRegex)) {
57
- const construct = m[0].match(/(?:abstract\s+)?(part|requirement|verification|state|use\s+case|action|attribute|item|port|interface|enum|connection|metadata)\s+def/)?.[0]?.trim() ?? 'part def';
58
- kinds.push({
59
- name: m[2],
60
- construct,
61
- derivesFrom: m[3] || undefined,
62
- description: m[1]?.replace(/\s+/g, ' ').trim() || undefined,
63
- isAbstract: /\babstract\s+(?:part|requirement|verification|state|use\s+case|action|attribute|item|port|interface|enum|connection|metadata)\s+def\b/.test(m[0]),
64
- });
65
- }
66
- // Match connection defs with endpoint type annotations
67
- // Pattern: connection def Name { end name : TypeName [mult]; end name : TypeName [mult]; }
68
- const connBlockRegex = /(?:connection|binding|allocation)\s+def\s+(\w+)\s*\{([^}]*)\}/g;
69
- for (const m of content.matchAll(connBlockRegex)) {
70
- const name = m[1];
71
- const body = m[2];
72
- // Extract typed ends: `end <name> : <TypeName> [` — ignore untyped ends like `end subject[1]`
73
- const endRegex = /end\s+\w+\s*:\s*(\w+)\s*\[/g;
85
+ const model = parseFileToAstSync(filePath);
86
+ if (!model)
87
+ return { kinds, relationships };
88
+ for (const { node, doc } of walkDefinitions(model)) {
89
+ const construct = CATALOG_CONSTRUCTS[node.$type];
90
+ if (!construct)
91
+ continue;
92
+ const name = node.name;
93
+ if (!name)
94
+ continue;
95
+ // The catalog reports the bare supertype name, matching how kinds are
96
+ // keyed in the browser DTO; the qualified form is preserved in the
97
+ // registry, which is what conformance walks.
98
+ const superType = node.specialization?.superType;
99
+ kinds.push({
100
+ name,
101
+ construct,
102
+ derivesFrom: superType ? superType.split('::').pop() : undefined,
103
+ description: doc,
104
+ isAbstract: node.isAbstract || undefined,
105
+ });
106
+ if (isConnectionDefinition(node)) {
74
107
  const typedEnds = [];
75
- for (const em of body.matchAll(endRegex))
76
- typedEnds.push(em[1]);
77
- relationships.push({
78
- name,
79
- sourceKind: typedEnds[0],
80
- targetKind: typedEnds[1],
81
- });
108
+ for (const member of node.body) {
109
+ if (isEndDeclaration(member) && member.type) {
110
+ typedEnds.push(member.type.split('::').pop() ?? member.type);
111
+ }
112
+ }
113
+ relationships.push({ name, sourceKind: typedEnds[0], targetKind: typedEnds[1] });
82
114
  }
83
115
  }
84
- catch { /* skip */ }
85
116
  return { kinds, relationships };
86
117
  }
118
+ /**
119
+ * Yield every definition in a model with the doc comment that precedes it.
120
+ *
121
+ * Packages nest arbitrarily, so this recurses rather than assuming the
122
+ * ontology's current two-level shape.
123
+ */
124
+ function* walkDefinitions(container) {
125
+ const members = (container.members ?? container.body ?? []);
126
+ let pendingDoc;
127
+ for (const member of members) {
128
+ if (!member || typeof member !== 'object')
129
+ continue;
130
+ if (isDocComment(member)) {
131
+ pendingDoc = cleanDoc(String(member.content ?? ''));
132
+ continue;
133
+ }
134
+ if (isPackageDeclaration(member)) {
135
+ yield* walkDefinitions(member);
136
+ pendingDoc = undefined;
137
+ continue;
138
+ }
139
+ if (typeof member.$type === 'string' && CATALOG_CONSTRUCTS[member.$type]) {
140
+ yield { node: member, doc: pendingDoc };
141
+ }
142
+ pendingDoc = undefined;
143
+ }
144
+ }
145
+ function cleanDoc(content) {
146
+ return content.replace(/\s+/g, ' ').trim() || undefined;
147
+ }
87
148
  /**
88
149
  * Build layer info by scanning the sysml/ directory tree.
89
150
  * Apollo-11 convention: sysml/<layer>/<file>.sysml
@@ -185,326 +246,195 @@ function buildRelationshipTypes(sysmlDir) {
185
246
  return result;
186
247
  }
187
248
  /**
188
- * Read a YAML file and extract a simple string field.
249
+ * Build OntologyPackageInfo for a single package directory.
189
250
  */
190
- function readYamlField(content, field) {
191
- const m = content.match(new RegExp(`^${field}:\\s*["']?([^"'\\n]+)["']?`, 'm'));
192
- return m ? m[1].trim() : '';
251
+ function buildPackageInfo(pkgDir, selected) {
252
+ const { path, manifest } = readPackageManifest(pkgDir);
253
+ if (!path)
254
+ return null;
255
+ const sysmlDir = manifest.sysmlDir
256
+ ? resolve(pkgDir, manifest.sysmlDir)
257
+ : join(pkgDir, 'sysml');
258
+ // Authority is decided by the resolved root a package sits under, from the
259
+ // native import graph. The manifest `type:` that used to declare it is gone.
260
+ const type = suppliesMethodology(sysmlDir) ? 'methodology' : 'ontology';
261
+ const layers = applyExplorerClassification(buildLayers(sysmlDir), sysmlDir);
262
+ const kindCount = layers.reduce((s, l) => s + l.kindCount, 0);
263
+ const relationshipTypes = buildRelationshipTypes(sysmlDir);
264
+ return {
265
+ name: manifest.name ?? basename(pkgDir),
266
+ version: manifest.version ?? '0.0.0',
267
+ type,
268
+ description: manifest.description ?? '',
269
+ layers,
270
+ kindCount,
271
+ relationshipCount: relationshipTypes.length,
272
+ relationshipTypes,
273
+ selected,
274
+ rootDir: pkgDir,
275
+ };
193
276
  }
194
277
  /**
195
- * Read the `methodology:` field from a project config.
196
- * Returns a Set of package names: the methodology pkg + every pkg on its
197
- * extends chain. Used to mark them as selected in getPackageMetadata.
278
+ * Does this source tree supply a methodology?
279
+ *
280
+ * A package that declares a `MethodologyDefinition` usage is a methodology
281
+ * package. This is derived from what the SysML says, because the manifest field
282
+ * that used to declare it selected model content and was removed with the rest.
198
283
  */
199
- function readMethodologyChain(configPath) {
200
- const out = new Set();
201
- let methodologyName;
202
- try {
203
- const content = readFileSync(configPath, 'utf-8');
204
- const m = content.match(/^methodology:\s*"?([^"\s#]+)"?/m);
205
- if (!m)
206
- return out;
207
- const raw = m[1];
208
- const lastAt = raw.lastIndexOf('@');
209
- methodologyName = lastAt > 0 ? raw.slice(0, lastAt) : raw;
210
- if (!methodologyName.startsWith('@memoarchitect/'))
211
- methodologyName = `@memoarchitect/${methodologyName}`;
212
- }
213
- catch {
214
- return out;
215
- }
216
- if (!methodologyName)
217
- return out;
218
- // Walk the extends chain starting at the methodology pkg.
219
- const stack = [methodologyName];
220
- const visited = new Set();
221
- while (stack.length) {
222
- const pkgName = stack.pop();
223
- if (visited.has(pkgName))
224
- continue;
225
- visited.add(pkgName);
226
- out.add(pkgName);
227
- const pkgCfg = resolvePackageConfig(pkgName, dirname(configPath));
228
- if (!pkgCfg)
229
- continue;
284
+ function suppliesMethodology(sysmlDir) {
285
+ for (const file of collectSysmlFiles(sysmlDir)) {
230
286
  let content = '';
231
287
  try {
232
- content = readFileSync(pkgCfg, 'utf-8');
288
+ content = readFileSync(file, 'utf-8');
233
289
  }
234
290
  catch {
235
291
  continue;
236
292
  }
237
- const single = content.match(/^extends:\s*"?(@[\w-]+\/[\w-]+)"?/m);
238
- if (single) {
239
- stack.push(single[1]);
293
+ // Prefilter on the name, then confirm against the AST. A file that
294
+ // merely mentions `MethodologyDefinition` in a comment or an import
295
+ // does not supply one.
296
+ if (!content.includes('MethodologyDefinition'))
240
297
  continue;
241
- }
242
- const arr = content.match(/^extends:\s*\n((?:\s+-\s+.+\n?)+)/m);
243
- if (arr) {
244
- for (const em of arr[1].matchAll(/^\s+-\s+"?(@[\w-]+\/[\w-]+)"?/gm))
245
- stack.push(em[1]);
246
- }
298
+ const model = parseFileToAstSync(file);
299
+ if (!model)
300
+ continue;
301
+ for (const _ of usagesOfType(model, 'MethodologyDefinition'))
302
+ return true;
247
303
  }
248
- return out;
304
+ return false;
249
305
  }
250
306
  /**
251
- * Get the list of selected ontology package names from a project config file.
307
+ * Read a string attribute from a usage body in the AST.
308
+ *
309
+ * Both the `:>>` redefinition and the plain declaration forms appear in
310
+ * authored ontology source, so both are accepted.
252
311
  */
253
- function readSelectedOntologies(configPath) {
254
- const selected = new Set();
255
- try {
256
- const content = readFileSync(configPath, 'utf-8');
257
- const section = content.split(/^ontologies:/m)[1];
258
- if (section) {
259
- const matches = section.matchAll(/^\s*-\s*name:\s*["']?([\w@\/-]+)["']?/gm);
260
- for (const m of matches)
261
- selected.add(m[1]);
312
+ function usageAttr(body, name) {
313
+ for (const member of (body ?? [])) {
314
+ if (!member || member.$type !== 'AttributeMember' || member.name !== name)
315
+ continue;
316
+ const value = member.value;
317
+ if (!value || value.$type !== 'StringValue')
318
+ continue;
319
+ try {
320
+ return JSON.parse(value.value ?? '""');
262
321
  }
263
- }
264
- catch { /* skip */ }
265
- return selected;
266
- }
267
- /**
268
- * Build OntologyPackageInfo for a single package directory.
269
- */
270
- function buildPackageInfo(pkgDir, selected) {
271
- const configCandidates = ['memo.package.yaml', 'memo.package.yml', 'memo.config.yaml', 'memo.config.yml'];
272
- let configContent = '';
273
- for (const name of configCandidates) {
274
- const p = join(pkgDir, name);
275
- if (existsSync(p)) {
276
- configContent = readFileSync(p, 'utf-8');
277
- break;
322
+ catch {
323
+ return String(value.value ?? '').replace(/^"|"$/g, '');
278
324
  }
279
325
  }
280
- if (!configContent)
281
- return null;
282
- const name = readYamlField(configContent, 'name') || basename(pkgDir);
283
- const version = readYamlField(configContent, 'version') || '0.0.0';
284
- const rawType = readYamlField(configContent, 'type') || 'ontology';
285
- const type = (['ontology', 'profile', 'extension', 'methodology'].includes(rawType) ? rawType : 'ontology');
286
- const description = readYamlField(configContent, 'description') || '';
287
- const extendsField = readYamlField(configContent, 'extends') || undefined;
288
- const sysmlDirOverride = readYamlField(configContent, 'sysmlDir');
289
- const sysmlDir = sysmlDirOverride
290
- ? resolve(pkgDir, sysmlDirOverride)
291
- : join(pkgDir, 'sysml');
292
- const layers = applyExplorerClassification(buildLayers(sysmlDir), pkgDir);
293
- const kindCount = layers.reduce((s, l) => s + l.kindCount, 0);
294
- const relationshipTypes = buildRelationshipTypes(sysmlDir);
295
- const optionalModules = readOptionalModulesList(configContent);
296
- return {
297
- name, version, type, description, extends: extendsField, layers, kindCount,
298
- relationshipCount: relationshipTypes.length, relationshipTypes, selected,
299
- optionalModules,
300
- rootDir: pkgDir,
301
- };
302
- }
303
- /** Apply the ontology-declared Explorer taxonomy to discovered kinds. */
304
- function applyExplorerClassification(layers, pkgDir) {
305
- const rendering = join(pkgDir, 'memo.rendering.yaml');
306
- if (!existsSync(rendering))
307
- return layers;
308
- try {
309
- const parsed = parseYaml(readFileSync(rendering, 'utf-8'));
310
- const classifications = parsed.explorer?.classifications ?? [];
311
- if (classifications.length === 0)
312
- return layers;
313
- const bySource = new Map(classifications.map(c => [c.source, c]));
314
- const domains = new Map();
315
- for (const layer of layers)
316
- for (const kind of layer.kinds) {
317
- const source = kind.group ?? kind.layer;
318
- const placement = bySource.get(source);
319
- if (!placement)
320
- continue;
321
- let domain = domains.get(placement.domain);
322
- if (!domain) {
323
- domain = { id: placement.domain, label: placement.domain.charAt(0).toUpperCase() + placement.domain.slice(1), color: '#6B7280', kindCount: 0, kinds: [] };
324
- domains.set(placement.domain, domain);
325
- }
326
- domain.kinds.push({ ...kind, layer: placement.domain, group: placement.group });
327
- }
328
- for (const domain of domains.values())
329
- domain.kindCount = domain.kinds.length;
330
- return [...domains.values()];
331
- }
332
- catch {
333
- return layers;
334
- }
335
- }
336
- /** Parse `optionalModules:` list from a manifest file content. */
337
- function readOptionalModulesList(content) {
338
- const out = [];
339
- const section = content.split(/^optionalModules:/m)[1];
340
- if (!section)
341
- return out;
342
- for (const m of section.matchAll(/^\s*-\s*"?([@\w/-]+)"?/gm)) {
343
- out.push(m[1]);
344
- // Guard: stop if we leave the list (no leading `-`)
345
- if (!m[0].match(/^\s*-/))
346
- break;
347
- }
348
- return out;
326
+ return undefined;
349
327
  }
350
- /**
351
- * Get ontology package metadata for all packages in the project's extends chain
352
- * plus any available-but-unselected packages under packages/ or node_modules/@memoarchitect/.
353
- *
354
- * @param projectRoot - Absolute path to the project root (where memo.package.yaml lives)
355
- */
356
- export function getPackageMetadata(projectRoot) {
357
- const configCandidates = ['memo.package.yaml', 'memo.package.yml', 'memo.config.yaml', 'memo.config.yml'];
358
- let primaryConfig = '';
359
- for (const name of configCandidates) {
360
- const p = join(projectRoot, name);
361
- if (existsSync(p)) {
362
- primaryConfig = p;
363
- break;
328
+ /** Every `part <name> : <Type> { … }` usage of `typeName`, from the AST. */
329
+ function* usagesOfType(container, typeName) {
330
+ const members = (container.members ?? container.body ?? []);
331
+ for (const member of members) {
332
+ if (!member || typeof member !== 'object')
333
+ continue;
334
+ if (isPackageDeclaration(member)) {
335
+ yield* usagesOfType(member, typeName);
336
+ continue;
337
+ }
338
+ const type = typeof member.type === 'string' ? member.type.split('::').pop() : undefined;
339
+ if (type === typeName && Array.isArray(member.body)) {
340
+ yield { name: member.name, body: member.body };
364
341
  }
365
342
  }
366
- if (!primaryConfig)
367
- return [];
368
- const selectedNames = readSelectedOntologies(primaryConfig);
369
- const result = [];
370
- const seen = new Set();
371
- // The active ontology often lives behind a logical package manifest. For
372
- // example, the medical profile resolves to MEMO's `ontology/` directory
373
- // rather than a sibling `packages/` directory. Follow the actual extends
374
- // chain first, so the Explorer receives the same canonical types that the
375
- // model builder uses to resolve usages.
376
- const inheritedDirs = new Set();
377
- const visitExtends = (configPath, visited = new Set()) => {
378
- const normalized = resolve(configPath);
379
- if (visited.has(normalized))
380
- return;
381
- visited.add(normalized);
343
+ }
344
+ function readRenderingMetadata(sysmlDir) {
345
+ const placements = new Map();
346
+ const palette = new Map();
347
+ for (const file of collectSysmlFiles(sysmlDir)) {
348
+ // Cheap textual prefilter, then a real parse. Section 13.1 forbids
349
+ // regex as a semantic DISCOVERY mechanism; deciding whether a file is
350
+ // worth parsing is not discovery, and the values below are read from
351
+ // the AST.
382
352
  let content = '';
383
353
  try {
384
- content = readFileSync(normalized, 'utf-8');
354
+ content = readFileSync(file, 'utf-8');
385
355
  }
386
356
  catch {
387
- return;
388
- }
389
- const parentNames = [];
390
- const single = content.match(/^extends:\s*"?(@[\w-]+\/[\w-]+)"?/m);
391
- if (single)
392
- parentNames.push(single[1]);
393
- const array = content.match(/^extends:\s*\n((?:\s+-\s+.+\n?)+)/m);
394
- if (array)
395
- for (const entry of array[1].matchAll(/^\s+-\s+"?(@[\w-]+\/[\w-]+)"?/gm))
396
- parentNames.push(entry[1]);
397
- for (const parentName of parentNames) {
398
- const parentConfig = resolvePackageConfig(parentName, dirname(normalized));
399
- if (!parentConfig)
400
- continue;
401
- inheritedDirs.add(dirname(parentConfig));
402
- visitExtends(parentConfig, visited);
357
+ continue;
403
358
  }
404
- };
405
- visitExtends(primaryConfig);
406
- // Gather package directories from the tools repo and its memo submodule.
407
- const candidates = [];
408
- candidates.push(...inheritedDirs);
409
- let searchDir = resolve(projectRoot);
410
- while (true) {
411
- const pkgsDir = join(searchDir, 'packages');
412
- if (existsSync(pkgsDir)) {
413
- try {
414
- for (const entry of readdirSync(pkgsDir, { withFileTypes: true })) {
415
- if (!entry.isDirectory())
416
- continue;
417
- candidates.push(join(pkgsDir, entry.name));
418
- }
359
+ if (!content.includes('ExplorerClassification') && !content.includes('LayerRendering'))
360
+ continue;
361
+ const model = parseFileToAstSync(file);
362
+ if (!model)
363
+ continue;
364
+ for (const usage of usagesOfType(model, 'ExplorerClassification')) {
365
+ const sourceNamespace = usageAttr(usage.body, 'sourceNamespace');
366
+ const explorerDomain = usageAttr(usage.body, 'explorerDomain');
367
+ const explorerGroup = usageAttr(usage.body, 'explorerGroup');
368
+ if (sourceNamespace && explorerDomain && explorerGroup) {
369
+ placements.set(sourceNamespace, { sourceNamespace, explorerDomain, explorerGroup });
419
370
  }
420
- catch { /* skip */ }
421
- break;
422
371
  }
423
- const parent = dirname(searchDir);
424
- if (parent === searchDir)
425
- break;
426
- searchDir = parent;
427
- }
428
- // Scan memo_packages/ for locally installed packages
429
- const memoPkgsDir = join(projectRoot, 'memo_packages');
430
- if (existsSync(memoPkgsDir)) {
431
- try {
432
- for (const entry of readdirSync(memoPkgsDir, { withFileTypes: true })) {
433
- if (entry.isDirectory())
434
- candidates.push(join(memoPkgsDir, entry.name));
372
+ for (const usage of usagesOfType(model, 'LayerRendering')) {
373
+ const layerId = usageAttr(usage.body, 'layerId');
374
+ const layerLabel = usageAttr(usage.body, 'layerLabel');
375
+ const layerColor = usageAttr(usage.body, 'layerColor');
376
+ if (layerId && layerLabel && layerColor) {
377
+ palette.set(layerId, { layerId, layerLabel, layerColor });
435
378
  }
436
379
  }
437
- catch { /* skip */ }
438
380
  }
439
- // Also scan node_modules/@memoarchitect/ for installed packages
440
- const nmMemo = join(projectRoot, 'node_modules', '@memoarchitect');
441
- if (existsSync(nmMemo)) {
442
- try {
443
- for (const entry of readdirSync(nmMemo, { withFileTypes: true })) {
444
- if (entry.isDirectory())
445
- candidates.push(join(nmMemo, entry.name));
446
- }
381
+ return { placements, palette };
382
+ }
383
+ /** Apply the ontology-declared Explorer taxonomy to discovered kinds. */
384
+ function applyExplorerClassification(layers, sysmlDir) {
385
+ const { placements, palette } = readRenderingMetadata(sysmlDir);
386
+ for (const layer of layers) {
387
+ const authored = palette.get(layer.id);
388
+ if (authored) {
389
+ layer.label = authored.layerLabel;
390
+ layer.color = authored.layerColor;
447
391
  }
448
- catch { /* skip */ }
449
- }
450
- // A bundled example runs from a disposable directory and intentionally has
451
- // no node_modules of its own. Its packages are nevertheless resolvable via
452
- // its methodology/extends chain, so use that same authoritative resolution
453
- // path when publishing metadata to clients such as Memo Architect.
454
- for (const packageDir of findOntologyPackageDirs(primaryConfig)) {
455
- candidates.push(packageDir);
456
392
  }
457
- // Collect which packages are declared as optionalModules by any base pkg.
458
- const optionalModuleNames = new Set();
459
- for (const pkgDir of candidates) {
460
- for (const cfg of configCandidates) {
461
- const manifestPath = join(pkgDir, cfg);
462
- if (!existsSync(manifestPath))
393
+ if (placements.size === 0)
394
+ return layers;
395
+ const domains = new Map();
396
+ for (const layer of layers)
397
+ for (const kind of layer.kinds) {
398
+ const source = kind.group ?? kind.layer;
399
+ const placement = placements.get(source);
400
+ if (!placement)
463
401
  continue;
464
- try {
465
- const content = readFileSync(manifestPath, 'utf-8');
466
- for (const m of readOptionalModulesList(content))
467
- optionalModuleNames.add(m);
468
- }
469
- catch { /* skip */ }
470
- break;
471
- }
472
- }
473
- // Also collect project-declared modules so they get selected=true.
474
- const projectModules = new Set(readDeclaredModules(primaryConfig));
475
- // Phase C: methodology field also marks packages selected — methodology
476
- // pkg itself plus everything on its extends chain.
477
- const methodologySelected = readMethodologyChain(primaryConfig);
478
- for (const pkgDir of candidates) {
479
- let sysmlPath = join(pkgDir, 'sysml');
480
- for (const cfg of CONFIG_SEARCH_ORDER) {
481
- const cp = join(pkgDir, cfg);
482
- if (existsSync(cp)) {
483
- const ov = readYamlField(readFileSync(cp, 'utf-8'), 'sysmlDir');
484
- if (ov)
485
- sysmlPath = resolve(pkgDir, ov);
486
- break;
402
+ let domain = domains.get(placement.explorerDomain);
403
+ if (!domain) {
404
+ domain = {
405
+ id: placement.explorerDomain,
406
+ label: placement.explorerDomain.charAt(0).toUpperCase() + placement.explorerDomain.slice(1),
407
+ color: '#6B7280',
408
+ kindCount: 0,
409
+ kinds: [],
410
+ };
411
+ domains.set(placement.explorerDomain, domain);
487
412
  }
413
+ domain.kinds.push({ ...kind, layer: placement.explorerDomain, group: placement.explorerGroup });
488
414
  }
489
- const hasSysml = existsSync(sysmlPath);
490
- if (!hasSysml)
491
- continue;
492
- if (seen.has(pkgDir))
493
- continue;
494
- seen.add(pkgDir);
495
- const info = buildPackageInfo(pkgDir, false);
496
- if (!info)
497
- continue;
498
- // Mark as selected if name is in project's ontologies list, or inferred heuristic
499
- info.selected = inheritedDirs.has(pkgDir)
500
- || selectedNames.has(info.name)
501
- || selectedNames.has(info.name.replace('@memoarchitect/', ''))
502
- || projectModules.has(info.name)
503
- || methodologySelected.has(info.name);
504
- info.isOptionalModule = optionalModuleNames.has(info.name);
505
- result.push(info);
415
+ if (domains.size === 0)
416
+ return layers;
417
+ for (const domain of domains.values())
418
+ domain.kindCount = domain.kinds.length;
419
+ return [...domains.values()];
420
+ }
421
+ /**
422
+ * Describe every package a project could resolve, marking the ones it does.
423
+ *
424
+ * "Available" comes from locators — distribution manifests, node_modules,
425
+ * workspace package directories. "Selected" comes from the native import
426
+ * closure and nothing else: a package a manifest points at but no import
427
+ * reaches is listed here as available and unselected, which is exactly what it
428
+ * is. Before the flip, selection was read out of `ontologies:`, `modules:`,
429
+ * `methodology:`, and the `extends` chain.
430
+ */
431
+ export function getPackageMetadata(projectRoot, selectedRootDirs) {
432
+ const result = [];
433
+ for (const root of discoverLibraryRoots(resolve(projectRoot))) {
434
+ const info = buildPackageInfo(root.dir, selectedRootDirs?.has(root.dir) ?? false);
435
+ if (info)
436
+ result.push(info);
506
437
  }
507
- // Sort: selected first, then by name
508
438
  result.sort((a, b) => {
509
439
  if (a.selected !== b.selected)
510
440
  return a.selected ? -1 : 1;
@@ -534,255 +464,14 @@ function collectSysmlFiles(dir) {
534
464
  }
535
465
  return files;
536
466
  }
537
- /**
538
- * Walk the config `extends` chain to find ontology package directories.
539
- * Returns absolute paths to directories containing `sysml/` subdirectories.
540
- *
541
- * Strategy:
542
- * 1. Start from the config file's directory
543
- * 2. Follow `extends` references (@memoarchitect/package-name → packages/package-name)
544
- * 3. For each package in the chain, check if it has a sysml/ directory
545
- * 4. Also check for ontology-core (may not be in extends chain directly)
546
- */
547
- export function findOntologyPackageDirs(configPath) {
548
- const dirs = [];
549
- const seen = new Set();
550
- // 0. (Phase C) If project pins a `methodology:`, resolve it and walk its
551
- // extends chain. The methodology package brings in its own SysML and
552
- // chain-pulls the kinds ontology (e.g. @memoarchitect/ontology).
553
- try {
554
- const content = readFileSync(configPath, 'utf-8');
555
- const methodologyMatch = content.match(/^methodology:\s*"?([^"\s#]+)"?/m);
556
- if (methodologyMatch) {
557
- // Strip optional version range "@^1.0" → just the package name.
558
- // The leading @memoarchitect/ scope must be preserved, so only strip the LAST `@`.
559
- const raw = methodologyMatch[1];
560
- const lastAt = raw.lastIndexOf('@');
561
- const methodologyName = lastAt > 0 ? raw.slice(0, lastAt) : raw;
562
- const fullName = methodologyName.startsWith('@memoarchitect/')
563
- ? methodologyName
564
- : `@memoarchitect/${methodologyName}`;
565
- const pkgConfig = resolvePackageConfig(fullName, dirname(configPath));
566
- if (pkgConfig)
567
- walkExtendsChain(pkgConfig, dirs, seen);
568
- }
569
- }
570
- catch { /* skip */ }
571
- // 1. Walk the primary extends chain
572
- walkExtendsChain(configPath, dirs, seen);
573
- // 2. Load additional ontologies from the config file's `ontologies` array.
574
- // This allows for a "Base + Plugin" model where users can add multiple domain-specific ontologies.
575
- try {
576
- const content = readFileSync(configPath, 'utf-8');
577
- // Lightweight YAML parsing for ontologies:
578
- const ontologySection = content.split(/^ontologies:/m)[1];
579
- if (ontologySection) {
580
- const matches = ontologySection.matchAll(/^\s*-\s*name:\s*"?([\w@\/-]+)"?/gm);
581
- for (const match of matches) {
582
- let ontologyName = match[1];
583
- // Ensure name has @memoarchitect/ prefix for resolution if missing
584
- if (!ontologyName.startsWith('@memoarchitect/')) {
585
- ontologyName = `@memoarchitect/${ontologyName}`;
586
- }
587
- const pkgConfig = resolvePackageConfig(ontologyName, dirname(configPath));
588
- if (pkgConfig) {
589
- walkExtendsChain(pkgConfig, dirs, seen);
590
- }
591
- }
592
- }
593
- }
594
- catch {
595
- // Skip inaccessible configs
596
- }
597
- // 3. Resolve optional modules declared under `modules:` in the project config.
598
- // Modules follow OWL import semantics — declared in the base ontology's
599
- // `optionalModules:` list, loaded only when the project opts in.
600
- for (const moduleName of readDeclaredModules(configPath)) {
601
- const pkgConfig = resolvePackageConfig(moduleName, dirname(configPath));
602
- if (pkgConfig)
603
- walkExtendsChain(pkgConfig, dirs, seen);
604
- }
605
- return dirs;
606
- }
607
- /**
608
- * Read the `modules:` array from a project config, resolving short aliases
609
- * (e.g. "ros") against the base ontology's `optionalModules:` list.
610
- * Returns fully-qualified @memoarchitect/... package names.
611
- */
612
- function readDeclaredModules(configPath) {
613
- const out = [];
614
- let rawModules = [];
615
- try {
616
- const content = readFileSync(configPath, 'utf-8');
617
- // Match `modules:\n - foo\n - "@memoarchitect/bar"`
618
- const section = content.split(/^modules:/m)[1];
619
- if (section) {
620
- const matches = section.matchAll(/^\s*-\s*"?([@\w/-]+)"?/gm);
621
- // Stop at the first non-list YAML key
622
- for (const m of matches) {
623
- const line = m[0];
624
- if (!line.match(/^\s*-/))
625
- break;
626
- rawModules.push(m[1]);
627
- }
628
- }
629
- }
630
- catch {
631
- return out;
632
- }
633
- if (rawModules.length === 0)
634
- return out;
635
- // Gather optional-module allowlist from the extends chain
636
- const allowlist = collectOptionalModules(configPath);
637
- const byShort = new Map(); // short → full name
638
- for (const full of allowlist) {
639
- const short = full.split('/').pop() ?? full;
640
- byShort.set(short, full);
641
- }
642
- for (const entry of rawModules) {
643
- if (entry.startsWith('@')) {
644
- out.push(entry);
645
- }
646
- else {
647
- out.push(byShort.get(entry) ?? entry);
648
- }
649
- }
650
- return out;
651
- }
652
- /**
653
- * Walk the extends chain of a config and collect all `optionalModules:` entries.
654
- */
655
- function collectOptionalModules(configPath) {
656
- const modules = new Set();
657
- const visited = new Set();
658
- const stack = [resolve(configPath)];
659
- while (stack.length) {
660
- const p = stack.pop();
661
- if (visited.has(p))
662
- continue;
663
- visited.add(p);
664
- let content = '';
665
- try {
666
- content = readFileSync(p, 'utf-8');
667
- }
668
- catch {
669
- continue;
670
- }
671
- const section = content.split(/^optionalModules:/m)[1];
672
- if (section) {
673
- for (const m of section.matchAll(/^\s*-\s*"?([@\w/-]+)"?/gm)) {
674
- const line = m[0];
675
- if (!line.match(/^\s*-/))
676
- break;
677
- modules.add(m[1]);
678
- }
679
- }
680
- // Handle both single and array extends forms
681
- const singleExt = content.match(/^extends:\s*"?(@[\w-]+\/[\w-]+)"?/m);
682
- if (singleExt) {
683
- const parent = resolvePackageConfig(singleExt[1], dirname(p));
684
- if (parent)
685
- stack.push(parent);
686
- }
687
- else {
688
- const arraySection = content.match(/^extends:\s*\n((?:\s+-\s+.+\n?)+)/m);
689
- if (arraySection) {
690
- for (const m of arraySection[1].matchAll(/^\s+-\s+"?(@[\w-]+\/[\w-]+)"?/gm)) {
691
- const parent = resolvePackageConfig(m[1], dirname(p));
692
- if (parent)
693
- stack.push(parent);
694
- }
695
- }
696
- }
697
- }
698
- return [...modules];
699
- }
700
- /**
701
- * Recursively walk the extends chain, collecting ontology package dirs.
702
- */
703
- function walkExtendsChain(configPath, dirs, seen) {
704
- const resolvedPath = resolve(configPath);
705
- if (seen.has(resolvedPath))
706
- return;
707
- seen.add(resolvedPath);
708
- // Read the YAML to find extends (lightweight — just look for extends line)
709
- let extendsPackages = [];
710
- let projectType;
711
- try {
712
- const content = readFileSync(resolvedPath, 'utf-8');
713
- // Handle both single-string extends and array extends in YAML:
714
- // extends: "@memoarchitect/ontology"
715
- // extends:
716
- // - "@memoarchitect/ontology"
717
- const singleMatch = content.match(/^extends:\s*"?(@[\w-]+\/[\w-]+)"?/m);
718
- if (singleMatch) {
719
- extendsPackages = [singleMatch[1]];
720
- }
721
- else {
722
- // Array form: collect all list entries under `extends:`
723
- const arraySection = content.match(/^extends:\s*\n((?:\s+-\s+.+\n?)+)/m);
724
- if (arraySection) {
725
- const entries = [...arraySection[1].matchAll(/^\s+-\s+"?(@[\w-]+\/[\w-]+)"?/gm)];
726
- extendsPackages = entries.map(m => m[1]);
727
- }
728
- }
729
- // Match both legacy (projectType:) and new format (type:)
730
- const typeMatch = content.match(/^(?:projectType|type):\s*(\w+)/m);
731
- if (typeMatch) {
732
- projectType = typeMatch[1];
733
- }
734
- }
735
- catch {
736
- return;
737
- }
738
- const packageDir = dirname(resolvedPath);
739
- // Honor `sysmlDir:` override (points outside package, e.g. ../../ontology)
740
- let sysmlDir;
741
- try {
742
- const content = readFileSync(resolvedPath, 'utf-8');
743
- const override = readYamlField(content, 'sysmlDir');
744
- sysmlDir = override ? resolve(packageDir, override) : resolve(packageDir, 'sysml');
745
- }
746
- catch {
747
- sysmlDir = resolve(packageDir, 'sysml');
748
- }
749
- if (existsSync(sysmlDir)) {
750
- dirs.push(packageDir);
751
- }
752
- // Follow extends chain (handles both single and array extends)
753
- for (const extendsPackage of extendsPackages) {
754
- const parentConfigPath = resolvePackageConfig(extendsPackage, packageDir);
755
- if (parentConfigPath) {
756
- walkExtendsChain(parentConfigPath, dirs, seen);
757
- }
758
- }
759
- }
760
467
  /**
761
468
  * Resolve the SysML root directory for an ontology package.
762
469
  * Honors `sysmlDir:` override in the package's manifest; falls back to `<pkgDir>/sysml`.
763
470
  */
764
471
  export function resolvePackageSysmlDir(pkgDir) {
765
- for (const cfg of CONFIG_SEARCH_ORDER) {
766
- const cp = resolve(pkgDir, cfg);
767
- if (existsSync(cp)) {
768
- try {
769
- const ov = readYamlField(readFileSync(cp, 'utf-8'), 'sysmlDir');
770
- if (ov)
771
- return resolve(pkgDir, ov);
772
- }
773
- catch { /* skip */ }
774
- break;
775
- }
776
- }
777
- return resolve(pkgDir, 'sysml');
472
+ const override = readPackageManifest(pkgDir).manifest.sysmlDir;
473
+ return override ? resolve(pkgDir, override) : resolve(pkgDir, 'sysml');
778
474
  }
779
- /** Ordered list of config filenames to search for (new format first, then legacy) */
780
- const CONFIG_SEARCH_ORDER = [
781
- 'memo.package.yaml',
782
- 'memo.package.yml',
783
- 'memo.config.yaml',
784
- 'memo.config.yml',
785
- ];
786
475
  /**
787
476
  * Resolve a @memoarchitect/package-name to its config file path.
788
477
  * Prefers memo.package.yaml (new format), falls back to memo.config.yaml (legacy).
@@ -796,10 +485,11 @@ export function resolvePackageConfig(packageName, fromDir) {
796
485
  // A logical package config is itself inside the physical content package.
797
486
  // It is not a user-project boundary: allow sibling logical packages to be
798
487
  // resolved through the nearest enclosing manifest.
488
+ // A logical package descriptor sits inside the physical content package, so
489
+ // it is not a user-project boundary. Sibling logical packages resolve
490
+ // through the nearest enclosing distribution manifest.
799
491
  if (projectConfig) {
800
- const type = readYamlField(readFileSync(projectConfig, 'utf-8'), 'type')
801
- || readYamlField(readFileSync(projectConfig, 'utf-8'), 'projectType');
802
- if (type && type !== 'device') {
492
+ {
803
493
  let manifestDir = dirname(projectConfig);
804
494
  while (true) {
805
495
  for (const manifest of discoverMemoManifests([manifestDir])) {
@@ -894,72 +584,108 @@ function findNearestProjectConfig(startDir) {
894
584
  }
895
585
  }
896
586
  /**
897
- * Load ontology registries by walking the config extends chain,
898
- * finding ontology SysML files, parsing them, and populating
899
- * KindRegistry + RelationshipRegistry.
587
+ * Load the reusable registries a project actually resolves.
588
+ *
589
+ * Selection is the native import closure. This used to walk the `extends`
590
+ * chain, the `methodology:` field, the `ontologies:` list, and the `modules:`
591
+ * opt-ins; all four are gone, and a package now contributes kinds because the
592
+ * project imports it, not because a settings file named it.
900
593
  *
901
- * @param configPath - Path to the project's memo.config.yaml
902
- * @returns Populated registries and diagnostic info
594
+ * Everything in the closure is parsed, including project-owned source, because
595
+ * a project may declare its own definitions and those are project content the
596
+ * builder must see. Provenance keeps the two apart.
903
597
  */
904
- export async function loadOntologyRegistries(configPath) {
598
+ export async function loadOntologyRegistries(projectRoot) {
905
599
  const kindRegistry = new KindRegistry();
906
600
  const relationshipRegistry = new RelationshipRegistry();
907
601
  const errors = [];
908
- // Find ontology package directories
909
- const ontologyDirs = findOntologyPackageDirs(configPath);
910
- if (ontologyDirs.length === 0) {
911
- return {
912
- registries: { kindRegistry, relationshipRegistry },
913
- fileCount: 0,
914
- ontologyDirs: [],
915
- errors: ['No ontology packages with sysml/ directories found in extends chain'],
916
- parsedDocuments: [],
917
- };
918
- }
919
- // Collect all SysML files from all ontology packages (honor sysmlDir override).
920
- // Dedupe by absolute path — methodology and base ontology pkgs may have
921
- // overlapping sysmlDirs (e.g. methodology points at ontology/methodology/memo
922
- // while @memoarchitect/ontology points at src/).
923
- const sysmlSet = new Set();
924
- for (const pkgDir of ontologyDirs) {
925
- let sysmlDir = resolve(pkgDir, 'sysml');
926
- for (const cfg of CONFIG_SEARCH_ORDER) {
927
- const cp = resolve(pkgDir, cfg);
928
- if (existsSync(cp)) {
929
- const ov = readYamlField(readFileSync(cp, 'utf-8'), 'sysmlDir');
930
- if (ov)
931
- sysmlDir = resolve(pkgDir, ov);
932
- break;
933
- }
934
- }
935
- for (const f of collectSysmlFiles(sysmlDir))
936
- sysmlSet.add(f);
937
- }
938
- const allSysmlFiles = [...sysmlSet];
939
- if (allSysmlFiles.length === 0) {
602
+ const resolution = await resolveNativeProject(projectRoot);
603
+ for (const diagnostic of resolution.diagnostics) {
604
+ errors.push(`${diagnostic.code}: ${diagnostic.message}`);
605
+ }
606
+ // Watch both distribution descriptors and their actual SysML source
607
+ // roots. Native packages may publish source outside the descriptor
608
+ // directory (for example ontology/memo.package.yaml -> ../src).
609
+ const ontologyDirs = [...new Set(resolution.selectedRoots.flatMap(r => [r.dir, r.sysmlDir]))];
610
+ // A package is resolved in full or not at all.
611
+ //
612
+ // The closure says which roots the project reaches; everything those roots
613
+ // supply is then loaded, because a methodology that declares
614
+ // `scopeMode = allAvailable` means "everything the resolved packages
615
+ // provide" and cannot mean that only the files some other file happened to
616
+ // import exist. Loading is not selecting: effective scope decides what is
617
+ // active, which keeps one filter rather than two.
618
+ //
619
+ // A root no import reaches supplies nothing — that is what makes this the
620
+ // import graph's answer and not the locator's.
621
+ const selectedSysmlDirs = resolution.selectedRoots.map(r => r.sysmlDir);
622
+ const closureFiles = new Set();
623
+ for (const pkg of resolution.closure.values()) {
624
+ for (const file of pkg.files)
625
+ closureFiles.add(file);
626
+ }
627
+ const documents = resolution.documents.filter(d => closureFiles.has(d.filePath) || selectedSysmlDirs.some(dir => d.filePath.startsWith(dir + sep)));
628
+ if (documents.length === 0) {
940
629
  return {
941
630
  registries: { kindRegistry, relationshipRegistry },
942
631
  fileCount: 0,
943
632
  ontologyDirs,
944
- errors: ['Ontology packages found but no .sysml files in sysml/ directories'],
633
+ errors: errors.length > 0 ? errors : [
634
+ 'No SysML reachable from the project entrypoint. Check the imports in model/catalog/project.sysml.',
635
+ ],
945
636
  parsedDocuments: [],
637
+ kindNameCollisions: [],
638
+ resolution,
946
639
  };
947
640
  }
948
- // Parse all ontology SysML files
949
- const parseResult = await parseFiles(allSysmlFiles, '');
950
- for (const err of parseResult.errors) {
951
- errors.push(`${err.file}${err.line ? `:${err.line}` : ''}: ${err.message}`);
952
- }
953
- // Populate registries from parsed documents
954
- kindRegistry.populateFromDocuments(parseResult.documents);
641
+ kindRegistry.populateFromDocuments(documents);
955
642
  kindRegistry.computeDerivedBy();
956
- relationshipRegistry.populateFromDocuments(parseResult.documents);
643
+ relationshipRegistry.populateFromDocuments(documents);
957
644
  return {
958
645
  registries: { kindRegistry, relationshipRegistry },
959
- fileCount: allSysmlFiles.length,
646
+ fileCount: documents.length,
960
647
  ontologyDirs,
961
648
  errors,
962
- parsedDocuments: parseResult.documents,
649
+ parsedDocuments: documents,
650
+ kindNameCollisions: kindRegistry.getCollisions(),
651
+ provenance: buildProvenanceTable(resolution),
652
+ resolution,
963
653
  };
964
654
  }
655
+ /**
656
+ * Classify each resolved package into an authority category.
657
+ *
658
+ * Origin comes from the resolved root a file sits under — never from what the
659
+ * file declares, what it is called, or where it sits in a directory tree.
660
+ * Import depth is now the real graph distance from the project entrypoint,
661
+ * which is what session 1 left this function waiting for; before, it was the
662
+ * package's position in an ordered walk.
663
+ */
664
+ function buildProvenanceTable(resolution) {
665
+ const byDir = new Map();
666
+ for (const pkg of resolution.closure.values()) {
667
+ if (!pkg.root)
668
+ continue;
669
+ const existing = byDir.get(pkg.root.dir);
670
+ if (existing && existing.importDepth <= pkg.importDepth)
671
+ continue;
672
+ byDir.set(pkg.root.dir, {
673
+ dir: pkg.root.dir,
674
+ origin: pkg.origin,
675
+ packageName: pkg.root.packageName,
676
+ packageVersion: pkg.root.packageVersion,
677
+ importDepth: pkg.importDepth,
678
+ });
679
+ }
680
+ const roots = [];
681
+ for (const root of byDir.values()) {
682
+ roots.push(root);
683
+ // A package may publish its SysML from a directory outside its own
684
+ // descriptor directory. Both physical roots are the same authority.
685
+ const lib = resolution.selectedRoots.find(r => r.dir === root.dir);
686
+ if (lib && lib.sysmlDir !== root.dir)
687
+ roots.push({ ...root, dir: lib.sysmlDir });
688
+ }
689
+ return new ProvenanceTable(resolution.projectRoot, roots);
690
+ }
965
691
  //# sourceMappingURL=ontology-loader.js.map