domainforge 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (481) hide show
  1. package/.cargo/config.toml +6 -0
  2. package/.claude/settings.local.json +18 -0
  3. package/.coderabbit.yml +43 -0
  4. package/.codex/skills/release-management/SKILL.md +151 -0
  5. package/.codex/skills/release-management/agents/openai.yaml +4 -0
  6. package/.github/actions/decrypt-secrets/action.yml +121 -0
  7. package/.github/agents/Coder.agent.md +97 -0
  8. package/.github/agents/DeepResearch.agent.md +61 -0
  9. package/.github/chatmodes/tdd.vibepro.chatmode.md +1183 -0
  10. package/.github/copilot-instructions.md +13 -0
  11. package/.github/dependabot.yml +68 -0
  12. package/.github/workflows/README.md +165 -0
  13. package/.github/workflows/ci.yml +335 -0
  14. package/.github/workflows/dependabot-automerge.yml +114 -0
  15. package/.github/workflows/dependency-review.yml +27 -0
  16. package/.github/workflows/deploy.yml +87 -0
  17. package/.github/workflows/prepare-release.yml +168 -0
  18. package/.github/workflows/release-crates.yml +42 -0
  19. package/.github/workflows/release-npm.yml +137 -0
  20. package/.github/workflows/release-please.yml +29 -0
  21. package/.github/workflows/release-pypi.yml +96 -0
  22. package/.gitkeep +1 -0
  23. package/.release-please-manifest.json +5 -0
  24. package/.sea-registry.toml +10 -0
  25. package/.serena/project.yml +133 -0
  26. package/.sops.yaml +10 -0
  27. package/AGENTS.md +216 -0
  28. package/CHANGELOG.md +400 -0
  29. package/CLAUDE.md +62 -0
  30. package/CONTRIBUTING.md +323 -0
  31. package/Cargo.lock +3612 -0
  32. package/Cargo.toml +12 -0
  33. package/LICENSE +201 -0
  34. package/README.md +660 -0
  35. package/README_PYTHON.md +256 -0
  36. package/README_TYPESCRIPT.md +305 -0
  37. package/README_WASM.md +329 -0
  38. package/RELEASE_NOTES.md +41 -0
  39. package/bun.lock +378 -0
  40. package/bunfig.toml +11 -0
  41. package/check_output.txt +83 -0
  42. package/clippy_output.txt +80 -0
  43. package/commitlint.config.cjs +8 -0
  44. package/deny.toml +42 -0
  45. package/devbox.json +14 -0
  46. package/devbox.lock +76 -0
  47. package/docs/RELEASE_PROCESS.md +360 -0
  48. package/docs/diagnostics.md +161 -0
  49. package/docs/doc_guidelines.md +53 -0
  50. package/docs/explanations/README.md +21 -0
  51. package/docs/explanations/architecture-overview.md +109 -0
  52. package/docs/explanations/cross-language-binding-strategy.md +68 -0
  53. package/docs/explanations/graph-store-design.md +47 -0
  54. package/docs/explanations/performance-benchmarks.md +63 -0
  55. package/docs/explanations/policy-evaluation-logic.md +106 -0
  56. package/docs/explanations/semantic-modeling-concepts.md +109 -0
  57. package/docs/explanations/three-valued-logic.md +66 -0
  58. package/docs/explanations/versioning-strategy.md +45 -0
  59. package/docs/governance.md +168 -0
  60. package/docs/how-tos/README.md +46 -0
  61. package/docs/how-tos/ci-cd-validation.md +93 -0
  62. package/docs/how-tos/create-custom-units.md +125 -0
  63. package/docs/how-tos/define-policies.md +119 -0
  64. package/docs/how-tos/export-to-calm.md +110 -0
  65. package/docs/how-tos/export-to-protobuf.md +312 -0
  66. package/docs/how-tos/extend-grammar.md +133 -0
  67. package/docs/how-tos/generate-rdf-turtle.md +106 -0
  68. package/docs/how-tos/import-from-calm.md +114 -0
  69. package/docs/how-tos/import-from-sbvr.md +249 -0
  70. package/docs/how-tos/install-cli.md +126 -0
  71. package/docs/how-tos/parse-sea-files.md +132 -0
  72. package/docs/how-tos/policy-evaluation-modes.md +30 -0
  73. package/docs/how-tos/run-cross-language-tests.md +115 -0
  74. package/docs/how-tos/troubleshoot-napi-builds.md +55 -0
  75. package/docs/how-tos/use-modules-imports.md +285 -0
  76. package/docs/index.md +13 -0
  77. package/docs/plans/canonical-normalizer.md +121 -0
  78. package/docs/plans/cd_improvement.md +112 -0
  79. package/docs/plans/cli-ast.md +29 -0
  80. package/docs/plans/expression-bindings-and-normalizer-integration.md +174 -0
  81. package/docs/plans/protobuf_advanced_features_plan.md +597 -0
  82. package/docs/plans/protobuf_plan.yml +525 -0
  83. package/docs/plans/refactor_dsl_architecture.md +131 -0
  84. package/docs/plans/release-plan.md +163 -0
  85. package/docs/plans/sea_fmt_implementation_plan.md +516 -0
  86. package/docs/playbooks/README.md +18 -0
  87. package/docs/playbooks/adding-new-primitive.md +68 -0
  88. package/docs/playbooks/debugging-parser-failures.md +42 -0
  89. package/docs/playbooks/local-release-preparation.md +139 -0
  90. package/docs/playbooks/migrating-schema-versions.md +43 -0
  91. package/docs/playbooks/onboarding-contributors.md +64 -0
  92. package/docs/playbooks/releasing-beta.md +86 -0
  93. package/docs/playbooks/secret-management.md +64 -0
  94. package/docs/reference/README.md +199 -0
  95. package/docs/reference/ast-json-api.md +427 -0
  96. package/docs/reference/calm-mapping.md +519 -0
  97. package/docs/reference/cli-commands.md +588 -0
  98. package/docs/reference/configuration.md +202 -0
  99. package/docs/reference/error-codes.md +664 -0
  100. package/docs/reference/generated-artifacts-policy.md +53 -0
  101. package/docs/reference/grammar-spec.md +255 -0
  102. package/docs/reference/primitives-api.md +317 -0
  103. package/docs/reference/protobuf-api.md +426 -0
  104. package/docs/reference/python-api.md +485 -0
  105. package/docs/reference/registry.md +50 -0
  106. package/docs/reference/sea-dsl-ai-cheatsheet.yaml +913 -0
  107. package/docs/reference/security-model.md +74 -0
  108. package/docs/reference/typescript-api.md +508 -0
  109. package/docs/reference/wasm-api.md +420 -0
  110. package/docs/semantic-pack-review.md +144 -0
  111. package/docs/semantic-pack-signing.md +234 -0
  112. package/docs/semantic-packs.md +284 -0
  113. package/docs/specs/ADR-001-sea-dsl-semantic-source-of-truth.md +33 -0
  114. package/docs/specs/ADR-002-projection-first-class-construct.md +50 -0
  115. package/docs/specs/ADR-003-protobuf-projection-target.md +51 -0
  116. package/docs/specs/ADR-004-projection-compatibility-semantics.md +57 -0
  117. package/docs/specs/ADR-005-multi-language-support-strategy.md +112 -0
  118. package/docs/specs/ADR-006-error-handling-strategy.md +115 -0
  119. package/docs/specs/ADR-007-policy-evaluation-engine.md +95 -0
  120. package/docs/specs/ADR-008-knowledge-graph-integration.md +90 -0
  121. package/docs/specs/ADR-009-module-resolution-strategy.md +115 -0
  122. package/docs/specs/ADR-010-unit-system.md +106 -0
  123. package/docs/specs/PRD-001-sea-projection-framework.md +155 -0
  124. package/docs/specs/PRD-002-sea-cli-tooling.md +169 -0
  125. package/docs/specs/PRD-003-dsl-core-capabilities.md +275 -0
  126. package/docs/specs/README.md +62 -0
  127. package/docs/specs/SDS-001-protobuf-projection-engine.md +451 -0
  128. package/docs/specs/SDS-002-sea-core-architecture.md +268 -0
  129. package/docs/specs/SDS-003-parser-semantic-graph.md +377 -0
  130. package/docs/specs/SDS-004-policy-engine-design.md +362 -0
  131. package/docs/specs/SDS-005-knowledge-graph-module.md +364 -0
  132. package/docs/specs/SDS-006-calm-integration.md +367 -0
  133. package/docs/specs/SDS-007-sbvr-import.md +347 -0
  134. package/docs/templates/template_explanation.md +14 -0
  135. package/docs/templates/template_howto.md +21 -0
  136. package/docs/templates/template_playbook.md +21 -0
  137. package/docs/templates/template_reference.md +17 -0
  138. package/docs/templates/template_tutorial.md +24 -0
  139. package/docs/tutorials/README.md +12 -0
  140. package/docs/tutorials/first-sea-model.md +85 -0
  141. package/docs/tutorials/getting-started.md +98 -0
  142. package/docs/tutorials/python-binding-quickstart.md +107 -0
  143. package/docs/tutorials/typescript-binding-quickstart.md +91 -0
  144. package/docs/tutorials/wasm-in-browser.md +75 -0
  145. package/domainforge-core/CHANGELOG.md +138 -0
  146. package/domainforge-core/Cargo.toml +101 -0
  147. package/domainforge-core/MIGRATING.md +32 -0
  148. package/domainforge-core/README.md +197 -0
  149. package/domainforge-core/benchmark_results.txt +51 -0
  150. package/domainforge-core/build.rs +6 -0
  151. package/domainforge-core/deny.toml +31 -0
  152. package/domainforge-core/docs/specs/projections/sbvr_kg_mapping.md +43 -0
  153. package/domainforge-core/examples/basic.sea +7 -0
  154. package/domainforge-core/examples/cli/import_export_workflow.sh +38 -0
  155. package/domainforge-core/examples/cli/validate_example.sh +30 -0
  156. package/domainforge-core/examples/evolution_semantics.sea +31 -0
  157. package/domainforge-core/examples/parser_demo.rs +203 -0
  158. package/domainforge-core/grammar/sea.pest +408 -0
  159. package/domainforge-core/schemas/calm-v1.schema.json +170 -0
  160. package/domainforge-core/schemas/shacl/sea_shapes.ttl +19 -0
  161. package/domainforge-core/src/authority/compiler.rs +309 -0
  162. package/domainforge-core/src/authority/environment.rs +203 -0
  163. package/domainforge-core/src/authority/error.rs +164 -0
  164. package/domainforge-core/src/authority/fact_resolver.rs +224 -0
  165. package/domainforge-core/src/authority/mod.rs +25 -0
  166. package/domainforge-core/src/authority/pack.rs +133 -0
  167. package/domainforge-core/src/authority/policy.rs +224 -0
  168. package/domainforge-core/src/authority/resolver.rs +446 -0
  169. package/domainforge-core/src/authority/trace.rs +217 -0
  170. package/domainforge-core/src/authority/transform.rs +168 -0
  171. package/domainforge-core/src/authority/types.rs +617 -0
  172. package/domainforge-core/src/bin/domainforge.rs +25 -0
  173. package/domainforge-core/src/calm/export.rs +538 -0
  174. package/domainforge-core/src/calm/import.rs +1220 -0
  175. package/domainforge-core/src/calm/mod.rs +9 -0
  176. package/domainforge-core/src/calm/models.rs +108 -0
  177. package/domainforge-core/src/calm/sbvr_import.rs +9 -0
  178. package/domainforge-core/src/cli/authority.rs +149 -0
  179. package/domainforge-core/src/cli/format.rs +85 -0
  180. package/domainforge-core/src/cli/import.rs +133 -0
  181. package/domainforge-core/src/cli/mod.rs +64 -0
  182. package/domainforge-core/src/cli/normalize.rs +180 -0
  183. package/domainforge-core/src/cli/pack.rs +904 -0
  184. package/domainforge-core/src/cli/parse.rs +112 -0
  185. package/domainforge-core/src/cli/project.rs +294 -0
  186. package/domainforge-core/src/cli/registry.rs +41 -0
  187. package/domainforge-core/src/cli/test.rs +12 -0
  188. package/domainforge-core/src/cli/validate.rs +195 -0
  189. package/domainforge-core/src/cli/validate_kg.rs +80 -0
  190. package/domainforge-core/src/concept_id.rs +89 -0
  191. package/domainforge-core/src/error/diagnostics.rs +426 -0
  192. package/domainforge-core/src/error/fuzzy.rs +253 -0
  193. package/domainforge-core/src/error/mod.rs +13 -0
  194. package/domainforge-core/src/formatter/comments.rs +223 -0
  195. package/domainforge-core/src/formatter/config.rs +114 -0
  196. package/domainforge-core/src/formatter/mod.rs +22 -0
  197. package/domainforge-core/src/formatter/printer.rs +906 -0
  198. package/domainforge-core/src/graph/mod.rs +858 -0
  199. package/domainforge-core/src/graph/to_ast.rs +66 -0
  200. package/domainforge-core/src/kg.rs +1476 -0
  201. package/domainforge-core/src/kg_import.rs +251 -0
  202. package/domainforge-core/src/lib.rs +203 -0
  203. package/domainforge-core/src/module/mod.rs +1 -0
  204. package/domainforge-core/src/module/resolver.rs +260 -0
  205. package/domainforge-core/src/parser/ast.rs +2919 -0
  206. package/domainforge-core/src/parser/ast_convert.rs +494 -0
  207. package/domainforge-core/src/parser/ast_schema.rs +491 -0
  208. package/domainforge-core/src/parser/error.rs +291 -0
  209. package/domainforge-core/src/parser/lint.rs +39 -0
  210. package/domainforge-core/src/parser/mod.rs +193 -0
  211. package/domainforge-core/src/parser/printer.rs +702 -0
  212. package/domainforge-core/src/parser/profiles.rs +71 -0
  213. package/domainforge-core/src/parser/string_utils.rs +138 -0
  214. package/domainforge-core/src/patterns.rs +68 -0
  215. package/domainforge-core/src/policy/core.rs +1148 -0
  216. package/domainforge-core/src/policy/expression.rs +399 -0
  217. package/domainforge-core/src/policy/mod.rs +18 -0
  218. package/domainforge-core/src/policy/normalize.rs +1028 -0
  219. package/domainforge-core/src/policy/quantifier.rs +940 -0
  220. package/domainforge-core/src/policy/three_valued.rs +140 -0
  221. package/domainforge-core/src/policy/three_valued_microbench.rs +104 -0
  222. package/domainforge-core/src/policy/type_inference.rs +67 -0
  223. package/domainforge-core/src/policy/violation.rs +36 -0
  224. package/domainforge-core/src/primitives/concept_change.rs +61 -0
  225. package/domainforge-core/src/primitives/entity.rs +224 -0
  226. package/domainforge-core/src/primitives/flow.rs +111 -0
  227. package/domainforge-core/src/primitives/instance.rs +93 -0
  228. package/domainforge-core/src/primitives/mapping_contract.rs +50 -0
  229. package/domainforge-core/src/primitives/metric.rs +79 -0
  230. package/domainforge-core/src/primitives/mod.rs +25 -0
  231. package/domainforge-core/src/primitives/projection_contract.rs +50 -0
  232. package/domainforge-core/src/primitives/quantity.rs +56 -0
  233. package/domainforge-core/src/primitives/relation.rs +68 -0
  234. package/domainforge-core/src/primitives/resource.rs +237 -0
  235. package/domainforge-core/src/primitives/resource_instance.rs +88 -0
  236. package/domainforge-core/src/primitives/role.rs +49 -0
  237. package/domainforge-core/src/projection/buf.rs +404 -0
  238. package/domainforge-core/src/projection/contracts.rs +22 -0
  239. package/domainforge-core/src/projection/engine.rs +19 -0
  240. package/domainforge-core/src/projection/mod.rs +16 -0
  241. package/domainforge-core/src/projection/protobuf.rs +3331 -0
  242. package/domainforge-core/src/projection/registry.rs +43 -0
  243. package/domainforge-core/src/python/authority.rs +253 -0
  244. package/domainforge-core/src/python/error.rs +227 -0
  245. package/domainforge-core/src/python/formatter.rs +86 -0
  246. package/domainforge-core/src/python/graph.rs +366 -0
  247. package/domainforge-core/src/python/mod.rs +9 -0
  248. package/domainforge-core/src/python/policy.rs +651 -0
  249. package/domainforge-core/src/python/primitives.rs +796 -0
  250. package/domainforge-core/src/python/registry.rs +98 -0
  251. package/domainforge-core/src/python/semantic_pack.rs +619 -0
  252. package/domainforge-core/src/python/units.rs +96 -0
  253. package/domainforge-core/src/registry/mod.rs +432 -0
  254. package/domainforge-core/src/registry/tests.rs +210 -0
  255. package/domainforge-core/src/sbvr.rs +744 -0
  256. package/domainforge-core/src/semantic_pack/builder.rs +470 -0
  257. package/domainforge-core/src/semantic_pack/canonical_json.rs +184 -0
  258. package/domainforge-core/src/semantic_pack/diagnostics.rs +214 -0
  259. package/domainforge-core/src/semantic_pack/diff.rs +216 -0
  260. package/domainforge-core/src/semantic_pack/mod.rs +31 -0
  261. package/domainforge-core/src/semantic_pack/pack_set.rs +240 -0
  262. package/domainforge-core/src/semantic_pack/resolver.rs +437 -0
  263. package/domainforge-core/src/semantic_pack/review.rs +125 -0
  264. package/domainforge-core/src/semantic_pack/schema.rs +342 -0
  265. package/domainforge-core/src/semantic_pack/signing.rs +105 -0
  266. package/domainforge-core/src/semantic_pack/validator.rs +368 -0
  267. package/domainforge-core/src/semantic_version.rs +140 -0
  268. package/domainforge-core/src/test_utils.rs +12 -0
  269. package/domainforge-core/src/typescript/authority.rs +184 -0
  270. package/domainforge-core/src/typescript/error.rs +146 -0
  271. package/domainforge-core/src/typescript/formatter.rs +76 -0
  272. package/domainforge-core/src/typescript/graph.rs +391 -0
  273. package/domainforge-core/src/typescript/mod.rs +9 -0
  274. package/domainforge-core/src/typescript/policy.rs +564 -0
  275. package/domainforge-core/src/typescript/primitives.rs +784 -0
  276. package/domainforge-core/src/typescript/registry.rs +88 -0
  277. package/domainforge-core/src/typescript/semantic_pack.rs +470 -0
  278. package/domainforge-core/src/typescript/units.rs +76 -0
  279. package/domainforge-core/src/units/mod.rs +462 -0
  280. package/domainforge-core/src/uuid_module.rs +42 -0
  281. package/domainforge-core/src/validation_error.rs +818 -0
  282. package/domainforge-core/src/validation_result.rs +30 -0
  283. package/domainforge-core/src/wasm/authority.rs +192 -0
  284. package/domainforge-core/src/wasm/error.rs +145 -0
  285. package/domainforge-core/src/wasm/formatter.rs +69 -0
  286. package/domainforge-core/src/wasm/graph.rs +471 -0
  287. package/domainforge-core/src/wasm/mod.rs +16 -0
  288. package/domainforge-core/src/wasm/policy.rs +607 -0
  289. package/domainforge-core/src/wasm/primitives.rs +295 -0
  290. package/domainforge-core/src/wasm/semantic_pack.rs +471 -0
  291. package/domainforge-core/src/wasm/units.rs +62 -0
  292. package/domainforge-core/std/aws.sea +6 -0
  293. package/domainforge-core/std/core.sea +6 -0
  294. package/domainforge-core/std/http.sea +27 -0
  295. package/domainforge-core/tests/aggregation_enhanced_tests.rs +162 -0
  296. package/domainforge-core/tests/aggregation_eval_tests.rs +248 -0
  297. package/domainforge-core/tests/aggregation_integration_tests.rs +379 -0
  298. package/domainforge-core/tests/aggregation_parser_tests.rs +92 -0
  299. package/domainforge-core/tests/aggregation_tests.rs +102 -0
  300. package/domainforge-core/tests/authority_conformance_tests.rs +1173 -0
  301. package/domainforge-core/tests/calm_round_trip_tests.rs +283 -0
  302. package/domainforge-core/tests/calm_schema_validation_tests.rs +137 -0
  303. package/domainforge-core/tests/cast_operator_tests.rs +85 -0
  304. package/domainforge-core/tests/cli_binary_check.rs +37 -0
  305. package/domainforge-core/tests/cli_import_tests.rs +291 -0
  306. package/domainforge-core/tests/cli_path_traversal_tests.rs +124 -0
  307. package/domainforge-core/tests/cli_tests.rs +63 -0
  308. package/domainforge-core/tests/diagnostics_tests.rs +203 -0
  309. package/domainforge-core/tests/dimension_unit_tests.rs +80 -0
  310. package/domainforge-core/tests/entity_tests.rs +69 -0
  311. package/domainforge-core/tests/evolution_semantics_tests.rs +157 -0
  312. package/domainforge-core/tests/flow_tests.rs +78 -0
  313. package/domainforge-core/tests/flow_unit_validation_tests.rs +31 -0
  314. package/domainforge-core/tests/graph_integration_tests.rs +218 -0
  315. package/domainforge-core/tests/graph_tests.rs +626 -0
  316. package/domainforge-core/tests/import_parsing_tests.rs +23 -0
  317. package/domainforge-core/tests/instance_integration_tests.rs +98 -0
  318. package/domainforge-core/tests/instance_parsing_tests.rs +58 -0
  319. package/domainforge-core/tests/instance_tests.rs +61 -0
  320. package/domainforge-core/tests/kg_uri_encoding_tests.rs +53 -0
  321. package/domainforge-core/tests/lint_tests.rs +19 -0
  322. package/domainforge-core/tests/metric_tests.rs +143 -0
  323. package/domainforge-core/tests/module_resolution_tests.rs +100 -0
  324. package/domainforge-core/tests/namespace_registry_tests.rs +247 -0
  325. package/domainforge-core/tests/null_handling_tests.rs +26 -0
  326. package/domainforge-core/tests/parser_ast_v3.rs +53 -0
  327. package/domainforge-core/tests/parser_dimension_registry_tests.rs +20 -0
  328. package/domainforge-core/tests/parser_integration_tests.rs +294 -0
  329. package/domainforge-core/tests/parser_metadata_tests.rs +97 -0
  330. package/domainforge-core/tests/parser_resource_domain_only_graph_test.rs +21 -0
  331. package/domainforge-core/tests/parser_resource_limits_tests.rs +122 -0
  332. package/domainforge-core/tests/parser_tests.rs +512 -0
  333. package/domainforge-core/tests/pattern_semantics_tests.rs +87 -0
  334. package/domainforge-core/tests/phase_14_determinism_tests.rs +166 -0
  335. package/domainforge-core/tests/phase_15_validation_error_tests.rs +136 -0
  336. package/domainforge-core/tests/phase_16_unicode_tests.rs +248 -0
  337. package/domainforge-core/tests/phase_17_export_tests.rs +285 -0
  338. package/domainforge-core/tests/phase_17_round_trip_tests.rs +264 -0
  339. package/domainforge-core/tests/policy_tests.rs +635 -0
  340. package/domainforge-core/tests/primitives_integration_tests.rs +151 -0
  341. package/domainforge-core/tests/print_rdf_xml.rs +14 -0
  342. package/domainforge-core/tests/printer_tests.rs +204 -0
  343. package/domainforge-core/tests/profile_tests.rs +35 -0
  344. package/domainforge-core/tests/projection_contracts_tests.rs +154 -0
  345. package/domainforge-core/tests/protobuf_projection_tests.rs +199 -0
  346. package/domainforge-core/tests/quantity_tests.rs +41 -0
  347. package/domainforge-core/tests/rdf_xml_typed_literal_tests.rs +105 -0
  348. package/domainforge-core/tests/registry_schema_tests.rs +33 -0
  349. package/domainforge-core/tests/resource_tests.rs +50 -0
  350. package/domainforge-core/tests/resource_unit_tests.rs +24 -0
  351. package/domainforge-core/tests/roles_relations_tests.rs +61 -0
  352. package/domainforge-core/tests/round_trip_tests.rs +34 -0
  353. package/domainforge-core/tests/runtime_toggle_tests.rs +70 -0
  354. package/domainforge-core/tests/sbvr_fact_schema_tests.rs +60 -0
  355. package/domainforge-core/tests/sbvr_flow_facts_tests.rs +55 -0
  356. package/domainforge-core/tests/sbvr_parsing_tests.rs +53 -0
  357. package/domainforge-core/tests/semantic_pack_alias_resolution.rs +197 -0
  358. package/domainforge-core/tests/semantic_pack_build.rs +302 -0
  359. package/domainforge-core/tests/semantic_pack_consumer_smoke.rs +150 -0
  360. package/domainforge-core/tests/semantic_pack_pack_set.rs +160 -0
  361. package/domainforge-core/tests/semantic_pack_signing.rs +157 -0
  362. package/domainforge-core/tests/semantic_pack_three_valued.rs +250 -0
  363. package/domainforge-core/tests/semantic_pack_validate.rs +196 -0
  364. package/domainforge-core/tests/std_lib_tests.rs +37 -0
  365. package/domainforge-core/tests/temporal_evaluation_tests.rs +159 -0
  366. package/domainforge-core/tests/temporal_semantics_tests.rs +214 -0
  367. package/domainforge-core/tests/three_valued_quantifiers_tests.rs +164 -0
  368. package/domainforge-core/tests/turtle_entity_export_tests.rs +38 -0
  369. package/domainforge-core/tests/turtle_escaping_tests.rs +53 -0
  370. package/domainforge-core/tests/turtle_resource_export_tests.rs +34 -0
  371. package/domainforge-core/tests/type_inference_tests.rs +40 -0
  372. package/domainforge-core/tests/unicode_validation_tests.rs +169 -0
  373. package/domainforge-core/tests/unit_tests.rs +81 -0
  374. package/domainforge-core/tests/validate_tests.rs +38 -0
  375. package/domainforge-core/tests/validation_unit_mismatch_tests.rs +83 -0
  376. package/domainforge-core/tests/wasm_tests.rs +229 -0
  377. package/domainforge-python/CHANGELOG-python.md +12 -0
  378. package/domainforge-python/MIGRATING.md +24 -0
  379. package/domainforge-python/README.md +256 -0
  380. package/domainforge-python/domainforge/__init__.py +95 -0
  381. package/domainforge-python/domainforge/domainforge.pyi +519 -0
  382. package/domainforge-python/pyproject.toml +36 -0
  383. package/domainforge-typescript/CHANGELOG-typescript.md +12 -0
  384. package/domainforge-typescript/LICENSE +201 -0
  385. package/domainforge-typescript/MIGRATING.md +24 -0
  386. package/domainforge-typescript/README.md +305 -0
  387. package/domainforge-typescript/index.d.ts +452 -0
  388. package/domainforge-typescript/index.js +361 -0
  389. package/domainforge-typescript/package.json +60 -0
  390. package/example.js +61 -0
  391. package/examples/browser.html +366 -0
  392. package/examples/namespaces/finance/cashflow.sea +5 -0
  393. package/examples/namespaces/logistics/core.sea +7 -0
  394. package/examples/observability_metrics.sea +38 -0
  395. package/fixtures/semantic_packs/acme_procurement/domain/entities.sea +39 -0
  396. package/fixtures/semantic_packs/acme_procurement/domain/metrics.sea +11 -0
  397. package/fixtures/semantic_packs/acme_procurement/domain/relations.sea +7 -0
  398. package/fixtures/semantic_packs/acme_procurement/domain/resources.sea +9 -0
  399. package/fixtures/semantic_packs/acme_procurement/review/acme.procurement.semantic-review.jsonl +7 -0
  400. package/fixtures/semantic_packs/acme_procurement/tests/ambiguous_vendor_alias.sea +8 -0
  401. package/fixtures/semantic_packs/acme_procurement/tests/deprecated_vendor_alias.sea +8 -0
  402. package/fixtures/semantic_packs/acme_procurement/tests/invalid_relation.sea +3 -0
  403. package/fixtures/semantic_packs/acme_procurement/tests/proposed_concept.sea +8 -0
  404. package/fixtures/semantic_packs/acme_procurement/tests/rejected_concept.sea +8 -0
  405. package/fixtures/semantic_packs/acme_procurement/tests/unit_mismatch.sea +7 -0
  406. package/fixtures/semantic_packs/acme_procurement/tests/unknown_vendor_policy.sea +8 -0
  407. package/fixtures/semantic_packs/acme_procurement/tests/valid_purchase_policy.sea +8 -0
  408. package/index.d.ts +2 -0
  409. package/index.js +8 -0
  410. package/justfile +200 -0
  411. package/lefthook.yml +13 -0
  412. package/lib/validate_native_exports.d.ts +4 -0
  413. package/lib/validate_native_exports.js +12 -0
  414. package/package.json +22 -0
  415. package/pytest.ini +5 -0
  416. package/python/tests/test_registry.py +75 -0
  417. package/python/tests/test_units.py +18 -0
  418. package/release-please-config.json +49 -0
  419. package/requirements-dev.txt +3 -0
  420. package/requirements.txt +3 -0
  421. package/rust-toolchain.toml +3 -0
  422. package/schemas/ast-v1.schema.json +72 -0
  423. package/schemas/ast-v2.schema.json +1200 -0
  424. package/schemas/ast-v3.schema.json +1200 -0
  425. package/schemas/sea-registry.schema.json +45 -0
  426. package/scripts/build-python.sh +37 -0
  427. package/scripts/build-release.sh +279 -0
  428. package/scripts/build-typescript.sh +13 -0
  429. package/scripts/build-wasm.sh +113 -0
  430. package/scripts/bump-version.sh +245 -0
  431. package/scripts/check_unused_test_imports.py +85 -0
  432. package/scripts/ci_tasks.py +379 -0
  433. package/scripts/clear_debug_test.sh +10 -0
  434. package/scripts/create-github-release.sh +262 -0
  435. package/scripts/create-tag.sh +203 -0
  436. package/scripts/find_and_link_test_binary.sh +70 -0
  437. package/scripts/generate-changelog.sh +271 -0
  438. package/scripts/generate-release-notes.sh +205 -0
  439. package/scripts/lint_release_security.py +96 -0
  440. package/scripts/lint_release_workflows.py +82 -0
  441. package/scripts/lint_workflow_gates.py +113 -0
  442. package/scripts/optimized-wasm-build.sh +61 -0
  443. package/scripts/patch_napi_types.py +62 -0
  444. package/scripts/pre-release-check.sh +289 -0
  445. package/scripts/prepare_rust_debug.sh +52 -0
  446. package/scripts/release.sh +373 -0
  447. package/scripts/resolve_rust_binary.py +230 -0
  448. package/scripts/run_commitlint.sh +29 -0
  449. package/scripts/test-all.sh +77 -0
  450. package/scripts/update_launch_program.py +93 -0
  451. package/secrets/README.md +27 -0
  452. package/secrets/secrets.yaml +21 -0
  453. package/test_integration.py +67 -0
  454. package/tests/test_authority.py +328 -0
  455. package/tests/test_ci_tasks.py +143 -0
  456. package/tests/test_expression.py +256 -0
  457. package/tests/test_golden_payment_flow.py +42 -0
  458. package/tests/test_graph.py +127 -0
  459. package/tests/test_instance.py +136 -0
  460. package/tests/test_parser.py +82 -0
  461. package/tests/test_primitives.py +68 -0
  462. package/tests/test_role_relation_parity.py +56 -0
  463. package/tests/test_runtime_toggle.py +156 -0
  464. package/tests/test_semantic_pack.py +639 -0
  465. package/tests/test_three_valued_eval.py +159 -0
  466. package/tsconfig.json +30 -0
  467. package/typescript-tests/advanced.test.ts +165 -0
  468. package/typescript-tests/authority.test.ts +216 -0
  469. package/typescript-tests/expression.test.ts +228 -0
  470. package/typescript-tests/golden-payment-flow.test.ts +51 -0
  471. package/typescript-tests/graph.test.ts +142 -0
  472. package/typescript-tests/native-binding.test.ts +20 -0
  473. package/typescript-tests/primitives.test.ts +88 -0
  474. package/typescript-tests/registry.test.ts +122 -0
  475. package/typescript-tests/role_relation.test.ts +63 -0
  476. package/typescript-tests/runtime_toggle.test.ts +141 -0
  477. package/typescript-tests/semantic-pack.test.ts +556 -0
  478. package/typescript-tests/three_valued_eval.test.ts +135 -0
  479. package/typescript-tests/units.test.ts +36 -0
  480. package/vitest.config.ts +13 -0
  481. package/wasm_demo.html +225 -0
