@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
@@ -16,6 +16,19 @@ const { loadConfigFile, writeConfigFile } = require('../utils/config-format');
16
16
  const { backupIntegrationFile } = require('../utils/integration-file-backup');
17
17
  const appConfigResolver = require('../utils/app-config-resolver');
18
18
  const { extractRbacFromSystem } = require('./repair-rbac-extract');
19
+ const { toKebabAliasKey } = require('./repair-datasource-auto-rbac');
20
+ const { mergeRbacIntoSystemJson } = require('../generator/external');
21
+ const { bindOpenApiOperationSecurityFromRbac } = require('./repair-datasource-operation-security');
22
+ const {
23
+ ensureNonEmptyPermissionRoles,
24
+ ensureReaderRoleOnReadPermissions
25
+ } = require('./repair-rbac-reader-roles');
26
+ const {
27
+ ensurePlatformRolesOnRbac,
28
+ applyPlatformRolesToPermissions,
29
+ ensureOrchestrationResourceType
30
+ } = require('./repair-rbac-platform-preset');
31
+ const { trackRepairWrite } = require('./repair-changed-files');
19
32
 
20
33
  const DEFAULT_CAPABILITIES = ['list', 'get', 'create', 'update', 'delete'];
21
34
 
@@ -26,6 +39,8 @@ function _safeString(v) {
26
39
  function _normalizeOperationKey(opKey) {
27
40
  const s = _safeString(opKey);
28
41
  if (!s) return '';
42
+ // Match dataplane autoRbac permission names: lowercase schema-valid camelCase keys.
43
+ if (/^[a-z][a-zA-Z0-9]*$/.test(s)) return s.toLowerCase();
29
44
  const withHyphens = s.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
30
45
  const cleaned = withHyphens.replace(/[^a-z0-9-]+/g, '-');
31
46
  return cleaned.replace(/-+/g, '-').replace(/^-+|-+$/g, '');
@@ -116,20 +131,39 @@ function _collectManagedResourceTypesFromDatasources(appPath, datasourceFiles) {
116
131
  return out;
117
132
  }
118
133
 
119
- function _buildDesiredPermissionNames(appPath, datasourceFiles) {
120
- const desired = collectPermissionNames(appPath, datasourceFiles);
121
- if (desired.size === 0) return { desired, managedResourceTypes: new Set(), aliases: new Map() };
122
-
123
- const managedResourceTypes = _collectManagedResourceTypesFromDatasources(appPath, datasourceFiles);
134
+ function _registerOpAlias(aliases, rt, opKey, canonicalOp, desired) {
135
+ const canonicalName = `${rt}:${canonicalOp}`;
136
+ desired.add(canonicalName);
137
+ const kebabLegacy = toKebabAliasKey(opKey);
138
+ if (kebabLegacy && kebabLegacy !== canonicalOp) {
139
+ aliases.set(`${rt}:${kebabLegacy}`, canonicalName);
140
+ }
141
+ }
124
142
 
125
- // Build alias map for rename support (kebab-case or case variants -> canonical).
143
+ function _collectOpAliasesFromDatasources(appPath, datasourceFiles, desired) {
126
144
  const aliases = new Map();
145
+ for (const fileName of datasourceFiles || []) {
146
+ const parsed = _safeLoadDatasource(appPath, fileName);
147
+ if (!parsed || !_hasAutoRbacOps(parsed)) {
148
+ continue;
149
+ }
150
+ const rt = _safeString(parsed.resourceType) || 'document';
151
+ for (const opKey of Object.keys(parsed.openapi.operations)) {
152
+ const canonicalOp = _normalizeOperationKey(opKey) || _safeString(opKey);
153
+ if (!canonicalOp) {
154
+ continue;
155
+ }
156
+ _registerOpAlias(aliases, rt, opKey, canonicalOp, desired);
157
+ }
158
+ }
159
+ return aliases;
160
+ }
161
+
162
+ function _addDesiredNameVariants(desired, aliases) {
127
163
  for (const name of desired) {
128
164
  const [rt, op] = String(name).split(':');
129
- if (!rt || !op) continue;
130
- const kebab = _normalizeOperationKey(op);
131
- if (kebab && `${rt}:${kebab}` !== name) {
132
- aliases.set(`${rt}:${kebab}`, name);
165
+ if (!rt || !op) {
166
+ continue;
133
167
  }
134
168
  const lower = `${rt}:${String(op).toLowerCase()}`;
135
169
  if (lower !== name) {
@@ -140,6 +174,17 @@ function _buildDesiredPermissionNames(appPath, datasourceFiles) {
140
174
  aliases.set(dehyphen, name);
141
175
  }
142
176
  }
177
+ }
178
+
179
+ function _buildDesiredPermissionNames(appPath, datasourceFiles) {
180
+ const desired = collectPermissionNames(appPath, datasourceFiles);
181
+ if (desired.size === 0) {
182
+ return { desired, managedResourceTypes: new Set(), aliases: new Map() };
183
+ }
184
+
185
+ const managedResourceTypes = _collectManagedResourceTypesFromDatasources(appPath, datasourceFiles);
186
+ const aliases = _collectOpAliasesFromDatasources(appPath, datasourceFiles, desired);
187
+ _addDesiredNameVariants(desired, aliases);
143
188
  return { desired, managedResourceTypes, aliases };
144
189
  }
145
190
 
@@ -253,80 +298,31 @@ function ensureDefaultRoles(rbac, systemKey, displayName, changes) {
253
298
  return true;
254
299
  }
255
300
 
256
- function _roleValues(rbac) {
257
- const roles = Array.isArray(rbac.roles) ? rbac.roles : [];
258
- return roles
259
- .map(r => r?.value)
260
- .filter(v => typeof v === 'string' && v.trim());
261
- }
262
-
263
- function _pickAdminRoleValue(roleValues, systemKey) {
264
- return (
265
- roleValues.find(v => v === `${systemKey}-admin`) ||
266
- roleValues.find(v => /-admin$/.test(v)) ||
267
- roleValues[0] ||
268
- null
269
- );
270
- }
271
-
272
- function _pickReaderRoleValue(roleValues, systemKey) {
273
- return (
274
- roleValues.find(v => v === `${systemKey}-reader`) ||
275
- roleValues.find(v => /-reader$/.test(v)) ||
276
- null
277
- );
278
- }
279
-
280
- function _capabilityFromPermissionName(name) {
281
- if (typeof name !== 'string' || !name.includes(':')) return null;
282
- return name.split(':')[1] || null;
283
- }
284
-
285
- function _defaultRolesForCapability(cap, { adminValue, readerValue }) {
286
- const roles = [];
287
- if ((cap === 'list' || cap === 'get') && readerValue) roles.push(readerValue);
288
- if (adminValue) roles.push(adminValue);
289
- return roles;
301
+ /**
302
+ * @param {Object} opts
303
+ * @returns {boolean}
304
+ */
305
+ function applyRbacPresetRoles(opts) {
306
+ const { rbac, rbacPreset, systemKey, displayName, appPath, datasourceFiles, changes } = opts;
307
+ if (rbacPreset === 'platform') {
308
+ return (
309
+ ensurePlatformRolesOnRbac(rbac, changes) ||
310
+ applyPlatformRolesToPermissions(rbac, appPath, datasourceFiles, changes)
311
+ );
312
+ }
313
+ return ensureDefaultRoles(rbac, systemKey, displayName, changes);
290
314
  }
291
315
 
292
316
  /**
293
- * Ensures every permission has at least one role assigned.
294
- *
295
- * When roles already exist, new permissions may be added with empty roles (invalid for manifest).
296
- * Apply a safe default:
297
- * - list/get -> reader + admin when those roles exist
298
- * - create/update/delete -> admin when it exists (otherwise first available role)
299
- *
300
- * Mutates rbac.
301
- * @param {Object} rbac - RBAC object (mutated)
302
- * @param {string} systemKey - System key
303
- * @param {string[]} changes - Array to append to
317
+ * @param {Object} opts
304
318
  * @returns {boolean}
305
319
  */
306
- function ensureNonEmptyPermissionRoles(rbac, systemKey, changes) {
307
- const roleValues = _roleValues(rbac);
308
- if (!Array.isArray(rbac.permissions) || roleValues.length === 0) return false;
309
-
310
- const adminValue = _pickAdminRoleValue(roleValues, systemKey);
311
- const readerValue = _pickReaderRoleValue(roleValues, systemKey);
312
-
313
- let updated = false;
314
- for (const p of rbac.permissions) {
315
- if (!p || typeof p !== 'object') continue;
316
- if (!Array.isArray(p.roles)) p.roles = [];
317
- if (p.roles.length > 0) continue;
318
-
319
- const cap = _capabilityFromPermissionName(p.name);
320
- const defaults = _defaultRolesForCapability(cap, { adminValue, readerValue });
321
- for (const rv of defaults) {
322
- if (!p.roles.includes(rv)) p.roles.push(rv);
323
- }
324
- if (p.roles.length > 0) {
325
- changes.push(`RBAC: defaulted empty roles for ${p.name}`);
326
- updated = true;
327
- }
320
+ function applyReaderRolesIfNeeded(opts) {
321
+ const { rbac, rbacPreset, appPath, datasourceFiles, systemKey, changes } = opts;
322
+ if (rbacPreset === 'platform') {
323
+ return false;
328
324
  }
329
- return updated;
325
+ return ensureReaderRoleOnReadPermissions(rbac, appPath, datasourceFiles, systemKey, changes);
330
326
  }
331
327
 
332
328
  /**
@@ -341,18 +337,35 @@ function ensureNonEmptyPermissionRoles(rbac, systemKey, changes) {
341
337
  * @returns {boolean} True if rbac was updated (or would be in dry-run)
342
338
  */
343
339
  function mergeRbacFromDatasources(appPath, systemParsed, datasourceFiles, extractRbacFromSystem, options) {
344
- const { format = 'yaml', dryRun, changes, backupCtx } = options;
340
+ const { format = 'yaml', dryRun, changes, backupCtx, rbacPreset } = options;
345
341
  const rbacFormat = format === 'json' ? 'json' : 'yaml';
346
- const { desired: permissionNames, managedResourceTypes, aliases } = _buildDesiredPermissionNames(appPath, datasourceFiles);
347
- if (permissionNames.size === 0) return false;
342
+ const { desired: permissionNames, managedResourceTypes, aliases } = _buildDesiredPermissionNames(
343
+ appPath,
344
+ datasourceFiles
345
+ );
346
+ if (permissionNames.size === 0) {
347
+ return false;
348
+ }
348
349
  const systemKey = systemParsed?.key || 'system';
349
350
  const displayName = systemParsed?.displayName || systemKey;
350
351
  const { rbac, rbacPath } = loadOrCreateRbac(appPath, systemParsed, extractRbacFromSystem, rbacFormat);
351
352
  let updated = _renameExistingPermissionIfAliasMatches(rbac, aliases, changes);
352
353
  updated = addMissingPermissions(rbac, permissionNames, changes) || updated;
353
354
  updated = _removeExtraAutoRbacPermissions(rbac, permissionNames, managedResourceTypes, changes) || updated;
354
- updated = ensureDefaultRoles(rbac, systemKey, displayName, changes) || updated;
355
+ updated =
356
+ applyRbacPresetRoles({
357
+ rbac,
358
+ rbacPreset,
359
+ systemKey,
360
+ displayName,
361
+ appPath,
362
+ datasourceFiles,
363
+ changes
364
+ }) || updated;
355
365
  updated = ensureNonEmptyPermissionRoles(rbac, systemKey, changes) || updated;
366
+ updated =
367
+ applyReaderRolesIfNeeded({ rbac, rbacPreset, appPath, datasourceFiles, systemKey, changes }) ||
368
+ updated;
356
369
  if (updated && !dryRun) {
357
370
  backupIntegrationFile(rbacPath, backupCtx);
358
371
  writeConfigFile(rbacPath, rbac);
@@ -386,6 +399,44 @@ function createRbacFromSystemIfNeeded(opts) {
386
399
  return true;
387
400
  }
388
401
 
402
+ /**
403
+ * Copy roles/permissions from rbac file into *-system.json for dataplane COM publish.
404
+ * @param {string} appPath
405
+ * @param {string} systemFilePath
406
+ * @param {Object} systemParsed
407
+ * @param {boolean} dryRun
408
+ * @param {string[]} changes
409
+ * @param {Object} backupCtx
410
+ * @returns {boolean}
411
+ */
412
+ function syncRbacFileIntoSystem(appPath, systemFilePath, systemParsed, dryRun, changes, backupCtx) {
413
+ const rbacPath = appConfigResolver.resolveRbacPath(appPath);
414
+ if (!rbacPath || !fs.existsSync(rbacPath)) return false;
415
+ let rbac;
416
+ try {
417
+ rbac = loadConfigFile(rbacPath);
418
+ } catch {
419
+ return false;
420
+ }
421
+ const before = JSON.stringify({
422
+ roles: systemParsed.roles || [],
423
+ permissions: systemParsed.permissions || []
424
+ });
425
+ mergeRbacIntoSystemJson(systemParsed, rbac);
426
+ const after = JSON.stringify({
427
+ roles: systemParsed.roles || [],
428
+ permissions: systemParsed.permissions || []
429
+ });
430
+ if (before === after) return false;
431
+ if (!dryRun) {
432
+ backupIntegrationFile(systemFilePath, backupCtx);
433
+ writeConfigFile(systemFilePath, systemParsed);
434
+ trackRepairWrite(systemFilePath, backupCtx);
435
+ }
436
+ changes.push('Synced roles/permissions from rbac file into system manifest');
437
+ return true;
438
+ }
439
+
389
440
  /**
390
441
  * @param {string} appPath
391
442
  * @param {string} systemFilePath
@@ -395,20 +446,46 @@ function createRbacFromSystemIfNeeded(opts) {
395
446
  * @returns {{ rbacMigratedFromSystem: boolean, rbacMergeUpdated: boolean }}
396
447
  */
397
448
  function maybeRepairRbac(appPath, systemFilePath, systemParsed, datasourceFiles, options) {
398
- if (!options.rbac) return { rbacMigratedFromSystem: false, rbacMergeUpdated: false };
399
- const { dryRun, changes, backupCtx, rbacFmt } = options;
449
+ if (!options.rbac) {
450
+ return {
451
+ rbacMigratedFromSystem: false,
452
+ rbacMergeUpdated: false,
453
+ rbacSyncedIntoSystem: false,
454
+ rbacSecurityBound: false
455
+ };
456
+ }
457
+ const { dryRun, changes, backupCtx, rbacFmt, rbacPreset } = options;
400
458
  const rbacMigratedFromSystem = migrateSystemRbacIntoRbacFile(appPath, systemFilePath, systemParsed, {
401
459
  dryRun,
402
460
  changes,
403
461
  backupCtx
404
462
  });
463
+ if (rbacPreset === 'platform' && !dryRun) {
464
+ ensureOrchestrationResourceType(appPath, datasourceFiles, changes, backupCtx);
465
+ }
405
466
  const rbacMergeUpdated = mergeRbacFromDatasources(appPath, systemParsed, datasourceFiles, extractRbacFromSystem, {
406
467
  format: rbacFmt,
407
468
  dryRun,
408
469
  changes,
409
- backupCtx
470
+ backupCtx,
471
+ rbacPreset
410
472
  });
411
- return { rbacMigratedFromSystem, rbacMergeUpdated };
473
+ const rbacSyncedIntoSystem = syncRbacFileIntoSystem(
474
+ appPath,
475
+ systemFilePath,
476
+ systemParsed,
477
+ dryRun,
478
+ changes,
479
+ backupCtx
480
+ );
481
+ const rbacSecurityBound = bindOpenApiOperationSecurityFromRbac(
482
+ appPath,
483
+ datasourceFiles,
484
+ dryRun,
485
+ changes,
486
+ backupCtx
487
+ );
488
+ return { rbacMigratedFromSystem, rbacMergeUpdated, rbacSyncedIntoSystem, rbacSecurityBound };
412
489
  }
413
490
 
414
491
  module.exports = {
@@ -20,6 +20,10 @@ const {
20
20
  ensureExternalIntegrationBlock,
21
21
  removeAuthVarsFromConfiguration
22
22
  } = require('./repair-system-alignment');
23
+ const {
24
+ repairAuthenticationsArray,
25
+ ensureAuthUsageSlots
26
+ } = require('./repair-authentications-454');
23
27
  const {
24
28
  isAllowedRepairAuth,
25
29
  normalizeRepairAuthOption,
@@ -80,7 +84,8 @@ function persistSystemFileRepair(ctx, flags) {
80
84
  flags.authShapeNormalized ||
81
85
  flags.systemAuthConfigNormalized ||
82
86
  flags.systemDataSourcesAligned ||
83
- flags.authVarsRemoved;
87
+ flags.authVarsRemoved ||
88
+ flags.authenticationsArrayUpdated;
84
89
  if (!systemFileUpdated) {
85
90
  return false;
86
91
  }
@@ -94,21 +99,60 @@ function persistSystemFileRepair(ctx, flags) {
94
99
 
95
100
  /**
96
101
  * @param {Object} ctx
97
- * @returns {{ updated: boolean, appKeyFixed: boolean, datasourceKeysFixed: boolean, rbacFileCreated: boolean, envTemplateRepaired: boolean }}
102
+ * @returns {{ updated: boolean, authenticationsArrayUpdated: boolean }}
98
103
  */
99
- function runRepairSteps(ctx) {
100
- const bc = ctx.backupCtx;
101
- let updated = ensureExternalIntegrationBlock(
102
- ctx.variables, ctx.systemFiles, ctx.datasourceFiles, ctx.changes
103
- );
104
+ function applyAuthUsageSlotsRepair(ctx) {
105
+ if (!ctx.options?.authWebhook && !ctx.options?.authSync) {
106
+ return { updated: false, authenticationsArrayUpdated: false };
107
+ }
108
+ const slotsResult = ensureAuthUsageSlots(ctx.systemParsed, {
109
+ authWebhook: Boolean(ctx.options.authWebhook),
110
+ authSync: Boolean(ctx.options.authSync),
111
+ systemKey: ctx.systemKey
112
+ });
113
+ if (slotsResult.warnings.length) {
114
+ ctx.warnings.push(...slotsResult.warnings);
115
+ slotsResult.warnings.forEach((msg) => ctx.changes.push(msg));
116
+ }
117
+ return {
118
+ updated: slotsResult.changed,
119
+ authenticationsArrayUpdated: slotsResult.changed
120
+ };
121
+ }
122
+
123
+ /**
124
+ * @param {Object} ctx
125
+ * @returns {{ updated: boolean, authReplaced: boolean, authShapeNormalized: boolean, authenticationsArrayUpdated: boolean }}
126
+ */
127
+ function runAuthRepairSteps(ctx) {
104
128
  const authReplaced = applyAuthMethod(ctx);
105
- updated = updated || authReplaced;
106
129
  const authShapeNormalized = normalizeAuthenticationSchemaShape(
107
130
  ctx.systemParsed,
108
131
  ctx.systemKey,
109
132
  ctx.changes
110
133
  );
111
- updated = updated || authShapeNormalized;
134
+ const authArrayResult = repairAuthenticationsArray(ctx.systemParsed);
135
+ let updated = authReplaced || authShapeNormalized;
136
+ let authenticationsArrayUpdated = authArrayResult.changed;
137
+ if (authArrayResult.changed) {
138
+ ctx.changes.push('Normalized legacy authentication to authentications[]');
139
+ updated = true;
140
+ }
141
+ if (authArrayResult.warnings.length) {
142
+ ctx.warnings.push(...authArrayResult.warnings);
143
+ }
144
+ const slotsResult = applyAuthUsageSlotsRepair(ctx);
145
+ updated = updated || slotsResult.updated;
146
+ authenticationsArrayUpdated = authenticationsArrayUpdated || slotsResult.authenticationsArrayUpdated;
147
+ return { updated, authReplaced, authShapeNormalized, authenticationsArrayUpdated };
148
+ }
149
+
150
+ /**
151
+ * @param {Object} ctx
152
+ * @param {Object} authFlags
153
+ * @returns {boolean}
154
+ */
155
+ function persistAuthSystemFileRepair(ctx, authFlags) {
112
156
  const systemAuthConfigNormalized = normalizeSystemFileAuthAndConfig(
113
157
  ctx.systemParsed, ctx.systemKey, ctx.changes
114
158
  );
@@ -118,14 +162,20 @@ function runRepairSteps(ctx) {
118
162
  const authVarsRemoved = removeAuthVarsFromConfiguration(
119
163
  ctx.systemParsed, ctx.systemKey, ctx.dryRun, ctx.changes
120
164
  );
121
- const systemFileUpdated = persistSystemFileRepair(ctx, {
122
- authReplaced,
123
- authShapeNormalized,
165
+ return persistSystemFileRepair(ctx, {
166
+ ...authFlags,
124
167
  systemAuthConfigNormalized,
125
168
  systemDataSourcesAligned,
126
169
  authVarsRemoved
127
170
  });
128
- updated = updated || systemFileUpdated;
171
+ }
172
+
173
+ /**
174
+ * @param {Object} ctx
175
+ * @param {Object} bc
176
+ * @returns {{ appKeyFixed: boolean, datasourceKeysFixed: boolean, rbacFileCreated: boolean, envTemplateRepaired: boolean }}
177
+ */
178
+ function runManifestRepairSteps(ctx, bc) {
129
179
  const appKeyFixed = alignAppKeyWithSystem(
130
180
  ctx.variables, ctx.systemKey, ctx.systemParsed, ctx.changes
131
181
  );
@@ -144,14 +194,29 @@ function runRepairSteps(ctx) {
144
194
  const envTemplateRepaired = repairEnvTemplate(
145
195
  ctx.appPath, ctx.systemParsed, ctx.systemKey, ctx.dryRun, ctx.changes, bc
146
196
  );
147
- updated = updated || appKeyFixed || datasourceKeysFixed || rbacFileCreated || envTemplateRepaired;
197
+ return { appKeyFixed, datasourceKeysFixed, rbacFileCreated, envTemplateRepaired };
198
+ }
199
+
200
+ /**
201
+ * @param {Object} ctx
202
+ * @returns {{ updated: boolean, appKeyFixed: boolean, datasourceKeysFixed: boolean, rbacFileCreated: boolean, envTemplateRepaired: boolean }}
203
+ */
204
+ function runRepairSteps(ctx) {
205
+ const bc = ctx.backupCtx;
206
+ let updated = ensureExternalIntegrationBlock(
207
+ ctx.variables, ctx.systemFiles, ctx.datasourceFiles, ctx.changes
208
+ );
209
+ const authResult = runAuthRepairSteps(ctx);
210
+ updated = updated || authResult.updated;
211
+ const systemFileUpdated = persistAuthSystemFileRepair(ctx, authResult);
212
+ updated = updated || systemFileUpdated;
213
+ const manifestResult = runManifestRepairSteps(ctx, bc);
214
+ updated = updated || manifestResult.appKeyFixed || manifestResult.datasourceKeysFixed
215
+ || manifestResult.rbacFileCreated || manifestResult.envTemplateRepaired;
148
216
  auditRepairAuthenticationWarnings(ctx.systemParsed, ctx.warnings);
149
217
  return {
150
218
  updated,
151
- appKeyFixed,
152
- datasourceKeysFixed,
153
- rbacFileCreated,
154
- envTemplateRepaired
219
+ ...manifestResult
155
220
  };
156
221
  }
157
222
 
@@ -17,6 +17,7 @@ function _safeString(v) {
17
17
  function _normalizeOperationKey(opKey) {
18
18
  const s = _safeString(opKey);
19
19
  if (!s) return '';
20
+ if (/^[a-z][a-zA-Z0-9]*$/.test(s)) return s.toLowerCase();
20
21
  const withHyphens = s.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
21
22
  const cleaned = withHyphens.replace(/[^a-z0-9-]+/g, '-');
22
23
  return cleaned.replace(/-+/g, '-').replace(/^-+|-+$/g, '');
@@ -51,7 +51,7 @@ async function validateAndResolveRepairPaths(appName, options) {
51
51
  if (authOption !== undefined && authOption !== null && typeof authOption !== 'string') {
52
52
  throw new Error('Option --auth must be a string');
53
53
  }
54
- const { appPath, isExternal } = await detectAppType(appName);
54
+ const { appPath, isExternal } = await detectAppType(appName, options);
55
55
  if (!isExternal) throw new Error(`App '${appName}' is not an external integration`);
56
56
  const configPath = resolveApplicationConfigPath(appPath);
57
57
  if (!fs.existsSync(configPath)) throw new Error(`Application config not found: ${configPath}`);