@aifabrix/builder 2.49.2 → 2.51.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 (459) hide show
  1. package/.cursor/plans/157.1-security-quality-violations-by-type.csv +374 -0
  2. package/.cursor/rules/assistant-driven-integration-build.mdc +40 -0
  3. package/.cursor/rules/deploy-rules/docker-image-ip-policy.mdc +49 -0
  4. package/.cursor/rules/plan-rules/application-lifecycle.mdc +30 -0
  5. package/.cursor/rules/plan-rules/plan-frontmatter.mdc +35 -0
  6. package/.cursor/rules/plan-rules/plan-lifecycle.mdc +31 -0
  7. package/.cursor/rules/plan-rules/plan-validation-gate.mdc +34 -0
  8. package/.cursor/skills/README.md +1 -0
  9. package/.dockerignore +52 -0
  10. package/.eslintignore +22 -0
  11. package/README.md +2 -0
  12. package/bin/builder-api-cleanup.js +26 -0
  13. package/bin/builder-api-nest.js +10 -0
  14. package/bin/builder-api-spike.js +19 -0
  15. package/enterprise-knowledge/README.md +50 -0
  16. package/enterprise-knowledge/enterprise-integration-lifecycle/README.md +22 -0
  17. package/enterprise-knowledge/enterprise-integration-lifecycle/application.json +15 -0
  18. package/enterprise-knowledge/enterprise-integration-lifecycle/deploy.js +69 -0
  19. package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-deploy.json +52 -0
  20. package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-system.json +29 -0
  21. package/enterprise-knowledge/enterprise-integration-lifecycle/env.template +2 -0
  22. package/integration/README.md +81 -0
  23. package/integration/github/README.md +53 -0
  24. package/integration/github/application.json +21 -0
  25. package/integration/github/deploy.js +72 -0
  26. package/integration/github/env.template +11 -0
  27. package/integration/github/github-datasource-issue-comments.json +239 -0
  28. package/integration/github/github-datasource-issues.json +399 -0
  29. package/integration/github/github-datasource-repository.json +354 -0
  30. package/integration/github/github-deploy.json +1202 -0
  31. package/integration/github/github-system.json +82 -0
  32. package/integration/hubspot-test/README.md +1 -1
  33. package/integration/hubspot-test/create-hubspot.js +1 -16
  34. package/jest.isolated-projects.js +31 -1
  35. package/jest.projects.js +87 -1
  36. package/lib/api/dev-server-https.js +1 -1
  37. package/lib/api/enterprise-knowledge.api.js +63 -0
  38. package/lib/api/evidence-kinds.api.js +128 -0
  39. package/lib/api/evidence.api.js +172 -0
  40. package/lib/api/external-systems.api.js +8 -2
  41. package/lib/api/pipeline.api.js +5 -1
  42. package/lib/api/resource-types.api.js +5 -4
  43. package/lib/api/roles.api.js +121 -0
  44. package/lib/api/types/enterprise-knowledge.types.js +46 -0
  45. package/lib/api/types/evidence-kinds.types.js +42 -0
  46. package/lib/api/types/evidence.types.js +67 -0
  47. package/lib/api/types/resource-types.types.js +2 -0
  48. package/lib/api/types/roles.types.js +36 -0
  49. package/lib/app/certification-verify-rows.js +1 -1
  50. package/lib/app/controller-application-filter.js +36 -0
  51. package/lib/app/deploy.js +1 -1
  52. package/lib/app/list-external-systems.js +130 -0
  53. package/lib/app/list.js +20 -8
  54. package/lib/app/run.js +3 -1
  55. package/lib/app/show-display.js +8 -3
  56. package/lib/app/show-online.js +178 -0
  57. package/lib/app/show.js +39 -90
  58. package/lib/build/builder-api-docker-staging.js +47 -0
  59. package/lib/build/miso-controller-npm-sdk-guard.js +2 -2
  60. package/lib/build/standard-docker-build.js +2 -0
  61. package/lib/certification/merge-certification-from-artifact.js +1 -1
  62. package/lib/certification/post-unified-cert-sync.js +4 -31
  63. package/lib/certification/sync-after-external-command.js +0 -1
  64. package/lib/certification/sync-system-certification.js +0 -3
  65. package/lib/channels/add-channel.js +40 -34
  66. package/lib/channels/approval-guides/chatgpt.js +33 -0
  67. package/lib/channels/approval-guides/credential-portal.js +38 -0
  68. package/lib/channels/approval-guides/index.js +110 -0
  69. package/lib/channels/approval-guides/microsoft-copilot.js +34 -0
  70. package/lib/channels/approval-guides/slack.js +34 -0
  71. package/lib/channels/approval-guides/teams-bot.js +35 -0
  72. package/lib/channels/approval-guides/web-embed.js +32 -0
  73. package/lib/channels/channel-approval-guide.js +11 -0
  74. package/lib/channels/channel-artifact-generator.js +18 -5
  75. package/lib/channels/channel-audit.js +3 -0
  76. package/lib/channels/channel-auth-context.js +1 -1
  77. package/lib/channels/channel-description.js +59 -0
  78. package/lib/channels/channel-integration-generator.js +13 -230
  79. package/lib/channels/channel-integration-template.js +94 -0
  80. package/lib/channels/channel-runtime-resolver.js +43 -3
  81. package/lib/channels/channel-status-display.js +66 -26
  82. package/lib/channels/channel-targets.js +3 -3
  83. package/lib/cli/index.js +31 -3
  84. package/lib/cli/infra-guided.js +5 -1
  85. package/lib/cli/setup-app-external-create.js +111 -0
  86. package/lib/cli/setup-app.help.js +1 -1
  87. package/lib/cli/setup-app.js +60 -130
  88. package/lib/cli/setup-app.test-commands.js +26 -52
  89. package/lib/cli/setup-certification-commands.js +4 -4
  90. package/lib/cli/setup-certification.help.js +9 -9
  91. package/lib/cli/setup-dev.js +30 -9
  92. package/lib/cli/setup-external-system-help.js +4 -6
  93. package/lib/cli/setup-external-system.js +58 -52
  94. package/lib/cli/setup-infra-up-builder-api-action.js +64 -0
  95. package/lib/cli/setup-infra-up-platform-action.js +3 -1
  96. package/lib/cli/setup-infra.js +15 -0
  97. package/lib/cli/setup-list.js +43 -0
  98. package/lib/cli/setup-utility-help-after.js +12 -0
  99. package/lib/cli/setup-utility-repair.js +26 -7
  100. package/lib/cli/setup-utility-validate.js +41 -2
  101. package/lib/cli/setup-utility.js +5 -3
  102. package/lib/commands/app.js +15 -43
  103. package/lib/commands/channel-add-setup.js +110 -0
  104. package/lib/commands/channel.js +42 -8
  105. package/lib/commands/datasource-sync-display.js +96 -0
  106. package/lib/commands/datasource-sync-policy.js +210 -0
  107. package/lib/commands/datasource-test-trust-cli.js +6 -6
  108. package/lib/commands/datasource-unified-test-cli.js +2 -1
  109. package/lib/commands/datasource-unified-test-cli.options.js +33 -23
  110. package/lib/commands/deploy-gate-failure-details.js +184 -0
  111. package/lib/commands/deploy-gate-orchestrator.js +368 -0
  112. package/lib/commands/dev-cli-handlers.js +7 -62
  113. package/lib/commands/dev-host-ops-params.js +91 -0
  114. package/lib/commands/dev-host-ops-poll.js +111 -0
  115. package/lib/commands/dev-host-ops.js +107 -94
  116. package/lib/commands/dev-init.js +6 -106
  117. package/lib/commands/dev-refresh.js +197 -0
  118. package/lib/commands/enterprise-knowledge.js +284 -0
  119. package/lib/commands/evidence-cli-leaves.js +250 -0
  120. package/lib/commands/evidence-kind.js +428 -0
  121. package/lib/commands/evidence.js +51 -0
  122. package/lib/commands/governance-cli-shared.js +2 -2
  123. package/lib/commands/governance-command-action.js +5 -3
  124. package/lib/commands/governance-fixture-subjects.js +85 -0
  125. package/lib/commands/governance.js +1 -1
  126. package/lib/commands/lifecycle-command-action.js +2 -2
  127. package/lib/commands/lifecycle-external.js +3 -3
  128. package/lib/commands/manifest-cli-auth.js +29 -0
  129. package/lib/commands/manifest-cli-commands.js +170 -0
  130. package/lib/commands/manifest-cli-integration-path.js +63 -0
  131. package/lib/commands/manifest.js +21 -0
  132. package/lib/commands/protection-cli-leaves.js +3 -3
  133. package/lib/commands/repair-auth-apply.js +15 -1
  134. package/lib/commands/repair-authentications-454.js +169 -0
  135. package/lib/commands/repair-capability-openapi-warnings.js +126 -0
  136. package/lib/commands/repair-datasource-apply.js +135 -0
  137. package/lib/commands/repair-datasource-auto-rbac.js +62 -1
  138. package/lib/commands/repair-datasource-http-service-contract.js +239 -0
  139. package/lib/commands/repair-datasource-operation-security.js +180 -0
  140. package/lib/commands/repair-datasource-run.js +7 -2
  141. package/lib/commands/repair-datasource-sync-operations.js +177 -0
  142. package/lib/commands/repair-datasource-webhooks-sync-bridge.js +133 -0
  143. package/lib/commands/repair-datasource.js +12 -68
  144. package/lib/commands/repair-env-template.js +11 -1
  145. package/lib/commands/repair-external-run.js +121 -31
  146. package/lib/commands/repair-internal.js +1 -1
  147. package/lib/commands/repair-openapi-export.js +156 -0
  148. package/lib/commands/repair-openapi-sync.js +33 -8
  149. package/lib/commands/repair-orchestration-datasource-split.js +259 -0
  150. package/lib/commands/repair-persist.js +22 -1
  151. package/lib/commands/repair-rbac-platform-preset.js +204 -0
  152. package/lib/commands/repair-rbac-reader-roles.js +191 -0
  153. package/lib/commands/repair-rbac.js +163 -86
  154. package/lib/commands/repair-steps.js +83 -18
  155. package/lib/commands/repair-system-permissions.js +1 -0
  156. package/lib/commands/repair.js +1 -1
  157. package/lib/commands/resource-type.js +166 -44
  158. package/lib/commands/role.js +452 -0
  159. package/lib/commands/run-post-publish-data-sync.js +68 -0
  160. package/lib/commands/setup-modes.js +1 -1
  161. package/lib/commands/setup.js +1 -1
  162. package/lib/commands/test-e2e-external.js +21 -8
  163. package/lib/commands/test-governance-cli-options.js +2 -2
  164. package/lib/commands/test-trust-cli-options.js +2 -2
  165. package/lib/commands/up-builder-api-bootstrap.js +71 -0
  166. package/lib/commands/up-builder-api-provision.js +241 -0
  167. package/lib/commands/up-builder-api.js +88 -0
  168. package/lib/commands/up-common.js +25 -1
  169. package/lib/commands/upload-credential-push-log.js +117 -0
  170. package/lib/commands/upload-data-sync-finalize.js +60 -0
  171. package/lib/commands/upload-probe.js +66 -0
  172. package/lib/commands/upload-publish-context.js +4 -1
  173. package/lib/commands/upload-sidecar-followups.js +55 -27
  174. package/lib/commands/upload.js +116 -157
  175. package/lib/commands/validate-json.js +230 -0
  176. package/lib/commands/verify-governance-combined-external.js +1 -1
  177. package/lib/commands/verify-governance-db.js +2 -2
  178. package/lib/commands/verify-operations-command-action.js +2 -2
  179. package/lib/commands/verify-operations-step-plan.js +79 -41
  180. package/lib/commands/verify-operations-steps.js +2 -2
  181. package/lib/commands/verify-trust-command-action.js +1 -1
  182. package/lib/commands/wizard-core.js +1 -1
  183. package/lib/commands/wizard-headless.js +2 -1
  184. package/lib/core/admin-secrets.js +2 -6
  185. package/lib/core/audit-logger.js +1 -1
  186. package/lib/core/secrets-env-content.js +10 -4
  187. package/lib/core/secrets-env-write.js +2 -13
  188. package/lib/core/secrets-load.js +1 -3
  189. package/lib/datasource/agent-trust-run.js +3 -3
  190. package/lib/datasource/capability/relate-operations.js +1 -1
  191. package/lib/datasource/deploy.js +3 -1
  192. package/lib/datasource/test-e2e.js +6 -1
  193. package/lib/datasource/unified-validation-run-body.js +4 -1
  194. package/lib/datasource/unified-validation-run.js +1 -1
  195. package/lib/deployment/deploy-poll-ui.js +73 -12
  196. package/lib/deployment/deployer-poll-run.js +113 -0
  197. package/lib/deployment/deployer.js +17 -87
  198. package/lib/evidence/dataplane-context.js +21 -0
  199. package/lib/evidence/evidence-display.js +78 -0
  200. package/lib/evidence/evidence-service.js +392 -0
  201. package/lib/external-system/deploy.js +290 -112
  202. package/lib/external-system/download.js +7 -3
  203. package/lib/external-system/test-execution.js +1 -1
  204. package/lib/external-system/test-system-level.js +8 -10
  205. package/lib/external-system/test.js +12 -6
  206. package/lib/generator/deploy-script.js +73 -0
  207. package/lib/generator/external.js +2 -1
  208. package/lib/generator/helpers.js +13 -5
  209. package/lib/generator/index.js +17 -2
  210. package/lib/generator/split-variables.js +9 -3
  211. package/lib/generator/wizard.js +3 -36
  212. package/lib/infrastructure/helpers-docker-check.js +6 -0
  213. package/lib/infrastructure/helpers.js +1 -1
  214. package/lib/internal/fs-real-sync.js +22 -1
  215. package/lib/internal/node-fs.js +2 -0
  216. package/lib/lifecycle/lifecycle-governance-options.js +1 -1
  217. package/lib/lifecycle/verify-step-progress.js +1 -1
  218. package/lib/programmatic/access-log.js +26 -0
  219. package/lib/programmatic/auth-config.js +45 -0
  220. package/lib/programmatic/bearer-auth.js +176 -0
  221. package/lib/programmatic/builder-api-request.js +175 -0
  222. package/lib/programmatic/builder-api-route-dispatch.js +82 -0
  223. package/lib/programmatic/builder-api-runtime-config.js +42 -0
  224. package/lib/programmatic/builder-api-server.js +230 -0
  225. package/lib/programmatic/builder-help-authentication-catalog.js +282 -0
  226. package/lib/programmatic/builder-help-connected-system-ui.js +266 -0
  227. package/lib/programmatic/builder-help-enterprise-sync-fabrix.js +60 -0
  228. package/lib/programmatic/builder-help-envelope.js +36 -0
  229. package/lib/programmatic/builder-help-fixtures.js +200 -0
  230. package/lib/programmatic/builder-help-governance.js +172 -0
  231. package/lib/programmatic/builder-help-schema-catalog.js +92 -0
  232. package/lib/programmatic/builder-help.js +361 -0
  233. package/lib/programmatic/capability-registry.js +77 -0
  234. package/lib/programmatic/command-options.js +32 -0
  235. package/lib/programmatic/enterprise-mcp-client.js +114 -0
  236. package/lib/programmatic/http-problem-details.js +99 -0
  237. package/lib/programmatic/http-route-match.js +40 -0
  238. package/lib/programmatic/idempotency-cache.js +69 -0
  239. package/lib/programmatic/index.js +53 -0
  240. package/lib/programmatic/integration-path-scope.js +39 -0
  241. package/lib/programmatic/log-redaction.js +66 -0
  242. package/lib/programmatic/manifest-get-section.js +146 -0
  243. package/lib/programmatic/manifest-patch-section.js +252 -0
  244. package/lib/programmatic/manifest-repair.js +122 -0
  245. package/lib/programmatic/manifest-section-dependency-graph.js +160 -0
  246. package/lib/programmatic/manifest-section-io.js +225 -0
  247. package/lib/programmatic/manifest-section-quality.js +171 -0
  248. package/lib/programmatic/manifest-section-registry-data.js +269 -0
  249. package/lib/programmatic/manifest-section-registry.js +222 -0
  250. package/lib/programmatic/nest-http-bridge.js +34 -0
  251. package/lib/programmatic/openapi-component-schemas.js +68 -0
  252. package/lib/programmatic/openapi-description-enricher.js +117 -0
  253. package/lib/programmatic/openapi-descriptions.js +190 -0
  254. package/lib/programmatic/openapi-docs-serving.js +123 -0
  255. package/lib/programmatic/openapi-help-schemas.js +63 -0
  256. package/lib/programmatic/openapi-manifest-schemas.js +141 -0
  257. package/lib/programmatic/openapi-operation-bindings.js +274 -0
  258. package/lib/programmatic/openapi-request-schemas.js +155 -0
  259. package/lib/programmatic/openapi-result-schemas.js +493 -0
  260. package/lib/programmatic/openapi-schema-descriptions-certify.js +139 -0
  261. package/lib/programmatic/openapi-schema-descriptions-core.js +162 -0
  262. package/lib/programmatic/openapi-schema-descriptions-help.js +40 -0
  263. package/lib/programmatic/openapi-schema-descriptions-manifest.js +143 -0
  264. package/lib/programmatic/openapi-schema-descriptions-mcp.js +118 -0
  265. package/lib/programmatic/openapi-schema-descriptions-operations.js +281 -0
  266. package/lib/programmatic/openapi-schema-helpers.js +108 -0
  267. package/lib/programmatic/openapi-spec.js +203 -0
  268. package/lib/programmatic/orchestration-openapi-meta.js +159 -0
  269. package/lib/programmatic/platform-rbac-catalog.js +90 -0
  270. package/lib/programmatic/request-timeout.js +53 -0
  271. package/lib/programmatic/route-handler-map.js +143 -0
  272. package/lib/programmatic/route-handlers-context.js +29 -0
  273. package/lib/programmatic/route-handlers.js +33 -0
  274. package/lib/programmatic/run-certify.js +57 -0
  275. package/lib/programmatic/run-enterprise-mcp.js +32 -0
  276. package/lib/programmatic/run-lifecycle.js +29 -0
  277. package/lib/programmatic/run-repair.js +41 -0
  278. package/lib/programmatic/run-repository-emcp.js +62 -0
  279. package/lib/programmatic/run-template-workspace.js +74 -0
  280. package/lib/programmatic/run-test.js +49 -0
  281. package/lib/programmatic/run-upload.js +63 -0
  282. package/lib/programmatic/run-validate.js +53 -0
  283. package/lib/programmatic/run-wizard.js +40 -0
  284. package/lib/programmatic/system-key.js +48 -0
  285. package/lib/programmatic/wizard-config-normalize.js +118 -0
  286. package/lib/programmatic/workspace-cleanup.js +128 -0
  287. package/lib/programmatic/workspace-context.js +145 -0
  288. package/lib/programmatic/workspace-lock.js +75 -0
  289. package/lib/programmatic/workspace-meta.js +64 -0
  290. package/lib/programmatic/workspace-ops.js +149 -0
  291. package/lib/protection/run-commands-upload-sync.js +35 -0
  292. package/lib/protection/run-commands.js +2 -20
  293. package/lib/protection/upload-batch.js +11 -7
  294. package/lib/resolvers/evidence-kind-file.js +230 -0
  295. package/lib/resolvers/resource-type-file.js +58 -1
  296. package/lib/resolvers/role-file.js +227 -0
  297. package/lib/schema/application-schema.json +22 -2
  298. package/lib/schema/external-datasource.schema.json +245 -2
  299. package/lib/schema/external-system.schema.json +259 -119
  300. package/lib/schema/flag-map-validation-run.json +3 -0
  301. package/lib/schema/infra.parameter.yaml +25 -1
  302. package/lib/schema/type/credential-field-registry.json +21 -5
  303. package/lib/schema/type/document-storage.json +9 -0
  304. package/lib/utils/agent-trust-run-display.js +1 -1
  305. package/lib/utils/api.js +8 -2
  306. package/lib/utils/app-path-resolve.js +168 -0
  307. package/lib/utils/app-register-config.js +4 -3
  308. package/lib/utils/authentication-env-template.js +222 -0
  309. package/lib/utils/cli-sync-options.js +62 -10
  310. package/lib/utils/cli-utils.js +15 -3
  311. package/lib/utils/cli-workspace-options.js +29 -0
  312. package/lib/utils/compose-generate-docker-compose.js +102 -0
  313. package/lib/utils/configuration-env-resolver.js +203 -27
  314. package/lib/utils/datasource-test-run-certificate-tty.js +28 -2
  315. package/lib/utils/datasource-test-run-certification-debug.js +130 -0
  316. package/lib/utils/datasource-test-run-debug-display.js +2 -0
  317. package/lib/utils/datasource-test-run-debug-slice.js +7 -0
  318. package/lib/utils/datasource-test-run-display.js +2 -1
  319. package/lib/utils/dev-ca-install.js +5 -6
  320. package/lib/utils/dev-config.js +2 -2
  321. package/lib/utils/dev-init-ssh-merge.js +165 -23
  322. package/lib/utils/dev-list-sort.js +145 -0
  323. package/lib/utils/dev-pin-share-instructions.js +110 -0
  324. package/lib/utils/dev-platform-tls.js +0 -63
  325. package/lib/utils/dev-ssh-config-helper.js +177 -33
  326. package/lib/utils/docker-build.js +46 -27
  327. package/lib/utils/docker-daemon-tls-ca.js +1 -1
  328. package/lib/utils/docker-exec.js +91 -6
  329. package/lib/utils/enterprise-knowledge-paths.js +142 -0
  330. package/lib/utils/env-copy.js +3 -4
  331. package/lib/utils/env-dotenv-format.js +103 -0
  332. package/lib/utils/error-formatters/error-parser.js +0 -3
  333. package/lib/utils/external-env-template.js +5 -2
  334. package/lib/utils/external-system-display.js +5 -1
  335. package/lib/utils/external-system-readiness-compact-blocks.js +248 -0
  336. package/lib/utils/external-system-readiness-compact-display.js +324 -0
  337. package/lib/utils/external-system-readiness-core.js +16 -0
  338. package/lib/utils/external-system-readiness-deploy-display.js +29 -11
  339. package/lib/utils/external-system-readiness-display-internals.js +3 -1
  340. package/lib/utils/external-system-readiness-display.js +20 -30
  341. package/lib/utils/external-system-system-test-tty-certification.js +135 -0
  342. package/lib/utils/external-system-system-test-tty.js +5 -41
  343. package/lib/utils/health-check-request.js +2 -3
  344. package/lib/utils/help-builder.js +9 -1
  345. package/lib/utils/host-ops-job-labels.js +236 -0
  346. package/lib/utils/host-ops-job-result.js +61 -0
  347. package/lib/utils/host-ops-poll-ui.js +163 -0
  348. package/lib/utils/image-name.js +22 -4
  349. package/lib/utils/integration-path-resolve.js +112 -0
  350. package/lib/utils/logger.js +37 -4
  351. package/lib/utils/manifest-source-emit.js +1 -1
  352. package/lib/utils/paths-reload-source.js +148 -0
  353. package/lib/utils/paths-system-builder-keys.js +25 -0
  354. package/lib/utils/paths.js +183 -30
  355. package/lib/utils/pipeline-upload-auth-retry.js +4 -0
  356. package/lib/utils/postgres-platform-bootstrap.js +24 -17
  357. package/lib/utils/postgres-wipe.js +5 -2
  358. package/lib/utils/remote-dev-auth.js +39 -4
  359. package/lib/utils/resolve-docker-image-ref.js +36 -6
  360. package/lib/utils/runtime-configuration-values.js +64 -2
  361. package/lib/utils/secrets-helpers.js +5 -1
  362. package/lib/utils/ssh-known-hosts.js +130 -0
  363. package/lib/utils/test-target-cli-options.js +75 -0
  364. package/lib/utils/token-manager.js +16 -0
  365. package/lib/utils/upload-sync-options.js +20 -2
  366. package/lib/utils/validation-run-request.js +11 -2
  367. package/lib/validation/external-manifest-validator.js +11 -1
  368. package/lib/validation/openapi-contract-surface-validator.js +430 -0
  369. package/lib/validation/openapi-contract-vendor-validation.js +238 -0
  370. package/lib/validation/validate-external-file.js +160 -0
  371. package/lib/validation/validate.js +6 -117
  372. package/lib/validation/validator.js +6 -5
  373. package/package.json +76 -37
  374. package/packages/builder-api/README.md +120 -0
  375. package/packages/builder-api/package.json +30 -0
  376. package/packages/builder-api/src/app.module.ts +7 -0
  377. package/packages/builder-api/src/auth/auth.module.ts +5 -0
  378. package/packages/builder-api/src/external-system/external-system.module.ts +5 -0
  379. package/packages/builder-api/src/main.ts +16 -0
  380. package/packages/builder-api/tsconfig.json +15 -0
  381. package/scripts/check-builder-api-architecture-grep.js +79 -0
  382. package/scripts/docker_image_content_gate.js +47 -0
  383. package/scripts/docker_image_content_gate.sh +5 -0
  384. package/scripts/export-builder-api-evidence.js +262 -0
  385. package/scripts/lib/builder-api-docker-staging-copy.js +60 -0
  386. package/scripts/lib/builder-api-docker-staging-core.js +183 -0
  387. package/scripts/lib/docker-image-content-gate-core.js +166 -0
  388. package/scripts/lib/plan-actor.js +109 -0
  389. package/scripts/lib/plan-config.js +20 -0
  390. package/scripts/lib/plan-gates.js +154 -0
  391. package/scripts/lib/plan-meta.js +104 -0
  392. package/scripts/lib/plan-parse.js +162 -0
  393. package/scripts/lib/plan-prevalidate-gates.js +337 -0
  394. package/scripts/lib/plan-run-core.js +125 -0
  395. package/scripts/lib/plan-run-report.js +119 -0
  396. package/scripts/plan-approve.js +24 -0
  397. package/scripts/plan-archive.js +49 -0
  398. package/scripts/plan-run.js +13 -0
  399. package/scripts/plan-set-actor.js +21 -0
  400. package/scripts/plan-validate.js +80 -0
  401. package/scripts/pnpm/af.mjs +110 -0
  402. package/scripts/pnpm/check-quiet.mjs +32 -0
  403. package/scripts/pnpm/dev-install.mjs +29 -0
  404. package/scripts/pnpm/dev-reload.mjs +18 -0
  405. package/scripts/pnpm/help.mjs +55 -0
  406. package/scripts/pnpm/lib/dev-reload-core.mjs +189 -0
  407. package/scripts/pnpm/lib/dev-reload-log-capture.mjs +67 -0
  408. package/scripts/pnpm/lib/dev-reload-log-utils.mjs +32 -0
  409. package/scripts/pnpm/lib/resolve-aifabrix-bin.mjs +124 -0
  410. package/scripts/pnpm/lib/resolve-app-url.mjs +183 -0
  411. package/scripts/pnpm/lib/spinner.mjs +42 -0
  412. package/scripts/stage_builder_api_for_docker.js +65 -0
  413. package/scripts/sync-builder-api-template.js +44 -0
  414. package/templates/README.md +3 -0
  415. package/templates/applications/builder-api/Dockerfile +38 -0
  416. package/templates/applications/builder-api/application.yaml +75 -0
  417. package/templates/applications/builder-api/env.template +48 -0
  418. package/templates/applications/dataplane/application.yaml +27 -5
  419. package/templates/applications/dataplane/env.template +38 -15
  420. package/templates/applications/dataplane/rbac.yaml +85 -3
  421. package/templates/applications/miso-controller/application.yaml +10 -1
  422. package/templates/applications/miso-controller/env.template +11 -10
  423. package/templates/applications/miso-controller/rbac.yaml +72 -0
  424. package/templates/channels/README.md +18 -0
  425. package/templates/channels/ai-fabrix-icon.jpg +0 -0
  426. package/templates/channels/chatgpt/install.template.md.hbs +21 -24
  427. package/templates/channels/chatgpt/integration/README.md +11 -0
  428. package/templates/channels/chatgpt/integration/application.json +15 -0
  429. package/templates/channels/chatgpt/integration/chatgpt-system.json +29 -0
  430. package/templates/channels/chatgpt/integration/env.template +4 -0
  431. package/templates/channels/microsoft-copilot/install.template.md.hbs +20 -25
  432. package/templates/channels/microsoft-copilot/integration/README.md +11 -0
  433. package/templates/channels/microsoft-copilot/integration/application.json +15 -0
  434. package/templates/channels/microsoft-copilot/integration/env.template +6 -0
  435. package/templates/channels/microsoft-copilot/integration/microsoft-copilot-system.json +34 -0
  436. package/templates/channels/slack/install.template.md.hbs +48 -18
  437. package/templates/channels/slack/integration/README.md +38 -0
  438. package/templates/channels/slack/integration/application.json +18 -0
  439. package/templates/channels/slack/integration/env.template +29 -0
  440. package/templates/channels/slack/integration/slack-datasource-conversations.json +226 -0
  441. package/templates/channels/slack/integration/slack-datasource-messages.json +269 -0
  442. package/templates/channels/slack/integration/slack-system.json +144 -0
  443. package/templates/channels/slack/manifest.template.json.hbs +20 -10
  444. package/templates/channels/teams-bot/install.template.md.hbs +31 -17
  445. package/templates/channels/teams-bot/integration/README.md +18 -0
  446. package/templates/channels/teams-bot/integration/application.json +17 -0
  447. package/templates/channels/teams-bot/integration/env.template +5 -0
  448. package/templates/channels/teams-bot/integration/teams-bot-system.json +55 -0
  449. package/templates/channels/teams-bot/manifest.template.json.hbs +27 -0
  450. package/templates/channels/web-embed/install.template.md.hbs +16 -26
  451. package/templates/channels/web-embed/integration/README.md +11 -0
  452. package/templates/channels/web-embed/integration/application.json +15 -0
  453. package/templates/channels/web-embed/integration/env.template +4 -0
  454. package/templates/channels/web-embed/integration/web-embed-system.json +29 -0
  455. package/templates/openapi/redoc_page.html +86 -0
  456. package/templates/python/docker-compose.hbs +11 -0
  457. package/templates/python/requirements.txt +2 -2
  458. package/templates/typescript/docker-compose.hbs +11 -0
  459. package/lib/certification/cli-cert-sync-skip.js +0 -21
