@aifabrix/builder 2.49.2 → 2.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (409) hide show
  1. package/.cursor/rules/deploy-rules/docker-image-ip-policy.mdc +49 -0
  2. package/.cursor/rules/plan-rules/application-lifecycle.mdc +30 -0
  3. package/.cursor/rules/plan-rules/plan-frontmatter.mdc +35 -0
  4. package/.cursor/rules/plan-rules/plan-lifecycle.mdc +31 -0
  5. package/.cursor/rules/plan-rules/plan-validation-gate.mdc +34 -0
  6. package/.cursor/skills/README.md +1 -0
  7. package/.dockerignore +52 -0
  8. package/.eslintignore +22 -0
  9. package/README.md +2 -0
  10. package/bin/builder-api-cleanup.js +26 -0
  11. package/bin/builder-api-nest.js +10 -0
  12. package/bin/builder-api-spike.js +19 -0
  13. package/enterprise-knowledge/README.md +50 -0
  14. package/enterprise-knowledge/enterprise-integration-lifecycle/README.md +22 -0
  15. package/enterprise-knowledge/enterprise-integration-lifecycle/application.json +15 -0
  16. package/enterprise-knowledge/enterprise-integration-lifecycle/deploy.js +69 -0
  17. package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-deploy.json +52 -0
  18. package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-system.json +29 -0
  19. package/enterprise-knowledge/enterprise-integration-lifecycle/env.template +2 -0
  20. package/integration/README.md +81 -0
  21. package/integration/github/README.md +53 -0
  22. package/integration/github/application.json +21 -0
  23. package/integration/github/deploy.js +72 -0
  24. package/integration/github/env.template +11 -0
  25. package/integration/github/github-datasource-issue-comments.json +239 -0
  26. package/integration/github/github-datasource-issues.json +399 -0
  27. package/integration/github/github-datasource-repository.json +354 -0
  28. package/integration/github/github-deploy.json +1202 -0
  29. package/integration/github/github-system.json +82 -0
  30. package/integration/hubspot-test/README.md +1 -1
  31. package/jest.isolated-projects.js +31 -1
  32. package/jest.projects.js +87 -1
  33. package/lib/api/dev-server-https.js +1 -1
  34. package/lib/api/enterprise-knowledge.api.js +63 -0
  35. package/lib/api/evidence.api.js +172 -0
  36. package/lib/api/external-systems.api.js +8 -2
  37. package/lib/api/resource-types.api.js +1 -0
  38. package/lib/api/types/enterprise-knowledge.types.js +46 -0
  39. package/lib/api/types/evidence.types.js +67 -0
  40. package/lib/api/types/resource-types.types.js +2 -0
  41. package/lib/app/controller-application-filter.js +36 -0
  42. package/lib/app/deploy.js +1 -1
  43. package/lib/app/list-external-systems.js +130 -0
  44. package/lib/app/list.js +20 -8
  45. package/lib/app/run.js +3 -1
  46. package/lib/app/show-display.js +8 -3
  47. package/lib/app/show-online.js +178 -0
  48. package/lib/app/show.js +37 -88
  49. package/lib/build/builder-api-docker-staging.js +47 -0
  50. package/lib/build/miso-controller-npm-sdk-guard.js +2 -2
  51. package/lib/build/standard-docker-build.js +2 -0
  52. package/lib/certification/post-unified-cert-sync.js +4 -31
  53. package/lib/certification/sync-after-external-command.js +0 -1
  54. package/lib/certification/sync-system-certification.js +0 -3
  55. package/lib/channels/add-channel.js +40 -34
  56. package/lib/channels/approval-guides/chatgpt.js +33 -0
  57. package/lib/channels/approval-guides/credential-portal.js +38 -0
  58. package/lib/channels/approval-guides/index.js +110 -0
  59. package/lib/channels/approval-guides/microsoft-copilot.js +34 -0
  60. package/lib/channels/approval-guides/slack.js +34 -0
  61. package/lib/channels/approval-guides/teams-bot.js +35 -0
  62. package/lib/channels/approval-guides/web-embed.js +32 -0
  63. package/lib/channels/channel-approval-guide.js +11 -0
  64. package/lib/channels/channel-artifact-generator.js +16 -4
  65. package/lib/channels/channel-audit.js +3 -0
  66. package/lib/channels/channel-auth-context.js +1 -1
  67. package/lib/channels/channel-description.js +59 -0
  68. package/lib/channels/channel-integration-generator.js +13 -230
  69. package/lib/channels/channel-integration-template.js +94 -0
  70. package/lib/channels/channel-runtime-resolver.js +43 -3
  71. package/lib/channels/channel-status-display.js +66 -26
  72. package/lib/channels/channel-targets.js +3 -3
  73. package/lib/cli/index.js +27 -3
  74. package/lib/cli/infra-guided.js +5 -1
  75. package/lib/cli/setup-app-external-create.js +111 -0
  76. package/lib/cli/setup-app.help.js +1 -1
  77. package/lib/cli/setup-app.js +38 -125
  78. package/lib/cli/setup-app.test-commands.js +26 -52
  79. package/lib/cli/setup-certification-commands.js +4 -4
  80. package/lib/cli/setup-certification.help.js +9 -9
  81. package/lib/cli/setup-dev.js +7 -2
  82. package/lib/cli/setup-external-system-help.js +4 -6
  83. package/lib/cli/setup-external-system.js +58 -52
  84. package/lib/cli/setup-infra-up-builder-api-action.js +64 -0
  85. package/lib/cli/setup-infra-up-platform-action.js +3 -1
  86. package/lib/cli/setup-infra.js +15 -0
  87. package/lib/cli/setup-list.js +43 -0
  88. package/lib/cli/setup-utility-repair.js +26 -7
  89. package/lib/cli/setup-utility.js +5 -3
  90. package/lib/commands/app.js +15 -43
  91. package/lib/commands/channel-add-setup.js +110 -0
  92. package/lib/commands/channel.js +42 -8
  93. package/lib/commands/datasource-sync-display.js +96 -0
  94. package/lib/commands/datasource-sync-policy.js +210 -0
  95. package/lib/commands/datasource-test-trust-cli.js +6 -6
  96. package/lib/commands/datasource-unified-test-cli.js +2 -1
  97. package/lib/commands/datasource-unified-test-cli.options.js +33 -23
  98. package/lib/commands/deploy-gate-failure-details.js +163 -0
  99. package/lib/commands/deploy-gate-orchestrator.js +322 -0
  100. package/lib/commands/dev-cli-handlers.js +1 -59
  101. package/lib/commands/dev-host-ops-params.js +91 -0
  102. package/lib/commands/dev-host-ops-poll.js +111 -0
  103. package/lib/commands/dev-host-ops.js +107 -94
  104. package/lib/commands/dev-init.js +3 -1
  105. package/lib/commands/enterprise-knowledge.js +284 -0
  106. package/lib/commands/evidence-cli-leaves.js +250 -0
  107. package/lib/commands/evidence.js +51 -0
  108. package/lib/commands/governance-cli-shared.js +2 -2
  109. package/lib/commands/governance-command-action.js +2 -2
  110. package/lib/commands/governance-fixture-subjects.js +85 -0
  111. package/lib/commands/governance.js +1 -1
  112. package/lib/commands/lifecycle-command-action.js +2 -2
  113. package/lib/commands/lifecycle-external.js +3 -3
  114. package/lib/commands/manifest-cli-auth.js +29 -0
  115. package/lib/commands/manifest-cli-commands.js +170 -0
  116. package/lib/commands/manifest-cli-integration-path.js +63 -0
  117. package/lib/commands/manifest.js +21 -0
  118. package/lib/commands/protection-cli-leaves.js +3 -3
  119. package/lib/commands/repair-auth-apply.js +15 -1
  120. package/lib/commands/repair-authentications-454.js +169 -0
  121. package/lib/commands/repair-capability-openapi-warnings.js +126 -0
  122. package/lib/commands/repair-datasource-apply.js +135 -0
  123. package/lib/commands/repair-datasource-auto-rbac.js +62 -1
  124. package/lib/commands/repair-datasource-http-service-contract.js +239 -0
  125. package/lib/commands/repair-datasource-operation-security.js +180 -0
  126. package/lib/commands/repair-datasource-run.js +7 -2
  127. package/lib/commands/repair-datasource-sync-operations.js +177 -0
  128. package/lib/commands/repair-datasource-webhooks-sync-bridge.js +133 -0
  129. package/lib/commands/repair-datasource.js +12 -68
  130. package/lib/commands/repair-env-template.js +11 -1
  131. package/lib/commands/repair-external-run.js +121 -31
  132. package/lib/commands/repair-internal.js +1 -1
  133. package/lib/commands/repair-openapi-export.js +156 -0
  134. package/lib/commands/repair-openapi-sync.js +19 -2
  135. package/lib/commands/repair-orchestration-datasource-split.js +259 -0
  136. package/lib/commands/repair-persist.js +22 -1
  137. package/lib/commands/repair-rbac-platform-preset.js +204 -0
  138. package/lib/commands/repair-rbac-reader-roles.js +191 -0
  139. package/lib/commands/repair-rbac.js +163 -86
  140. package/lib/commands/repair-steps.js +83 -18
  141. package/lib/commands/repair-system-permissions.js +1 -0
  142. package/lib/commands/repair.js +1 -1
  143. package/lib/commands/resource-type.js +65 -26
  144. package/lib/commands/run-post-publish-data-sync.js +68 -0
  145. package/lib/commands/setup-modes.js +1 -1
  146. package/lib/commands/test-e2e-external.js +21 -8
  147. package/lib/commands/test-governance-cli-options.js +2 -2
  148. package/lib/commands/test-trust-cli-options.js +2 -2
  149. package/lib/commands/up-builder-api-bootstrap.js +71 -0
  150. package/lib/commands/up-builder-api-provision.js +241 -0
  151. package/lib/commands/up-builder-api.js +88 -0
  152. package/lib/commands/up-common.js +25 -1
  153. package/lib/commands/upload-credential-push-log.js +117 -0
  154. package/lib/commands/upload-data-sync-finalize.js +60 -0
  155. package/lib/commands/upload-probe.js +66 -0
  156. package/lib/commands/upload-publish-context.js +4 -1
  157. package/lib/commands/upload-sidecar-followups.js +55 -27
  158. package/lib/commands/upload.js +116 -157
  159. package/lib/commands/verify-governance-combined-external.js +1 -1
  160. package/lib/commands/verify-governance-db.js +2 -2
  161. package/lib/commands/verify-operations-command-action.js +2 -2
  162. package/lib/commands/verify-operations-step-plan.js +2 -2
  163. package/lib/commands/verify-operations-steps.js +2 -2
  164. package/lib/commands/verify-trust-command-action.js +1 -1
  165. package/lib/commands/wizard-core.js +1 -1
  166. package/lib/commands/wizard-headless.js +2 -1
  167. package/lib/core/admin-secrets.js +2 -6
  168. package/lib/core/secrets-env-content.js +10 -4
  169. package/lib/core/secrets-env-write.js +2 -13
  170. package/lib/datasource/agent-trust-run.js +3 -3
  171. package/lib/datasource/deploy.js +3 -1
  172. package/lib/datasource/test-e2e.js +6 -1
  173. package/lib/datasource/unified-validation-run-body.js +4 -1
  174. package/lib/datasource/unified-validation-run.js +1 -1
  175. package/lib/deployment/deploy-poll-ui.js +73 -12
  176. package/lib/deployment/deployer-poll-run.js +113 -0
  177. package/lib/deployment/deployer.js +17 -87
  178. package/lib/evidence/dataplane-context.js +21 -0
  179. package/lib/evidence/evidence-display.js +78 -0
  180. package/lib/evidence/evidence-service.js +392 -0
  181. package/lib/external-system/deploy.js +290 -112
  182. package/lib/external-system/download.js +7 -3
  183. package/lib/external-system/test-execution.js +1 -1
  184. package/lib/external-system/test-system-level.js +8 -10
  185. package/lib/external-system/test.js +12 -6
  186. package/lib/generator/deploy-script.js +73 -0
  187. package/lib/generator/external.js +2 -1
  188. package/lib/generator/index.js +17 -2
  189. package/lib/generator/wizard.js +3 -36
  190. package/lib/internal/fs-real-sync.js +22 -1
  191. package/lib/internal/node-fs.js +2 -0
  192. package/lib/lifecycle/lifecycle-governance-options.js +1 -1
  193. package/lib/lifecycle/verify-step-progress.js +1 -1
  194. package/lib/programmatic/access-log.js +26 -0
  195. package/lib/programmatic/auth-config.js +44 -0
  196. package/lib/programmatic/bearer-auth.js +176 -0
  197. package/lib/programmatic/builder-api-request.js +175 -0
  198. package/lib/programmatic/builder-api-route-dispatch.js +82 -0
  199. package/lib/programmatic/builder-api-runtime-config.js +42 -0
  200. package/lib/programmatic/builder-api-server.js +230 -0
  201. package/lib/programmatic/builder-help-authentication-catalog.js +282 -0
  202. package/lib/programmatic/builder-help-connected-system-ui.js +266 -0
  203. package/lib/programmatic/builder-help-enterprise-sync-fabrix.js +60 -0
  204. package/lib/programmatic/builder-help-envelope.js +36 -0
  205. package/lib/programmatic/builder-help-fixtures.js +200 -0
  206. package/lib/programmatic/builder-help-governance.js +172 -0
  207. package/lib/programmatic/builder-help-schema-catalog.js +92 -0
  208. package/lib/programmatic/builder-help.js +361 -0
  209. package/lib/programmatic/capability-registry.js +77 -0
  210. package/lib/programmatic/command-options.js +32 -0
  211. package/lib/programmatic/enterprise-mcp-client.js +98 -0
  212. package/lib/programmatic/http-problem-details.js +99 -0
  213. package/lib/programmatic/http-route-match.js +40 -0
  214. package/lib/programmatic/idempotency-cache.js +69 -0
  215. package/lib/programmatic/index.js +53 -0
  216. package/lib/programmatic/integration-path-scope.js +39 -0
  217. package/lib/programmatic/log-redaction.js +66 -0
  218. package/lib/programmatic/manifest-get-section.js +146 -0
  219. package/lib/programmatic/manifest-patch-section.js +252 -0
  220. package/lib/programmatic/manifest-repair.js +122 -0
  221. package/lib/programmatic/manifest-section-dependency-graph.js +160 -0
  222. package/lib/programmatic/manifest-section-io.js +225 -0
  223. package/lib/programmatic/manifest-section-quality.js +171 -0
  224. package/lib/programmatic/manifest-section-registry-data.js +269 -0
  225. package/lib/programmatic/manifest-section-registry.js +205 -0
  226. package/lib/programmatic/nest-http-bridge.js +34 -0
  227. package/lib/programmatic/openapi-component-schemas.js +68 -0
  228. package/lib/programmatic/openapi-description-enricher.js +117 -0
  229. package/lib/programmatic/openapi-descriptions.js +190 -0
  230. package/lib/programmatic/openapi-docs-serving.js +123 -0
  231. package/lib/programmatic/openapi-help-schemas.js +63 -0
  232. package/lib/programmatic/openapi-manifest-schemas.js +141 -0
  233. package/lib/programmatic/openapi-operation-bindings.js +274 -0
  234. package/lib/programmatic/openapi-request-schemas.js +155 -0
  235. package/lib/programmatic/openapi-result-schemas.js +476 -0
  236. package/lib/programmatic/openapi-schema-descriptions-certify.js +139 -0
  237. package/lib/programmatic/openapi-schema-descriptions-core.js +159 -0
  238. package/lib/programmatic/openapi-schema-descriptions-help.js +40 -0
  239. package/lib/programmatic/openapi-schema-descriptions-manifest.js +143 -0
  240. package/lib/programmatic/openapi-schema-descriptions-mcp.js +118 -0
  241. package/lib/programmatic/openapi-schema-descriptions-operations.js +281 -0
  242. package/lib/programmatic/openapi-schema-helpers.js +93 -0
  243. package/lib/programmatic/openapi-spec.js +203 -0
  244. package/lib/programmatic/orchestration-openapi-meta.js +159 -0
  245. package/lib/programmatic/platform-rbac-catalog.js +90 -0
  246. package/lib/programmatic/request-timeout.js +53 -0
  247. package/lib/programmatic/route-handler-map.js +143 -0
  248. package/lib/programmatic/route-handlers-context.js +29 -0
  249. package/lib/programmatic/route-handlers.js +33 -0
  250. package/lib/programmatic/run-certify.js +57 -0
  251. package/lib/programmatic/run-enterprise-mcp.js +32 -0
  252. package/lib/programmatic/run-lifecycle.js +29 -0
  253. package/lib/programmatic/run-repair.js +41 -0
  254. package/lib/programmatic/run-repository-emcp.js +54 -0
  255. package/lib/programmatic/run-template-workspace.js +61 -0
  256. package/lib/programmatic/run-test.js +49 -0
  257. package/lib/programmatic/run-upload.js +63 -0
  258. package/lib/programmatic/run-validate.js +53 -0
  259. package/lib/programmatic/run-wizard.js +40 -0
  260. package/lib/programmatic/system-key.js +48 -0
  261. package/lib/programmatic/wizard-config-normalize.js +118 -0
  262. package/lib/programmatic/workspace-cleanup.js +128 -0
  263. package/lib/programmatic/workspace-context.js +145 -0
  264. package/lib/programmatic/workspace-lock.js +75 -0
  265. package/lib/programmatic/workspace-meta.js +64 -0
  266. package/lib/programmatic/workspace-ops.js +149 -0
  267. package/lib/protection/run-commands-upload-sync.js +35 -0
  268. package/lib/protection/run-commands.js +2 -20
  269. package/lib/protection/upload-batch.js +11 -7
  270. package/lib/resolvers/resource-type-file.js +22 -0
  271. package/lib/schema/external-datasource.schema.json +161 -1
  272. package/lib/schema/external-system.schema.json +244 -118
  273. package/lib/schema/flag-map-validation-run.json +3 -0
  274. package/lib/schema/type/credential-field-registry.json +2 -2
  275. package/lib/schema/type/document-storage.json +9 -0
  276. package/lib/utils/agent-trust-run-display.js +1 -1
  277. package/lib/utils/app-path-resolve.js +168 -0
  278. package/lib/utils/authentication-env-template.js +222 -0
  279. package/lib/utils/cli-sync-options.js +7 -11
  280. package/lib/utils/cli-utils.js +4 -0
  281. package/lib/utils/cli-workspace-options.js +29 -0
  282. package/lib/utils/compose-generate-docker-compose.js +102 -0
  283. package/lib/utils/configuration-env-resolver.js +203 -27
  284. package/lib/utils/datasource-test-run-certificate-tty.js +28 -2
  285. package/lib/utils/datasource-test-run-certification-debug.js +130 -0
  286. package/lib/utils/datasource-test-run-debug-display.js +2 -0
  287. package/lib/utils/datasource-test-run-debug-slice.js +7 -0
  288. package/lib/utils/datasource-test-run-display.js +2 -1
  289. package/lib/utils/dev-init-ssh-merge.js +165 -23
  290. package/lib/utils/dev-pin-share-instructions.js +110 -0
  291. package/lib/utils/dev-ssh-config-helper.js +177 -33
  292. package/lib/utils/enterprise-knowledge-paths.js +142 -0
  293. package/lib/utils/env-copy.js +2 -1
  294. package/lib/utils/env-dotenv-format.js +103 -0
  295. package/lib/utils/external-env-template.js +4 -1
  296. package/lib/utils/external-system-display.js +5 -1
  297. package/lib/utils/external-system-readiness-compact-blocks.js +221 -0
  298. package/lib/utils/external-system-readiness-compact-display.js +324 -0
  299. package/lib/utils/external-system-readiness-core.js +16 -0
  300. package/lib/utils/external-system-readiness-deploy-display.js +29 -11
  301. package/lib/utils/external-system-readiness-display-internals.js +3 -1
  302. package/lib/utils/external-system-readiness-display.js +20 -30
  303. package/lib/utils/external-system-system-test-tty-certification.js +135 -0
  304. package/lib/utils/external-system-system-test-tty.js +5 -41
  305. package/lib/utils/help-builder.js +6 -1
  306. package/lib/utils/host-ops-job-labels.js +236 -0
  307. package/lib/utils/host-ops-job-result.js +61 -0
  308. package/lib/utils/host-ops-poll-ui.js +163 -0
  309. package/lib/utils/integration-path-resolve.js +112 -0
  310. package/lib/utils/paths-reload-source.js +148 -0
  311. package/lib/utils/paths-system-builder-keys.js +25 -0
  312. package/lib/utils/paths.js +151 -26
  313. package/lib/utils/runtime-configuration-values.js +64 -2
  314. package/lib/utils/secrets-helpers.js +5 -1
  315. package/lib/utils/ssh-known-hosts.js +130 -0
  316. package/lib/utils/test-target-cli-options.js +75 -0
  317. package/lib/utils/upload-sync-options.js +4 -0
  318. package/lib/utils/validation-run-request.js +11 -2
  319. package/lib/validation/external-manifest-validator.js +11 -1
  320. package/lib/validation/openapi-contract-surface-validator.js +426 -0
  321. package/lib/validation/openapi-contract-vendor-validation.js +238 -0
  322. package/lib/validation/validate-external-file.js +160 -0
  323. package/lib/validation/validate.js +6 -117
  324. package/package.json +46 -29
  325. package/packages/builder-api/README.md +120 -0
  326. package/packages/builder-api/package.json +30 -0
  327. package/packages/builder-api/src/app.module.ts +7 -0
  328. package/packages/builder-api/src/auth/auth.module.ts +5 -0
  329. package/packages/builder-api/src/external-system/external-system.module.ts +5 -0
  330. package/packages/builder-api/src/main.ts +16 -0
  331. package/packages/builder-api/tsconfig.json +15 -0
  332. package/scripts/check-builder-api-architecture-grep.js +79 -0
  333. package/scripts/docker_image_content_gate.js +47 -0
  334. package/scripts/docker_image_content_gate.sh +5 -0
  335. package/scripts/export-builder-api-evidence.js +262 -0
  336. package/scripts/lib/builder-api-docker-staging-copy.js +60 -0
  337. package/scripts/lib/builder-api-docker-staging-core.js +183 -0
  338. package/scripts/lib/docker-image-content-gate-core.js +166 -0
  339. package/scripts/lib/plan-actor.js +109 -0
  340. package/scripts/lib/plan-config.js +20 -0
  341. package/scripts/lib/plan-gates.js +154 -0
  342. package/scripts/lib/plan-meta.js +104 -0
  343. package/scripts/lib/plan-parse.js +162 -0
  344. package/scripts/lib/plan-prevalidate-gates.js +326 -0
  345. package/scripts/lib/plan-run-core.js +125 -0
  346. package/scripts/lib/plan-run-report.js +108 -0
  347. package/scripts/plan-approve.js +24 -0
  348. package/scripts/plan-archive.js +49 -0
  349. package/scripts/plan-run.js +13 -0
  350. package/scripts/plan-set-actor.js +21 -0
  351. package/scripts/plan-validate.js +80 -0
  352. package/scripts/pnpm/af.mjs +110 -0
  353. package/scripts/pnpm/check-quiet.mjs +32 -0
  354. package/scripts/pnpm/dev-install.mjs +29 -0
  355. package/scripts/pnpm/dev-reload.mjs +18 -0
  356. package/scripts/pnpm/help.mjs +55 -0
  357. package/scripts/pnpm/lib/dev-reload-core.mjs +189 -0
  358. package/scripts/pnpm/lib/dev-reload-log-capture.mjs +67 -0
  359. package/scripts/pnpm/lib/dev-reload-log-utils.mjs +32 -0
  360. package/scripts/pnpm/lib/resolve-aifabrix-bin.mjs +124 -0
  361. package/scripts/pnpm/lib/resolve-app-url.mjs +183 -0
  362. package/scripts/pnpm/lib/spinner.mjs +42 -0
  363. package/scripts/stage_builder_api_for_docker.js +65 -0
  364. package/scripts/sync-builder-api-template.js +44 -0
  365. package/templates/README.md +3 -0
  366. package/templates/applications/builder-api/Dockerfile +38 -0
  367. package/templates/applications/builder-api/application.yaml +75 -0
  368. package/templates/applications/builder-api/env.template +48 -0
  369. package/templates/applications/dataplane/application.yaml +1 -1
  370. package/templates/applications/dataplane/env.template +10 -6
  371. package/templates/applications/dataplane/rbac.yaml +21 -1
  372. package/templates/applications/miso-controller/application.yaml +1 -1
  373. package/templates/applications/miso-controller/env.template +1 -3
  374. package/templates/channels/README.md +18 -0
  375. package/templates/channels/ai-fabrix-icon.jpg +0 -0
  376. package/templates/channels/chatgpt/install.template.md.hbs +21 -24
  377. package/templates/channels/chatgpt/integration/README.md +11 -0
  378. package/templates/channels/chatgpt/integration/application.json +15 -0
  379. package/templates/channels/chatgpt/integration/chatgpt-system.json +29 -0
  380. package/templates/channels/chatgpt/integration/env.template +4 -0
  381. package/templates/channels/microsoft-copilot/install.template.md.hbs +20 -25
  382. package/templates/channels/microsoft-copilot/integration/README.md +11 -0
  383. package/templates/channels/microsoft-copilot/integration/application.json +15 -0
  384. package/templates/channels/microsoft-copilot/integration/env.template +6 -0
  385. package/templates/channels/microsoft-copilot/integration/microsoft-copilot-system.json +34 -0
  386. package/templates/channels/slack/install.template.md.hbs +48 -18
  387. package/templates/channels/slack/integration/README.md +38 -0
  388. package/templates/channels/slack/integration/application.json +18 -0
  389. package/templates/channels/slack/integration/env.template +29 -0
  390. package/templates/channels/slack/integration/slack-datasource-conversations.json +226 -0
  391. package/templates/channels/slack/integration/slack-datasource-messages.json +269 -0
  392. package/templates/channels/slack/integration/slack-system.json +86 -0
  393. package/templates/channels/slack/manifest.template.json.hbs +20 -10
  394. package/templates/channels/teams-bot/install.template.md.hbs +31 -17
  395. package/templates/channels/teams-bot/integration/README.md +18 -0
  396. package/templates/channels/teams-bot/integration/application.json +17 -0
  397. package/templates/channels/teams-bot/integration/env.template +5 -0
  398. package/templates/channels/teams-bot/integration/teams-bot-system.json +55 -0
  399. package/templates/channels/teams-bot/manifest.template.json.hbs +27 -0
  400. package/templates/channels/web-embed/install.template.md.hbs +16 -26
  401. package/templates/channels/web-embed/integration/README.md +11 -0
  402. package/templates/channels/web-embed/integration/application.json +15 -0
  403. package/templates/channels/web-embed/integration/env.template +4 -0
  404. package/templates/channels/web-embed/integration/web-embed-system.json +29 -0
  405. package/templates/openapi/redoc_page.html +86 -0
  406. package/templates/python/docker-compose.hbs +11 -0
  407. package/templates/python/requirements.txt +1 -1
  408. package/templates/typescript/docker-compose.hbs +11 -0
  409. package/lib/certification/cli-cert-sync-skip.js +0 -21
