@aifabrix/builder 2.49.1 → 2.50.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 (413) hide show
  1. package/.cursor/process/README.md +9 -0
  2. package/.cursor/rules/deploy-rules/docker-image-ip-policy.mdc +49 -0
  3. package/.cursor/rules/plan-rules/application-lifecycle.mdc +30 -0
  4. package/.cursor/rules/plan-rules/plan-frontmatter.mdc +35 -0
  5. package/.cursor/rules/plan-rules/plan-lifecycle.mdc +31 -0
  6. package/.cursor/rules/plan-rules/plan-validation-gate.mdc +34 -0
  7. package/.cursor/skills/README.md +1 -0
  8. package/.dockerignore +52 -0
  9. package/.eslintignore +22 -0
  10. package/README.md +2 -0
  11. package/bin/builder-api-cleanup.js +26 -0
  12. package/bin/builder-api-nest.js +10 -0
  13. package/bin/builder-api-spike.js +19 -0
  14. package/enterprise-knowledge/README.md +50 -0
  15. package/enterprise-knowledge/enterprise-integration-lifecycle/README.md +22 -0
  16. package/enterprise-knowledge/enterprise-integration-lifecycle/application.json +15 -0
  17. package/enterprise-knowledge/enterprise-integration-lifecycle/deploy.js +69 -0
  18. package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-deploy.json +52 -0
  19. package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-system.json +29 -0
  20. package/enterprise-knowledge/enterprise-integration-lifecycle/env.template +2 -0
  21. package/integration/README.md +81 -0
  22. package/integration/github/README.md +53 -0
  23. package/integration/github/application.json +21 -0
  24. package/integration/github/deploy.js +72 -0
  25. package/integration/github/env.template +11 -0
  26. package/integration/github/github-datasource-issue-comments.json +239 -0
  27. package/integration/github/github-datasource-issues.json +399 -0
  28. package/integration/github/github-datasource-repository.json +354 -0
  29. package/integration/github/github-deploy.json +1202 -0
  30. package/integration/github/github-system.json +82 -0
  31. package/integration/hubspot-test/README.md +1 -1
  32. package/jest.isolated-projects.js +31 -1
  33. package/jest.projects.js +87 -1
  34. package/lib/api/dev-server-https.js +1 -1
  35. package/lib/api/dev.api.js +1 -0
  36. package/lib/api/enterprise-knowledge.api.js +63 -0
  37. package/lib/api/evidence.api.js +172 -0
  38. package/lib/api/external-systems.api.js +8 -2
  39. package/lib/api/host-ops.api.js +69 -0
  40. package/lib/api/resource-types.api.js +1 -0
  41. package/lib/api/types/enterprise-knowledge.types.js +46 -0
  42. package/lib/api/types/evidence.types.js +67 -0
  43. package/lib/api/types/resource-types.types.js +2 -0
  44. package/lib/app/controller-application-filter.js +36 -0
  45. package/lib/app/deploy.js +1 -1
  46. package/lib/app/list-external-systems.js +130 -0
  47. package/lib/app/list.js +20 -8
  48. package/lib/app/run.js +3 -1
  49. package/lib/app/show-display.js +8 -3
  50. package/lib/app/show-online.js +178 -0
  51. package/lib/app/show.js +37 -88
  52. package/lib/build/builder-api-docker-staging.js +47 -0
  53. package/lib/build/miso-controller-npm-sdk-guard.js +2 -2
  54. package/lib/build/standard-docker-build.js +2 -0
  55. package/lib/certification/post-unified-cert-sync.js +4 -31
  56. package/lib/certification/sync-after-external-command.js +0 -1
  57. package/lib/certification/sync-system-certification.js +0 -3
  58. package/lib/channels/add-channel.js +40 -34
  59. package/lib/channels/approval-guides/chatgpt.js +33 -0
  60. package/lib/channels/approval-guides/credential-portal.js +38 -0
  61. package/lib/channels/approval-guides/index.js +110 -0
  62. package/lib/channels/approval-guides/microsoft-copilot.js +34 -0
  63. package/lib/channels/approval-guides/slack.js +34 -0
  64. package/lib/channels/approval-guides/teams-bot.js +35 -0
  65. package/lib/channels/approval-guides/web-embed.js +32 -0
  66. package/lib/channels/channel-approval-guide.js +11 -0
  67. package/lib/channels/channel-artifact-generator.js +16 -4
  68. package/lib/channels/channel-audit.js +3 -0
  69. package/lib/channels/channel-auth-context.js +1 -1
  70. package/lib/channels/channel-description.js +59 -0
  71. package/lib/channels/channel-integration-generator.js +13 -230
  72. package/lib/channels/channel-integration-template.js +94 -0
  73. package/lib/channels/channel-runtime-resolver.js +43 -3
  74. package/lib/channels/channel-status-display.js +66 -26
  75. package/lib/channels/channel-targets.js +3 -3
  76. package/lib/cli/index.js +27 -3
  77. package/lib/cli/infra-guided.js +5 -1
  78. package/lib/cli/setup-app-external-create.js +111 -0
  79. package/lib/cli/setup-app.help.js +1 -1
  80. package/lib/cli/setup-app.js +38 -125
  81. package/lib/cli/setup-app.test-commands.js +26 -52
  82. package/lib/cli/setup-certification-commands.js +4 -4
  83. package/lib/cli/setup-certification.help.js +9 -9
  84. package/lib/cli/setup-dev-path-commands.js +24 -0
  85. package/lib/cli/setup-dev.js +115 -16
  86. package/lib/cli/setup-external-system-help.js +4 -6
  87. package/lib/cli/setup-external-system.js +58 -52
  88. package/lib/cli/setup-infra-up-builder-api-action.js +64 -0
  89. package/lib/cli/setup-infra-up-platform-action.js +3 -1
  90. package/lib/cli/setup-infra.js +15 -0
  91. package/lib/cli/setup-list.js +43 -0
  92. package/lib/cli/setup-utility-repair.js +26 -7
  93. package/lib/cli/setup-utility.js +5 -3
  94. package/lib/commands/app.js +15 -43
  95. package/lib/commands/channel-add-setup.js +110 -0
  96. package/lib/commands/channel.js +42 -8
  97. package/lib/commands/datasource-sync-display.js +96 -0
  98. package/lib/commands/datasource-sync-policy.js +210 -0
  99. package/lib/commands/datasource-test-trust-cli.js +6 -6
  100. package/lib/commands/datasource-unified-test-cli.js +2 -1
  101. package/lib/commands/datasource-unified-test-cli.options.js +33 -23
  102. package/lib/commands/deploy-gate-failure-details.js +163 -0
  103. package/lib/commands/deploy-gate-orchestrator.js +322 -0
  104. package/lib/commands/dev-cli-handlers.js +64 -61
  105. package/lib/commands/dev-host-ops-params.js +91 -0
  106. package/lib/commands/dev-host-ops-poll.js +111 -0
  107. package/lib/commands/dev-host-ops.js +252 -0
  108. package/lib/commands/dev-init.js +3 -1
  109. package/lib/commands/enterprise-knowledge.js +284 -0
  110. package/lib/commands/evidence-cli-leaves.js +250 -0
  111. package/lib/commands/evidence.js +51 -0
  112. package/lib/commands/governance-cli-shared.js +2 -2
  113. package/lib/commands/governance-command-action.js +2 -2
  114. package/lib/commands/governance-fixture-subjects.js +85 -0
  115. package/lib/commands/governance.js +1 -1
  116. package/lib/commands/lifecycle-command-action.js +2 -2
  117. package/lib/commands/lifecycle-external.js +3 -3
  118. package/lib/commands/manifest-cli-auth.js +29 -0
  119. package/lib/commands/manifest-cli-commands.js +170 -0
  120. package/lib/commands/manifest-cli-integration-path.js +63 -0
  121. package/lib/commands/manifest.js +21 -0
  122. package/lib/commands/protection-cli-leaves.js +3 -3
  123. package/lib/commands/repair-auth-apply.js +15 -1
  124. package/lib/commands/repair-authentications-454.js +169 -0
  125. package/lib/commands/repair-capability-openapi-warnings.js +126 -0
  126. package/lib/commands/repair-datasource-apply.js +135 -0
  127. package/lib/commands/repair-datasource-auto-rbac.js +62 -1
  128. package/lib/commands/repair-datasource-http-service-contract.js +239 -0
  129. package/lib/commands/repair-datasource-operation-security.js +180 -0
  130. package/lib/commands/repair-datasource-run.js +7 -2
  131. package/lib/commands/repair-datasource-sync-operations.js +177 -0
  132. package/lib/commands/repair-datasource-webhooks-sync-bridge.js +133 -0
  133. package/lib/commands/repair-datasource.js +12 -68
  134. package/lib/commands/repair-env-template.js +11 -1
  135. package/lib/commands/repair-external-run.js +121 -31
  136. package/lib/commands/repair-internal.js +1 -1
  137. package/lib/commands/repair-openapi-export.js +156 -0
  138. package/lib/commands/repair-openapi-sync.js +19 -2
  139. package/lib/commands/repair-orchestration-datasource-split.js +259 -0
  140. package/lib/commands/repair-persist.js +22 -1
  141. package/lib/commands/repair-rbac-platform-preset.js +204 -0
  142. package/lib/commands/repair-rbac-reader-roles.js +191 -0
  143. package/lib/commands/repair-rbac.js +163 -86
  144. package/lib/commands/repair-steps.js +83 -18
  145. package/lib/commands/repair-system-permissions.js +1 -0
  146. package/lib/commands/repair.js +1 -1
  147. package/lib/commands/resource-type.js +65 -26
  148. package/lib/commands/run-post-publish-data-sync.js +68 -0
  149. package/lib/commands/setup-modes.js +1 -1
  150. package/lib/commands/test-e2e-external.js +21 -8
  151. package/lib/commands/test-governance-cli-options.js +2 -2
  152. package/lib/commands/test-trust-cli-options.js +2 -2
  153. package/lib/commands/up-builder-api-bootstrap.js +71 -0
  154. package/lib/commands/up-builder-api-provision.js +241 -0
  155. package/lib/commands/up-builder-api.js +88 -0
  156. package/lib/commands/up-common.js +25 -1
  157. package/lib/commands/upload-credential-push-log.js +117 -0
  158. package/lib/commands/upload-data-sync-finalize.js +60 -0
  159. package/lib/commands/upload-probe.js +66 -0
  160. package/lib/commands/upload-publish-context.js +4 -1
  161. package/lib/commands/upload-sidecar-followups.js +55 -27
  162. package/lib/commands/upload.js +116 -157
  163. package/lib/commands/verify-governance-combined-external.js +1 -1
  164. package/lib/commands/verify-governance-db.js +2 -2
  165. package/lib/commands/verify-operations-command-action.js +2 -2
  166. package/lib/commands/verify-operations-step-plan.js +2 -2
  167. package/lib/commands/verify-operations-steps.js +2 -2
  168. package/lib/commands/verify-trust-command-action.js +1 -1
  169. package/lib/commands/wizard-core.js +1 -1
  170. package/lib/commands/wizard-headless.js +2 -1
  171. package/lib/core/admin-secrets.js +2 -6
  172. package/lib/core/secrets-env-content.js +10 -4
  173. package/lib/core/secrets-env-write.js +2 -13
  174. package/lib/datasource/agent-trust-run.js +3 -3
  175. package/lib/datasource/deploy.js +3 -1
  176. package/lib/datasource/test-e2e.js +6 -1
  177. package/lib/datasource/unified-validation-run-body.js +4 -1
  178. package/lib/datasource/unified-validation-run.js +1 -1
  179. package/lib/deployment/deploy-poll-ui.js +73 -12
  180. package/lib/deployment/deployer-poll-run.js +113 -0
  181. package/lib/deployment/deployer.js +17 -87
  182. package/lib/evidence/dataplane-context.js +21 -0
  183. package/lib/evidence/evidence-display.js +78 -0
  184. package/lib/evidence/evidence-service.js +392 -0
  185. package/lib/external-system/deploy.js +290 -112
  186. package/lib/external-system/download.js +7 -3
  187. package/lib/external-system/test-execution.js +1 -1
  188. package/lib/external-system/test-system-level.js +8 -10
  189. package/lib/external-system/test.js +12 -6
  190. package/lib/generator/deploy-script.js +73 -0
  191. package/lib/generator/external.js +2 -1
  192. package/lib/generator/index.js +17 -2
  193. package/lib/generator/wizard.js +3 -36
  194. package/lib/internal/fs-real-sync.js +22 -1
  195. package/lib/internal/node-fs.js +2 -0
  196. package/lib/lifecycle/lifecycle-governance-options.js +1 -1
  197. package/lib/lifecycle/verify-step-progress.js +1 -1
  198. package/lib/programmatic/access-log.js +26 -0
  199. package/lib/programmatic/auth-config.js +44 -0
  200. package/lib/programmatic/bearer-auth.js +176 -0
  201. package/lib/programmatic/builder-api-request.js +175 -0
  202. package/lib/programmatic/builder-api-route-dispatch.js +82 -0
  203. package/lib/programmatic/builder-api-runtime-config.js +42 -0
  204. package/lib/programmatic/builder-api-server.js +230 -0
  205. package/lib/programmatic/builder-help-authentication-catalog.js +282 -0
  206. package/lib/programmatic/builder-help-connected-system-ui.js +266 -0
  207. package/lib/programmatic/builder-help-enterprise-sync-fabrix.js +60 -0
  208. package/lib/programmatic/builder-help-envelope.js +36 -0
  209. package/lib/programmatic/builder-help-fixtures.js +200 -0
  210. package/lib/programmatic/builder-help-governance.js +172 -0
  211. package/lib/programmatic/builder-help-schema-catalog.js +92 -0
  212. package/lib/programmatic/builder-help.js +361 -0
  213. package/lib/programmatic/capability-registry.js +77 -0
  214. package/lib/programmatic/command-options.js +32 -0
  215. package/lib/programmatic/enterprise-mcp-client.js +98 -0
  216. package/lib/programmatic/http-problem-details.js +99 -0
  217. package/lib/programmatic/http-route-match.js +40 -0
  218. package/lib/programmatic/idempotency-cache.js +69 -0
  219. package/lib/programmatic/index.js +53 -0
  220. package/lib/programmatic/integration-path-scope.js +39 -0
  221. package/lib/programmatic/log-redaction.js +66 -0
  222. package/lib/programmatic/manifest-get-section.js +146 -0
  223. package/lib/programmatic/manifest-patch-section.js +252 -0
  224. package/lib/programmatic/manifest-repair.js +122 -0
  225. package/lib/programmatic/manifest-section-dependency-graph.js +160 -0
  226. package/lib/programmatic/manifest-section-io.js +225 -0
  227. package/lib/programmatic/manifest-section-quality.js +171 -0
  228. package/lib/programmatic/manifest-section-registry-data.js +269 -0
  229. package/lib/programmatic/manifest-section-registry.js +205 -0
  230. package/lib/programmatic/nest-http-bridge.js +34 -0
  231. package/lib/programmatic/openapi-component-schemas.js +68 -0
  232. package/lib/programmatic/openapi-description-enricher.js +117 -0
  233. package/lib/programmatic/openapi-descriptions.js +190 -0
  234. package/lib/programmatic/openapi-docs-serving.js +123 -0
  235. package/lib/programmatic/openapi-help-schemas.js +63 -0
  236. package/lib/programmatic/openapi-manifest-schemas.js +141 -0
  237. package/lib/programmatic/openapi-operation-bindings.js +274 -0
  238. package/lib/programmatic/openapi-request-schemas.js +155 -0
  239. package/lib/programmatic/openapi-result-schemas.js +476 -0
  240. package/lib/programmatic/openapi-schema-descriptions-certify.js +139 -0
  241. package/lib/programmatic/openapi-schema-descriptions-core.js +159 -0
  242. package/lib/programmatic/openapi-schema-descriptions-help.js +40 -0
  243. package/lib/programmatic/openapi-schema-descriptions-manifest.js +143 -0
  244. package/lib/programmatic/openapi-schema-descriptions-mcp.js +118 -0
  245. package/lib/programmatic/openapi-schema-descriptions-operations.js +281 -0
  246. package/lib/programmatic/openapi-schema-helpers.js +93 -0
  247. package/lib/programmatic/openapi-spec.js +203 -0
  248. package/lib/programmatic/orchestration-openapi-meta.js +159 -0
  249. package/lib/programmatic/platform-rbac-catalog.js +90 -0
  250. package/lib/programmatic/request-timeout.js +53 -0
  251. package/lib/programmatic/route-handler-map.js +143 -0
  252. package/lib/programmatic/route-handlers-context.js +29 -0
  253. package/lib/programmatic/route-handlers.js +33 -0
  254. package/lib/programmatic/run-certify.js +57 -0
  255. package/lib/programmatic/run-enterprise-mcp.js +32 -0
  256. package/lib/programmatic/run-lifecycle.js +29 -0
  257. package/lib/programmatic/run-repair.js +41 -0
  258. package/lib/programmatic/run-repository-emcp.js +54 -0
  259. package/lib/programmatic/run-template-workspace.js +61 -0
  260. package/lib/programmatic/run-test.js +49 -0
  261. package/lib/programmatic/run-upload.js +63 -0
  262. package/lib/programmatic/run-validate.js +53 -0
  263. package/lib/programmatic/run-wizard.js +40 -0
  264. package/lib/programmatic/system-key.js +48 -0
  265. package/lib/programmatic/wizard-config-normalize.js +118 -0
  266. package/lib/programmatic/workspace-cleanup.js +128 -0
  267. package/lib/programmatic/workspace-context.js +145 -0
  268. package/lib/programmatic/workspace-lock.js +75 -0
  269. package/lib/programmatic/workspace-meta.js +64 -0
  270. package/lib/programmatic/workspace-ops.js +149 -0
  271. package/lib/protection/run-commands-upload-sync.js +35 -0
  272. package/lib/protection/run-commands.js +2 -20
  273. package/lib/protection/upload-batch.js +11 -7
  274. package/lib/resolvers/resource-type-file.js +22 -0
  275. package/lib/schema/external-datasource.schema.json +161 -1
  276. package/lib/schema/external-system.schema.json +242 -4
  277. package/lib/schema/flag-map-validation-run.json +3 -0
  278. package/lib/schema/type/credential-field-registry.json +2 -2
  279. package/lib/schema/type/document-storage.json +9 -0
  280. package/lib/utils/agent-trust-run-display.js +1 -1
  281. package/lib/utils/app-path-resolve.js +168 -0
  282. package/lib/utils/authentication-env-template.js +222 -0
  283. package/lib/utils/cli-sync-options.js +7 -11
  284. package/lib/utils/cli-utils.js +4 -0
  285. package/lib/utils/cli-workspace-options.js +29 -0
  286. package/lib/utils/compose-generate-docker-compose.js +102 -0
  287. package/lib/utils/configuration-env-resolver.js +203 -27
  288. package/lib/utils/datasource-test-run-certificate-tty.js +28 -2
  289. package/lib/utils/datasource-test-run-certification-debug.js +130 -0
  290. package/lib/utils/datasource-test-run-debug-display.js +2 -0
  291. package/lib/utils/datasource-test-run-debug-slice.js +7 -0
  292. package/lib/utils/datasource-test-run-display.js +2 -1
  293. package/lib/utils/dev-init-ssh-merge.js +165 -23
  294. package/lib/utils/dev-pin-share-instructions.js +110 -0
  295. package/lib/utils/dev-ssh-config-helper.js +177 -33
  296. package/lib/utils/enterprise-knowledge-paths.js +142 -0
  297. package/lib/utils/env-copy.js +2 -1
  298. package/lib/utils/env-dotenv-format.js +103 -0
  299. package/lib/utils/external-env-template.js +4 -1
  300. package/lib/utils/external-system-display.js +5 -1
  301. package/lib/utils/external-system-readiness-compact-blocks.js +221 -0
  302. package/lib/utils/external-system-readiness-compact-display.js +324 -0
  303. package/lib/utils/external-system-readiness-core.js +16 -0
  304. package/lib/utils/external-system-readiness-deploy-display.js +29 -11
  305. package/lib/utils/external-system-readiness-display-internals.js +3 -1
  306. package/lib/utils/external-system-readiness-display.js +20 -30
  307. package/lib/utils/external-system-system-test-tty-certification.js +135 -0
  308. package/lib/utils/external-system-system-test-tty.js +5 -41
  309. package/lib/utils/help-builder.js +6 -1
  310. package/lib/utils/host-ops-job-labels.js +236 -0
  311. package/lib/utils/host-ops-job-result.js +61 -0
  312. package/lib/utils/host-ops-poll-ui.js +163 -0
  313. package/lib/utils/integration-path-resolve.js +112 -0
  314. package/lib/utils/paths-reload-source.js +148 -0
  315. package/lib/utils/paths-system-builder-keys.js +25 -0
  316. package/lib/utils/paths.js +151 -26
  317. package/lib/utils/runtime-configuration-values.js +64 -2
  318. package/lib/utils/secrets-helpers.js +5 -1
  319. package/lib/utils/ssh-known-hosts.js +130 -0
  320. package/lib/utils/test-target-cli-options.js +75 -0
  321. package/lib/utils/upload-sync-options.js +4 -0
  322. package/lib/utils/validation-run-request.js +11 -2
  323. package/lib/validation/external-manifest-validator.js +11 -1
  324. package/lib/validation/openapi-contract-surface-validator.js +426 -0
  325. package/lib/validation/openapi-contract-vendor-validation.js +238 -0
  326. package/lib/validation/validate-external-file.js +160 -0
  327. package/lib/validation/validate.js +6 -117
  328. package/package.json +46 -29
  329. package/packages/builder-api/README.md +120 -0
  330. package/packages/builder-api/package.json +30 -0
  331. package/packages/builder-api/src/app.module.ts +7 -0
  332. package/packages/builder-api/src/auth/auth.module.ts +5 -0
  333. package/packages/builder-api/src/external-system/external-system.module.ts +5 -0
  334. package/packages/builder-api/src/main.ts +16 -0
  335. package/packages/builder-api/tsconfig.json +15 -0
  336. package/scripts/check-builder-api-architecture-grep.js +79 -0
  337. package/scripts/docker_image_content_gate.js +47 -0
  338. package/scripts/docker_image_content_gate.sh +5 -0
  339. package/scripts/export-builder-api-evidence.js +262 -0
  340. package/scripts/lib/builder-api-docker-staging-copy.js +60 -0
  341. package/scripts/lib/builder-api-docker-staging-core.js +183 -0
  342. package/scripts/lib/docker-image-content-gate-core.js +166 -0
  343. package/scripts/lib/plan-actor.js +109 -0
  344. package/scripts/lib/plan-config.js +20 -0
  345. package/scripts/lib/plan-gates.js +154 -0
  346. package/scripts/lib/plan-meta.js +104 -0
  347. package/scripts/lib/plan-parse.js +162 -0
  348. package/scripts/lib/plan-prevalidate-gates.js +326 -0
  349. package/scripts/lib/plan-run-core.js +125 -0
  350. package/scripts/lib/plan-run-report.js +108 -0
  351. package/scripts/plan-approve.js +24 -0
  352. package/scripts/plan-archive.js +49 -0
  353. package/scripts/plan-run.js +13 -0
  354. package/scripts/plan-set-actor.js +21 -0
  355. package/scripts/plan-validate.js +80 -0
  356. package/scripts/pnpm/af.mjs +110 -0
  357. package/scripts/pnpm/check-quiet.mjs +32 -0
  358. package/scripts/pnpm/dev-install.mjs +29 -0
  359. package/scripts/pnpm/dev-reload.mjs +18 -0
  360. package/scripts/pnpm/help.mjs +55 -0
  361. package/scripts/pnpm/lib/dev-reload-core.mjs +189 -0
  362. package/scripts/pnpm/lib/dev-reload-log-capture.mjs +67 -0
  363. package/scripts/pnpm/lib/dev-reload-log-utils.mjs +32 -0
  364. package/scripts/pnpm/lib/resolve-aifabrix-bin.mjs +124 -0
  365. package/scripts/pnpm/lib/resolve-app-url.mjs +183 -0
  366. package/scripts/pnpm/lib/spinner.mjs +42 -0
  367. package/scripts/stage_builder_api_for_docker.js +65 -0
  368. package/scripts/sync-builder-api-template.js +44 -0
  369. package/templates/README.md +3 -0
  370. package/templates/applications/builder-api/Dockerfile +38 -0
  371. package/templates/applications/builder-api/application.yaml +75 -0
  372. package/templates/applications/builder-api/env.template +48 -0
  373. package/templates/applications/dataplane/application.yaml +1 -1
  374. package/templates/applications/dataplane/env.template +10 -6
  375. package/templates/applications/dataplane/rbac.yaml +21 -1
  376. package/templates/applications/miso-controller/application.yaml +1 -1
  377. package/templates/applications/miso-controller/env.template +1 -3
  378. package/templates/channels/README.md +18 -0
  379. package/templates/channels/ai-fabrix-icon.jpg +0 -0
  380. package/templates/channels/chatgpt/install.template.md.hbs +21 -24
  381. package/templates/channels/chatgpt/integration/README.md +11 -0
  382. package/templates/channels/chatgpt/integration/application.json +15 -0
  383. package/templates/channels/chatgpt/integration/chatgpt-system.json +29 -0
  384. package/templates/channels/chatgpt/integration/env.template +4 -0
  385. package/templates/channels/microsoft-copilot/install.template.md.hbs +20 -25
  386. package/templates/channels/microsoft-copilot/integration/README.md +11 -0
  387. package/templates/channels/microsoft-copilot/integration/application.json +15 -0
  388. package/templates/channels/microsoft-copilot/integration/env.template +6 -0
  389. package/templates/channels/microsoft-copilot/integration/microsoft-copilot-system.json +34 -0
  390. package/templates/channels/slack/install.template.md.hbs +48 -18
  391. package/templates/channels/slack/integration/README.md +38 -0
  392. package/templates/channels/slack/integration/application.json +18 -0
  393. package/templates/channels/slack/integration/env.template +29 -0
  394. package/templates/channels/slack/integration/slack-datasource-conversations.json +226 -0
  395. package/templates/channels/slack/integration/slack-datasource-messages.json +269 -0
  396. package/templates/channels/slack/integration/slack-system.json +86 -0
  397. package/templates/channels/slack/manifest.template.json.hbs +20 -10
  398. package/templates/channels/teams-bot/install.template.md.hbs +31 -17
  399. package/templates/channels/teams-bot/integration/README.md +18 -0
  400. package/templates/channels/teams-bot/integration/application.json +17 -0
  401. package/templates/channels/teams-bot/integration/env.template +5 -0
  402. package/templates/channels/teams-bot/integration/teams-bot-system.json +55 -0
  403. package/templates/channels/teams-bot/manifest.template.json.hbs +27 -0
  404. package/templates/channels/web-embed/install.template.md.hbs +16 -26
  405. package/templates/channels/web-embed/integration/README.md +11 -0
  406. package/templates/channels/web-embed/integration/application.json +15 -0
  407. package/templates/channels/web-embed/integration/env.template +4 -0
  408. package/templates/channels/web-embed/integration/web-embed-system.json +29 -0
  409. package/templates/openapi/redoc_page.html +86 -0
  410. package/templates/python/docker-compose.hbs +11 -0
  411. package/templates/python/requirements.txt +1 -1
  412. package/templates/typescript/docker-compose.hbs +11 -0
  413. package/lib/certification/cli-cert-sync-skip.js +0 -21
