@aifabrix/builder 2.49.2 → 2.51.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (459) hide show
  1. package/.cursor/plans/157.1-security-quality-violations-by-type.csv +374 -0
  2. package/.cursor/rules/assistant-driven-integration-build.mdc +40 -0
  3. package/.cursor/rules/deploy-rules/docker-image-ip-policy.mdc +49 -0
  4. package/.cursor/rules/plan-rules/application-lifecycle.mdc +30 -0
  5. package/.cursor/rules/plan-rules/plan-frontmatter.mdc +35 -0
  6. package/.cursor/rules/plan-rules/plan-lifecycle.mdc +31 -0
  7. package/.cursor/rules/plan-rules/plan-validation-gate.mdc +34 -0
  8. package/.cursor/skills/README.md +1 -0
  9. package/.dockerignore +52 -0
  10. package/.eslintignore +22 -0
  11. package/README.md +2 -0
  12. package/bin/builder-api-cleanup.js +26 -0
  13. package/bin/builder-api-nest.js +10 -0
  14. package/bin/builder-api-spike.js +19 -0
  15. package/enterprise-knowledge/README.md +50 -0
  16. package/enterprise-knowledge/enterprise-integration-lifecycle/README.md +22 -0
  17. package/enterprise-knowledge/enterprise-integration-lifecycle/application.json +15 -0
  18. package/enterprise-knowledge/enterprise-integration-lifecycle/deploy.js +69 -0
  19. package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-deploy.json +52 -0
  20. package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-system.json +29 -0
  21. package/enterprise-knowledge/enterprise-integration-lifecycle/env.template +2 -0
  22. package/integration/README.md +81 -0
  23. package/integration/github/README.md +53 -0
  24. package/integration/github/application.json +21 -0
  25. package/integration/github/deploy.js +72 -0
  26. package/integration/github/env.template +11 -0
  27. package/integration/github/github-datasource-issue-comments.json +239 -0
  28. package/integration/github/github-datasource-issues.json +399 -0
  29. package/integration/github/github-datasource-repository.json +354 -0
  30. package/integration/github/github-deploy.json +1202 -0
  31. package/integration/github/github-system.json +82 -0
  32. package/integration/hubspot-test/README.md +1 -1
  33. package/integration/hubspot-test/create-hubspot.js +1 -16
  34. package/jest.isolated-projects.js +31 -1
  35. package/jest.projects.js +87 -1
  36. package/lib/api/dev-server-https.js +1 -1
  37. package/lib/api/enterprise-knowledge.api.js +63 -0
  38. package/lib/api/evidence-kinds.api.js +128 -0
  39. package/lib/api/evidence.api.js +172 -0
  40. package/lib/api/external-systems.api.js +8 -2
  41. package/lib/api/pipeline.api.js +5 -1
  42. package/lib/api/resource-types.api.js +5 -4
  43. package/lib/api/roles.api.js +121 -0
  44. package/lib/api/types/enterprise-knowledge.types.js +46 -0
  45. package/lib/api/types/evidence-kinds.types.js +42 -0
  46. package/lib/api/types/evidence.types.js +67 -0
  47. package/lib/api/types/resource-types.types.js +2 -0
  48. package/lib/api/types/roles.types.js +36 -0
  49. package/lib/app/certification-verify-rows.js +1 -1
  50. package/lib/app/controller-application-filter.js +36 -0
  51. package/lib/app/deploy.js +1 -1
  52. package/lib/app/list-external-systems.js +130 -0
  53. package/lib/app/list.js +20 -8
  54. package/lib/app/run.js +3 -1
  55. package/lib/app/show-display.js +8 -3
  56. package/lib/app/show-online.js +178 -0
  57. package/lib/app/show.js +39 -90
  58. package/lib/build/builder-api-docker-staging.js +47 -0
  59. package/lib/build/miso-controller-npm-sdk-guard.js +2 -2
  60. package/lib/build/standard-docker-build.js +2 -0
  61. package/lib/certification/merge-certification-from-artifact.js +1 -1
  62. package/lib/certification/post-unified-cert-sync.js +4 -31
  63. package/lib/certification/sync-after-external-command.js +0 -1
  64. package/lib/certification/sync-system-certification.js +0 -3
  65. package/lib/channels/add-channel.js +40 -34
  66. package/lib/channels/approval-guides/chatgpt.js +33 -0
  67. package/lib/channels/approval-guides/credential-portal.js +38 -0
  68. package/lib/channels/approval-guides/index.js +110 -0
  69. package/lib/channels/approval-guides/microsoft-copilot.js +34 -0
  70. package/lib/channels/approval-guides/slack.js +34 -0
  71. package/lib/channels/approval-guides/teams-bot.js +35 -0
  72. package/lib/channels/approval-guides/web-embed.js +32 -0
  73. package/lib/channels/channel-approval-guide.js +11 -0
  74. package/lib/channels/channel-artifact-generator.js +18 -5
  75. package/lib/channels/channel-audit.js +3 -0
  76. package/lib/channels/channel-auth-context.js +1 -1
  77. package/lib/channels/channel-description.js +59 -0
  78. package/lib/channels/channel-integration-generator.js +13 -230
  79. package/lib/channels/channel-integration-template.js +94 -0
  80. package/lib/channels/channel-runtime-resolver.js +43 -3
  81. package/lib/channels/channel-status-display.js +66 -26
  82. package/lib/channels/channel-targets.js +3 -3
  83. package/lib/cli/index.js +31 -3
  84. package/lib/cli/infra-guided.js +5 -1
  85. package/lib/cli/setup-app-external-create.js +111 -0
  86. package/lib/cli/setup-app.help.js +1 -1
  87. package/lib/cli/setup-app.js +60 -130
  88. package/lib/cli/setup-app.test-commands.js +26 -52
  89. package/lib/cli/setup-certification-commands.js +4 -4
  90. package/lib/cli/setup-certification.help.js +9 -9
  91. package/lib/cli/setup-dev.js +30 -9
  92. package/lib/cli/setup-external-system-help.js +4 -6
  93. package/lib/cli/setup-external-system.js +58 -52
  94. package/lib/cli/setup-infra-up-builder-api-action.js +64 -0
  95. package/lib/cli/setup-infra-up-platform-action.js +3 -1
  96. package/lib/cli/setup-infra.js +15 -0
  97. package/lib/cli/setup-list.js +43 -0
  98. package/lib/cli/setup-utility-help-after.js +12 -0
  99. package/lib/cli/setup-utility-repair.js +26 -7
  100. package/lib/cli/setup-utility-validate.js +41 -2
  101. package/lib/cli/setup-utility.js +5 -3
  102. package/lib/commands/app.js +15 -43
  103. package/lib/commands/channel-add-setup.js +110 -0
  104. package/lib/commands/channel.js +42 -8
  105. package/lib/commands/datasource-sync-display.js +96 -0
  106. package/lib/commands/datasource-sync-policy.js +210 -0
  107. package/lib/commands/datasource-test-trust-cli.js +6 -6
  108. package/lib/commands/datasource-unified-test-cli.js +2 -1
  109. package/lib/commands/datasource-unified-test-cli.options.js +33 -23
  110. package/lib/commands/deploy-gate-failure-details.js +184 -0
  111. package/lib/commands/deploy-gate-orchestrator.js +368 -0
  112. package/lib/commands/dev-cli-handlers.js +7 -62
  113. package/lib/commands/dev-host-ops-params.js +91 -0
  114. package/lib/commands/dev-host-ops-poll.js +111 -0
  115. package/lib/commands/dev-host-ops.js +107 -94
  116. package/lib/commands/dev-init.js +6 -106
  117. package/lib/commands/dev-refresh.js +197 -0
  118. package/lib/commands/enterprise-knowledge.js +284 -0
  119. package/lib/commands/evidence-cli-leaves.js +250 -0
  120. package/lib/commands/evidence-kind.js +428 -0
  121. package/lib/commands/evidence.js +51 -0
  122. package/lib/commands/governance-cli-shared.js +2 -2
  123. package/lib/commands/governance-command-action.js +5 -3
  124. package/lib/commands/governance-fixture-subjects.js +85 -0
  125. package/lib/commands/governance.js +1 -1
  126. package/lib/commands/lifecycle-command-action.js +2 -2
  127. package/lib/commands/lifecycle-external.js +3 -3
  128. package/lib/commands/manifest-cli-auth.js +29 -0
  129. package/lib/commands/manifest-cli-commands.js +170 -0
  130. package/lib/commands/manifest-cli-integration-path.js +63 -0
  131. package/lib/commands/manifest.js +21 -0
  132. package/lib/commands/protection-cli-leaves.js +3 -3
  133. package/lib/commands/repair-auth-apply.js +15 -1
  134. package/lib/commands/repair-authentications-454.js +169 -0
  135. package/lib/commands/repair-capability-openapi-warnings.js +126 -0
  136. package/lib/commands/repair-datasource-apply.js +135 -0
  137. package/lib/commands/repair-datasource-auto-rbac.js +62 -1
  138. package/lib/commands/repair-datasource-http-service-contract.js +239 -0
  139. package/lib/commands/repair-datasource-operation-security.js +180 -0
  140. package/lib/commands/repair-datasource-run.js +7 -2
  141. package/lib/commands/repair-datasource-sync-operations.js +177 -0
  142. package/lib/commands/repair-datasource-webhooks-sync-bridge.js +133 -0
  143. package/lib/commands/repair-datasource.js +12 -68
  144. package/lib/commands/repair-env-template.js +11 -1
  145. package/lib/commands/repair-external-run.js +121 -31
  146. package/lib/commands/repair-internal.js +1 -1
  147. package/lib/commands/repair-openapi-export.js +156 -0
  148. package/lib/commands/repair-openapi-sync.js +33 -8
  149. package/lib/commands/repair-orchestration-datasource-split.js +259 -0
  150. package/lib/commands/repair-persist.js +22 -1
  151. package/lib/commands/repair-rbac-platform-preset.js +204 -0
  152. package/lib/commands/repair-rbac-reader-roles.js +191 -0
  153. package/lib/commands/repair-rbac.js +163 -86
  154. package/lib/commands/repair-steps.js +83 -18
  155. package/lib/commands/repair-system-permissions.js +1 -0
  156. package/lib/commands/repair.js +1 -1
  157. package/lib/commands/resource-type.js +166 -44
  158. package/lib/commands/role.js +452 -0
  159. package/lib/commands/run-post-publish-data-sync.js +68 -0
  160. package/lib/commands/setup-modes.js +1 -1
  161. package/lib/commands/setup.js +1 -1
  162. package/lib/commands/test-e2e-external.js +21 -8
  163. package/lib/commands/test-governance-cli-options.js +2 -2
  164. package/lib/commands/test-trust-cli-options.js +2 -2
  165. package/lib/commands/up-builder-api-bootstrap.js +71 -0
  166. package/lib/commands/up-builder-api-provision.js +241 -0
  167. package/lib/commands/up-builder-api.js +88 -0
  168. package/lib/commands/up-common.js +25 -1
  169. package/lib/commands/upload-credential-push-log.js +117 -0
  170. package/lib/commands/upload-data-sync-finalize.js +60 -0
  171. package/lib/commands/upload-probe.js +66 -0
  172. package/lib/commands/upload-publish-context.js +4 -1
  173. package/lib/commands/upload-sidecar-followups.js +55 -27
  174. package/lib/commands/upload.js +116 -157
  175. package/lib/commands/validate-json.js +230 -0
  176. package/lib/commands/verify-governance-combined-external.js +1 -1
  177. package/lib/commands/verify-governance-db.js +2 -2
  178. package/lib/commands/verify-operations-command-action.js +2 -2
  179. package/lib/commands/verify-operations-step-plan.js +79 -41
  180. package/lib/commands/verify-operations-steps.js +2 -2
  181. package/lib/commands/verify-trust-command-action.js +1 -1
  182. package/lib/commands/wizard-core.js +1 -1
  183. package/lib/commands/wizard-headless.js +2 -1
  184. package/lib/core/admin-secrets.js +2 -6
  185. package/lib/core/audit-logger.js +1 -1
  186. package/lib/core/secrets-env-content.js +10 -4
  187. package/lib/core/secrets-env-write.js +2 -13
  188. package/lib/core/secrets-load.js +1 -3
  189. package/lib/datasource/agent-trust-run.js +3 -3
  190. package/lib/datasource/capability/relate-operations.js +1 -1
  191. package/lib/datasource/deploy.js +3 -1
  192. package/lib/datasource/test-e2e.js +6 -1
  193. package/lib/datasource/unified-validation-run-body.js +4 -1
  194. package/lib/datasource/unified-validation-run.js +1 -1
  195. package/lib/deployment/deploy-poll-ui.js +73 -12
  196. package/lib/deployment/deployer-poll-run.js +113 -0
  197. package/lib/deployment/deployer.js +17 -87
  198. package/lib/evidence/dataplane-context.js +21 -0
  199. package/lib/evidence/evidence-display.js +78 -0
  200. package/lib/evidence/evidence-service.js +392 -0
  201. package/lib/external-system/deploy.js +290 -112
  202. package/lib/external-system/download.js +7 -3
  203. package/lib/external-system/test-execution.js +1 -1
  204. package/lib/external-system/test-system-level.js +8 -10
  205. package/lib/external-system/test.js +12 -6
  206. package/lib/generator/deploy-script.js +73 -0
  207. package/lib/generator/external.js +2 -1
  208. package/lib/generator/helpers.js +13 -5
  209. package/lib/generator/index.js +17 -2
  210. package/lib/generator/split-variables.js +9 -3
  211. package/lib/generator/wizard.js +3 -36
  212. package/lib/infrastructure/helpers-docker-check.js +6 -0
  213. package/lib/infrastructure/helpers.js +1 -1
  214. package/lib/internal/fs-real-sync.js +22 -1
  215. package/lib/internal/node-fs.js +2 -0
  216. package/lib/lifecycle/lifecycle-governance-options.js +1 -1
  217. package/lib/lifecycle/verify-step-progress.js +1 -1
  218. package/lib/programmatic/access-log.js +26 -0
  219. package/lib/programmatic/auth-config.js +45 -0
  220. package/lib/programmatic/bearer-auth.js +176 -0
  221. package/lib/programmatic/builder-api-request.js +175 -0
  222. package/lib/programmatic/builder-api-route-dispatch.js +82 -0
  223. package/lib/programmatic/builder-api-runtime-config.js +42 -0
  224. package/lib/programmatic/builder-api-server.js +230 -0
  225. package/lib/programmatic/builder-help-authentication-catalog.js +282 -0
  226. package/lib/programmatic/builder-help-connected-system-ui.js +266 -0
  227. package/lib/programmatic/builder-help-enterprise-sync-fabrix.js +60 -0
  228. package/lib/programmatic/builder-help-envelope.js +36 -0
  229. package/lib/programmatic/builder-help-fixtures.js +200 -0
  230. package/lib/programmatic/builder-help-governance.js +172 -0
  231. package/lib/programmatic/builder-help-schema-catalog.js +92 -0
  232. package/lib/programmatic/builder-help.js +361 -0
  233. package/lib/programmatic/capability-registry.js +77 -0
  234. package/lib/programmatic/command-options.js +32 -0
  235. package/lib/programmatic/enterprise-mcp-client.js +114 -0
  236. package/lib/programmatic/http-problem-details.js +99 -0
  237. package/lib/programmatic/http-route-match.js +40 -0
  238. package/lib/programmatic/idempotency-cache.js +69 -0
  239. package/lib/programmatic/index.js +53 -0
  240. package/lib/programmatic/integration-path-scope.js +39 -0
  241. package/lib/programmatic/log-redaction.js +66 -0
  242. package/lib/programmatic/manifest-get-section.js +146 -0
  243. package/lib/programmatic/manifest-patch-section.js +252 -0
  244. package/lib/programmatic/manifest-repair.js +122 -0
  245. package/lib/programmatic/manifest-section-dependency-graph.js +160 -0
  246. package/lib/programmatic/manifest-section-io.js +225 -0
  247. package/lib/programmatic/manifest-section-quality.js +171 -0
  248. package/lib/programmatic/manifest-section-registry-data.js +269 -0
  249. package/lib/programmatic/manifest-section-registry.js +222 -0
  250. package/lib/programmatic/nest-http-bridge.js +34 -0
  251. package/lib/programmatic/openapi-component-schemas.js +68 -0
  252. package/lib/programmatic/openapi-description-enricher.js +117 -0
  253. package/lib/programmatic/openapi-descriptions.js +190 -0
  254. package/lib/programmatic/openapi-docs-serving.js +123 -0
  255. package/lib/programmatic/openapi-help-schemas.js +63 -0
  256. package/lib/programmatic/openapi-manifest-schemas.js +141 -0
  257. package/lib/programmatic/openapi-operation-bindings.js +274 -0
  258. package/lib/programmatic/openapi-request-schemas.js +155 -0
  259. package/lib/programmatic/openapi-result-schemas.js +493 -0
  260. package/lib/programmatic/openapi-schema-descriptions-certify.js +139 -0
  261. package/lib/programmatic/openapi-schema-descriptions-core.js +162 -0
  262. package/lib/programmatic/openapi-schema-descriptions-help.js +40 -0
  263. package/lib/programmatic/openapi-schema-descriptions-manifest.js +143 -0
  264. package/lib/programmatic/openapi-schema-descriptions-mcp.js +118 -0
  265. package/lib/programmatic/openapi-schema-descriptions-operations.js +281 -0
  266. package/lib/programmatic/openapi-schema-helpers.js +108 -0
  267. package/lib/programmatic/openapi-spec.js +203 -0
  268. package/lib/programmatic/orchestration-openapi-meta.js +159 -0
  269. package/lib/programmatic/platform-rbac-catalog.js +90 -0
  270. package/lib/programmatic/request-timeout.js +53 -0
  271. package/lib/programmatic/route-handler-map.js +143 -0
  272. package/lib/programmatic/route-handlers-context.js +29 -0
  273. package/lib/programmatic/route-handlers.js +33 -0
  274. package/lib/programmatic/run-certify.js +57 -0
  275. package/lib/programmatic/run-enterprise-mcp.js +32 -0
  276. package/lib/programmatic/run-lifecycle.js +29 -0
  277. package/lib/programmatic/run-repair.js +41 -0
  278. package/lib/programmatic/run-repository-emcp.js +62 -0
  279. package/lib/programmatic/run-template-workspace.js +74 -0
  280. package/lib/programmatic/run-test.js +49 -0
  281. package/lib/programmatic/run-upload.js +63 -0
  282. package/lib/programmatic/run-validate.js +53 -0
  283. package/lib/programmatic/run-wizard.js +40 -0
  284. package/lib/programmatic/system-key.js +48 -0
  285. package/lib/programmatic/wizard-config-normalize.js +118 -0
  286. package/lib/programmatic/workspace-cleanup.js +128 -0
  287. package/lib/programmatic/workspace-context.js +145 -0
  288. package/lib/programmatic/workspace-lock.js +75 -0
  289. package/lib/programmatic/workspace-meta.js +64 -0
  290. package/lib/programmatic/workspace-ops.js +149 -0
  291. package/lib/protection/run-commands-upload-sync.js +35 -0
  292. package/lib/protection/run-commands.js +2 -20
  293. package/lib/protection/upload-batch.js +11 -7
  294. package/lib/resolvers/evidence-kind-file.js +230 -0
  295. package/lib/resolvers/resource-type-file.js +58 -1
  296. package/lib/resolvers/role-file.js +227 -0
  297. package/lib/schema/application-schema.json +22 -2
  298. package/lib/schema/external-datasource.schema.json +245 -2
  299. package/lib/schema/external-system.schema.json +259 -119
  300. package/lib/schema/flag-map-validation-run.json +3 -0
  301. package/lib/schema/infra.parameter.yaml +25 -1
  302. package/lib/schema/type/credential-field-registry.json +21 -5
  303. package/lib/schema/type/document-storage.json +9 -0
  304. package/lib/utils/agent-trust-run-display.js +1 -1
  305. package/lib/utils/api.js +8 -2
  306. package/lib/utils/app-path-resolve.js +168 -0
  307. package/lib/utils/app-register-config.js +4 -3
  308. package/lib/utils/authentication-env-template.js +222 -0
  309. package/lib/utils/cli-sync-options.js +62 -10
  310. package/lib/utils/cli-utils.js +15 -3
  311. package/lib/utils/cli-workspace-options.js +29 -0
  312. package/lib/utils/compose-generate-docker-compose.js +102 -0
  313. package/lib/utils/configuration-env-resolver.js +203 -27
  314. package/lib/utils/datasource-test-run-certificate-tty.js +28 -2
  315. package/lib/utils/datasource-test-run-certification-debug.js +130 -0
  316. package/lib/utils/datasource-test-run-debug-display.js +2 -0
  317. package/lib/utils/datasource-test-run-debug-slice.js +7 -0
  318. package/lib/utils/datasource-test-run-display.js +2 -1
  319. package/lib/utils/dev-ca-install.js +5 -6
  320. package/lib/utils/dev-config.js +2 -2
  321. package/lib/utils/dev-init-ssh-merge.js +165 -23
  322. package/lib/utils/dev-list-sort.js +145 -0
  323. package/lib/utils/dev-pin-share-instructions.js +110 -0
  324. package/lib/utils/dev-platform-tls.js +0 -63
  325. package/lib/utils/dev-ssh-config-helper.js +177 -33
  326. package/lib/utils/docker-build.js +46 -27
  327. package/lib/utils/docker-daemon-tls-ca.js +1 -1
  328. package/lib/utils/docker-exec.js +91 -6
  329. package/lib/utils/enterprise-knowledge-paths.js +142 -0
  330. package/lib/utils/env-copy.js +3 -4
  331. package/lib/utils/env-dotenv-format.js +103 -0
  332. package/lib/utils/error-formatters/error-parser.js +0 -3
  333. package/lib/utils/external-env-template.js +5 -2
  334. package/lib/utils/external-system-display.js +5 -1
  335. package/lib/utils/external-system-readiness-compact-blocks.js +248 -0
  336. package/lib/utils/external-system-readiness-compact-display.js +324 -0
  337. package/lib/utils/external-system-readiness-core.js +16 -0
  338. package/lib/utils/external-system-readiness-deploy-display.js +29 -11
  339. package/lib/utils/external-system-readiness-display-internals.js +3 -1
  340. package/lib/utils/external-system-readiness-display.js +20 -30
  341. package/lib/utils/external-system-system-test-tty-certification.js +135 -0
  342. package/lib/utils/external-system-system-test-tty.js +5 -41
  343. package/lib/utils/health-check-request.js +2 -3
  344. package/lib/utils/help-builder.js +9 -1
  345. package/lib/utils/host-ops-job-labels.js +236 -0
  346. package/lib/utils/host-ops-job-result.js +61 -0
  347. package/lib/utils/host-ops-poll-ui.js +163 -0
  348. package/lib/utils/image-name.js +22 -4
  349. package/lib/utils/integration-path-resolve.js +112 -0
  350. package/lib/utils/logger.js +37 -4
  351. package/lib/utils/manifest-source-emit.js +1 -1
  352. package/lib/utils/paths-reload-source.js +148 -0
  353. package/lib/utils/paths-system-builder-keys.js +25 -0
  354. package/lib/utils/paths.js +183 -30
  355. package/lib/utils/pipeline-upload-auth-retry.js +4 -0
  356. package/lib/utils/postgres-platform-bootstrap.js +24 -17
  357. package/lib/utils/postgres-wipe.js +5 -2
  358. package/lib/utils/remote-dev-auth.js +39 -4
  359. package/lib/utils/resolve-docker-image-ref.js +36 -6
  360. package/lib/utils/runtime-configuration-values.js +64 -2
  361. package/lib/utils/secrets-helpers.js +5 -1
  362. package/lib/utils/ssh-known-hosts.js +130 -0
  363. package/lib/utils/test-target-cli-options.js +75 -0
  364. package/lib/utils/token-manager.js +16 -0
  365. package/lib/utils/upload-sync-options.js +20 -2
  366. package/lib/utils/validation-run-request.js +11 -2
  367. package/lib/validation/external-manifest-validator.js +11 -1
  368. package/lib/validation/openapi-contract-surface-validator.js +430 -0
  369. package/lib/validation/openapi-contract-vendor-validation.js +238 -0
  370. package/lib/validation/validate-external-file.js +160 -0
  371. package/lib/validation/validate.js +6 -117
  372. package/lib/validation/validator.js +6 -5
  373. package/package.json +76 -37
  374. package/packages/builder-api/README.md +120 -0
  375. package/packages/builder-api/package.json +30 -0
  376. package/packages/builder-api/src/app.module.ts +7 -0
  377. package/packages/builder-api/src/auth/auth.module.ts +5 -0
  378. package/packages/builder-api/src/external-system/external-system.module.ts +5 -0
  379. package/packages/builder-api/src/main.ts +16 -0
  380. package/packages/builder-api/tsconfig.json +15 -0
  381. package/scripts/check-builder-api-architecture-grep.js +79 -0
  382. package/scripts/docker_image_content_gate.js +47 -0
  383. package/scripts/docker_image_content_gate.sh +5 -0
  384. package/scripts/export-builder-api-evidence.js +262 -0
  385. package/scripts/lib/builder-api-docker-staging-copy.js +60 -0
  386. package/scripts/lib/builder-api-docker-staging-core.js +183 -0
  387. package/scripts/lib/docker-image-content-gate-core.js +166 -0
  388. package/scripts/lib/plan-actor.js +109 -0
  389. package/scripts/lib/plan-config.js +20 -0
  390. package/scripts/lib/plan-gates.js +154 -0
  391. package/scripts/lib/plan-meta.js +104 -0
  392. package/scripts/lib/plan-parse.js +162 -0
  393. package/scripts/lib/plan-prevalidate-gates.js +337 -0
  394. package/scripts/lib/plan-run-core.js +125 -0
  395. package/scripts/lib/plan-run-report.js +119 -0
  396. package/scripts/plan-approve.js +24 -0
  397. package/scripts/plan-archive.js +49 -0
  398. package/scripts/plan-run.js +13 -0
  399. package/scripts/plan-set-actor.js +21 -0
  400. package/scripts/plan-validate.js +80 -0
  401. package/scripts/pnpm/af.mjs +110 -0
  402. package/scripts/pnpm/check-quiet.mjs +32 -0
  403. package/scripts/pnpm/dev-install.mjs +29 -0
  404. package/scripts/pnpm/dev-reload.mjs +18 -0
  405. package/scripts/pnpm/help.mjs +55 -0
  406. package/scripts/pnpm/lib/dev-reload-core.mjs +189 -0
  407. package/scripts/pnpm/lib/dev-reload-log-capture.mjs +67 -0
  408. package/scripts/pnpm/lib/dev-reload-log-utils.mjs +32 -0
  409. package/scripts/pnpm/lib/resolve-aifabrix-bin.mjs +124 -0
  410. package/scripts/pnpm/lib/resolve-app-url.mjs +183 -0
  411. package/scripts/pnpm/lib/spinner.mjs +42 -0
  412. package/scripts/stage_builder_api_for_docker.js +65 -0
  413. package/scripts/sync-builder-api-template.js +44 -0
  414. package/templates/README.md +3 -0
  415. package/templates/applications/builder-api/Dockerfile +38 -0
  416. package/templates/applications/builder-api/application.yaml +75 -0
  417. package/templates/applications/builder-api/env.template +48 -0
  418. package/templates/applications/dataplane/application.yaml +27 -5
  419. package/templates/applications/dataplane/env.template +38 -15
  420. package/templates/applications/dataplane/rbac.yaml +85 -3
  421. package/templates/applications/miso-controller/application.yaml +10 -1
  422. package/templates/applications/miso-controller/env.template +11 -10
  423. package/templates/applications/miso-controller/rbac.yaml +72 -0
  424. package/templates/channels/README.md +18 -0
  425. package/templates/channels/ai-fabrix-icon.jpg +0 -0
  426. package/templates/channels/chatgpt/install.template.md.hbs +21 -24
  427. package/templates/channels/chatgpt/integration/README.md +11 -0
  428. package/templates/channels/chatgpt/integration/application.json +15 -0
  429. package/templates/channels/chatgpt/integration/chatgpt-system.json +29 -0
  430. package/templates/channels/chatgpt/integration/env.template +4 -0
  431. package/templates/channels/microsoft-copilot/install.template.md.hbs +20 -25
  432. package/templates/channels/microsoft-copilot/integration/README.md +11 -0
  433. package/templates/channels/microsoft-copilot/integration/application.json +15 -0
  434. package/templates/channels/microsoft-copilot/integration/env.template +6 -0
  435. package/templates/channels/microsoft-copilot/integration/microsoft-copilot-system.json +34 -0
  436. package/templates/channels/slack/install.template.md.hbs +48 -18
  437. package/templates/channels/slack/integration/README.md +38 -0
  438. package/templates/channels/slack/integration/application.json +18 -0
  439. package/templates/channels/slack/integration/env.template +29 -0
  440. package/templates/channels/slack/integration/slack-datasource-conversations.json +226 -0
  441. package/templates/channels/slack/integration/slack-datasource-messages.json +269 -0
  442. package/templates/channels/slack/integration/slack-system.json +144 -0
  443. package/templates/channels/slack/manifest.template.json.hbs +20 -10
  444. package/templates/channels/teams-bot/install.template.md.hbs +31 -17
  445. package/templates/channels/teams-bot/integration/README.md +18 -0
  446. package/templates/channels/teams-bot/integration/application.json +17 -0
  447. package/templates/channels/teams-bot/integration/env.template +5 -0
  448. package/templates/channels/teams-bot/integration/teams-bot-system.json +55 -0
  449. package/templates/channels/teams-bot/manifest.template.json.hbs +27 -0
  450. package/templates/channels/web-embed/install.template.md.hbs +16 -26
  451. package/templates/channels/web-embed/integration/README.md +11 -0
  452. package/templates/channels/web-embed/integration/application.json +15 -0
  453. package/templates/channels/web-embed/integration/env.template +4 -0
  454. package/templates/channels/web-embed/integration/web-embed-system.json +29 -0
  455. package/templates/openapi/redoc_page.html +86 -0
  456. package/templates/python/docker-compose.hbs +11 -0
  457. package/templates/python/requirements.txt +2 -2
  458. package/templates/typescript/docker-compose.hbs +11 -0
  459. package/lib/certification/cli-cert-sync-skip.js +0 -21
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Section-scoped manifest repair orchestration (plan 154.4).
3
+ *
4
+ * @fileoverview Graph-ordered hooks delegating to repair command
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const { repairExternalIntegration } = require('../commands/repair');
12
+ const { getRepairTraversalOrder } = require('./manifest-section-dependency-graph');
13
+ const { computeSectionQuality } = require('./manifest-section-quality');
14
+ const { loadSystemDocument, loadDatasourceDocument } = require('./manifest-section-io');
15
+ const { runWithWorkspaceContext } = require('./workspace-context');
16
+ const { touchWorkspaceMeta } = require('./workspace-meta');
17
+
18
+ const HOOK_FLAG_MAP = Object.freeze({
19
+ fieldMappings: 'sync',
20
+ expose: 'expose',
21
+ rbac: 'rbac',
22
+ sync: 'sync',
23
+ test: 'test',
24
+ api: 'api',
25
+ operations: 'operations'
26
+ });
27
+
28
+ /**
29
+ * @param {import('./workspace-context').WorkspaceContext} ctx
30
+ * @param {{ hooks?: string[], sectionKey?: string, datasourceKey?: string, dryRun?: boolean, auth?: string }} body
31
+ */
32
+ async function runManifestRepair(ctx, body = {}) {
33
+ return runWithWorkspaceContext(ctx, async() => {
34
+ const requestedHooks = normalizeHooks(body.hooks, body.sectionKey);
35
+ const repairOptions = buildRepairOptions(requestedHooks, body);
36
+ const result = await repairExternalIntegration(ctx.systemKey, repairOptions);
37
+ if (body.dryRun !== true) {
38
+ touchWorkspaceMeta(ctx, { lastOperation: 'manifest-repair' });
39
+ }
40
+ const qualitySnapshot = buildPostRepairQuality(ctx, body);
41
+ return {
42
+ hooksRun: requestedHooks,
43
+ derivedSectionsUpdated: body.sectionKey ? getRepairTraversalOrder(body.sectionKey).sections : [],
44
+ repairResult: result,
45
+ dryRun: body.dryRun === true,
46
+ quality: qualitySnapshot
47
+ };
48
+ });
49
+ }
50
+
51
+ /**
52
+ * @param {string[]|undefined} hooks
53
+ * @param {string|undefined} sectionKey
54
+ * @returns {string[]}
55
+ */
56
+ function normalizeHooks(hooks, sectionKey) {
57
+ if (Array.isArray(hooks) && hooks.length) {
58
+ return hooks.map(String);
59
+ }
60
+ if (sectionKey) {
61
+ return getRepairTraversalOrder(sectionKey).hooks;
62
+ }
63
+ const err = new Error('hooks[] is required when sectionKey is not provided');
64
+ err.statusCode = 400;
65
+ throw err;
66
+ }
67
+
68
+ /**
69
+ * @param {string[]} hooks
70
+ * @param {Object} body
71
+ * @returns {Object}
72
+ */
73
+ function buildRepairOptions(hooks, body) {
74
+ /** @type {Object} */
75
+ const options = {
76
+ dryRun: body.dryRun === true,
77
+ auth: body.auth
78
+ };
79
+ for (const hook of hooks) {
80
+ const flag = HOOK_FLAG_MAP[hook];
81
+ if (flag) {
82
+ options[flag] = true;
83
+ }
84
+ }
85
+ if (options.rbac === true) {
86
+ options.operations = true;
87
+ }
88
+ return options;
89
+ }
90
+
91
+ /**
92
+ * @param {import('./workspace-context').WorkspaceContext} ctx
93
+ * @param {Object} body
94
+ * @returns {Object|null}
95
+ */
96
+ function buildPostRepairQuality(ctx, body) {
97
+ if (!body.sectionKey) {
98
+ return null;
99
+ }
100
+ try {
101
+ if (body.sectionKey.startsWith('system.')) {
102
+ const { systemDoc } = loadSystemDocument(ctx);
103
+ return computeSectionQuality({ sectionKey: body.sectionKey, currentValue: systemDoc });
104
+ }
105
+ if (body.datasourceKey) {
106
+ const { datasourceDoc } = loadDatasourceDocument(ctx, body.datasourceKey);
107
+ return computeSectionQuality({
108
+ sectionKey: body.sectionKey,
109
+ currentValue: datasourceDoc,
110
+ datasourceDoc
111
+ });
112
+ }
113
+ } catch {
114
+ return null;
115
+ }
116
+ return null;
117
+ }
118
+
119
+ module.exports = {
120
+ runManifestRepair,
121
+ HOOK_FLAG_MAP
122
+ };
@@ -0,0 +1,160 @@
1
+ /**
2
+ * Directed dependency graph for governed manifest sections (plan 154.4).
3
+ *
4
+ * @fileoverview Repair traversal and nextActions generation
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ /** @type {ReadonlyArray<[string, string]>} */
12
+ const SECTION_EDGES = Object.freeze([
13
+ ['datasource.metadata', 'datasource.fieldMappings'],
14
+ ['datasource.fieldMappings', 'datasource.exposedAttributes'],
15
+ ['datasource.exposedAttributes', 'datasource.openapiOperations'],
16
+ ['datasource.openapiOperations', 'datasource.mcpOperations'],
17
+ ['datasource.mcpOperations', 'system.rolesPermissions'],
18
+ ['datasource.capabilities', 'datasource.openapiOperations'],
19
+ ['datasource.identity', 'datasource.fieldMappings'],
20
+ ['datasource.entityType', 'datasource.metadata']
21
+ ]);
22
+
23
+ /** @type {Readonly<Record<string, string[]>>} */
24
+ const SECTION_REPAIR_HOOKS = Object.freeze({
25
+ 'datasource.metadata': ['fieldMappings', 'expose', 'rbac'],
26
+ 'datasource.fieldMappings': ['fieldMappings', 'expose'],
27
+ 'datasource.exposedAttributes': ['expose'],
28
+ 'datasource.openapiOperations': ['expose', 'rbac'],
29
+ 'datasource.mcpOperations': ['rbac'],
30
+ 'datasource.capabilities': ['expose', 'rbac', 'operations'],
31
+ 'datasource.identity': ['fieldMappings'],
32
+ 'system.rolesPermissions': ['rbac']
33
+ });
34
+
35
+ /**
36
+ * @param {string} sectionKey
37
+ * @returns {string[]}
38
+ */
39
+ function getDownstream(sectionKey) {
40
+ const adjacency = buildAdjacency();
41
+ const visited = new Set();
42
+ const order = [];
43
+ const queue = [sectionKey];
44
+ while (queue.length > 0) {
45
+ const current = queue.shift();
46
+ const next = adjacency.get(current) || [];
47
+ for (const dep of next) {
48
+ if (visited.has(dep)) {
49
+ continue;
50
+ }
51
+ visited.add(dep);
52
+ order.push(dep);
53
+ queue.push(dep);
54
+ }
55
+ }
56
+ return order;
57
+ }
58
+
59
+ /**
60
+ * @param {string} sectionKey
61
+ * @returns {{ sections: string[], hooks: string[] }}
62
+ */
63
+ function getRepairTraversalOrder(sectionKey) {
64
+ const sections = getDownstream(sectionKey);
65
+ const hookSet = new Set();
66
+ const allKeys = [sectionKey, ...sections];
67
+ for (const key of allKeys) {
68
+ const hooks = SECTION_REPAIR_HOOKS[key] || [];
69
+ for (const hook of hooks) {
70
+ hookSet.add(hook);
71
+ }
72
+ }
73
+ return { sections, hooks: [...hookSet] };
74
+ }
75
+
76
+ /**
77
+ * @param {Object} _ctx
78
+ * @param {{ sectionKey: string, lastOp?: string, quality?: Object }} input
79
+ * @returns {string[]}
80
+ */
81
+ function computeNextActions(_ctx, input) {
82
+ const quality = input.quality || {};
83
+ const missing = Array.isArray(quality.missingInputs) ? quality.missingInputs : [];
84
+ const hasRequiredMissing = missing.some((item) => item && item.required === true);
85
+ if (hasRequiredMissing) {
86
+ return ['askUser'];
87
+ }
88
+ if (input.lastOp === 'getSection') {
89
+ return ['patchSection', 'repair', 'validate'];
90
+ }
91
+ if (input.lastOp === 'patchSection') {
92
+ const downstream = getDownstream(input.sectionKey);
93
+ if (downstream.length > 0) {
94
+ return ['repair', 'validate', 'test'];
95
+ }
96
+ return ['validate', 'test'];
97
+ }
98
+ if (input.lastOp === 'repair') {
99
+ return ['validate', 'test'];
100
+ }
101
+ return ['patchSection', 'repair', 'validate'];
102
+ }
103
+
104
+ /**
105
+ * @returns {Map<string, string[]>}
106
+ */
107
+ function buildAdjacency() {
108
+ /** @type {Map<string, string[]>} */
109
+ const map = new Map();
110
+ for (const [source, target] of SECTION_EDGES) {
111
+ const list = map.get(source) || [];
112
+ list.push(target);
113
+ map.set(source, list);
114
+ }
115
+ return map;
116
+ }
117
+
118
+ /**
119
+ * @returns {boolean}
120
+ */
121
+ function isAcyclicGraph() {
122
+ const adjacency = buildAdjacency();
123
+ const visiting = new Set();
124
+ const visited = new Set();
125
+
126
+ /** @param {string} node */
127
+ function visit(node) {
128
+ if (visited.has(node)) {
129
+ return true;
130
+ }
131
+ if (visiting.has(node)) {
132
+ return false;
133
+ }
134
+ visiting.add(node);
135
+ for (const next of adjacency.get(node) || []) {
136
+ if (!visit(next)) {
137
+ return false;
138
+ }
139
+ }
140
+ visiting.delete(node);
141
+ visited.add(node);
142
+ return true;
143
+ }
144
+
145
+ for (const node of adjacency.keys()) {
146
+ if (!visit(node)) {
147
+ return false;
148
+ }
149
+ }
150
+ return true;
151
+ }
152
+
153
+ module.exports = {
154
+ SECTION_EDGES,
155
+ SECTION_REPAIR_HOOKS,
156
+ getDownstream,
157
+ getRepairTraversalOrder,
158
+ computeNextActions,
159
+ isAcyclicGraph
160
+ };
@@ -0,0 +1,225 @@
1
+ /**
2
+ * Workspace manifest file IO for section editing (plan 154.4).
3
+ *
4
+ * @fileoverview Load/save system and datasource JSON with discovery
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const crypto = require('crypto');
12
+ const fs = require('../internal/fs-real-sync');
13
+ const path = require('path');
14
+ const { discoverIntegrationFiles } = require('../commands/repair-internal');
15
+ const { loadConfigFile } = require('../utils/config-format');
16
+ const { resolveApplicationConfigPath } = require('../utils/app-config-resolver');
17
+
18
+ const AUDIT_FILENAME = '.builder-section-audit.jsonl';
19
+ const SECRET_PATTERN = /kv:\/\/|secure:\/\/|Bearer\s+[A-Za-z0-9._-]+/gi;
20
+
21
+ /**
22
+ * @param {import('./workspace-context').WorkspaceContext} ctx
23
+ * @returns {string}
24
+ */
25
+ function getIntegrationPath(ctx) {
26
+ return ctx.getIntegrationPath(ctx.systemKey);
27
+ }
28
+
29
+ /**
30
+ * @param {import('./workspace-context').WorkspaceContext} ctx
31
+ * @returns {{ systemFile: string, systemPath: string, systemDoc: Object }}
32
+ */
33
+ function loadSystemDocument(ctx) {
34
+ const appPath = getIntegrationPath(ctx);
35
+ const { systemFiles } = discoverIntegrationFiles(appPath);
36
+ if (!systemFiles.length) {
37
+ const err = new Error(`No system file found in workspace for ${ctx.systemKey}`);
38
+ err.statusCode = 404;
39
+ throw err;
40
+ }
41
+ const systemFile = systemFiles[0];
42
+ const systemPath = path.join(appPath, systemFile);
43
+ return { systemFile, systemPath, systemDoc: loadConfigFile(systemPath) };
44
+ }
45
+
46
+ /**
47
+ * @param {string} appPath
48
+ * @param {string} datasourceKey
49
+ * @returns {string|undefined}
50
+ */
51
+ function findDatasourceFileName(appPath, datasourceKey) {
52
+ const { datasourceFiles } = discoverIntegrationFiles(appPath);
53
+ const key = typeof datasourceKey === 'string' ? datasourceKey.trim() : '';
54
+ if (!key) return undefined;
55
+
56
+ for (const name of datasourceFiles) {
57
+ try {
58
+ const doc = loadConfigFile(path.join(appPath, name));
59
+ if (doc && doc.key === key) return name;
60
+ } catch {
61
+ // skip unreadable files
62
+ }
63
+ }
64
+
65
+ const suffixMatch = datasourceFiles.find((name) => {
66
+ const m = name.match(/-datasource-(.+)\.(json|ya?ml)$/i);
67
+ if (!m) return false;
68
+ const suffix = m[1];
69
+ return key === suffix || key.endsWith(`-${suffix}`);
70
+ });
71
+ if (suffixMatch) return suffixMatch;
72
+
73
+ return datasourceFiles.find((name) => name.includes(key));
74
+ }
75
+
76
+ /**
77
+ * @param {import('./workspace-context').WorkspaceContext} ctx
78
+ * @param {string} datasourceKey
79
+ * @returns {{ datasourceFile: string, datasourcePath: string, datasourceDoc: Object }}
80
+ */
81
+ function loadDatasourceDocument(ctx, datasourceKey) {
82
+ const appPath = getIntegrationPath(ctx);
83
+ const match = findDatasourceFileName(appPath, datasourceKey);
84
+ if (!match) {
85
+ const err = new Error(`Datasource file not found for key ${datasourceKey}`);
86
+ err.statusCode = 404;
87
+ throw err;
88
+ }
89
+ const datasourcePath = path.join(appPath, match);
90
+ return { datasourceFile: match, datasourcePath, datasourceDoc: loadConfigFile(datasourcePath) };
91
+ }
92
+
93
+ /**
94
+ * @param {string} filePath
95
+ * @param {Object} doc
96
+ */
97
+ function writeJsonDocument(filePath, doc) {
98
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
99
+ fs.writeFileSync(filePath, `${JSON.stringify(doc, null, 2)}\n`, 'utf8');
100
+ }
101
+
102
+ /**
103
+ * @param {string} integrationPath
104
+ * @param {string} relativeName
105
+ */
106
+ function backupFile(integrationPath, relativeName) {
107
+ const source = path.join(integrationPath, relativeName);
108
+ if (!fs.existsSync(source)) {
109
+ return null;
110
+ }
111
+ const backupDir = path.join(integrationPath, 'backup');
112
+ fs.mkdirSync(backupDir, { recursive: true });
113
+ const stamp = new Date().toISOString().replace(/[:.]/g, '-');
114
+ const dest = path.join(backupDir, `${relativeName}.${stamp}.bak`);
115
+ fs.copyFileSync(source, dest);
116
+ return dest;
117
+ }
118
+
119
+ /**
120
+ * @param {*} value
121
+ * @returns {string}
122
+ */
123
+ function hashValue(value) {
124
+ const payload = JSON.stringify(value);
125
+ return `sha256:${crypto.createHash('sha256').update(payload).digest('hex')}`;
126
+ }
127
+
128
+ /**
129
+ * @param {import('./workspace-context').WorkspaceContext} ctx
130
+ * @param {Object} entry
131
+ */
132
+ function appendSectionAudit(ctx, entry) {
133
+ const auditPath = path.join(getIntegrationPath(ctx), AUDIT_FILENAME);
134
+ const line = `${JSON.stringify({ ...entry, timestamp: new Date().toISOString() })}\n`;
135
+ fs.appendFileSync(auditPath, line, 'utf8');
136
+ }
137
+
138
+ /**
139
+ * @param {*} value
140
+ * @returns {*}
141
+ */
142
+ function redactSecrets(value) {
143
+ if (value === null || value === undefined) {
144
+ return value;
145
+ }
146
+ if (typeof value === 'string') {
147
+ return value.replace(SECRET_PATTERN, '[REDACTED]');
148
+ }
149
+ if (Array.isArray(value)) {
150
+ return value.map(redactSecrets);
151
+ }
152
+ if (typeof value === 'object') {
153
+ /** @type {Record<string, *>} */
154
+ const out = {};
155
+ for (const [key, child] of Object.entries(value)) {
156
+ if (/secret|password|token|apikey/i.test(key)) {
157
+ out[key] = '[REDACTED]';
158
+ } else {
159
+ out[key] = redactSecrets(child);
160
+ }
161
+ }
162
+ return out;
163
+ }
164
+ return value;
165
+ }
166
+
167
+ /**
168
+ * @param {import('./workspace-context').WorkspaceContext} ctx
169
+ * @returns {string[]}
170
+ */
171
+ function listDatasourceKeys(ctx) {
172
+ const appPath = getIntegrationPath(ctx);
173
+ let fromConfig = null;
174
+ try {
175
+ const configPath = resolveApplicationConfigPath(appPath);
176
+ if (fs.existsSync(configPath)) {
177
+ const variables = loadConfigFile(configPath);
178
+ fromConfig = variables.externalIntegration?.dataSources;
179
+ }
180
+ } catch {
181
+ fromConfig = null;
182
+ }
183
+ if (Array.isArray(fromConfig) && fromConfig.length) {
184
+ return fromConfig.map((name) => {
185
+ const filePath = path.join(appPath, name);
186
+ if (fs.existsSync(filePath)) {
187
+ try {
188
+ const doc = loadConfigFile(filePath);
189
+ if (doc && typeof doc.key === 'string' && doc.key.trim()) {
190
+ return doc.key.trim();
191
+ }
192
+ } catch {
193
+ // fall through to filename heuristic
194
+ }
195
+ }
196
+ return name.replace(/\.(json|ya?ml)$/i, '').replace(/^.*-datasource-/, '');
197
+ });
198
+ }
199
+ const { datasourceFiles } = discoverIntegrationFiles(appPath);
200
+ return datasourceFiles.map((name) => {
201
+ try {
202
+ const doc = loadConfigFile(path.join(appPath, name));
203
+ if (doc && typeof doc.key === 'string' && doc.key.trim()) {
204
+ return doc.key.trim();
205
+ }
206
+ } catch {
207
+ // fall through
208
+ }
209
+ return name.replace(/\.(json|ya?ml)$/i, '').replace(/^.*-datasource-/, '');
210
+ });
211
+ }
212
+
213
+ module.exports = {
214
+ AUDIT_FILENAME,
215
+ getIntegrationPath,
216
+ findDatasourceFileName,
217
+ loadSystemDocument,
218
+ loadDatasourceDocument,
219
+ writeJsonDocument,
220
+ backupFile,
221
+ hashValue,
222
+ appendSectionAudit,
223
+ redactSecrets,
224
+ listDatasourceKeys
225
+ };
@@ -0,0 +1,171 @@
1
+ /**
2
+ * Deterministic section quality scoring (plan 154.4).
3
+ *
4
+ * @fileoverview SectionQuality, missingInputs, blockingIssues
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const RECORD_STORAGE_TYPES = new Set(['recordStorage', 'documentStorage']);
12
+
13
+ /**
14
+ * @param {Object} input
15
+ * @param {string} input.sectionKey
16
+ * @param {Object} input.currentValue
17
+ * @param {Object} [input.datasourceDoc]
18
+ * @returns {Object}
19
+ */
20
+ function computeSectionQuality(input) {
21
+ const blockingIssues = [];
22
+ const warnings = [];
23
+ const missingInputs = [];
24
+ const assumptions = [];
25
+
26
+ if (input.sectionKey === 'datasource.entityType') {
27
+ evaluateEntityType(input.currentValue, missingInputs, blockingIssues);
28
+ }
29
+ if (input.sectionKey === 'datasource.identity') {
30
+ evaluateIdentity(input.datasourceDoc, missingInputs, warnings);
31
+ }
32
+ if (input.sectionKey === 'datasource.metadata') {
33
+ evaluateMetadata(input.currentValue, warnings);
34
+ }
35
+ if (input.sectionKey === 'datasource.openapiOperations') {
36
+ evaluateWriteOps(input.currentValue, warnings);
37
+ }
38
+ if (input.sectionKey === 'datasource.capabilities' && input.datasourceDoc) {
39
+ evaluateCapabilityExecutionParity(input.datasourceDoc, blockingIssues, warnings);
40
+ evaluateCapabilityOpenApiParity(input.datasourceDoc, warnings);
41
+ }
42
+ if (input.sectionKey === 'datasource.openapiOperations' && input.datasourceDoc) {
43
+ evaluateCapabilityOpenApiParity(input.datasourceDoc, warnings);
44
+ }
45
+
46
+ let score = 100 - blockingIssues.length * 15 - warnings.length * 5 - missingInputs.filter((m) => m.required).length * 10;
47
+ score = Math.max(0, Math.min(100, score));
48
+ return { score, blockingIssues, warnings, missingInputs, assumptions };
49
+ }
50
+
51
+ /**
52
+ * @param {Object|string} currentValue
53
+ * @param {Object[]} missingInputs
54
+ * @param {Object[]} blockingIssues
55
+ */
56
+ function evaluateEntityType(currentValue, missingInputs, blockingIssues) {
57
+ const entityType = typeof currentValue === 'string' ? currentValue : currentValue?.entityType;
58
+ if (!entityType) {
59
+ missingInputs.push({
60
+ field: 'entityType',
61
+ question: 'Which entity type best describes this datasource (recordStorage, documentStorage, serviceContract, none)?',
62
+ required: true
63
+ });
64
+ blockingIssues.push({ severity: 'error', message: 'entityType is required' });
65
+ }
66
+ }
67
+
68
+ /**
69
+ * @param {Object} [datasourceDoc]
70
+ * @param {Object[]} missingInputs
71
+ * @param {Object[]} warnings
72
+ */
73
+ function evaluateIdentity(datasourceDoc, missingInputs, warnings) {
74
+ const entityType = datasourceDoc?.entityType;
75
+ if (!entityType || !RECORD_STORAGE_TYPES.has(entityType)) {
76
+ return;
77
+ }
78
+ const primaryKey = datasourceDoc?.primaryKey;
79
+ if (!primaryKey || (Array.isArray(primaryKey) && primaryKey.length === 0)) {
80
+ missingInputs.push({
81
+ field: 'primaryKey',
82
+ question: 'Which field uniquely identifies this record?',
83
+ required: true
84
+ });
85
+ }
86
+ if (!datasourceDoc?.metadataSchema?.properties || Object.keys(datasourceDoc.metadataSchema.properties).length === 0) {
87
+ warnings.push('metadataSchema has no properties defined yet');
88
+ }
89
+ }
90
+
91
+ /**
92
+ * @param {Object} currentValue
93
+ * @param {Object[]} warnings
94
+ */
95
+ function evaluateMetadata(currentValue, warnings) {
96
+ const properties = currentValue?.properties;
97
+ if (!properties || Object.keys(properties).length === 0) {
98
+ warnings.push('metadataSchema has no required fields');
99
+ }
100
+ }
101
+
102
+ /**
103
+ * @param {Object} currentValue
104
+ * @param {Object[]} warnings
105
+ */
106
+ function evaluateWriteOps(currentValue, warnings) {
107
+ const ops = currentValue?.operations;
108
+ if (!ops || typeof ops !== 'object') {
109
+ return;
110
+ }
111
+ const writeOps = Object.entries(ops).filter(([, op]) => op && /put|post|patch|delete/i.test(String(op.method || '')));
112
+ if (writeOps.length > 0) {
113
+ warnings.push('Write operations present — RBAC repair may be required before test');
114
+ }
115
+ }
116
+
117
+ /**
118
+ * @param {Object} quality
119
+ * @returns {boolean}
120
+ */
121
+ function hasRequiredMissingInputs(quality) {
122
+ const missing = Array.isArray(quality?.missingInputs) ? quality.missingInputs : [];
123
+ return missing.some((item) => item && item.required === true);
124
+ }
125
+
126
+ /**
127
+ * @param {Object} datasourceDoc
128
+ * @param {Object[]} blockingIssues
129
+ * @param {Object[]} warnings
130
+ */
131
+ function evaluateCapabilityExecutionParity(datasourceDoc, blockingIssues, warnings) {
132
+ const { listCapabilityKeys } = require('../datasource/capability/capability-manifest');
133
+ const capKeys = listCapabilityKeys(datasourceDoc?.capabilities);
134
+ const cipOps = datasourceDoc?.execution?.cip?.operations;
135
+ const cipCount =
136
+ cipOps && typeof cipOps === 'object' ? Object.keys(cipOps).length : 0;
137
+ if (capKeys.length === 0) {
138
+ return;
139
+ }
140
+ if (cipCount !== capKeys.length) {
141
+ blockingIssues.push({
142
+ severity: 'error',
143
+ message: `Capability count (${capKeys.length}) does not match execution.cip.operations count (${cipCount}) — run repair with operations hook`
144
+ });
145
+ return;
146
+ }
147
+ const missing = capKeys.filter((key) => !cipOps[key]);
148
+ if (missing.length > 0) {
149
+ warnings.push(`execution.cip.operations missing keys: ${missing.join(', ')}`);
150
+ }
151
+ }
152
+
153
+ /**
154
+ * @param {Object} datasourceDoc
155
+ * @param {Object[]} warnings
156
+ */
157
+ function evaluateCapabilityOpenApiParity(datasourceDoc, warnings) {
158
+ const { findCapabilityKeysMissingFromOpenApi, formatCapabilityOpenApiDriftWarning } = require('../commands/repair-capability-openapi-warnings');
159
+ const missingKeys = findCapabilityKeysMissingFromOpenApi(datasourceDoc);
160
+ if (missingKeys.length === 0) {
161
+ return;
162
+ }
163
+ warnings.push(formatCapabilityOpenApiDriftWarning(datasourceDoc?.key || 'datasource', datasourceDoc, missingKeys));
164
+ }
165
+
166
+ module.exports = {
167
+ computeSectionQuality,
168
+ hasRequiredMissingInputs,
169
+ evaluateCapabilityExecutionParity,
170
+ evaluateCapabilityOpenApiParity
171
+ };