@@ -0,0 +1,230 @@
1
+ /**
2
+ * Evidence kind catalog file helpers for create/import/export.
3
+ *
4
+ * File JSON uses `domain`; Controller API uses `domainKey`.
5
+ *
6
+ * @fileoverview Evidence kind catalog file parsing and API mapping
7
+ * @author AI Fabrix Team
8
+ * @version 1.0.0
9
+ */
10
+
11
+ 'use strict';
12
+
13
+ const path = require('path');
14
+ const { existsSync, readFileSync, writeFileSync } = require('../internal/fs-real-sync');
15
+
16
+ const DOMAIN_KEY_PATTERN = /^[a-z][a-z0-9-]*$/;
17
+ const SEVERITIES = new Set(['low', 'medium', 'high', 'critical']);
18
+
19
+ /**
20
+ * @param {string} filePath
21
+ * @returns {object|Array}
22
+ */
23
+ function loadEvidenceKindJson(filePath) {
24
+ const p = path.resolve(String(filePath || '').trim());
25
+ if (!p) {
26
+ throw new Error('--file is required');
27
+ }
28
+ if (!existsSync(p)) {
29
+ throw new Error(`File not found: ${p}`);
30
+ }
31
+ let parsed;
32
+ try {
33
+ parsed = JSON.parse(readFileSync(p, 'utf8'));
34
+ } catch (e) {
35
+ throw new Error(`Invalid JSON in ${p}: ${e.message}`);
36
+ }
37
+ if (parsed === null || typeof parsed !== 'object') {
38
+ throw new Error(`Evidence kind file must be a JSON object or array: ${p}`);
39
+ }
40
+ return parsed;
41
+ }
42
+
43
+ /**
44
+ * @param {object} entry
45
+ * @param {number} index
46
+ * @returns {string}
47
+ */
48
+ function requireDomainValue(entry, index) {
49
+ const raw = entry.domain !== undefined ? entry.domain : entry.domainKey;
50
+ const value = typeof raw === 'string' ? raw.trim().toLowerCase() : '';
51
+ if (!value) {
52
+ throw new Error(`evidenceKinds[${index}].domain is required`);
53
+ }
54
+ if (!DOMAIN_KEY_PATTERN.test(value)) {
55
+ throw new Error(
56
+ 'domain must start with a lowercase letter and contain only lowercase letters, numbers, and hyphens'
57
+ );
58
+ }
59
+ return value;
60
+ }
61
+
62
+ /**
63
+ * Map baseline/file evidence kind row to Controller create payload (domain → domainKey).
64
+ * @param {object} row
65
+ * @param {number} [index]
66
+ * @returns {Object}
67
+ */
68
+ function mapEvidenceKindFileToApiPayload(row, index = 0) {
69
+ if (!row || typeof row !== 'object') {
70
+ throw new Error(`evidenceKinds[${index}] must be a JSON object`);
71
+ }
72
+ const key = String(row.key || '').trim();
73
+ if (!key) {
74
+ throw new Error(`evidenceKinds[${index}].key is required`);
75
+ }
76
+ const displayName = String(row.displayName || '').trim();
77
+ if (!displayName) {
78
+ throw new Error(`evidenceKinds[${index}].displayName is required`);
79
+ }
80
+ const purpose = String(row.purpose || '').trim();
81
+ if (!purpose) {
82
+ throw new Error(`evidenceKinds[${index}].purpose is required`);
83
+ }
84
+ const domainKey = requireDomainValue(row, index);
85
+ const payload = { key, displayName, purpose, domainKey };
86
+ copyOptionalFields(payload, row, [
87
+ 'description',
88
+ 'expectedUse',
89
+ 'requiresApproval',
90
+ 'isActive',
91
+ 'sortOrder',
92
+ 'source'
93
+ ]);
94
+ assignOptionalSeverity(payload, row, index);
95
+ if (row.metadata && typeof row.metadata === 'object') {
96
+ payload.metadata = row.metadata;
97
+ }
98
+ return payload;
99
+ }
100
+
101
+ /**
102
+ * @param {Object} payload
103
+ * @param {object} row
104
+ * @param {number} index
105
+ * @returns {void}
106
+ */
107
+ function assignOptionalSeverity(payload, row, index) {
108
+ if (row.defaultSeverity === undefined) {
109
+ return;
110
+ }
111
+ const severity = String(row.defaultSeverity).trim();
112
+ if (!SEVERITIES.has(severity)) {
113
+ throw new Error(
114
+ `evidenceKinds[${index}].defaultSeverity must be one of: ${[...SEVERITIES].join(', ')}`
115
+ );
116
+ }
117
+ payload.defaultSeverity = severity;
118
+ }
119
+
120
+ /**
121
+ * @param {Object} target
122
+ * @param {object} source
123
+ * @param {string[]} fields
124
+ * @returns {void}
125
+ */
126
+ function copyOptionalFields(target, source, fields) {
127
+ for (const field of fields) {
128
+ if (source[field] !== undefined) {
129
+ target[field] = source[field];
130
+ }
131
+ }
132
+ }
133
+
134
+ /**
135
+ * Map Controller evidence kind record to baseline-shaped JSON (domainKey → domain).
136
+ * @param {object} record
137
+ * @returns {Object}
138
+ */
139
+ function mapEvidenceKindApiToFileRow(record) {
140
+ const row = {
141
+ key: record.key,
142
+ displayName: record.displayName,
143
+ domain: record.domainKey || record.domain,
144
+ purpose: record.purpose
145
+ };
146
+ if (record.description) row.description = record.description;
147
+ if (record.expectedUse) row.expectedUse = record.expectedUse;
148
+ if (record.defaultSeverity) row.defaultSeverity = record.defaultSeverity;
149
+ if (record.requiresApproval !== undefined) row.requiresApproval = record.requiresApproval;
150
+ if (record.sortOrder !== undefined) row.sortOrder = record.sortOrder;
151
+ if (record.metadata && typeof record.metadata === 'object') {
152
+ row.metadata = record.metadata;
153
+ }
154
+ return row;
155
+ }
156
+
157
+ /**
158
+ * @param {object} parsed
159
+ * @returns {void}
160
+ */
161
+ function rejectBaselineCatalogShape(parsed) {
162
+ if (
163
+ parsed &&
164
+ typeof parsed === 'object' &&
165
+ Array.isArray(parsed.evidenceKinds) &&
166
+ !parsed.key
167
+ ) {
168
+ throw new Error(
169
+ 'File is a baseline catalog (evidenceKinds[]). ' +
170
+ 'Use `aifabrix evidence-kind import --file <path>` to seed all entries, ' +
171
+ 'or pass a single evidence kind object with key and displayName.'
172
+ );
173
+ }
174
+ }
175
+
176
+ /**
177
+ * @param {string} filePath
178
+ * @returns {Object}
179
+ */
180
+ function readEvidenceKindCreateFile(filePath) {
181
+ const parsed = loadEvidenceKindJson(filePath);
182
+ rejectBaselineCatalogShape(parsed);
183
+ return mapEvidenceKindFileToApiPayload(parsed, 0);
184
+ }
185
+
186
+ /**
187
+ * @param {string} filePath
188
+ * @returns {Object[]}
189
+ */
190
+ function readEvidenceKindCatalogFile(filePath) {
191
+ const parsed = loadEvidenceKindJson(filePath);
192
+ let rows;
193
+ if (Array.isArray(parsed)) {
194
+ rows = parsed;
195
+ } else if (Array.isArray(parsed.evidenceKinds)) {
196
+ rows = parsed.evidenceKinds;
197
+ } else {
198
+ throw new Error(
199
+ 'Import file must be a baseline catalog with evidenceKinds[] or a JSON array of evidence kinds.'
200
+ );
201
+ }
202
+ if (rows.length === 0) {
203
+ throw new Error('Import file contains no evidence kinds');
204
+ }
205
+ return rows.map((row, index) => mapEvidenceKindFileToApiPayload(row, index));
206
+ }
207
+
208
+ /**
209
+ * @param {string} filePath
210
+ * @param {Object[]} rows
211
+ * @param {string} [version]
212
+ * @returns {void}
213
+ */
214
+ function writeEvidenceKindCatalogFile(filePath, rows, version = '1.0.0') {
215
+ const p = path.resolve(String(filePath || '').trim());
216
+ if (!p) {
217
+ throw new Error('--file is required');
218
+ }
219
+ const catalog = { version, evidenceKinds: rows };
220
+ writeFileSync(p, `${JSON.stringify(catalog, null, 2)}\n`, 'utf8');
221
+ }
222
+
223
+ module.exports = {
224
+ mapEvidenceKindFileToApiPayload,
225
+ mapEvidenceKindApiToFileRow,
226
+ readEvidenceKindCreateFile,
227
+ readEvidenceKindCatalogFile,
228
+ writeEvidenceKindCatalogFile,
229
+ SEVERITIES
230
+ };
@@ -9,7 +9,7 @@
9
9
  'use strict';