@@ -9,12 +9,21 @@
9
9
  'use strict';
10
10
 
11
11
  const { normalizeDatasourceKeysAndFilenames } = require('./repair-datasource-keys');
12
- const { resolveSystemContext } = require('./repair-system-alignment');
13
- const { persistChangesAndRegenerate, regenerateReadmeIfRequested } = require('./repair-persist');
12
+ const {
13
+ resolveSystemContext,
14
+ alignSystemFileDataSources,
15
+ ensureExternalIntegrationBlock
16
+ } = require('./repair-system-alignment');
17
+ const { persistChangesAndRegenerate, regenerateReadmeIfRequested, regenerateDeployScript } = require('./repair-persist');
14
18
  const { runRepairSteps } = require('./repair-steps');
15
19
  const { runDatasourceRepairs } = require('./repair-datasource-run');
20
+ const { repairSplitOrchestrationDatasources } = require('./repair-orchestration-datasource-split');
16
21
  const { maybeRepairRbac } = require('./repair-rbac');
22
+ const { collectCapabilityOpenApiDriftWarnings } = require('./repair-capability-openapi-warnings');
17
23
  const { maybeRunOpenApiSyncForMcp } = require('./repair-openapi-sync');
24
+ const { writeConfigFile } = require('../utils/config-format');
25
+ const { backupIntegrationFile } = require('../utils/integration-file-backup');
26
+ const { trackRepairWrite } = require('./repair-changed-files');
18
27
 