@@ -394,7 +394,7 @@
394
394
  ]
395
395
  },
396
396
  "oidc": {
397
- "active": false,
397
+ "active": true,
398
398
  "display": {
399
399
  "label": "OIDC",
400
400
  "order": 5
@@ -485,7 +485,7 @@
485
485
  ]
486
486
  },
487
487
  "hmac": {
488
- "active": false,
488
+ "active": true,
489
489
  "display": {
490
490
  "label": "HMAC",
491
491
  "order": 6
@@ -279,6 +279,15 @@
279
279
  }
280
280
  },
281
281
  "additionalProperties": false
282
+ },
283
+ "fieldHints": {
284
+ "type": "object",
285
+ "description": "Optional per-field extraction hints for governed FK review (plan 441.1).",
286
+ "additionalProperties": {
287
+ "type": "string",
288
+ "minLength": 1,
289
+ "maxLength": 512
290
+ }
282
291
  }
283
292
  },
284
293
  "additionalProperties": false
@@ -90,7 +90,7 @@ function logTrustWarningsAndFindings(run, opts) {
90
90
  function logTrustFooter(run, opts) {
91
91
  logger.log('');
92
92
  logger.log(metaGray(' ── Integration reality (informative) ──'));
93
- logger.log(metaGray(` Local manifest: ${opts.noSync ? 'not uploaded (--no-sync)' : 'uploaded before run'}`));
93
+ logger.log(metaGray(` Local manifest: ${opts.noPublish ? 'not uploaded (--no-publish)' : 'uploaded before run'}`));
94
94
  logger.log(metaGray(` Publish gate: ${publishGateLine(run.trustDecision, opts.strict === true)}`));
95
95
  logger.log(SEP);
96
96
  }
@@ -0,0 +1,168 @@
1
+ /**
2
+ * Resolve Connected Systems vs Enterprise Knowledge authoring trees (456.5).
3
+ *
4
+ * @fileoverview Workspace resolution from systemKind and CLI --workspace
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const path = require('path');
12
+ const fs = require('../internal/fs-real-sync');
13
+ const {
14
+ WORKSPACE_ENTERPRISE_KNOWLEDGE,
15
+ SYSTEM_KIND_ENTERPRISE_KNOWLEDGE,
16
+ getEnterpriseKnowledgePath
17
+ } = require('./enterprise-knowledge-paths');
18
+
19
+ const WORKSPACE_INTEGRATION = 'integration';
20
+
21
+ /**
22
+ * Reads systemKind from <app>-system.json when present.
23
+ * @param {string} appPath - Anchor directory
24
+ * @param {string} appName - Anchor key
25
+ * @returns {string|null}
26
+ */
27
+ function readSystemKindFromAppDir(appPath, appName) {
28
+ if (!appPath || !appName) {
29
+ return null;
30
+ }
31
+ const systemFile = path.join(appPath, `${appName}-system.json`);
32
+ if (!fs.existsSync(systemFile)) {
33
+ return null;
34
+ }
35
+ try {
36
+ const raw = JSON.parse(fs.readFileSync(systemFile, 'utf8'));
37
+ const kind = raw && (raw.systemKind || raw.systemKindKey);
38
+ return typeof kind === 'string' && kind.trim() ? kind.trim() : null;
39
+ } catch {
40
+ return null;
41
+ }
42
+ }
43
+
44
+ /**
45
+ * @param {string} dirPath
46
+ * @returns {boolean}
47
+ */
48
+ function isExistingDirectory(dirPath) {
49
+ try {
50
+ return fs.existsSync(dirPath) && fs.statSync(dirPath).isDirectory();
51
+ } catch {
52
+ return false;
53
+ }
54
+ }
55
+
56
+ /**
57
+ * @param {string|undefined|null} raw
58
+ * @returns {string|null}
59
+ */
60
+ function normalizeWorkspaceOverride(raw) {
61
+ if (raw === undefined || raw === null || raw === '') {
62
+ return null;
63
+ }
64
+ const v = String(raw).trim().toLowerCase();
65
+ if (v === WORKSPACE_INTEGRATION || v === WORKSPACE_ENTERPRISE_KNOWLEDGE) {
66
+ return v;
67
+ }
68
+ throw new Error(`Unknown workspace "${raw}". Use integration or enterprise-knowledge.`);
69
+ }
70
+
71
+ function workspacePair(appPath, baseDir) {
72
+ return { appPath, baseDir };
73
+ }
74
+
75
+ function resolveFromWorkspaceOverride(workspaceOverride, appName, getIntegrationPath) {
76
+ if (workspaceOverride === WORKSPACE_ENTERPRISE_KNOWLEDGE) {
77
+ return workspacePair(getEnterpriseKnowledgePath(appName), WORKSPACE_ENTERPRISE_KNOWLEDGE);
78
+ }
79
+ if (workspaceOverride === WORKSPACE_INTEGRATION) {
80
+ return workspacePair(getIntegrationPath(appName), WORKSPACE_INTEGRATION);
81
+ }
82
+ return null;
83
+ }
84
+
85
+ function resolveAmbiguousWorkspace(ekPath, intPath, explicitKind, appName) {
86
+ const kind =
87
+ explicitKind ||
88
+ readSystemKindFromAppDir(ekPath, appName) ||
89
+ readSystemKindFromAppDir(intPath, appName);
90
+ if (kind === SYSTEM_KIND_ENTERPRISE_KNOWLEDGE) {
91
+ return workspacePair(ekPath, WORKSPACE_ENTERPRISE_KNOWLEDGE);
92
+ }
93
+ return workspacePair(intPath, WORKSPACE_INTEGRATION);
94
+ }
95
+
96
+ function resolveFromExistingPaths(ekPath, intPath, ekExists, intExists, explicitKind, appName) {
97
+ if (ekExists && !intExists) {
98
+ return workspacePair(ekPath, WORKSPACE_ENTERPRISE_KNOWLEDGE);
99
+ }
100
+ if (intExists && !ekExists) {
101
+ return workspacePair(intPath, WORKSPACE_INTEGRATION);
102
+ }
103
+ if (ekExists && intExists) {
104
+ return resolveAmbiguousWorkspace(ekPath, intPath, explicitKind, appName);
105
+ }
106
+ const kind = explicitKind || readSystemKindFromAppDir(intPath, appName);
107
+ if (kind === SYSTEM_KIND_ENTERPRISE_KNOWLEDGE) {
108
+ return workspacePair(ekPath, WORKSPACE_ENTERPRISE_KNOWLEDGE);
109
+ }
110
+ return workspacePair(intPath, WORKSPACE_INTEGRATION);
111
+ }
112
+
113
+ /**
114
+ * Resolves authoring tree for an external system or Enterprise Knowledge anchor.
115
+ * @param {string} appName - App or anchor key
116
+ * @param {Object} [options]
117
+ * @param {string} [options.workspace] - integration | enterprise-knowledge
118
+ * @param {string} [options.systemKind] - Explicit systemKind override
119
+ * @returns {{ appPath: string, baseDir: 'integration' | 'enterprise-knowledge' }}
120
+ */
121
+ function resolveAppWorkspace(appName, options = {}) {
122
+ if (!appName || typeof appName !== 'string') {
123
+ throw new Error('App name is required and must be a string');
124
+ }
125
+ const { getIntegrationPath } = require('./paths');
126
+ const workspaceOverride = normalizeWorkspaceOverride(options.workspace);
127
+ const explicitKind = typeof options.systemKind === 'string' ? options.systemKind.trim() : '';
128
+
129
+ const fromOverride = resolveFromWorkspaceOverride(
130
+ workspaceOverride,
131
+ appName,
132
+ getIntegrationPath
133
+ );
134
+ if (fromOverride) {
135
+ return fromOverride;
136
+ }
137
+
138
+ const ekPath = getEnterpriseKnowledgePath(appName);
139
+ const intPath = getIntegrationPath(appName);
140
+ return resolveFromExistingPaths(
141
+ ekPath,
142
+ intPath,
143
+ isExistingDirectory(ekPath),
144
+ isExistingDirectory(intPath),
145
+ explicitKind,
146
+ appName
147
+ );
148
+ }
149
+
150
+ /**
151
+ * Absolute path for external / Enterprise Knowledge anchor files.
152
+ * @param {string} appName
153
+ * @param {Object} [options]
154
+ * @returns {string}
155
+ */
156
+ function resolveExternalSystemPath(appName, options = {}) {
157
+ return resolveAppWorkspace(appName, options).appPath;
158
+ }
159
+
160
+ module.exports = {
161
+ WORKSPACE_INTEGRATION,
162
+ WORKSPACE_ENTERPRISE_KNOWLEDGE,
163
+ SYSTEM_KIND_ENTERPRISE_KNOWLEDGE,
164
+ readSystemKindFromAppDir,
165
+ normalizeWorkspaceOverride,
166
+ resolveAppWorkspace,
167
+ resolveExternalSystemPath
168
+ };
@@ -0,0 +1,222 @@
1
+ /**
2
+ * Multi-slot authentications[] helpers for env.template repair (454.11).
3
+ *
4
+ * @fileoverview KV env names and paths per authentication usage slot
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const { getAuthCredentialTemplate } = require('./authentication-shape');
10
+ const { isPlatformCatalogKvRef, isLegacyKvValue } = require('./platform-kv-ref');
11
+ const {
12
+ kvEnvKeyToPath,
13
+ securityKeyToVar,
14
+ systemKeyToKvPrefix
15
+ } = require('./credential-secrets-env');
16
+ const { getKvPathSegmentForSecurityKey } = require('./credential-secrets-env-kv');
17
+
18
+ /**
19
+ * @param {string} slotKey
20
+ * @returns {string}
21
+ */
22
+ function slotKeyToEnvSegment(slotKey) {
23
+ if (!slotKey || slotKey === 'default') {
24
+ return '';
25
+ }
26
+ return `_${String(slotKey).replace(/-/g, '_').toUpperCase()}`;
27
+ }
28
+
29
+ /**
30
+ * @param {string} prefix
31
+ * @param {string} slotKey
32
+ * @param {string} securityKey
33
+ * @returns {string}
34
+ */
35
+ function buildSlotEnvName(prefix, slotKey, securityKey) {
36
+ return `KV_${prefix}${slotKeyToEnvSegment(slotKey)}_${securityKeyToVar(securityKey)}`;
37
+ }
38
+
39
+ /**
40
+ * @param {string} systemKey
41
+ * @param {string} slotKey
42
+ * @param {string} securityKey
43
+ * @returns {string|null}
44
+ */
45
+ function buildSlotKvPath(systemKey, slotKey, securityKey) {
46
+ const segment = getKvPathSegmentForSecurityKey(securityKey);
47
+ if (!segment) {
48
+ return null;
49
+ }
50
+ if (slotKey && slotKey !== 'default') {
51
+ return `kv://${systemKey}/${slotKey}/${segment}`;
52
+ }
53
+ return `kv://${systemKey}/${segment}`;
54
+ }
55
+
56
+ /**
57
+ * @param {Array} effective
58
+ * @param {Set<string>} seenNames
59
+ * @param {string} systemKey
60
+ * @param {string} prefix
61
+ * @param {object} authBlock
62
+ * @param {string} slotKey
63
+ */
64
+ function addSecurityKeysFromAuthBlock(
65
+ effective,
66
+ seenNames,
67
+ systemKey,
68
+ prefix,
69
+ authBlock,
70
+ slotKey
71
+ ) {
72
+ const credential = getAuthCredentialTemplate(authBlock);
73
+ const security = credential?.security ?? authBlock?.security;
74
+ if (!security || typeof security !== 'object') {
75
+ return;
76
+ }
77
+ for (const key of Object.keys(security)) {
78
+ const securityVal = security[key];
79
+ if (typeof securityVal === 'string' && isPlatformCatalogKvRef(securityVal)) {
80
+ continue;
81
+ }
82
+ const envName = buildSlotEnvName(prefix, slotKey, key);
83
+ if (seenNames.has(envName)) {
84
+ continue;
85
+ }
86
+ const pathVal =
87
+ kvEnvKeyToPath(envName, systemKey) || buildSlotKvPath(systemKey, slotKey, key);
88
+ if (!pathVal) {
89
+ continue;
90
+ }
91
+ effective.push({
92
+ name: envName,
93
+ value: pathVal.replace(/^kv:\/\//, ''),
94
+ location: 'keyvault'
95
+ });
96
+ seenNames.add(envName);
97
+ }
98
+ }
99
+
100
+ /**
101
+ * @param {Array} effective
102
+ * @param {object} systemParsed
103
+ * @param {string} prefix
104
+ * @param {Set<string>} seenNames
105
+ * @param {string} systemKey
106
+ */
107
+ function addFromAuthenticationsArray(effective, systemParsed, prefix, seenNames, systemKey) {
108
+ const rows = systemParsed.authentications;
109
+ if (!Array.isArray(rows) || rows.length === 0) {
110
+ return;
111
+ }
112
+ for (const row of rows) {
113
+ if (!row || typeof row !== 'object') {
114
+ continue;
115
+ }
116
+ const slotKey = typeof row.key === 'string' && row.key.trim() ? row.key.trim() : 'default';
117
+ addSecurityKeysFromAuthBlock(effective, seenNames, systemKey, prefix, row, slotKey);
118
+ }
119
+ }
120
+
121
+ /**
122
+ * @param {object} system
123
+ * @returns {Array<{name: string, value: string, usage?: string}>}
124
+ */
125
+ function buildAuthSecureVarsFromAllSlots(system) {
126
+ const systemKey = system?.key || 'external-system';
127
+ const prefix = systemKeyToKvPrefix(systemKey);
128
+ if (!prefix) {
129
+ return [];
130
+ }
131
+ const effective = [];
132
+ const seenNames = new Set();
133
+ addFromAuthenticationsArray(effective, system, prefix, seenNames, systemKey);
134
+ if (effective.length > 0) {
135
+ const rows = Array.isArray(system.authentications) ? system.authentications : [];
136
+ return effective.map((entry) => {
137
+ const suffix = entry.name.slice(`KV_${prefix}`.length);
138
+ const slot = rows.find((row) => {
139
+ const seg = slotKeyToEnvSegment(row?.key || 'default');
140
+ return seg && suffix.startsWith(`${seg}_`);
141
+ });
142
+ let value = entry.value;
143
+ if (entry.location === 'keyvault' && value && !String(value).startsWith('kv://')) {
144
+ value = `kv://${value}`;
145
+ }
146
+ return {
147
+ ...entry,
148
+ value,
149
+ usage: slot?.usage || 'api'
150
+ };
151
+ });
152
+ }
153
+ return [];
154
+ }
155
+
156
+ /**
157
+ * @param {object} security
158
+ * @param {string} prefix
159
+ * @param {string} systemKey
160
+ * @param {string} slotKey
161
+ * @param {string[]} changes
162
+ * @returns {boolean}
163
+ */
164
+ function normalizeAuthSlotSecurity(security, prefix, systemKey, slotKey, changes) {
165
+ let updated = false;
166
+ for (const key of Object.keys(security)) {
167
+ const val = security[key];
168
+ if (typeof val !== 'string' || !isLegacyKvValue(val)) {
169
+ continue;
170
+ }
171
+ const envName = buildSlotEnvName(prefix, slotKey, key);
172
+ const pathVal = kvEnvKeyToPath(envName, systemKey) || buildSlotKvPath(systemKey, slotKey, key);
173
+ if (pathVal) {
174
+ security[key] = pathVal;
175
+ changes.push(
176
+ `authentications[${slotKey}].security.${key}: normalized to path-style ${pathVal}`
177
+ );
178
+ updated = true;
179
+ }
180
+ }
181
+ return updated;
182
+ }
183
+
184
+ /**
185
+ * @param {object} systemParsed
186
+ * @param {string} systemKey
187
+ * @param {string[]} changes
188
+ * @returns {boolean}
189
+ */
190
+ function normalizeAuthenticationsSecurity(systemParsed, systemKey, changes) {
191
+ const prefix = systemKeyToKvPrefix(systemKey);
192
+ if (!prefix) {
193
+ return false;
194
+ }
195
+ const rows = systemParsed.authentications;
196
+ if (!Array.isArray(rows) || rows.length === 0) {
197
+ return false;
198
+ }
199
+ let updated = false;
200
+ for (const row of rows) {
201
+ if (!row || typeof row !== 'object') {
202
+ continue;
203
+ }
204
+ const slotKey = typeof row.key === 'string' && row.key.trim() ? row.key.trim() : 'default';
205
+ const credential = getAuthCredentialTemplate(row);
206
+ const security = credential?.security ?? row.security;
207
+ if (security && typeof security === 'object') {
208
+ updated =
209
+ normalizeAuthSlotSecurity(security, prefix, systemKey, slotKey, changes) || updated;
210
+ }
211
+ }
212
+ return updated;
213
+ }
214
+
215
+ module.exports = {
216
+ addFromAuthenticationsArray,
217
+ buildAuthSecureVarsFromAllSlots,
218
+ buildSlotEnvName,
219
+ buildSlotKvPath,
220
+ normalizeAuthenticationsSecurity,
221
+ slotKeyToEnvSegment
222
+ };
@@ -1,33 +1,29 @@
1
1
  /**
2
- * @fileoverview Detect skip-sync from Commander options and raw argv (--no-sync → sync: false).
2
+ * @fileoverview Detect skip-manifest-publish from Commander options (--no-publish).
3
3
  * @author AI Fabrix Team
4
- * @version 1.0.0
4
+ * @version 2.0.0
5
5
  */
6
6
 
7
7
  'use strict';
8
8
 
9
9
  /**
10
- * True when the user passed `--no-sync` or Commander set `sync: false` / `noSync: true`.
11
- * Do not use for `protection upload --no-sync` (post-upload datasource sync only).
10
+ * True when the user passed `--no-publish` or set `noPublish: true` (programmatic).
12
11
  *
13
12
  * @param {Object|null|undefined} options - Commander-parsed options
14
13
  * @param {import('commander').Command} [cmd] - Commander command (for rawArgs fallback)
15
14
  * @returns {boolean}
16
15
  */
17
- function cliOptsSkipSync(options, cmd) {
16
+ function cliOptsSkipPublish(options, cmd) {
18
17
  if (!options || typeof options !== 'object') {
19
18
  return false;
20
19
  }
21
- if (options.noSync === true) {
22
- return true;
23
- }
24
- if (options.sync === false) {
20
+ if (options.noPublish === true) {
25
21
  return true;
26
22
  }
27
23
  const raw = cmd && Array.isArray(cmd.rawArgs) ? cmd.rawArgs : [];
28
- return raw.includes('--no-sync');
24
+ return raw.includes('--no-publish');
29
25
  }
30
26
 
31
27
  module.exports = {
32
- cliOptsSkipSync
28
+ cliOptsSkipPublish
33
29
  };
@@ -336,6 +336,10 @@ function tryFormatErrorWithFormatters(errorMsg) {
336
336
  }
337
337
 
338
338
  function formatError(error) {
339
+ if (error && error.gateFailure === true) {
340
+ return [` ${error.message || 'Deploy gate failed'}`];
341
+ }
342
+
339
343
  // If error has formatted message (from API error handler), use it directly
340
344
  if (error.formatted) {
341
345
  return formatFormattedError(error.formatted);
@@ -0,0 +1,29 @@
1
+ /**
2
+ * CLI workspace helpers (456.5) — auto-detect only; `--workspace` flag removed in 155.0.
3
+ *
4
+ * @fileoverview Path options for external / Enterprise Knowledge anchors
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ /**
12
+ * @param {Object} [_cliOptions]
13
+ * @returns {{}}
14
+ */
15
+ function workspaceDetectionOptions(_cliOptions = {}) {
16
+ return {};
17
+ }
18
+
19
+ /**
20
+ * @returns {null}
21
+ */
22
+ function workspaceOptionDefinition() {
23
+ return null;
24
+ }
25
+
26
+ module.exports = {
27
+ workspaceDetectionOptions,
28
+ workspaceOptionDefinition
29
+ };
@@ -12,6 +12,11 @@ const fsSync = require('fs');
12
12
  const path = require('path');
13
13
  const buildCopy = require('./build-copy');
14
14
  const paths = require('./paths');
15
+ const { isSystemBuilderAppName } = require('./paths-system-builder-keys');
16
+ const {
17
+ isValidReloadSourceRoot,
18
+ resolveSystemAppReloadSourceRoot
19
+ } = require('./paths-reload-source');
15
20
  const { getInfraDirName } = require('../infrastructure/helpers');
16
21
  const { resolveMisoEnvironment } = require('./compose-miso-env');
17
22
  const { buildCeleryWorkerComposeContext } = require('./compose-celery-worker');
@@ -131,11 +136,106 @@ function resolveInfraPgpassPath(devId, pathsUtil, existsSyncFn = fsSync.existsSy
131
136
  : sysPgpass;
132
137
  }
133
138
 
139
+ /**
140
+ * Builder manifest paths to try when resolving storage mount source (CI-safe order).
141
+ *
142
+ * @param {string} appName
143
+ * @returns {string[]}
144
+ */
145
+ function collectComposeBuilderPathCandidates(appName) {
146
+ const candidates = [];
147
+ const seen = new Set();
148
+ const push = (candidate) => {
149
+ if (candidate && typeof candidate === 'string' && !seen.has(candidate)) {
150
+ seen.add(candidate);
151
+ candidates.push(candidate);
152
+ }
153
+ };
154
+ push(paths.getCwdBuilderAppPath(appName));
155
+ const projectRoot = paths.getProjectRoot();
156
+ if (projectRoot) {
157
+ push(path.join(projectRoot, 'builder', appName));
158
+ }
159
+ try {
160
+ push(paths.getBuilderPath(appName));
161
+ } catch {
162
+ // materialized builder path unavailable in this environment
163
+ }
164
+ return candidates;
165
+ }
166
+
167
+ /**
168
+ * @param {string} appName
169
+ * @param {string} buildContext
170
+ * @returns {string|null}
171
+ */
172
+ function resolveStorageMountSourceRoot(appName, buildContext) {
173
+ for (const builderPath of collectComposeBuilderPathCandidates(appName)) {
174
+ const sourceRoot = resolveSystemAppReloadSourceRoot(appName, builderPath, buildContext);
175
+ if (!isSystemBuilderAppName(appName) || isValidReloadSourceRoot(appName, sourceRoot)) {
176
+ return sourceRoot;
177
+ }
178
+ }
179
+ const projectRoot = paths.getProjectRoot();
180
+ if (
181
+ projectRoot &&
182
+ (!isSystemBuilderAppName(appName) || isValidReloadSourceRoot(appName, projectRoot))
183
+ ) {
184
+ return projectRoot;
185
+ }
186
+ return null;
187
+ }
188
+
189
+ /**
190
+ * Host `mount/` directory bind-mounted to `/mnt/data` when storage is required.
191
+ *
192
+ * @param {object} ctx - Compose template context (`devMountPath`, `appName`, `appConfig`, `serviceConfig`)
193
+ * @returns {string|null}
194
+ */
195
+ function resolveLocalDataMountPathForCompose(ctx) {
196
+ if (ctx.devMountPath && typeof ctx.devMountPath === 'string') {
197
+ return path.join(ctx.devMountPath, 'mount').replace(/\\/g, '/');
198
+ }
199
+ const requiresStorage =
200
+ ctx.serviceConfig?.requiresStorage ||
201
+ ctx.appConfig?.requires?.storage ||
202
+ ctx.appConfig?.services?.storage ||
203
+ false;
204
+ if (!requiresStorage || !ctx.appName) {
205
+ return null;
206
+ }
207
+ try {
208
+ const sourceRoot = resolveStorageMountSourceRoot(
209
+ ctx.appName,
210
+ ctx.appConfig?.build?.context || '../..'
211
+ );
212
+ if (!sourceRoot) {
213
+ return null;
214
+ }
215
+ return path.join(sourceRoot, 'mount').replace(/\\/g, '/');
216
+ } catch {
217
+ return null;
218
+ }
219
+ }
220
+
134
221
  /**
135
222
  * @param {object} ctx - Template context fields
136
223
  * @returns {object} Spread-ready payload for Handlebars template
137
224
  */
138
225
  function buildComposeTemplateContext(ctx) {
226
+ const localDataMountPath = resolveLocalDataMountPathForCompose(ctx);
227
+ const requiresStorage =
228
+ ctx.serviceConfig?.requiresStorage ||
229
+ ctx.appConfig?.requires?.storage ||
230
+ ctx.appConfig?.services?.storage ||
231
+ false;
232
+ if (localDataMountPath && requiresStorage && !fsSync.existsSync(localDataMountPath)) {
233
+ try {
234
+ fsSync.mkdirSync(localDataMountPath, { recursive: true });
235
+ } catch {
236
+ // Non-fatal: tests may use non-writable devMountPath; host must create mount/ before run.
237
+ }
238
+ }
139
239
  return {
140
240
  ...ctx.serviceConfig,
141
241
  ...ctx.volumesConfig,
@@ -150,6 +250,7 @@ function buildComposeTemplateContext(ctx) {
150
250
  containerName: ctx.containerName,
151
251
  misoEnvironment: resolveMisoEnvironment(ctx.options),
152
252
  devMountPath: ctx.devMountPath,
253
+ localDataMountPath,
153
254
  reloadStartCommand: ctx.reloadStartCommand,
154
255
  infraPgpassPath: ctx.useInfraPgpass ? ctx.infraPgpassPath : null,
155
256
  useInfraPgpass: !!ctx.useInfraPgpass,
@@ -339,6 +440,7 @@ function createGenerateDockerCompose(deps) {
339
440
  module.exports = {
340
441
  createGenerateDockerCompose,
341
442
  resolveInfraPgpassPath,
443
+ resolveLocalDataMountPathForCompose,
342
444
  derivePythonImageStartFromReload,
343
445
  buildReloadStartCommandForCompose,
344
446
  normalizePythonReloadForComposeMounted