@@ -0,0 +1,112 @@
1
+ //! Parse SEA files and output AST or Graph JSON.
2
+ //!
3
+ //! This command parses a SEA DSL file and outputs the result in the specified format.
4
+ //! Use `--format json` to get structured JSON output suitable for tooling.
5
+
6
+ use anyhow::{Context, Result};
7
+ use clap::{Args, ValueEnum};
8
+ use std::fs;
9
+ use std::path::PathBuf;
10
+
11
+ #[derive(Args)]
12
+ pub struct ParseArgs {
13
+ /// Input SEA file to parse
14
+ #[arg(required = true)]
15
+ pub input: PathBuf,
16
+
17
+ /// Output format
18
+ #[arg(long, value_enum, default_value_t = ParseFormat::Human)]
19
+ pub format: ParseFormat,
20
+
21
+ /// Output file (stdout if not specified)
22
+ #[arg(long, short)]
23
+ pub out: Option<PathBuf>,
24
+
25
+ /// Output AST instead of Graph (preserves source structure and line numbers)
26
+ #[arg(long)]
27
+ pub ast: bool,
28
+
29
+ /// Output AST v3 (alias for --ast)
30
+ #[arg(long)]
31
+ pub ast_v3: bool,
32
+ }
33
+
34
+ #[derive(ValueEnum, Clone, Debug, Copy, Default)]
35
+ pub enum ParseFormat {
36
+ /// Human-readable summary
37
+ #[default]
38
+ Human,
39
+ /// JSON output
40
+ Json,
41
+ }
42
+
43
+ pub fn run(args: ParseArgs) -> Result<()> {
44
+ let source = fs::read_to_string(&args.input)
45
+ .with_context(|| format!("Failed to read file: {}", args.input.display()))?;
46
+
47
+ let output = match (args.ast || args.ast_v3, args.format) {
48
+ // AST output (uses schema types for stable JSON format)
49
+ (true, ParseFormat::Json) => {
50
+ let internal_ast =
51
+ crate::parser::parse(&source).map_err(|e| anyhow::anyhow!("Parse error: {}", e))?;
52
+ let schema_ast: crate::parser::ast_schema::Ast = internal_ast.into();
53
+ serde_json::to_string_pretty(&schema_ast).context("Failed to serialize AST to JSON")?
54
+ }
55
+ (true, ParseFormat::Human) => {
56
+ let ast =
57
+ crate::parser::parse(&source).map_err(|e| anyhow::anyhow!("Parse error: {}", e))?;
58
+ format!(
59
+ "AST parsed successfully: {}\n\
60
+ Namespace: {}\n\
61
+ Version: {}\n\
62
+ Declarations: {}",
63
+ args.input.display(),
64
+ ast.metadata.namespace.as_deref().unwrap_or("(none)"),
65
+ ast.metadata.version.as_deref().unwrap_or("(none)"),
66
+ ast.declarations.len()
67
+ )
68
+ }
69
+ // Graph output (default)
70
+ (false, ParseFormat::Json) => {
71
+ let graph = crate::parser::parse_to_graph(&source)
72
+ .map_err(|e| anyhow::anyhow!("Parse error: {}", e))?;
73
+ serde_json::to_string_pretty(&graph).context("Failed to serialize Graph to JSON")?
74
+ }
75
+ (false, ParseFormat::Human) => {
76
+ let graph = crate::parser::parse_to_graph(&source)
77
+ .map_err(|e| anyhow::anyhow!("Parse error: {}", e))?;
78
+ format!(
79
+ "Graph parsed successfully: {}\n\
80
+ Entities: {}\n\
81
+ Resources: {}\n\
82
+ Flows: {}\n\
83
+ Roles: {}\n\
84
+ Relations: {}\n\
85
+ Instances: {}\n\
86
+ Policies: {}",
87
+ args.input.display(),
88
+ graph.entity_count(),
89
+ graph.resource_count(),
90
+ graph.flow_count(),
91
+ graph.role_count(),
92
+ graph.relation_count(),
93
+ graph.instance_count(),
94
+ graph.pattern_count()
95
+ )
96
+ }
97
+ };
98
+
99
+ // Write output
100
+ match args.out {
101
+ Some(path) => {
102
+ fs::write(&path, &output)
103
+ .with_context(|| format!("Failed to write to: {}", path.display()))?;
104
+ eprintln!("Wrote output to: {}", path.display());
105
+ }
106
+ None => {
107
+ println!("{}", output);
108
+ }
109
+ }
110
+
111
+ Ok(())
112
+ }
@@ -0,0 +1,294 @@
1
+ use crate::parser::{parse_to_graph_with_options, ParseOptions};
2
+ use crate::projection::protobuf::{CompatibilityMode, SchemaHistory};
3
+ use crate::projection::ProtobufEngine;
4
+ use crate::NamespaceRegistry;
5
+ use anyhow::{Context, Result};
6
+ use clap::{Parser, ValueEnum};
7
+ use std::fs::{read_to_string, write};
8
+ use std::path::{Path, PathBuf};
9
+
10
+ #[derive(Parser)]
11
+ pub struct ProjectArgs {
12
+ #[arg(long, value_enum)]
13
+ pub format: ProjectFormat,
14
+
15
+ /// Optional namespace filter (project only entities from this namespace)
16
+ #[arg(long)]
17
+ pub namespace: Option<String>,
18
+
19
+ /// Protobuf package name (for protobuf format)
20
+ #[arg(long, default_value = "sea.generated")]
21
+ pub package: String,
22
+
23
+ /// Include governance messages (for protobuf format)
24
+ #[arg(long)]
25
+ pub include_governance: bool,
26
+
27
+ /// Generate gRPC service definitions from Flow patterns (protobuf only)
28
+ #[arg(long)]
29
+ pub include_services: bool,
30
+
31
+ /// Schema compatibility mode: additive, backward, or breaking (protobuf only)
32
+ #[arg(long, value_enum, default_value = "backward")]
33
+ pub compatibility: CliCompatibilityMode,
34
+
35
+ /// Directory to store schema history for compatibility checking (protobuf only)
36
+ #[arg(long)]
37
+ pub schema_history: Option<PathBuf>,
38
+
39
+ /// Automatically apply fixes (add reserved fields) for backward compatibility
40
+ #[arg(long)]
41
+ pub apply_fixes: bool,
42
+
43
+ /// Run 'buf lint' on the generated output
44
+ #[arg(long)]
45
+ pub buf_lint: bool,
46
+
47
+ /// Run 'buf breaking' check against previous version
48
+ #[arg(long)]
49
+ pub buf_breaking: bool,
50
+
51
+ /// Run 'buf generate' to build code artifacts
52
+ #[arg(long)]
53
+ pub buf_generate: bool,
54
+
55
+ /// Generate multiple files (one per namespace) instead of a single file
56
+ #[arg(long)]
57
+ pub multi_file: bool,
58
+
59
+ pub input: PathBuf,
60
+ pub output: PathBuf,
61
+ }
62
+
63
+ #[derive(ValueEnum, Clone, Debug, Copy)]
64
+ pub enum ProjectFormat {
65
+ Calm,
66
+ Kg,
67
+ Protobuf,
68
+ Proto, // alias for protobuf
69
+ }
70
+
71
+ #[derive(ValueEnum, Clone, Debug, Copy, Default)]
72
+ pub enum CliCompatibilityMode {
73
+ /// Only additions allowed - strictest mode for public APIs
74
+ Additive,
75
+ /// Removals become reserved fields - default for internal APIs
76
+ #[default]
77
+ Backward,
78
+ /// All changes allowed - for breaking releases
79
+ Breaking,
80
+ }
81
+
82
+ impl From<CliCompatibilityMode> for CompatibilityMode {
83
+ fn from(mode: CliCompatibilityMode) -> Self {
84
+ match mode {
85
+ CliCompatibilityMode::Additive => CompatibilityMode::Additive,
86
+ CliCompatibilityMode::Backward => CompatibilityMode::Backward,
87
+ CliCompatibilityMode::Breaking => CompatibilityMode::Breaking,
88
+ }
89
+ }
90
+ }
91
+
92
+ pub fn run(args: ProjectArgs) -> Result<()> {
93
+ let source = read_to_string(&args.input)
94
+ .with_context(|| format!("Failed to read input file {}", args.input.display()))?;
95
+
96
+ // Parse input
97
+ let registry =
98
+ NamespaceRegistry::discover(&args.input).context("discovering namespace registry")?;
99
+ let default_namespace = registry
100
+ .as_ref()
101
+ .and_then(|reg| reg.namespace_for(&args.input).map(|ns| ns.to_string()));
102
+ let options = ParseOptions {
103
+ default_namespace: default_namespace.clone(),
104
+ namespace_registry: registry.clone(),
105
+ entry_path: Some(args.input.clone()),
106
+ ..Default::default()
107
+ };
108
+ let graph = parse_to_graph_with_options(&source, &options)
109
+ .map_err(|e| anyhow::anyhow!("Parse failed for {}: {}", args.input.display(), e))?;
110
+
111
+ match args.format {
112
+ ProjectFormat::Calm => {
113
+ let value = crate::calm::export(&graph)
114
+ .map_err(|e| anyhow::anyhow!("Failed to export to CALM: {}", e))?;
115
+ let json =
116
+ serde_json::to_string_pretty(&value).context("Failed to serialize CALM JSON")?;
117
+ write(&args.output, json)
118
+ .with_context(|| format!("Failed to write output to {}", args.output.display()))?;
119
+ println!("Projected to CALM: {}", args.output.display());
120
+ }
121
+ ProjectFormat::Kg => {
122
+ let kg = crate::KnowledgeGraph::from_graph(&graph)
123
+ .map_err(|e| anyhow::anyhow!("Failed to convert to Knowledge Graph: {}", e))?;
124
+
125
+ let output_str = if args
126
+ .output
127
+ .extension()
128
+ .and_then(|ext| ext.to_str())
129
+ .is_some_and(|ext| {
130
+ ext.eq_ignore_ascii_case("xml") || ext.eq_ignore_ascii_case("rdf")
131
+ }) {
132
+ kg.to_rdf_xml()
133
+ } else {
134
+ kg.to_turtle()
135
+ };
136
+
137
+ write(&args.output, output_str)
138
+ .with_context(|| format!("Failed to write output to {}", args.output.display()))?;
139
+ println!("Projected to KG: {}", args.output.display());
140
+ }
141
+ ProjectFormat::Protobuf | ProjectFormat::Proto => {
142
+ let namespace_filter = args.namespace.as_deref().unwrap_or("");
143
+ let projection_name = args
144
+ .input
145
+ .file_stem()
146
+ .and_then(|s| s.to_str())
147
+ .unwrap_or("projection");
148
+
149
+ if args.multi_file {
150
+ if args.schema_history.is_some() {
151
+ eprintln!(
152
+ "Warning: --schema-history is currently ignored in --multi-file mode."
153
+ );
154
+ }
155
+
156
+ if !args.output.exists() {
157
+ std::fs::create_dir_all(&args.output).with_context(|| {
158
+ format!(
159
+ "Failed to create output directory {}",
160
+ args.output.display()
161
+ )
162
+ })?;
163
+ } else if !args.output.is_dir() {
164
+ return Err(anyhow::anyhow!(
165
+ "Output path must be a directory for --multi-file projection"
166
+ ));
167
+ }
168
+
169
+ let files = ProtobufEngine::project_multi_file(
170
+ &graph,
171
+ &args.package,
172
+ args.include_governance,
173
+ args.include_services,
174
+ );
175
+
176
+ for (rel_path, proto) in &files {
177
+ let abs_path = args.output.join(rel_path);
178
+ crate::projection::protobuf::validate_output_path(&args.output, &abs_path)
179
+ .map_err(|e| anyhow::anyhow!("{}", e))?;
180
+ if let Some(parent) = abs_path.parent() {
181
+ std::fs::create_dir_all(parent)?;
182
+ }
183
+
184
+ let content = proto.to_proto_string();
185
+ write(&abs_path, content)
186
+ .with_context(|| format!("Failed to write {}", abs_path.display()))?;
187
+ }
188
+
189
+ println!(
190
+ "Projected to Protobuf (Multi-file): {}",
191
+ args.output.display()
192
+ );
193
+ println!(" Files: {}", files.len());
194
+ println!(" Base Package: {}", args.package);
195
+ } else {
196
+ let mut proto_file = ProtobufEngine::project_with_full_options(
197
+ &graph,
198
+ namespace_filter,
199
+ &args.package,
200
+ projection_name,
201
+ args.include_governance,
202
+ args.include_services,
203
+ );
204
+
205
+ // Handle compatibility checking if schema history is provided
206
+ if let Some(ref history_dir) = args.schema_history {
207
+ let history = SchemaHistory::new(history_dir);
208
+ let mode: CompatibilityMode = args.compatibility.into();
209
+
210
+ let result = history
211
+ .check_and_update(&mut proto_file, mode, args.apply_fixes)
212
+ .map_err(|e| anyhow::anyhow!("Compatibility check failed: {}", e))?;
213
+
214
+ // Print compatibility report
215
+ if result.has_violations() {
216
+ eprintln!("\n{}", result.to_report());
217
+ }
218
+
219
+ // Fail if not compatible (unless in breaking mode)
220
+ if !result.is_compatible {
221
+ return Err(anyhow::anyhow!(
222
+ "Schema evolution is not compatible in {} mode. Use --compatibility breaking to force, or --apply-fixes to auto-fix.",
223
+ mode
224
+ ));
225
+ }
226
+
227
+ if result.has_violations() {
228
+ println!(
229
+ " Compatibility: {} (with {} warnings)",
230
+ mode,
231
+ result.violations.len()
232
+ );
233
+ } else {
234
+ println!(" Compatibility: {} (clean)", mode);
235
+ }
236
+ }
237
+
238
+ let proto_string = proto_file.to_proto_string();
239
+ write(&args.output, &proto_string).with_context(|| {
240
+ format!("Failed to write output to {}", args.output.display())
241
+ })?;
242
+ println!("Projected to Protobuf: {}", args.output.display());
243
+ println!(" Package: {}", args.package);
244
+ println!(" Messages: {}", proto_file.messages.len());
245
+ if !proto_file.services.is_empty() {
246
+ println!(
247
+ " Services: {} ({} methods)",
248
+ proto_file.services.len(),
249
+ proto_file
250
+ .services
251
+ .iter()
252
+ .map(|s| s.methods.len())
253
+ .sum::<usize>()
254
+ );
255
+ }
256
+ }
257
+
258
+ // Buf integration
259
+ if args.buf_lint || args.buf_breaking || args.buf_generate {
260
+ use crate::projection::buf::BufIntegration;
261
+ let buf = BufIntegration::new();
262
+ let output_dir = if args.multi_file {
263
+ &args.output
264
+ } else {
265
+ args.output.parent().unwrap_or(Path::new("."))
266
+ };
267
+
268
+ if args.buf_lint {
269
+ print!(" Running buf lint... ");
270
+ match buf.lint(output_dir) {
271
+ Ok(result) => {
272
+ if result.success {
273
+ println!("clean");
274
+ } else {
275
+ println!("issues found:");
276
+ println!("{}", result.raw_output);
277
+ }
278
+ }
279
+ Err(e) => println!("failed: {}", e),
280
+ }
281
+ }
282
+
283
+ if args.buf_breaking {
284
+ if let Some(history) = args.schema_history {
285
+ print!(" Running buf breaking check... ");
286
+ println!("(checking against {})", history.display());
287
+ }
288
+ }
289
+ }
290
+ }
291
+ }
292
+
293
+ Ok(())
294
+ }
@@ -0,0 +1,41 @@
1
+ use crate::registry::NamespaceRegistry;
2
+ use clap::{Args, Subcommand};
3
+ use std::path::PathBuf;
4
+
5
+ #[derive(Debug, Args)]
6
+ pub struct RegistryArgs {
7
+ #[command(subcommand)]
8
+ pub command: RegistryCommands,
9
+ }
10
+
11
+ #[derive(Debug, Subcommand)]
12
+ pub enum RegistryCommands {
13
+ /// Resolve the namespace for a file
14
+ Resolve(ResolveArgs),
15
+ }
16
+
17
+ #[derive(Debug, Args)]
18
+ pub struct ResolveArgs {
19
+ /// Fail if multiple namespaces match with equal specificity
20
+ #[arg(long)]
21
+ pub fail_on_ambiguity: bool,
22
+
23
+ /// The file path to resolve
24
+ pub file: PathBuf,
25
+ }
26
+
27
+ pub fn run(args: RegistryArgs) -> anyhow::Result<()> {
28
+ match args.command {
29
+ RegistryCommands::Resolve(resolve_args) => run_resolve(resolve_args),
30
+ }
31
+ }
32
+
33
+ fn run_resolve(args: ResolveArgs) -> anyhow::Result<()> {
34
+ let path = args.file;
35
+ let registry = NamespaceRegistry::discover(&path)?
36
+ .ok_or_else(|| anyhow::anyhow!("No .sea-registry.toml found"))?;
37
+
38
+ let namespace = registry.namespace_for_with_options(&path, args.fail_on_ambiguity)?;
39
+ println!("{}", namespace);
40
+ Ok(())
41
+ }
@@ -0,0 +1,12 @@
1
+ use anyhow::Result;
2
+ use clap::Parser;
3
+
4
+ #[derive(Parser)]
5
+ pub struct TestArgs {
6
+ pub pattern: String,
7
+ }
8
+
9
+ pub fn run(args: TestArgs) -> Result<()> {
10
+ println!("Test runner not yet implemented. Pattern: {}", args.pattern);
11
+ Ok(())
12
+ }
@@ -0,0 +1,195 @@
1
+ use crate::parser::{parse_to_graph_with_options, ParseOptions};
2
+ use crate::{Graph, NamespaceRegistry};
3
+ use anyhow::{Context, Result};
4
+ use clap::{Parser, ValueEnum};
5
+ use std::fs::read_to_string;
6
+ use std::path::{Path, PathBuf};
7
+
8
+ #[derive(Parser)]
9
+ pub struct ValidateArgs {
10
+ #[arg(long, value_enum, default_value_t = OutputFormat::Human)]
11
+ pub format: OutputFormat,
12
+
13
+ #[arg(long)]
14
+ pub no_color: bool,
15
+
16
+ #[arg(long)]
17
+ pub show_source: bool,
18
+
19
+ #[arg(required = true)]
20
+ pub target: PathBuf,
21
+ }
22
+
23
+ #[derive(ValueEnum, Clone, Debug, Copy)]
24
+ pub enum OutputFormat {
25
+ Json,
26
+ Human,
27
+ Lsp,
28
+ }
29
+
30
+ pub fn run(args: ValidateArgs) -> Result<()> {
31
+ let use_color = !args.no_color;
32
+
33
+ if args.target.is_dir() {
34
+ validate_directory(&args.target, args.format, use_color, args.show_source)
35
+ } else {
36
+ validate_file(&args.target, args.format, use_color, args.show_source)
37
+ }
38
+ }
39
+
40
+ fn validate_file(
41
+ path: &Path,
42
+ format: OutputFormat,
43
+ use_color: bool,
44
+ show_source: bool,
45
+ ) -> Result<()> {
46
+ let source =
47
+ read_to_string(path).with_context(|| format!("Failed to read file {}", path.display()))?;
48
+ let registry = NamespaceRegistry::discover(path).map_err(|e| anyhow::anyhow!(e.to_string()))?;
49
+ let default_namespace = registry
50
+ .as_ref()
51
+ .and_then(|reg| reg.namespace_for(path).map(|ns| ns.to_string()));
52
+ let options = ParseOptions {
53
+ default_namespace,
54
+ namespace_registry: registry.clone(),
55
+ entry_path: Some(path.to_path_buf()),
56
+ ..Default::default()
57
+ };
58
+ let graph = parse_to_graph_with_options(&source, &options)
59
+ .map_err(|e| anyhow::anyhow!("Parse failed for {}: {}", path.display(), e))?;
60
+ report_validation(graph, format, use_color, show_source, Some(&source))
61
+ }
62
+
63
+ fn validate_directory(
64
+ path: &Path,
65
+ format: OutputFormat,
66
+ use_color: bool,
67
+ show_source: bool,
68
+ ) -> Result<()> {
69
+ let registry = NamespaceRegistry::discover(path)
70
+ .map_err(|e| anyhow::anyhow!("Failed to load registry near {}: {}", path.display(), e))?
71
+ .ok_or_else(|| {
72
+ anyhow::anyhow!(
73
+ "No .sea-registry.toml found for {}. Run inside a workspace with a registry file.",
74
+ path.display()
75
+ )
76
+ })?;
77
+
78
+ let files = registry
79
+ .resolve_files()
80
+ .map_err(|e| anyhow::anyhow!("Failed to expand registry: {}", e))?;
81
+
82
+ if files.is_empty() {
83
+ return Err(anyhow::anyhow!(
84
+ "Registry at '{}' did not match any .sea files",
85
+ registry.root().display()
86
+ ));
87
+ }
88
+
89
+ let mut graph = Graph::new();
90
+ for binding in files {
91
+ let source = read_to_string(&binding.path)
92
+ .with_context(|| format!("Failed to read {}", binding.path.display()))?;
93
+ let options = ParseOptions {
94
+ default_namespace: Some(binding.namespace.clone()),
95
+ namespace_registry: Some(registry.clone()),
96
+ entry_path: Some(binding.path.clone()),
97
+ ..Default::default()
98
+ };
99
+ let file_graph = parse_to_graph_with_options(&source, &options)
100
+ .map_err(|e| anyhow::anyhow!("Parse failed for {}: {}", binding.path.display(), e))?;
101
+ graph
102
+ .extend(file_graph)
103
+ .map_err(|e| anyhow::anyhow!("Failed to merge {}: {}", binding.path.display(), e))?;
104
+ }
105
+
106
+ // For directory validation, we don't pass source code for now as errors could be from any file
107
+ // TODO: Map errors back to specific files in directory mode
108
+ report_validation(graph, format, use_color, show_source, None)
109
+ }
110
+
111
+ fn report_validation(
112
+ graph: Graph,
113
+ format: OutputFormat,
114
+ use_color: bool,
115
+ show_source: bool,
116
+ source: Option<&str>,
117
+ ) -> Result<()> {
118
+ // Note: show_source and source are currently unused because validation violations
119
+ // don't yet include source range information. These parameters are kept for future
120
+ // implementation when source snippets can be displayed.
121
+ let _ = (show_source, source); // Acknowledge parameters for future use
122
+
123
+ let result = graph.validate();
124
+
125
+ match format {
126
+ OutputFormat::Json => {
127
+ let json_output = serde_json::json!({
128
+ "error_count": result.error_count,
129
+ "violations": result.violations.iter().map(|v| {
130
+ serde_json::json!({
131
+ "severity": match v.severity {
132
+ crate::policy::Severity::Error => "error",
133
+ crate::policy::Severity::Warning => "warning",
134
+ crate::policy::Severity::Info => "info",
135
+ },
136
+ "policy_name": v.policy_name,
137
+ "message": v.message,
138
+ "context": v.context,
139
+ })
140
+ }).collect::<Vec<_>>(),
141
+ });
142
+ println!(
143
+ "{}",
144
+ serde_json::to_string_pretty(&json_output).context("Failed to serialize output")?
145
+ );
146
+ }
147
+ OutputFormat::Human | OutputFormat::Lsp => {
148
+ if result.error_count > 0 {
149
+ let msg = format!("Validation failed: {} errors", result.error_count);
150
+ if use_color {
151
+ use colored::Colorize;
152
+ println!("{}", msg.red());
153
+ } else {
154
+ println!("{}", msg);
155
+ }
156
+
157
+ for v in &result.violations {
158
+ let severity = match v.severity {
159
+ crate::policy::Severity::Error => "ERROR",
160
+ crate::policy::Severity::Warning => "WARN",
161
+ crate::policy::Severity::Info => "INFO",
162
+ };
163
+ let severity_colored = if use_color {
164
+ use colored::Colorize;
165
+ match v.severity {
166
+ crate::policy::Severity::Error => severity.red().to_string(),
167
+ crate::policy::Severity::Warning => severity.yellow().to_string(),
168
+ crate::policy::Severity::Info => severity.blue().to_string(),
169
+ }
170
+ } else {
171
+ severity.to_string()
172
+ };
173
+ println!("- [{}] {}: {}", severity_colored, v.policy_name, v.message);
174
+ }
175
+ } else {
176
+ let msg = format!(
177
+ "Validation succeeded: {} violations total",
178
+ result.violations.len()
179
+ );
180
+ if use_color {
181
+ use colored::Colorize;
182
+ println!("{}", msg.green());
183
+ } else {
184
+ println!("{}", msg);
185
+ }
186
+ }
187
+ }
188
+ }
189
+
190
+ if result.error_count > 0 {
191
+ Err(anyhow::anyhow!("Validation errors detected"))
192
+ } else {
193
+ Ok(())
194
+ }
195
+ }