@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,40 @@
1
+ /**
2
+ * Match builder-api route patterns to pathnames.
3
+ *
4
+ * @fileoverview /systems/:systemKey/upload style matching
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const BASE = '/api/v1/builder';
12
+
13
+ /**
14
+ * @param {string} pattern
15
+ * @param {string} pathname
16
+ * @returns {Object|null}
17
+ */
18
+ function matchRoutePattern(pattern, pathname) {
19
+ const fullPattern = `${BASE}${pattern}`;
20
+ const names = [];
21
+ const regexBody = fullPattern.replace(/:[A-Za-z]+/g, (token) => {
22
+ names.push(token.slice(1));
23
+ return '([^/]+)';
24
+ });
25
+ const re = new RegExp(`^${regexBody}$`);
26
+ const match = pathname.match(re);
27
+ if (!match) {
28
+ return null;
29
+ }
30
+ const params = {};
31
+ names.forEach((name, idx) => {
32
+ params[name] = match[idx + 1];
33
+ });
34
+ return params;
35
+ }
36
+
37
+ module.exports = {
38
+ BASE,
39
+ matchRoutePattern
40
+ };
@@ -0,0 +1,69 @@
1
+ /**
2
+ * In-memory idempotency cache for mutating routes — V1 single replica.
3
+ *
4
+ * @fileoverview Key: userId + Idempotency-Key + route + systemKey
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const DEFAULT_TTL_MS = 24 * 60 * 60 * 1000;
12
+
13
+ /** @type {Map<string, { expiresAt: number, entry: Object }>} */
14
+ const cache = new Map();
15
+
16
+ /**
17
+ * @param {Object} params
18
+ * @param {string} params.userId
19
+ * @param {string} params.idempotencyKey
20
+ * @param {string} params.route
21
+ * @param {string} params.systemKey
22
+ * @returns {string}
23
+ */
24
+ function buildIdempotencyCacheKey(params) {
25
+ return `${params.userId}:${params.route}:${params.systemKey}:${params.idempotencyKey}`;
26
+ }
27
+
28
+ /**
29
+ * @param {Object} params
30
+ * @param {string} params.userId
31
+ * @param {string} params.idempotencyKey
32
+ * @param {string} params.route
33
+ * @param {string} params.systemKey
34
+ * @returns {Object|null}
35
+ */
36
+ function getIdempotentResult(params) {
37
+ const key = buildIdempotencyCacheKey(params);
38
+ const row = cache.get(key);
39
+ if (!row) {
40
+ return null;
41
+ }
42
+ if (Date.now() > row.expiresAt) {
43
+ cache.delete(key);
44
+ return null;
45
+ }
46
+ return row.entry;
47
+ }
48
+
49
+ /**
50
+ * @param {Object} params
51
+ * @param {Object} entry
52
+ * @param {number} [ttlMs]
53
+ */
54
+ function setIdempotentResult(params, entry, ttlMs = DEFAULT_TTL_MS) {
55
+ const key = buildIdempotencyCacheKey(params);
56
+ cache.set(key, { expiresAt: Date.now() + ttlMs, entry });
57
+ }
58
+
59
+ function clearIdempotencyCache() {
60
+ cache.clear();
61
+ }
62
+
63
+ module.exports = {
64
+ getIdempotentResult,
65
+ setIdempotentResult,
66
+ clearIdempotencyCache,
67
+ buildIdempotencyCacheKey,
68
+ DEFAULT_TTL_MS
69
+ };
@@ -0,0 +1,53 @@
1
+ /**
2
+ * @fileoverview builder-api public exports
3
+ */
4
+
5
+ 'use strict';
6
+
7
+ const workspaceContext = require('./workspace-context');
8
+ const runUpload = require('./run-upload');
9
+ const runWizard = require('./run-wizard');
10
+ const runRepair = require('./run-repair');
11
+ const runValidate = require('./run-validate');
12
+ const runTest = require('./run-test');
13
+ const runCertify = require('./run-certify');
14
+ const runLifecycle = require('./run-lifecycle');
15
+ const workspaceOps = require('./workspace-ops');
16
+ const capabilityRegistry = require('./capability-registry');
17
+ const bearerAuth = require('./bearer-auth');
18
+ const workspaceMeta = require('./workspace-meta');
19
+ const authConfig = require('./auth-config');
20
+ const commandOptions = require('./command-options');
21
+ const builderApiServer = require('./builder-api-server');
22
+ const routeHandlers = require('./route-handlers');
23
+ const openapiSpec = require('./openapi-spec');
24
+ const workspaceCleanup = require('./workspace-cleanup');
25
+ const nestHttpBridge = require('./nest-http-bridge');
26
+ const requestTimeout = require('./request-timeout');
27
+ const enterpriseMcpClient = require('./enterprise-mcp-client');
28
+
29
+ module.exports = {
30
+ ...workspaceContext,
31
+ ...runUpload,
32
+ ...runWizard,
33
+ ...runRepair,
34
+ ...runValidate,
35
+ ...runTest,
36
+ ...runCertify,
37
+ ...runLifecycle,
38
+ ...workspaceOps,
39
+ ...capabilityRegistry,
40
+ ...bearerAuth,
41
+ ...workspaceMeta,
42
+ ...authConfig,
43
+ ...commandOptions,
44
+ builderApiServer,
45
+ routeHandlers,
46
+ openapiSpec,
47
+ workspaceCleanup,
48
+ nestHttpBridge,
49
+ requestTimeout,
50
+ enterpriseMcpClient,
51
+ // Back-compat alias
52
+ spikeServer: builderApiServer
53
+ };
@@ -0,0 +1,39 @@
1
+ /**
2
+ * AsyncLocalStorage scope for per-request integration path resolution (builder-api).
3
+ *
4
+ * @fileoverview Programmatic integration path override for multi-user workspaces
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const { AsyncLocalStorage } = require('async_hooks');
12
+
13
+ const storage = new AsyncLocalStorage();
14
+
15
+ /**
16
+ * @typedef {Object} IntegrationPathScope
17
+ * @property {(systemKey: string) => string} resolveIntegrationPath
18
+ */
19
+
20
+ /**
21
+ * @param {IntegrationPathScope} scope
22
+ * @param {() => Promise<*> | *} fn
23
+ * @returns {Promise<*>}
24
+ */
25
+ function runWithIntegrationPathScope(scope, fn) {
26
+ return storage.run(scope, fn);
27
+ }
28
+
29
+ /**
30
+ * @returns {IntegrationPathScope | undefined}
31
+ */
32
+ function getIntegrationPathScope() {
33
+ return storage.getStore();
34
+ }
35
+
36
+ module.exports = {
37
+ runWithIntegrationPathScope,
38
+ getIntegrationPathScope
39
+ };
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Redact sensitive values from structured logs (plan 154.0 §7).
3
+ *
4
+ * @fileoverview Never log Bearer tokens or secret field values
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const SENSITIVE_KEY_RE =
12
+ /^(authorization|bearer|token|secret|password|apikey|clientsecret|accesstoken|refreshtoken)$/i;
13
+
14
+ /**
15
+ * @param {string} value
16
+ * @returns {string}
17
+ */
18
+ function redactSecretString(value) {
19
+ if (!value || typeof value !== 'string') {
20
+ return '[REDACTED]';
21
+ }
22
+ if (value.length <= 8) {
23
+ return '[REDACTED]';
24
+ }
25
+ return `[REDACTED:${value.slice(-4)}]`;
26
+ }
27
+
28
+ /**
29
+ * @param {unknown} input
30
+ * @returns {unknown}
31
+ */
32
+ function redactForLog(input) {
33
+ if (input === null || input === undefined) {
34
+ return input;
35
+ }
36
+ if (typeof input === 'string') {
37
+ if (/^Bearer\s+/i.test(input)) {
38
+ return 'Bearer [REDACTED]';
39
+ }
40
+ if (/^(kv|secure):\/\//i.test(input)) {
41
+ return '[REDACTED:uri]';
42
+ }
43
+ return input;
44
+ }
45
+ if (Array.isArray(input)) {
46
+ return input.map((item) => redactForLog(item));
47
+ }
48
+ if (typeof input !== 'object') {
49
+ return input;
50
+ }
51
+ const out = {};
52
+ for (const [key, value] of Object.entries(input)) {
53
+ if (SENSITIVE_KEY_RE.test(key)) {
54
+ out[key] = typeof value === 'string' ? redactSecretString(value) : '[REDACTED]';
55
+ continue;
56
+ }
57
+ out[key] = redactForLog(value);
58
+ }
59
+ return out;
60
+ }
61
+
62
+ module.exports = {
63
+ redactForLog,
64
+ redactSecretString,
65
+ SENSITIVE_KEY_RE
66
+ };
@@ -0,0 +1,146 @@
1
+ /**
2
+ * GET manifest section handler (plan 154.4).
3
+ *
4
+ * @fileoverview ManifestSectionView with quality, graph, read token
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const {
12
+ getDownstream,
13
+ computeNextActions,
14
+ getRepairTraversalOrder
15
+ } = require('./manifest-section-dependency-graph');
16
+ const {
17
+ getSectionDefinition,
18
+ listSectionKeys,
19
+ extractSectionValue,
20
+ buildSchemaFragment
21
+ } = require('./manifest-section-registry');
22
+ const { computeSectionQuality, hasRequiredMissingInputs } = require('./manifest-section-quality');
23
+ const {
24
+ loadSystemDocument,
25
+ loadDatasourceDocument,
26
+ hashValue,
27
+ redactSecrets,
28
+ listDatasourceKeys
29
+ } = require('./manifest-section-io');
30
+ const { runWithWorkspaceContext } = require('./workspace-context');
31
+
32
+ /**
33
+ * @param {Object} def
34
+ * @param {{ sectionKey: string, datasourceKey?: string }} options
35
+ */
36
+ function validateManifestSectionRequest(def, options) {
37
+ if (def.blocked) {
38
+ const err = new Error(`Section ${options.sectionKey} is blocked for MCP editing`);
39
+ err.statusCode = 403;
40
+ throw err;
41
+ }
42
+ if (def.target === 'datasource' && !options.datasourceKey) {
43
+ const err = new Error('datasourceKey is required for datasource sections');
44
+ err.statusCode = 400;
45
+ throw err;
46
+ }
47
+ if (def.target === 'system' && options.datasourceKey) {
48
+ const err = new Error('datasourceKey must not be set for system sections');
49
+ err.statusCode = 400;
50
+ throw err;
51
+ }
52
+ }
53
+
54
+ /**
55
+ * @param {import('./workspace-context').WorkspaceContext} ctx
56
+ * @param {{ sectionKey: string, datasourceKey?: string }} options
57
+ * @param {Object} def
58
+ * @returns {Object}
59
+ */
60
+ function buildManifestSectionView(ctx, options, def) {
61
+ const { doc, datasourceDoc } = loadDocuments(ctx, def.target, options.datasourceKey);
62
+ const rawValue = extractSectionValue(doc, def);
63
+ const currentValue = redactSecrets(rawValue);
64
+ const quality = computeSectionQuality({
65
+ sectionKey: options.sectionKey,
66
+ currentValue: rawValue,
67
+ datasourceDoc
68
+ });
69
+ const downstreamFromThis = getDownstream(options.sectionKey);
70
+ const traversal = getRepairTraversalOrder(options.sectionKey);
71
+ let recommendedNextActions = computeNextActions(ctx, {
72
+ sectionKey: options.sectionKey,
73
+ lastOp: 'getSection',
74
+ quality
75
+ });
76
+ if (hasRequiredMissingInputs(quality)) {
77
+ recommendedNextActions = ['askUser'];
78
+ }
79
+
80
+ return {
81
+ sectionKey: options.sectionKey,
82
+ target: def.target,
83
+ datasourceKey: options.datasourceKey || null,
84
+ currentValue,
85
+ schemaFragment: buildSchemaFragment(def.target, def.paths[0]),
86
+ required: def.required,
87
+ mutable: def.mutable,
88
+ sourceOfTruth: def.sourceOfTruth,
89
+ dependencyGraph: { downstreamFromThis },
90
+ repairHooks: traversal.hooks,
91
+ recommendedNextActions,
92
+ sectionReadToken: hashValue({ sectionKey: options.sectionKey, value: rawValue }),
93
+ quality
94
+ };
95
+ }
96
+
97
+ /**
98
+ * @param {import('./workspace-context').WorkspaceContext} ctx
99
+ * @param {{ sectionKey: string, datasourceKey?: string }} options
100
+ */
101
+ async function getManifestSection(ctx, options) {
102
+ return runWithWorkspaceContext(ctx, async() => {
103
+ const def = getSectionDefinition(options.sectionKey);
104
+ validateManifestSectionRequest(def, options);
105
+ return buildManifestSectionView(ctx, options, def);
106
+ });
107
+ }
108
+
109
+ /**
110
+ * @param {import('./workspace-context').WorkspaceContext} ctx
111
+ * @param {{ target?: string }} [options]
112
+ */
113
+ async function listManifestSections(ctx, options = {}) {
114
+ return runWithWorkspaceContext(ctx, async() => {
115
+ const target = options.target;
116
+ const systemKeys = listSectionKeys(target === 'datasource' ? 'datasource' : target === 'system' ? 'system' : undefined);
117
+ const datasourceKeys = listDatasourceKeys(ctx);
118
+ return {
119
+ systemKey: ctx.systemKey,
120
+ sections: systemKeys.map((sectionKey) => ({
121
+ sectionKey,
122
+ target: getSectionDefinition(sectionKey).target
123
+ })),
124
+ datasourceKeys
125
+ };
126
+ });
127
+ }
128
+
129
+ /**
130
+ * @param {import('./workspace-context').WorkspaceContext} ctx
131
+ * @param {'system' | 'datasource'} target
132
+ * @param {string} [datasourceKey]
133
+ */
134
+ function loadDocuments(ctx, target, datasourceKey) {
135
+ if (target === 'system') {
136
+ const { systemDoc } = loadSystemDocument(ctx);
137
+ return { doc: systemDoc, datasourceDoc: undefined };
138
+ }
139
+ const { datasourceDoc } = loadDatasourceDocument(ctx, datasourceKey);
140
+ return { doc: datasourceDoc, datasourceDoc };
141
+ }
142
+
143
+ module.exports = {
144
+ getManifestSection,
145
+ listManifestSections
146
+ };
@@ -0,0 +1,252 @@
1
+ /**
2
+ * PATCH manifest section handler (plan 154.4).
3
+ *
4
+ * @fileoverview Intent audit, read token, risk hints
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const {
12
+ getDownstream,
13
+ computeNextActions,
14
+ getRepairTraversalOrder
15
+ } = require('./manifest-section-dependency-graph');
16
+ const {
17
+ getSectionDefinition,
18
+ extractSectionValue,
19
+ injectSectionValue
20
+ } = require('./manifest-section-registry');
21
+ const manifestSectionRegistry = require('./manifest-section-registry');
22
+ const { computeSectionQuality, hasRequiredMissingInputs } = require('./manifest-section-quality');
23
+ const {
24
+ loadSystemDocument,
25
+ loadDatasourceDocument,
26
+ writeJsonDocument,
27
+ backupFile,
28
+ hashValue,
29
+ appendSectionAudit,
30
+ getIntegrationPath
31
+ } = require('./manifest-section-io');
32
+ const { runWithWorkspaceContext } = require('./workspace-context');
33
+
34
+ /**
35
+ * @param {import('./workspace-context').WorkspaceContext} ctx
36
+ * @param {{ sectionKey: string, datasourceKey?: string, intent: string, patch: Object, mode: string, sectionReadToken: string, dryRun?: boolean }} body
37
+ */
38
+ async function patchManifestSection(ctx, body) {
39
+ return runWithWorkspaceContext(ctx, async() => {
40
+ assertPatchRequest(body);
41
+ const def = getSectionDefinition(body.sectionKey);
42
+ assertPatchAllowed(def, body);
43
+
44
+ const loaded = loadTargetDocument(ctx, def.target, body.datasourceKey);
45
+ const beforeValue = extractSectionValue(loaded.doc, def);
46
+ verifyReadToken(body, beforeValue);
47
+
48
+ const draft = JSON.parse(JSON.stringify(loaded.doc));
49
+ injectSectionValue(draft, def, body.patch, body.mode === 'replace' ? 'replace' : 'merge');
50
+ validateDraftDocument(def.target, draft);
51
+
52
+ const afterValue = extractSectionValue(draft, def);
53
+ if (body.dryRun !== true) {
54
+ persistPatchedDocument(ctx, loaded, draft, body, beforeValue, afterValue);
55
+ }
56
+
57
+ return buildPatchResult(ctx, body, def, beforeValue, afterValue, draft);
58
+ });
59
+ }
60
+
61
+ /**
62
+ * @param {Object} body
63
+ * @param {*} beforeValue
64
+ */
65
+ function verifyReadToken(body, beforeValue) {
66
+ const expectedToken = hashValue({ sectionKey: body.sectionKey, value: beforeValue });
67
+ if (body.sectionReadToken !== expectedToken) {
68
+ const err = new Error('Section read token is stale — GET the section again before patching');
69
+ err.statusCode = 409;
70
+ throw err;
71
+ }
72
+ }
73
+
74
+ /**
75
+ * @param {'system' | 'datasource'} target
76
+ * @param {Object} draft
77
+ */
78
+ function validateDraftDocument(target, draft) {
79
+ const validation = manifestSectionRegistry.validateManifestDocument(target, draft);
80
+ if (!validation.valid) {
81
+ const err = new Error('Patched manifest failed schema validation');
82
+ err.statusCode = 422;
83
+ err.errors = validation.errors;
84
+ throw err;
85
+ }
86
+ }
87
+
88
+ /**
89
+ * @param {import('./workspace-context').WorkspaceContext} ctx
90
+ * @param {Object} loaded
91
+ * @param {Object} draft
92
+ * @param {Object} body
93
+ * @param {*} beforeValue
94
+ * @param {*} afterValue
95
+ */
96
+ function persistPatchedDocument(ctx, loaded, draft, body, beforeValue, afterValue) {
97
+ backupFile(getIntegrationPath(ctx), loaded.fileName);
98
+ writeJsonDocument(loaded.filePath, draft);
99
+ appendSectionAudit(ctx, {
100
+ sectionKey: body.sectionKey,
101
+ datasourceKey: body.datasourceKey || null,
102
+ intent: body.intent,
103
+ beforeHash: hashValue(beforeValue),
104
+ afterHash: hashValue(afterValue),
105
+ mode: body.mode
106
+ });
107
+ }
108
+
109
+ /**
110
+ * @param {import('./workspace-context').WorkspaceContext} ctx
111
+ * @param {Object} body
112
+ * @param {import('./manifest-section-registry-data').SectionDefinition} def
113
+ * @param {*} beforeValue
114
+ * @param {*} afterValue
115
+ * @param {Object} draft
116
+ */
117
+ function buildPatchResult(ctx, body, def, beforeValue, afterValue, draft) {
118
+ const quality = computeSectionQuality({
119
+ sectionKey: body.sectionKey,
120
+ currentValue: afterValue,
121
+ datasourceDoc: def.target === 'datasource' ? draft : undefined
122
+ });
123
+ const downstream = getDownstream(body.sectionKey);
124
+ const traversal = getRepairTraversalOrder(body.sectionKey);
125
+ let nextActions = computeNextActions(ctx, {
126
+ sectionKey: body.sectionKey,
127
+ lastOp: 'patchSection',
128
+ quality
129
+ });
130
+ if (hasRequiredMissingInputs(quality)) {
131
+ nextActions = ['askUser'];
132
+ }
133
+ return {
134
+ sectionKey: body.sectionKey,
135
+ datasourceKey: body.datasourceKey || null,
136
+ intent: body.intent,
137
+ changedPaths: collectChangedPaths(beforeValue, afterValue),
138
+ beforeHash: hashValue(beforeValue),
139
+ afterHash: hashValue(afterValue),
140
+ derivedSectionsAffected: downstream,
141
+ repairRecommended: downstream.length > 0,
142
+ repairHooks: traversal.hooks,
143
+ validationPreview: { valid: true },
144
+ riskHints: buildRiskHints(body.sectionKey, body.patch, downstream),
145
+ nextActions,
146
+ dryRun: body.dryRun === true,
147
+ quality
148
+ };
149
+ }
150
+
151
+ /**
152
+ * @param {Object} body
153
+ */
154
+ function assertPatchRequest(body) {
155
+ if (!body.intent || typeof body.intent !== 'string' || !body.intent.trim()) {
156
+ const err = new Error('intent is required and must be a non-empty string');
157
+ err.statusCode = 400;
158
+ throw err;
159
+ }
160
+ if (!body.patch || typeof body.patch !== 'object') {
161
+ const err = new Error('patch object is required');
162
+ err.statusCode = 400;
163
+ throw err;
164
+ }
165
+ if (!body.sectionReadToken) {
166
+ const err = new Error('sectionReadToken is required — GET the section first');
167
+ err.statusCode = 400;
168
+ throw err;
169
+ }
170
+ if (body.mode !== 'merge' && body.mode !== 'replace') {
171
+ const err = new Error('mode must be merge or replace');
172
+ err.statusCode = 400;
173
+ throw err;
174
+ }
175
+ }
176
+
177
+ /**
178
+ * @param {import('./manifest-section-registry-data').SectionDefinition} def
179
+ * @param {Object} body
180
+ */
181
+ function assertPatchAllowed(def, body) {
182
+ if (def.blocked) {
183
+ const err = new Error(`Section ${body.sectionKey} is blocked for MCP editing`);
184
+ err.statusCode = 403;
185
+ throw err;
186
+ }
187
+ if (!def.mutable) {
188
+ const err = new Error(`Section ${body.sectionKey} is repair-only and cannot be patched directly`);
189
+ err.statusCode = 403;
190
+ throw err;
191
+ }
192
+ if (def.target === 'datasource' && !body.datasourceKey) {
193
+ const err = new Error('datasourceKey is required for datasource sections');
194
+ err.statusCode = 400;
195
+ throw err;
196
+ }
197
+ }
198
+
199
+ /**
200
+ * @param {import('./workspace-context').WorkspaceContext} ctx
201
+ * @param {'system' | 'datasource'} target
202
+ * @param {string} [datasourceKey]
203
+ */
204
+ function loadTargetDocument(ctx, target, datasourceKey) {
205
+ if (target === 'system') {
206
+ const { systemFile, systemPath, systemDoc } = loadSystemDocument(ctx);
207
+ return { doc: systemDoc, filePath: systemPath, fileName: systemFile };
208
+ }
209
+ const { datasourceFile, datasourcePath, datasourceDoc } = loadDatasourceDocument(ctx, datasourceKey);
210
+ return { doc: datasourceDoc, filePath: datasourcePath, fileName: datasourceFile };
211
+ }
212
+
213
+ /**
214
+ * @param {*} beforeValue
215
+ * @param {*} afterValue
216
+ * @returns {string[]}
217
+ */
218
+ function collectChangedPaths(beforeValue, afterValue) {
219
+ if (JSON.stringify(beforeValue) === JSON.stringify(afterValue)) {
220
+ return [];
221
+ }
222
+ return ['sectionRoot'];
223
+ }
224
+
225
+ /**
226
+ * @param {string} sectionKey
227
+ * @param {Object} patch
228
+ * @param {string[]} downstream
229
+ * @returns {string[]}
230
+ */
231
+ function buildRiskHints(sectionKey, patch, downstream) {
232
+ /** @type {string[]} */
233
+ const hints = [];
234
+ if (downstream.includes('datasource.fieldMappings')) {
235
+ hints.push('Derived fieldMappings will change on repair');
236
+ }
237
+ if (downstream.includes('system.rolesPermissions')) {
238
+ hints.push('Cross-system section system.rolesPermissions may change');
239
+ }
240
+ if (sectionKey === 'datasource.openapiOperations' || sectionKey === 'datasource.capabilities') {
241
+ hints.push('New write capability added');
242
+ hints.push('RBAC repair required before test');
243
+ }
244
+ if (JSON.stringify(patch).match(/put|post|patch|delete/i)) {
245
+ hints.push('Approval may be required before production');
246
+ }
247
+ return [...new Set(hints)];
248
+ }
249
+
250
+ module.exports = {
251
+ patchManifestSection
252
+ };