10
10
 
11
11
  const path = require('path');
12
- const { existsSync, readFileSync } = require('../internal/fs-real-sync');
12
+ const { existsSync, readFileSync, writeFileSync } = require('../internal/fs-real-sync');
13
13
 
14
14
  /**
15
15
  * @typedef {Object} ResourceTypeCreateInput
@@ -19,6 +19,7 @@ const { existsSync, readFileSync } = require('../internal/fs-real-sync');
19
19
  * @property {string} [category]
20
20
  * @property {string} [defaultRiskLevel]
21
21
  * @property {string} [status]
22
+ * @property {string} domain
22
23
  */
23
24
 
24
25
  const CATEGORIES = new Set([
@@ -32,6 +33,7 @@ const CATEGORIES = new Set([
32
33
 
33
34
  const RISK_LEVELS = new Set(['low', 'medium', 'high', 'critical']);
34
35
  const STATUSES = new Set(['draft', 'active', 'deprecated', 'retired']);
36
+ const DOMAIN_KEY_PATTERN = /^[a-z][a-z0-9-]*$/;
35
37
 
36
38
  /**
37
39
  * @param {string} filePath
@@ -75,6 +77,25 @@ function applyOptionalEnumField(parsed, field, allowedValues, label) {
75
77
  parsed[field] = value;
76
78
  }
77
79
 
80
+ /**
81
+ * @param {object} entry
82
+ * @param {number} index
83
+ * @returns {void}
84
+ */
85
+ function applyRequiredDomainField(entry, index) {
86
+ const raw = entry.domain;
87
+ const value = typeof raw === 'string' ? raw.trim().toLowerCase() : '';
88
+ if (!value) {
89
+ throw new Error(`resourceTypes[${index}].domain is required`);
90
+ }
91
+ if (!DOMAIN_KEY_PATTERN.test(value)) {
92
+ throw new Error(
93
+ 'domain must start with a lowercase letter and contain only lowercase letters, numbers, and hyphens'
94
+ );
95
+ }
96
+ entry.domain = value;
97
+ }
98
+
78
99
  /**
79
100
  * @param {object} parsed
80
101
  * @returns {void}
@@ -102,6 +123,7 @@ function normalizeResourceTypeCreateRow(row, index) {
102
123
  applyOptionalEnumField(entry, 'category', CATEGORIES, 'category');
103
124
  applyOptionalEnumField(entry, 'defaultRiskLevel', RISK_LEVELS, 'defaultRiskLevel');
104
125
  applyOptionalEnumField(entry, 'status', STATUSES, 'status');
126
+ applyRequiredDomainField(entry, index);
105
127
  const key = String(entry.key || '').trim();
106
128
  if (!key) {
107
129
  throw new Error(`resourceTypes[${index}].key is required`);
@@ -150,9 +172,44 @@ function readResourceTypeCatalogFile(filePath) {
150
172
  return rows.map((row, index) => normalizeResourceTypeCreateRow(row, index));
151
173
  }
152
174
 
175
+ /**
176
+ * Map Controller resource type record to baseline-shaped JSON.
177
+ * @param {object} record
178
+ * @returns {Object}
179
+ */
180
+ function mapResourceTypeApiToFileRow(record) {
181
+ const row = {
182
+ key: record.key,
183
+ displayName: record.displayName,
184
+ domain: record.domain
185
+ };
186
+ if (record.description) row.description = record.description;
187
+ if (record.category) row.category = record.category;
188
+ if (record.defaultRiskLevel) row.defaultRiskLevel = record.defaultRiskLevel;
189
+ if (record.status) row.status = record.status;
190
+ return row;
191
+ }
192
+
193
+ /**
194
+ * @param {string} filePath
195
+ * @param {Object[]} rows - baseline-shaped resource type rows
196
+ * @param {string} [version]
197
+ * @returns {void}
198
+ */
199
+ function writeResourceTypeCatalogFile(filePath, rows, version = '1.0.0') {
200
+ const p = path.resolve(String(filePath || '').trim());
201
+ if (!p) {
202
+ throw new Error('--file is required');
203
+ }
204
+ const catalog = { version, resourceTypes: rows };
205
+ writeFileSync(p, `${JSON.stringify(catalog, null, 2)}\n`, 'utf8');
206
+ }
207
+
153
208
  module.exports = {
154
209
  readResourceTypeCreateFile,
155
210
  readResourceTypeCatalogFile,
211
+ mapResourceTypeApiToFileRow,
212
+ writeResourceTypeCatalogFile,
156
213
  CATEGORIES,
157
214
  RISK_LEVELS,
158
215
  STATUSES
@@ -0,0 +1,227 @@
1
+ /**
2
+ * Role catalog file helpers for create/import/export.
3
+ *
4
+ * File JSON uses `domain`; Controller API uses `domainKey`.
5
+ * Compiler fields nest under `metadata` on the API payload.
6
+ *
7
+ * @fileoverview Role catalog file parsing and API mapping
8
+ * @author AI Fabrix Team
9
+ * @version 1.0.0
10
+ */
11
+
12
+ 'use strict';
13
+
14
+ const path = require('path');
15
+ const { existsSync, readFileSync, writeFileSync } = require('../internal/fs-real-sync');
16
+
17
+ /** Compiler fields that live top-level in baseline JSON and under metadata in the API. */
18
+ const ROLE_COMPILER_FIELDS = [
19
+ 'defaultResourceType',
20
+ 'primaryResourceTypes',
21
+ 'defaultCapability',
22
+ 'defaultCapabilities',
23
+ 'defaultKnowledgeProfiles',
24
+ 'defaultEvidenceKinds',
25
+ 'defaultKnowledgeKeys',
26
+ 'defaultKnowledgeGenerationProfiles'
27
+ ];
28
+
29
+ const DOMAIN_KEY_PATTERN = /^[a-z][a-z0-9-]*$/;
30
+
31
+ /**
32
+ * @param {string} filePath
33
+ * @returns {object|Array}
34
+ */
35
+ function loadRoleJson(filePath) {
36
+ const p = path.resolve(String(filePath || '').trim());
37
+ if (!p) {
38
+ throw new Error('--file is required');
39
+ }
40
+ if (!existsSync(p)) {
41
+ throw new Error(`File not found: ${p}`);
42
+ }
43
+ let parsed;
44
+ try {
45
+ parsed = JSON.parse(readFileSync(p, 'utf8'));
46
+ } catch (e) {
47
+ throw new Error(`Invalid JSON in ${p}: ${e.message}`);
48
+ }
49
+ if (parsed === null || typeof parsed !== 'object') {
50
+ throw new Error(`Role file must be a JSON object or array: ${p}`);
51
+ }
52
+ return parsed;
53
+ }
54
+
55
+ /**
56
+ * @param {object} entry
57
+ * @param {number} index
58
+ * @returns {string}
59
+ */
60
+ function requireDomainValue(entry, index) {
61
+ const raw = entry.domain !== undefined ? entry.domain : entry.domainKey;
62
+ const value = typeof raw === 'string' ? raw.trim().toLowerCase() : '';
63
+ if (!value) {
64
+ throw new Error(`roles[${index}].domain is required`);
65
+ }
66
+ if (!DOMAIN_KEY_PATTERN.test(value)) {
67
+ throw new Error(
68
+ 'domain must start with a lowercase letter and contain only lowercase letters, numbers, and hyphens'
69
+ );
70
+ }
71
+ return value;
72
+ }
73
+
74
+ /**
75
+ * Map baseline/file role row to Controller create payload (domain → domainKey; compiler → metadata).
76
+ * @param {object} row
77
+ * @param {number} [index]
78
+ * @returns {Object}
79
+ */
80
+ function mapRoleFileToApiPayload(row, index = 0) {
81
+ if (!row || typeof row !== 'object') {
82
+ throw new Error(`roles[${index}] must be a JSON object`);
83
+ }
84
+ const key = String(row.key || '').trim();
85
+ if (!key) {
86
+ throw new Error(`roles[${index}].key is required`);
87
+ }
88
+ const displayName = String(row.displayName || '').trim();
89
+ if (!displayName) {
90
+ throw new Error(`roles[${index}].displayName is required`);
91
+ }
92
+ const domainKey = requireDomainValue(row, index);
93
+ const metadata = collectRoleCompilerMetadata(row);
94
+ const payload = { key, displayName, domainKey };
95
+ copyOptionalFields(payload, row, ['description', 'purpose', 'businessOutcome', 'isActive', 'source']);
96
+ if (Object.keys(metadata).length > 0) {
97
+ payload.metadata = metadata;
98
+ }
99
+ return payload;
100
+ }
101
+
102
+ /**
103
+ * @param {object} row
104
+ * @returns {Object}
105
+ */
106
+ function collectRoleCompilerMetadata(row) {
107
+ const metadata = {
108
+ ...(row.metadata && typeof row.metadata === 'object' ? row.metadata : {})
109
+ };
110
+ for (const field of ROLE_COMPILER_FIELDS) {
111
+ if (row[field] !== undefined) {
112
+ metadata[field] = row[field];
113
+ }
114
+ }
115
+ return metadata;
116
+ }
117
+
118
+ /**
119
+ * @param {Object} target
120
+ * @param {object} source
121
+ * @param {string[]} fields
122
+ * @returns {void}
123
+ */
124
+ function copyOptionalFields(target, source, fields) {
125
+ for (const field of fields) {
126
+ if (source[field] !== undefined) {
127
+ target[field] = source[field];
128
+ }
129
+ }
130
+ }
131
+
132
+ /**
133
+ * Map Controller role record to baseline-shaped JSON (domainKey → domain; flatten compiler metadata).
134
+ * @param {object} record
135
+ * @returns {Object}
136
+ */
137
+ function mapRoleApiToFileRow(record) {
138
+ const row = {
139
+ key: record.key,
140
+ displayName: record.displayName,
141
+ domain: record.domainKey || record.domain
142
+ };
143
+ if (record.description) row.description = record.description;
144
+ if (record.purpose) row.purpose = record.purpose;
145
+ if (record.businessOutcome) row.businessOutcome = record.businessOutcome;
146
+ const meta = record.metadata && typeof record.metadata === 'object' ? { ...record.metadata } : {};
147
+ for (const field of ROLE_COMPILER_FIELDS) {
148
+ if (meta[field] !== undefined) {
149
+ row[field] = meta[field];
150
+ delete meta[field];
151
+ }
152
+ }
153
+ if (Object.keys(meta).length > 0) {
154
+ row.metadata = meta;
155
+ }
156
+ return row;
157
+ }
158
+
159
+ /**
160
+ * @param {object} parsed
161
+ * @returns {void}
162
+ */
163
+ function rejectBaselineCatalogShape(parsed) {
164
+ if (parsed && typeof parsed === 'object' && Array.isArray(parsed.roles) && !parsed.key) {
165
+ throw new Error(
166
+ 'File is a baseline catalog (roles[]). ' +
167
+ 'Use `aifabrix role import --file <path>` to seed all entries, ' +
168
+ 'or pass a single role object with key and displayName.'
169
+ );
170
+ }
171
+ }
172
+
173
+ /**
174
+ * @param {string} filePath
175
+ * @returns {Object}
176
+ */
177
+ function readRoleCreateFile(filePath) {
178
+ const parsed = loadRoleJson(filePath);
179
+ rejectBaselineCatalogShape(parsed);
180
+ return mapRoleFileToApiPayload(parsed, 0);
181
+ }
182
+
183
+ /**
184
+ * @param {string} filePath
185
+ * @returns {Object[]}
186
+ */
187
+ function readRoleCatalogFile(filePath) {
188
+ const parsed = loadRoleJson(filePath);
189
+ let rows;
190
+ if (Array.isArray(parsed)) {
191
+ rows = parsed;
192
+ } else if (Array.isArray(parsed.roles)) {
193
+ rows = parsed.roles;
194
+ } else {
195
+ throw new Error(
196
+ 'Import file must be a baseline catalog with roles[] or a JSON array of roles.'
197
+ );
198
+ }
199
+ if (rows.length === 0) {
200
+ throw new Error('Import file contains no roles');
201
+ }
202
+ return rows.map((row, index) => mapRoleFileToApiPayload(row, index));
203
+ }
204
+
205
+ /**
206
+ * @param {string} filePath
207
+ * @param {Object[]} rows - baseline-shaped role rows
208
+ * @param {string} [version]
209
+ * @returns {void}
210
+ */
211
+ function writeRoleCatalogFile(filePath, rows, version = '1.0.0') {
212
+ const p = path.resolve(String(filePath || '').trim());
213
+ if (!p) {
214
+ throw new Error('--file is required');
215
+ }
216
+ const catalog = { version, roles: rows };
217
+ writeFileSync(p, `${JSON.stringify(catalog, null, 2)}\n`, 'utf8');
218
+ }
219
+
220
+ module.exports = {
221
+ ROLE_COMPILER_FIELDS,
222
+ mapRoleFileToApiPayload,
223
+ mapRoleApiToFileRow,
224
+ readRoleCreateFile,
225
+ readRoleCatalogFile,
226
+ writeRoleCatalogFile
227
+ };
@@ -7,12 +7,12 @@
7
7
  "key": "application-schema",
8
8
  "name": "Application Configuration Schema",
9
9
  "description": "JSON schema for validating AI Fabrix application configuration files",
10
- "version": "1.4.0",
10
+ "version": "1.5.0",
11
11
  "type": "schema",
12
12
  "category": "infrastructure",
13
13
  "author": "AI Fabrix Team",
14
14
  "createdAt": "2024-01-01T00:00:00Z",
15
- "updatedAt": "2026-04-06T00:00:00Z",
15
+ "updatedAt": "2026-07-21T00:00:00Z",
16
16
  "compatibility": {
17
17
  "minVersion": "1.0.0",
18
18
  "maxVersion": "2.0.0",
@@ -30,6 +30,14 @@
30
30
  "external-datasource.schema.json"
31
31
  ],
32
32
  "changelog": [
33
+ {
34
+ "version": "1.5.0",
35
+ "date": "2026-07-21T00:00:00Z",
36
+ "changes": [
37
+ "Added optional configuration[].category (and conditionalConfiguration item category) for portal UI grouping labels in Miso Configuration tab."
38
+ ],
39
+ "breaking": false
40
+ },
33
41
  {
34
42
  "version": "1.4.0",
35
43
  "date": "2026-04-06T00:00:00Z",
@@ -203,6 +211,12 @@
203
211
  "type": "boolean",
204
212
  "description": "Whether this configuration is required"
205
213
  },
214
+ "category": {
215
+ "type": "string",
216
+ "description": "Optional UI grouping label for portal/deployment wizard Configuration tab",
217
+ "minLength": 1,
218
+ "maxLength": 100
219
+ },
206
220
  "portalInput": {
207
221
  "type": "object",
208
222
  "description": "Portal input configuration for user-provided values",
@@ -315,6 +329,12 @@
315
329
  "type": "boolean",
316
330
  "description": "Whether this configuration is required"
317
331
  },
332
+ "category": {
333
+ "type": "string",
334
+ "description": "Optional UI grouping label for portal/deployment wizard Configuration tab",
335
+ "minLength": 1,
336
+ "maxLength": 100
337
+ },
318
338
  "portalInput": {
319
339
  "type": "object",
320
340
  "description": "Portal input configuration for user-provided values",