19
28
  /**
20
29
  * @param {Object} steps
@@ -95,25 +104,48 @@ function prepareRepairWorkspace(params) {
95
104
 
96
105
  /**
97
106
  * @param {Object} ws
98
- * @returns {Promise<Object>}
107
+ * @returns {boolean}
99
108
  */
100
- async function runRepairIntegrationFileSteps(ws) {
101
- const steps = runRepairSteps({
102
- appPath: ws.appPath,
103
- configPath: ws.configPath,
104
- variables: ws.variables,
105
- systemFilePath: ws.systemFilePath,
106
- systemParsed: ws.systemParsed,
107
- systemKey: ws.systemKey,
108
- systemFiles: ws.systemFiles,
109
- datasourceFiles: ws.datasourceFiles,
110
- dryRun: ws.dryRun,
111
- changes: ws.changes,
112
- warnings: ws.warnings,
113
- auth: ws.authOption,
114
- format: ws.rbacFmt,
115
- backupCtx: ws.backupCtx
116
- });
109
+ function reconcileManifestsAfterDatasourceSplit(ws) {
110
+ const dataSourcesAligned = alignSystemFileDataSources(
111
+ ws.appPath,
112
+ ws.systemParsed,
113
+ ws.datasourceFiles,
114
+ ws.systemKey,
115
+ ws.dryRun,
116
+ ws.changes
117
+ );
118
+ const extAligned = ensureExternalIntegrationBlock(
119
+ ws.variables,
120
+ ws.systemFiles,
121
+ ws.datasourceFiles,
122
+ ws.changes
123
+ );
124
+ if ((dataSourcesAligned || extAligned) && !ws.dryRun) {
125
+ backupIntegrationFile(ws.systemFilePath, ws.backupCtx);
126
+ writeConfigFile(ws.systemFilePath, ws.systemParsed);
127
+ trackRepairWrite(ws.systemFilePath, ws.backupCtx);
128
+ }
129
+ return dataSourcesAligned || extAligned;
130
+ }
131
+
132
+ /**
133
+ * @param {Object} ws
134
+ * @returns {Promise<{ datasourceRepairUpdated: boolean, openapiActionsPerformed: boolean }>}
135
+ */
136
+ async function runDatasourceOpenApiRepairs(ws) {
137
+ const splitResult = repairSplitOrchestrationDatasources(
138
+ ws.appPath,
139
+ ws.systemKey,
140
+ ws.datasourceFiles,
141
+ ws.options,
142
+ ws.dryRun,
143
+ ws.changes
144
+ );
145
+ if (splitResult.updated) {
146
+ ws.datasourceFiles = splitResult.datasourceFiles;
147
+ reconcileManifestsAfterDatasourceSplit(ws);
148
+ }
117
149
  const datasourceRepairUpdated = runDatasourceRepairs(
118
150
  ws.appPath,
119
151
  ws.datasourceFiles,
@@ -121,10 +153,12 @@ async function runRepairIntegrationFileSteps(ws) {
121
153
  expose: Boolean(ws.options.expose),
122
154
  sync: Boolean(ws.options.sync),
123
155
  test: Boolean(ws.options.test),
156
+ operations: Boolean(ws.options.operations) || Boolean(ws.options.rbac),
124
157
  backupCtx: ws.backupCtx
125
158
  },
126
159
  ws.dryRun,
127
- ws.changes
160
+ ws.changes,
161
+ { systemParsed: ws.systemParsed, warnings: ws.warnings }
128
162
  );
129
163
  const openapiActionsPerformed = await maybeRunOpenApiSyncForMcp({
130
164
  options: ws.options,
@@ -132,23 +166,68 @@ async function runRepairIntegrationFileSteps(ws) {
132
166
  appPath: ws.appPath,
133
167
  systemKey: ws.systemKey,
134
168
  datasourceFiles: ws.datasourceFiles,
135
- changes: ws.changes
169
+ changes: ws.changes,
170
+ backupCtx: ws.backupCtx
136
171
  });
137
- const { rbacMigratedFromSystem, rbacMergeUpdated } = maybeRepairRbac(
138
- ws.appPath,
139
- ws.systemFilePath,
140
- ws.systemParsed,
141
- ws.datasourceFiles,
142
- { rbac: Boolean(ws.options.rbac), rbacFmt: ws.rbacFmt, dryRun: ws.dryRun, changes: ws.changes, backupCtx: ws.backupCtx }
143
- );
172
+ return { datasourceRepairUpdated: datasourceRepairUpdated || splitResult.updated, openapiActionsPerformed };
173
+ }
174
+
175
+ /**
176
+ * @param {Object} ws
177
+ * @returns {Promise<Object>}
178
+ */
179
+ async function runRepairIntegrationFileSteps(ws) {
180
+ const steps = runRepairSteps({
181
+ appPath: ws.appPath,
182
+ configPath: ws.configPath,
183
+ variables: ws.variables,
184
+ systemFilePath: ws.systemFilePath,
185
+ systemParsed: ws.systemParsed,
186
+ systemKey: ws.systemKey,
187
+ systemFiles: ws.systemFiles,
188
+ datasourceFiles: ws.datasourceFiles,
189
+ dryRun: ws.dryRun,
190
+ changes: ws.changes,
191
+ warnings: ws.warnings,
192
+ auth: ws.authOption,
193
+ format: ws.rbacFmt,
194
+ backupCtx: ws.backupCtx,
195
+ options: ws.options
196
+ });
197
+ if (ws.options.rbac) {
198
+ collectCapabilityOpenApiDriftWarnings(ws.appPath, ws.datasourceFiles, ws.warnings);
199
+ }
200
+ const { datasourceRepairUpdated, openapiActionsPerformed } = await runDatasourceOpenApiRepairs(ws);
201
+ const { rbacMigratedFromSystem, rbacMergeUpdated, rbacSyncedIntoSystem, rbacSecurityBound } =
202
+ maybeRepairRbac(
203
+ ws.appPath,
204
+ ws.systemFilePath,
205
+ ws.systemParsed,
206
+ ws.datasourceFiles,
207
+ {
208
+ rbac: Boolean(ws.options.rbac),
209
+ rbacFmt: ws.rbacFmt,
210
+ rbacPreset: ws.options.rbacPreset,
211
+ dryRun: ws.dryRun,
212
+ changes: ws.changes,
213
+ backupCtx: ws.backupCtx
214
+ }
215
+ );
144
216
  const anyLocalUpdated =
145
- ws.keysNormalized || steps.updated || datasourceRepairUpdated || rbacMigratedFromSystem || rbacMergeUpdated;
217
+ ws.keysNormalized ||
218
+ steps.updated ||
219
+ datasourceRepairUpdated ||
220
+ rbacMigratedFromSystem ||
221
+ rbacMergeUpdated ||
222
+ rbacSyncedIntoSystem ||
223
+ rbacSecurityBound;
146
224
  return {
147
225
  steps,
148
226
  anyLocalUpdated,
149
227
  changes: ws.changes,
150
228
  warnings: ws.warnings,
151
229
  openapiActionsPerformed,
230
+ systemKey: ws.systemKey,
152
231
  systemFiles: ws.systemFiles,
153
232
  datasourceFiles: ws.datasourceFiles
154
233
  };
@@ -171,7 +250,8 @@ async function runRepairLocalUpdates(params) {
171
250
  async function finalizeRepairIntegration(params, local) {
172
251
  const { appName, options, appPath, configPath, dryRun, backupPaths, backupCtx, variables, originalYamlContent } =
173
252
  params;
174
- const { steps, anyLocalUpdated, changes, warnings, openapiActionsPerformed, systemFiles, datasourceFiles } = local;
253
+ const { steps, anyLocalUpdated, changes, warnings, openapiActionsPerformed, systemKey, systemFiles, datasourceFiles } =
254
+ local;
175
255
  let manifestRegenerated = false;
176
256
  if (anyLocalUpdated && !dryRun) {
177
257
  manifestRegenerated = await persistChangesAndRegenerate({
@@ -190,6 +270,16 @@ async function finalizeRepairIntegration(params, local) {
190
270
  { ...options, backupCtx },
191
271
  changes
192
272
  );
273
+ if (!dryRun) {
274
+ await regenerateDeployScript(
275
+ appPath,
276
+ systemKey || appName,
277
+ systemFiles,
278
+ datasourceFiles,
279
+ changes,
280
+ backupCtx
281
+ );
282
+ }
193
283
  const changedFiles = dryRun ? backupCtx.wouldChangeFiles : backupCtx.changedFiles;
194
284
  return buildRepairResult(steps, anyLocalUpdated, manifestRegenerated, readmeRegenerated, {
195
285
  actionsPerformed: openapiActionsPerformed,
@@ -9,7 +9,7 @@
9
9
  'use strict';
10
10
 
11
11
  const path = require('path');
12
- const fs = require('fs');
12
+ const fs = require('../internal/fs-real-sync');
13
13
  const chalk = require('chalk');
14
14
  const logger = require('../utils/logger');
15
15
 
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Export full programmatic OpenAPI (components + request/response schemas) for repair --api.
3
+ *
4
+ * @fileoverview Materialize integration/<systemKey>/openapi/*.json from buildOpenApiSpec
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const fs = require('../internal/fs-real-sync');
12
+ const path = require('path');
13
+ const { buildOpenApiSpec } = require('../programmatic/openapi-spec');
14
+ const { loadConfigFile } = require('../utils/config-format');
15
+ const { backupIntegrationFile } = require('../utils/integration-file-backup');
16
+ const { trackRepairWrite } = require('./repair-changed-files');
17
+
18
+ /**
19
+ * @param {string} appPath
20
+ * @param {string} systemKey
21
+ * @param {string} documentKey
22
+ * @returns {string}
23
+ */
24
+ function documentKeyToLocalOpenApiPath(appPath, systemKey, documentKey) {
25
+ const openapiDir = path.join(appPath, 'openapi');
26
+ const suffix = documentKey.startsWith(`${systemKey}-`)
27
+ ? documentKey.slice(systemKey.length + 1)
28
+ : documentKey;
29
+ return path.join(openapiDir, `${suffix}.json`);
30
+ }
31
+
32
+ /** @type {Set<string>} */
33
+ const PROGRAMMATIC_ORCHESTRATION_SYSTEM_KEYS = new Set(['aifabrix-builder-api']);
34
+
35
+ /**
36
+ * @param {string} systemKey
37
+ * @returns {boolean}
38
+ */
39
+ function isProgrammaticOrchestrationSystem(systemKey) {
40
+ return PROGRAMMATIC_ORCHESTRATION_SYSTEM_KEYS.has(String(systemKey || '').trim());
41
+ }
42
+
43
+ /**
44
+ * @param {string} appPath
45
+ * @param {string} fileName
46
+ * @returns {string|null}
47
+ */
48
+ function readDatasourceDocumentKey(appPath, fileName) {
49
+ const dsPath = path.join(appPath, fileName);
50
+ if (!fs.existsSync(dsPath)) {
51
+ return null;
52
+ }
53
+ const parsed = loadConfigFile(dsPath);
54
+ const openapi = parsed && typeof parsed.openapi === 'object' && !Array.isArray(parsed.openapi) ? parsed.openapi : null;
55
+ return openapi && typeof openapi.documentKey === 'string' ? openapi.documentKey.trim() : null;
56
+ }
57
+
58
+ /**
59
+ * @param {string} appPath
60
+ * @param {string[]} datasourceFiles
61
+ * @returns {string|null}
62
+ */
63
+ function resolveSharedDocumentKey(appPath, datasourceFiles) {
64
+ const keys = new Set();
65
+ for (const fileName of datasourceFiles || []) {
66
+ const dk = readDatasourceDocumentKey(appPath, fileName);
67
+ if (dk) {
68
+ keys.add(dk);
69
+ }
70
+ }
71
+ if (keys.size === 1) {
72
+ return [...keys][0];
73
+ }
74
+ return null;
75
+ }
76
+
77
+ /**
78
+ * @param {Object} spec
79
+ * @returns {boolean}
80
+ */
81
+ function specHasComponentSchemas(spec) {
82
+ const schemas = spec && spec.components && spec.components.schemas;
83
+ return Boolean(schemas && typeof schemas === 'object' && Object.keys(schemas).length > 0);
84
+ }
85
+
86
+ /**
87
+ * @param {string} localPath
88
+ * @param {Object} spec
89
+ * @param {boolean} dryRun
90
+ * @param {Object} backupCtx
91
+ * @returns {Promise<void>}
92
+ */
93
+ async function writeOpenApiSpecToDisk(localPath, spec, dryRun, backupCtx) {
94
+ if (dryRun) {
95
+ return;
96
+ }
97
+ const openapiDir = path.dirname(localPath);
98
+ fs.mkdirSync(openapiDir, { recursive: true });
99
+ if (fs.existsSync(localPath)) {
100
+ backupIntegrationFile(localPath, backupCtx);
101
+ }
102
+ fs.writeFileSync(localPath, `${JSON.stringify(spec, null, 2)}\n`, 'utf8');
103
+ trackRepairWrite(localPath, backupCtx);
104
+ }
105
+
106
+ /**
107
+ * @param {string} localPath
108
+ * @param {Object} spec
109
+ * @returns {string}
110
+ */
111
+ function formatOpenApiExportSummary(localPath, spec) {
112
+ const rel = path.relative(process.cwd(), localPath);
113
+ return (
114
+ `Exported full OpenAPI (${Object.keys(spec.paths || {}).length} paths, `
115
+ + `${Object.keys(spec.components.schemas || {}).length} schemas) to ${rel}`
116
+ );
117
+ }
118
+
119
+ /**
120
+ * @param {Object} opts
121
+ * @param {string} opts.appPath
122
+ * @param {string} opts.systemKey
123
+ * @param {string[]} opts.datasourceFiles
124
+ * @param {boolean} opts.dryRun
125
+ * @param {Object} opts.backupCtx
126
+ * @returns {Promise<string[]>}
127
+ */
128
+ async function exportProgrammaticOpenApiForRepair(opts) {
129
+ const { appPath, systemKey, datasourceFiles, dryRun, backupCtx } = opts;
130
+ const lines = [];
131
+ if (!isProgrammaticOrchestrationSystem(systemKey)) {
132
+ return lines;
133
+ }
134
+ const documentKey = resolveSharedDocumentKey(appPath, datasourceFiles);
135
+ if (!documentKey) {
136
+ lines.push('Skipped OpenAPI export: datasources do not share a single openapi.documentKey');
137
+ return lines;
138
+ }
139
+ const localPath = documentKeyToLocalOpenApiPath(appPath, systemKey, documentKey);
140
+ const spec = buildOpenApiSpec();
141
+ if (!specHasComponentSchemas(spec)) {
142
+ lines.push('Skipped OpenAPI export: programmatic buildOpenApiSpec() has no component schemas');
143
+ return lines;
144
+ }
145
+ await writeOpenApiSpecToDisk(localPath, spec, dryRun, backupCtx);
146
+ lines.push(formatOpenApiExportSummary(localPath, spec));
147
+ return lines;
148
+ }
149
+
150
+ module.exports = {
151
+ documentKeyToLocalOpenApiPath,
152
+ exportProgrammaticOpenApiForRepair,
153
+ isProgrammaticOrchestrationSystem,
154
+ resolveSharedDocumentKey,
155
+ specHasComponentSchemas
156
+ };
@@ -24,6 +24,7 @@ const { resolveDataplaneUrl } = require('../utils/dataplane-resolver');
24
24
  const { uploadFileAs } = require('../utils/file-upload');
25
25
  const { listOpenAPIFiles } = require('../api/external-systems.api');
26
26
  const { resolveLabDataplaneApiKey } = require('../utils/credential-secrets-env');
27
+ const { exportProgrammaticOpenApiForRepair } = require('./repair-openapi-export');
27
28
 
28
29
  async function fileExistsAsync(filePath) {
29
30
  try {
@@ -190,9 +191,25 @@ async function maybeSyncOpenApiFilesForMcp(opts) {
190
191
  * @param {Object} args
191
192
  * @returns {Promise<boolean>}
192
193
  */
193
- async function maybeRunOpenApiSyncForMcp({ options, dryRun, appPath, systemKey, datasourceFiles, changes }) {
194
+ async function maybeRunOpenApiSyncForMcp({
195
+ options,
196
+ dryRun,
197
+ appPath,
198
+ systemKey,
199
+ datasourceFiles,
200
+ changes,
201
+ backupCtx
202
+ }) {
194
203
  if (!options.api) return false;
195
204
  try {
205
+ const exportLines = await exportProgrammaticOpenApiForRepair({
206
+ appPath,
207
+ systemKey,
208
+ datasourceFiles,
209
+ dryRun,
210
+ backupCtx
211
+ });
212
+ exportLines.forEach((line) => changes.push(line));
196
213
  const openapiLines = await maybeSyncOpenApiFilesForMcp({
197
214
  enabled: true,
198
215
  dryRun,
@@ -201,7 +218,7 @@ async function maybeRunOpenApiSyncForMcp({ options, dryRun, appPath, systemKey,
201
218
  datasourceFiles
202
219
  });
203
220
  openapiLines.forEach((l) => changes.push(l));
204
- return openapiLines.length > 0;
221
+ return exportLines.length > 0 || openapiLines.length > 0;
205
222
  } catch (err) {
206
223
  changes.push(`OpenAPI upload for MCP failed: ${err.message}`);
207
224
  return false;
@@ -0,0 +1,259 @@
1
+ /**
2
+ * Split monolithic orchestration datasource into per-OpenAPI-tag datasources (plan 154.7).
3
+ *
4
+ * @fileoverview repair-orchestration-datasource-split
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const fs = require('fs');
12
+ const path = require('path');
13
+ const { CAPABILITIES } = require('../programmatic/capability-registry');
14
+ const { buildOperationXAfabrix, resolveTagCatalogEntry } = require('../programmatic/orchestration-openapi-meta');
15
+ const { loadConfigFile, writeConfigFile } = require('../utils/config-format');
16
+ const { backupIntegrationFile } = require('../utils/integration-file-backup');
17
+ const { trackRepairWrite } = require('./repair-changed-files');
18
+
19
+ /**
20
+ * @returns {Map<string, string>}
21
+ */
22
+ function buildHandlerIdToTagMap() {
23
+ /** @type {Map<string, string>} */
24
+ const map = new Map();
25
+ for (const capability of CAPABILITIES) {
26
+ map.set(capability.handlerId, buildOperationXAfabrix(capability).datasourceTag);
27
+ }
28
+ return map;
29
+ }
30
+
31
+ /**
32
+ * @param {Object} parsed
33
+ * @param {Map<string, string>} handlerToTag
34
+ * @returns {Map<string, string>}
35
+ */
36
+ function buildManifestKeyToTagMap(parsed, handlerToTag) {
37
+ /** @type {Map<string, string>} */
38
+ const keyToTag = new Map();
39
+ const ops = parsed?.openapi?.operations;
40
+ if (!ops || typeof ops !== 'object') {
41
+ return keyToTag;
42
+ }
43
+ for (const [manifestKey, entry] of Object.entries(ops)) {
44
+ if (!entry || typeof entry !== 'object') {
45
+ continue;
46
+ }
47
+ const opId = entry.operationId;
48
+ const tag = typeof opId === 'string' ? handlerToTag.get(opId) : undefined;
49
+ if (tag) {
50
+ keyToTag.set(manifestKey, tag);
51
+ keyToTag.set(manifestKey.toLowerCase(), tag);
52
+ }
53
+ }
54
+ return keyToTag;
55
+ }
56
+
57
+ /**
58
+ * @param {Object|undefined} block
59
+ * @param {Set<string>} keys
60
+ * @returns {Object}
61
+ */
62
+ function pickOperationMap(block, keys) {
63
+ if (!block || typeof block !== 'object') {
64
+ return {};
65
+ }
66
+ /** @type {Object} */
67
+ const picked = {};
68
+ for (const [opKey, value] of Object.entries(block)) {
69
+ const normalized = String(opKey).toLowerCase();
70
+ if (keys.has(opKey) || keys.has(normalized)) {
71
+ picked[opKey] = value;
72
+ }
73
+ }
74
+ return picked;
75
+ }
76
+
77
+ /**
78
+ * @param {Object} parsed
79
+ * @param {string} tag
80
+ * @param {Set<string>} keys
81
+ * @param {string} systemKey
82
+ * @returns {Object}
83
+ */
84
+ function buildTagDatasource(parsed, tag, keys, systemKey) {
85
+ const catalog = resolveTagCatalogEntry(tag);
86
+ const key = `${systemKey}-${tag}`;
87
+ const capabilities = Array.isArray(parsed.capabilities)
88
+ ? parsed.capabilities.filter((row) => {
89
+ if (!row || !row.key) {
90
+ return false;
91
+ }
92
+ const rowKey = String(row.key).toLowerCase();
93
+ return [...keys].some((key) => String(key).toLowerCase() === rowKey);
94
+ })
95
+ : [];
96
+ const openapiOps = pickOperationMap(parsed.openapi?.operations, keys);
97
+ const cipOps = pickOperationMap(parsed.execution?.cip?.operations, keys);
98
+ const mcpTools = pickOperationMap(parsed.mcpContract?.tools, keys);
99
+ return {
100
+ ...parsed,
101
+ key,
102
+ displayName: `${catalog.displayName} operations`,
103
+ resourceType: catalog.resourceType,
104
+ description: `${catalog.displayName} operations from ${systemKey} via orchestration-api`,
105
+ capabilities,
106
+ openapi: {
107
+ ...(parsed.openapi || {}),
108
+ operations: openapiOps
109
+ },
110
+ execution: {
111
+ ...(parsed.execution || {}),
112
+ cip: {
113
+ ...(parsed.execution?.cip || {}),
114
+ operations: cipOps
115
+ }
116
+ },
117
+ mcpContract: parsed.mcpContract
118
+ ? {
119
+ ...parsed.mcpContract,
120
+ tools: mcpTools
121
+ }
122
+ : parsed.mcpContract
123
+ };
124
+ }
125
+
126
+ /**
127
+ * @param {string} fileName
128
+ * @returns {boolean}
129
+ */
130
+ function isMonolithicOperationsDatasource(fileName) {
131
+ return /-datasource-operations\.(json|ya?ml)$/i.test(fileName);
132
+ }
133
+
134
+ /**
135
+ * @param {Map<string, string>} keyToTag
136
+ * @returns {Map<string, Set<string>>}
137
+ */
138
+ function groupManifestKeysByTag(keyToTag) {
139
+ /** @type {Map<string, Set<string>>} */
140
+ const tagBuckets = new Map();
141
+ for (const [manifestKey, tag] of keyToTag.entries()) {
142
+ const bucket = tagBuckets.get(tag) || new Set();
143
+ bucket.add(manifestKey);
144
+ tagBuckets.set(tag, bucket);
145
+ }
146
+ return tagBuckets;
147
+ }
148
+
149
+ /**
150
+ * @param {string} appPath
151
+ * @param {string} monolithFile
152
+ * @returns {{ monolithPath: string, parsed: Object, tagBuckets: Map<string, Set<string>> }|null}
153
+ */
154
+ function loadMonolithSplitContext(appPath, monolithFile) {
155
+ const monolithPath = path.join(appPath, monolithFile);
156
+ if (!fs.existsSync(monolithPath)) {
157
+ return null;
158
+ }
159
+ const parsed = loadConfigFile(monolithPath);
160
+ const keyToTag = buildManifestKeyToTagMap(parsed, buildHandlerIdToTagMap());
161
+ if (keyToTag.size === 0) {
162
+ return null;
163
+ }
164
+ const tagBuckets = groupManifestKeysByTag(keyToTag);
165
+ if (tagBuckets.size <= 1) {
166
+ return null;
167
+ }
168
+ return { monolithPath, parsed, tagBuckets };
169
+ }
170
+
171
+ /**
172
+ * @param {Object} params
173
+ * @returns {string[]}
174
+ */
175
+ function writeSplitTagDatasources(params) {
176
+ const { appPath, systemKey, monolithFile, parsed, tagBuckets, options, dryRun, changes } = params;
177
+ const newFiles = [];
178
+ for (const [tag, keys] of [...tagBuckets.entries()].sort(([a], [b]) => a.localeCompare(b))) {
179
+ const fileName = `${systemKey}-datasource-${tag}.json`;
180
+ newFiles.push(fileName);
181
+ changes.push(`Split ${monolithFile} → ${fileName} (${keys.size} operations)`);
182
+ if (dryRun) {
183
+ continue;
184
+ }
185
+ const outPath = path.join(appPath, fileName);
186
+ backupIntegrationFile(outPath, options.backupCtx);
187
+ writeConfigFile(outPath, buildTagDatasource(parsed, tag, keys, systemKey));
188
+ trackRepairWrite(outPath, options.backupCtx);
189
+ }
190
+ return newFiles;
191
+ }
192
+
193
+ /**
194
+ * @param {Object} params
195
+ */
196
+ function removeMonolithDatasource(params) {
197
+ const { monolithPath, monolithFile, options, dryRun, changes } = params;
198
+ changes.push(`Remove monolithic datasource ${monolithFile}`);
199
+ if (dryRun) {
200
+ return;
201
+ }
202
+ backupIntegrationFile(monolithPath, options.backupCtx);
203
+ fs.unlinkSync(monolithPath);
204
+ trackRepairWrite(monolithPath, options.backupCtx);
205
+ }
206
+
207
+ /**
208
+ * @param {string} appPath
209
+ * @param {string} systemKey
210
+ * @param {string[]} datasourceFiles
211
+ * @param {Object} options
212
+ * @param {boolean} dryRun
213
+ * @param {string[]} changes
214
+ * @returns {{ updated: boolean, datasourceFiles: string[] }}
215
+ */
216
+ function repairSplitOrchestrationDatasources(
217
+ appPath,
218
+ systemKey,
219
+ datasourceFiles,
220
+ options,
221
+ dryRun,
222
+ changes
223
+ ) {
224
+ if (!options.splitDatasources) {
225
+ return { updated: false, datasourceFiles };
226
+ }
227
+ const monolithFile = datasourceFiles.find(isMonolithicOperationsDatasource);
228
+ if (!monolithFile) {
229
+ return { updated: false, datasourceFiles };
230
+ }
231
+ const splitCtx = loadMonolithSplitContext(appPath, monolithFile);
232
+ if (!splitCtx) {
233
+ return { updated: false, datasourceFiles };
234
+ }
235
+ const newFiles = writeSplitTagDatasources({
236
+ appPath,
237
+ systemKey,
238
+ monolithFile,
239
+ parsed: splitCtx.parsed,
240
+ tagBuckets: splitCtx.tagBuckets,
241
+ options,
242
+ dryRun,
243
+ changes
244
+ });
245
+ removeMonolithDatasource({
246
+ monolithPath: splitCtx.monolithPath,
247
+ monolithFile,
248
+ options,
249
+ dryRun,
250
+ changes
251
+ });
252
+ const remaining = datasourceFiles.filter((f) => f !== monolithFile).concat(newFiles);
253
+ return { updated: true, datasourceFiles: remaining };
254
+ }
255
+
256
+ module.exports = {
257
+ repairSplitOrchestrationDatasources,
258
+ isMonolithicOperationsDatasource
259
+ };