@aifabrix/builder 2.45.5 → 2.47.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 (355) hide show
  1. package/.cursor/rules/cli-layout.mdc +2 -0
  2. package/.cursor/rules/cli-product-neutral.mdc +43 -0
  3. package/.cursor/rules/project-rules.mdc +1 -0
  4. package/.npmrc.token +1 -0
  5. package/.temp/jest-protection-convert/run-IFN2nv/.protection/hubspot-companies.json +1 -0
  6. package/.temp/jest-protection-convert/run-IvmKLO/.protection/hubspot-companies.yaml +17 -0
  7. package/.temp/jest-protection-convert/run-SdvblF/.protection/hubspot-companies.json +1 -0
  8. package/.temp/jest-protection-convert/run-b51TsW/.protection/hubspot-companies.json +1 -0
  9. package/.temp/jest-protection-convert/run-fiLmb1/.protection/hubspot-companies.json +1 -0
  10. package/.temp/jest-protection-convert/run-qYGHMU/.protection/hubspot-companies.yaml +17 -0
  11. package/.temp/jest-protection-fixtures/hubspot-Mq5re8/hubspot-companies.yaml +17 -0
  12. package/.temp/jest-protection-fixtures/hubspot-f3u4YL/hubspot-companies.yaml +17 -0
  13. package/.temp/jest-protection-fixtures/hubspot-iQtd1O/hubspot-companies.yaml +17 -0
  14. package/.temp/jest-protection-fixtures/hubspot-mdmz5M/hubspot-companies.yaml +17 -0
  15. package/.temp/jest-protection-fixtures/hubspot-qbKYxQ/hubspot-companies.yaml +17 -0
  16. package/.temp/jest-protection-fixtures/hubspot-yzlJy6/hubspot-companies.yaml +17 -0
  17. package/.temp/validation/summary.txt +5 -0
  18. package/README.md +43 -17
  19. package/integration/hubspot-test/test-artifacts/wizard-hubspot-credential-real.yaml +1 -1
  20. package/integration/hubspot-test/test-artifacts/wizard-hubspot-env-vars.yaml +1 -1
  21. package/jest.config.default.js +2 -1
  22. package/jest.config.isolated.js +2 -1
  23. package/jest.global-live-fabrix-hooks.js +36 -0
  24. package/jest.isolated-projects.js +146 -0
  25. package/jest.projects.js +65 -136
  26. package/lib/api/api-response-errors.js +124 -0
  27. package/lib/api/dataplane-health.api.js +19 -7
  28. package/lib/api/governance-scenario-pack.api.js +159 -0
  29. package/lib/api/index.js +43 -3
  30. package/lib/api/lifecycle.api.js +98 -0
  31. package/lib/api/pipeline.api.js +3 -1
  32. package/lib/api/records-bulk.api.js +14 -1
  33. package/lib/api/resource-types.api.js +107 -0
  34. package/lib/api/runtime-configuration.api.js +72 -0
  35. package/lib/api/types/resource-types.types.js +45 -0
  36. package/lib/api/user-groups.api.js +9 -9
  37. package/lib/api/users.api.js +8 -8
  38. package/lib/api/validation-runner.js +3 -1
  39. package/lib/api/wizard.api.js +10 -2
  40. package/lib/app/deploy-config.js +4 -1
  41. package/lib/app/down.js +78 -27
  42. package/lib/app/index.js +2 -2
  43. package/lib/app/push.js +4 -5
  44. package/lib/app/register.js +7 -4
  45. package/lib/app/run-env-compose.js +84 -30
  46. package/lib/app/run-resolve-image.js +2 -1
  47. package/lib/app/run-stop-containers.js +113 -0
  48. package/lib/app/run.js +1 -31
  49. package/lib/app/show-display.js +35 -0
  50. package/lib/app/show.js +32 -1
  51. package/lib/build/index.js +22 -5
  52. package/lib/build/miso-controller-npm-sdk-guard.js +25 -0
  53. package/lib/certification/sync-system-certification.js +13 -6
  54. package/lib/channels/add-channel.js +348 -0
  55. package/lib/channels/channel-artifact-generator.js +141 -0
  56. package/lib/channels/channel-audit.js +101 -0
  57. package/lib/channels/channel-auth-context.js +37 -0
  58. package/lib/channels/channel-credential.js +200 -0
  59. package/lib/channels/channel-display-name.js +64 -0
  60. package/lib/channels/channel-external-system.js +106 -0
  61. package/lib/channels/channel-integration-generator.js +274 -0
  62. package/lib/channels/channel-probe.js +89 -0
  63. package/lib/channels/channel-runtime-resolver.js +152 -0
  64. package/lib/channels/channel-status-display.js +141 -0
  65. package/lib/channels/channel-targets.js +115 -0
  66. package/lib/cli/index.js +20 -4
  67. package/lib/cli/infra-guided-auth.js +109 -0
  68. package/lib/cli/infra-guided.js +84 -81
  69. package/lib/cli/setup-app.help.js +0 -31
  70. package/lib/cli/setup-app.js +82 -5
  71. package/lib/cli/setup-app.test-commands.js +5 -57
  72. package/lib/cli/setup-auth.js +25 -0
  73. package/lib/cli/setup-certification-commands.js +147 -0
  74. package/lib/cli/setup-certification.help.js +141 -0
  75. package/lib/cli/setup-environment.js +19 -2
  76. package/lib/cli/setup-external-system-help.js +62 -0
  77. package/lib/cli/setup-external-system.js +25 -3
  78. package/lib/cli/setup-infra-up-dataplane-action.js +2 -2
  79. package/lib/cli/setup-infra-up-platform-action.js +2 -1
  80. package/lib/cli/setup-infra.js +9 -1
  81. package/lib/cli/setup-platform.js +6 -1
  82. package/lib/cli/setup-secrets.js +33 -1
  83. package/lib/cli/setup-utility-help-after.js +25 -2
  84. package/lib/cli/setup-utility-repair.js +198 -0
  85. package/lib/cli/setup-utility-resolve.js +44 -5
  86. package/lib/cli/setup-utility-validate.js +197 -0
  87. package/lib/cli/setup-utility.js +4 -239
  88. package/lib/commands/app-logs.js +54 -26
  89. package/lib/commands/app.js +41 -0
  90. package/lib/commands/auth-status-client-tokens.js +214 -0
  91. package/lib/commands/auth-status-dataplane-version.js +142 -68
  92. package/lib/commands/auth-status.js +43 -54
  93. package/lib/commands/channel.js +58 -0
  94. package/lib/commands/datasource-test-trust-cli.js +27 -23
  95. package/lib/commands/datasource-unified-test-cli.js +6 -3
  96. package/lib/commands/datasource-unified-test-cli.options.js +5 -1
  97. package/lib/commands/datasource.js +8 -8
  98. package/lib/commands/dev-show-display.js +8 -1
  99. package/lib/commands/governance-cli-shared.js +94 -0
  100. package/lib/commands/governance-command-action.js +132 -0
  101. package/lib/commands/governance-download-external.js +34 -0
  102. package/lib/commands/governance-generate-external.js +71 -0
  103. package/lib/commands/governance-upload-external.js +36 -0
  104. package/lib/commands/governance-verify-external.js +64 -0
  105. package/lib/commands/governance.js +144 -0
  106. package/lib/commands/identity-apply-sync.js +49 -8
  107. package/lib/commands/identity-group-cli.js +66 -26
  108. package/lib/commands/identity-membership-role-cache.js +58 -37
  109. package/lib/commands/identity-shared.js +22 -1
  110. package/lib/commands/identity-user-cli.js +80 -34
  111. package/lib/commands/lifecycle-command-action.js +123 -0
  112. package/lib/commands/lifecycle-external.js +268 -0
  113. package/lib/commands/login.js +11 -2
  114. package/lib/commands/repair-auth-apply.js +153 -0
  115. package/lib/commands/repair-auth-config.js +8 -13
  116. package/lib/commands/repair-changed-files.js +41 -0
  117. package/lib/commands/repair-datasource-com-v2.js +15 -0
  118. package/lib/commands/repair-datasource-keys.js +4 -1
  119. package/lib/commands/repair-datasource-run.js +59 -0
  120. package/lib/commands/repair-datasource-service-contract.js +206 -0
  121. package/lib/commands/repair-datasource-test-payload.js +259 -0
  122. package/lib/commands/repair-datasource.js +49 -64
  123. package/lib/commands/repair-env-template.js +76 -25
  124. package/lib/commands/repair-external-run.js +216 -0
  125. package/lib/commands/repair-openapi-sync.js +49 -4
  126. package/lib/commands/repair-persist.js +4 -0
  127. package/lib/commands/repair-rbac.js +52 -1
  128. package/lib/commands/repair-steps.js +160 -0
  129. package/lib/commands/repair-system-alignment.js +7 -4
  130. package/lib/commands/repair.js +29 -296
  131. package/lib/commands/resource-type.js +371 -0
  132. package/lib/commands/secrets-get.js +184 -0
  133. package/lib/commands/secrets-remove-all.js +3 -1
  134. package/lib/commands/setup-image-refresh.js +146 -0
  135. package/lib/commands/setup-modes.js +158 -162
  136. package/lib/commands/setup-platform-auth.js +76 -0
  137. package/lib/commands/setup-prompts-admin.js +244 -0
  138. package/lib/commands/setup-prompts-platform-mode.js +70 -0
  139. package/lib/commands/setup-prompts-validators.js +36 -0
  140. package/lib/commands/setup-prompts.js +24 -76
  141. package/lib/commands/setup-run-context.js +45 -0
  142. package/lib/commands/setup-spinners.js +39 -0
  143. package/lib/commands/setup.js +27 -5
  144. package/lib/commands/teardown.js +39 -0
  145. package/lib/commands/test-e2e-external.js +24 -8
  146. package/lib/commands/test-governance-external.js +3 -24
  147. package/lib/commands/test-trust-external.js +48 -100
  148. package/lib/commands/up-common.js +57 -13
  149. package/lib/commands/up-dataplane.js +56 -15
  150. package/lib/commands/upload-publish-context.js +75 -0
  151. package/lib/commands/upload-sidecar-followups.js +89 -0
  152. package/lib/commands/upload.js +113 -110
  153. package/lib/commands/verify-governance-combined-external.js +61 -0
  154. package/lib/commands/verify-governance-command-action.js +64 -0
  155. package/lib/commands/verify-governance-db.js +102 -0
  156. package/lib/commands/verify-governance-external.js +77 -0
  157. package/lib/commands/verify-governance-result-builders.js +71 -0
  158. package/lib/commands/verify-operations-command-action.js +68 -0
  159. package/lib/commands/verify-operations-external.js +268 -0
  160. package/lib/commands/verify-operations-persist.js +75 -0
  161. package/lib/commands/verify-operations-step-plan.js +68 -0
  162. package/lib/commands/verify-operations-steps.js +111 -0
  163. package/lib/commands/verify-trust-command-action.js +73 -0
  164. package/lib/commands/verify-trust-external.js +59 -0
  165. package/lib/commands/wizard-config-normalizer.js +43 -23
  166. package/lib/commands/wizard-core.js +2 -0
  167. package/lib/core/admin-password-generator.js +38 -0
  168. package/lib/core/admin-secrets-bundle.js +111 -0
  169. package/lib/core/admin-secrets-env-overlay.js +62 -0
  170. package/lib/core/admin-secrets.js +32 -4
  171. package/lib/core/config-attach-extensions.js +3 -0
  172. package/lib/core/config-platform-controller.js +44 -0
  173. package/lib/core/config-setup-installation-profile.js +42 -0
  174. package/lib/core/config-setup-platform-mode.js +46 -0
  175. package/lib/core/config.js +46 -36
  176. package/lib/core/secrets-admin-env.js +6 -2
  177. package/lib/core/secrets-ensure.js +4 -0
  178. package/lib/core/secrets-env-content.js +54 -48
  179. package/lib/core/secrets-env-write.js +10 -1
  180. package/lib/core/secrets-infra-placeholder-sync.js +2 -0
  181. package/lib/core/setup-installation-profile.js +43 -0
  182. package/lib/core/setup-platform-mode.js +90 -0
  183. package/lib/datasource/agent-trust-debug-log.js +1 -1
  184. package/lib/datasource/agent-trust-run.js +5 -3
  185. package/lib/datasource/audit-evidence-extract-debug.js +30 -18
  186. package/lib/datasource/audit-evidence-extract.js +7 -4
  187. package/lib/datasource/audit-evidence-verify-matrix.js +54 -26
  188. package/lib/datasource/bulk-loader-run-batches.js +15 -3
  189. package/lib/datasource/capability/capability-diff-slice.js +2 -2
  190. package/lib/datasource/capability/capability-manifest.js +254 -0
  191. package/lib/datasource/capability/capability-resolve.js +3 -4
  192. package/lib/datasource/capability/copy-operations.js +5 -3
  193. package/lib/datasource/capability/remove-operations.js +2 -1
  194. package/lib/datasource/capability/run-capability-copy.js +32 -4
  195. package/lib/datasource/capability/run-capability-diff.js +3 -3
  196. package/lib/datasource/capability/run-capability-dimension.js +2 -4
  197. package/lib/datasource/capability/run-capability-edit.js +4 -7
  198. package/lib/datasource/capability/run-capability-relate.js +2 -4
  199. package/lib/datasource/capability/run-capability-remove.js +2 -4
  200. package/lib/datasource/capability/validate-capability-slice.js +2 -1
  201. package/lib/datasource/datasource-identifier.js +2 -1
  202. package/lib/datasource/datasource-load-export-context.js +3 -0
  203. package/lib/datasource/datasource-validate-display.js +1 -1
  204. package/lib/datasource/field-reference-validator.js +24 -3
  205. package/lib/datasource/log-cleaner.js +2 -2
  206. package/lib/datasource/log-viewer.js +8 -8
  207. package/lib/datasource/orphan-profiles-validator.js +98 -0
  208. package/lib/datasource/test-e2e.js +4 -1
  209. package/lib/datasource/unified-validation-run-body.js +3 -1
  210. package/lib/datasource/unified-validation-run.js +5 -2
  211. package/lib/datasource/validate.js +41 -23
  212. package/lib/deployment/environment-poll-status.js +138 -0
  213. package/lib/deployment/environment.js +42 -34
  214. package/lib/external-system/download-helpers.js +87 -0
  215. package/lib/external-system/download.js +78 -138
  216. package/lib/external-system/generator.js +1 -55
  217. package/lib/external-system/integration-auth-context.js +45 -0
  218. package/lib/external-system/test-auth.js +12 -5
  219. package/lib/external-system/test.js +16 -21
  220. package/lib/generator/builders.js +11 -1
  221. package/lib/generator/external-controller-manifest.js +18 -0
  222. package/lib/generator/split.js +3 -1
  223. package/lib/generator/wizard.js +1 -28
  224. package/lib/governance/governance-cli-errors.js +96 -0
  225. package/lib/governance/governance-download-display.js +38 -0
  226. package/lib/governance/governance-run-display.js +215 -25
  227. package/lib/identity/fk-reference.js +65 -0
  228. package/lib/identity/identity-apply-core.js +13 -58
  229. package/lib/identity/identity-apply-phases.js +5 -1
  230. package/lib/identity/identity-display.js +243 -0
  231. package/lib/identity/identity-response-helpers.js +52 -0
  232. package/lib/identity/identity-sync-errors.js +62 -0
  233. package/lib/identity/resolve-user-id.js +129 -0
  234. package/lib/identity/username-default.js +31 -0
  235. package/lib/infrastructure/admin-secrets-apply.js +84 -0
  236. package/lib/infrastructure/admin-secrets-ensure.js +130 -0
  237. package/lib/infrastructure/admin-secrets-resolve.js +95 -0
  238. package/lib/infrastructure/admin-secrets-sync.js +91 -0
  239. package/lib/infrastructure/helpers.js +23 -129
  240. package/lib/infrastructure/index.js +5 -6
  241. package/lib/infrastructure/orphan-infra-docker-teardown.js +11 -5
  242. package/lib/lifecycle/certification-progress.js +231 -0
  243. package/lib/lifecycle/dataplane-ui-url.js +145 -0
  244. package/lib/lifecycle/exit-codes.js +24 -0
  245. package/lib/lifecycle/json-envelope.js +25 -0
  246. package/lib/lifecycle/lifecycle-governance-options.js +51 -0
  247. package/lib/lifecycle/logger-quiet.js +29 -0
  248. package/lib/lifecycle/open-api-published.js +59 -0
  249. package/lib/lifecycle/operations-readiness-metrics.js +101 -0
  250. package/lib/lifecycle/product-model.js +196 -0
  251. package/lib/lifecycle/report-display-trust.js +70 -0
  252. package/lib/lifecycle/report-display.js +472 -0
  253. package/lib/lifecycle/scenario-upload.js +191 -0
  254. package/lib/lifecycle/verify-step-progress.js +87 -0
  255. package/lib/parameters/infra-kv-discovery.js +27 -2
  256. package/lib/protection/auth-context.js +10 -4
  257. package/lib/resolvers/datasource-resolver.js +2 -3
  258. package/lib/resolvers/resource-type-file.js +159 -0
  259. package/lib/schema/application-schema.json +17 -1
  260. package/lib/schema/datasource-test-run.schema.json +89 -6
  261. package/lib/schema/deployment-rules.yaml +2 -1
  262. package/lib/schema/external-datasource.schema.json +2947 -2619
  263. package/lib/schema/external-system.schema.json +1418 -761
  264. package/lib/schema/infra.parameter.yaml +45 -0
  265. package/lib/schema/type/credential-field-registry.json +103 -97
  266. package/lib/schema/type/document-storage.json +9 -5
  267. package/lib/utils/aifabrix-test-runtime-guard.js +125 -0
  268. package/lib/utils/api.js +55 -31
  269. package/lib/utils/app-relative-path-env.js +112 -0
  270. package/lib/utils/app-run-containers.js +25 -2
  271. package/lib/utils/authentication-shape.js +224 -0
  272. package/lib/utils/build-copy.js +36 -5
  273. package/lib/utils/build-resolve-image.js +66 -12
  274. package/lib/utils/celery-companion-apps.js +53 -0
  275. package/lib/utils/cli-secrets-error-format.js +83 -21
  276. package/lib/utils/cli-utils.js +20 -4
  277. package/lib/utils/compose-celery-worker.js +23 -0
  278. package/lib/utils/compose-generate-docker-compose.js +13 -1
  279. package/lib/utils/compose-traefik-ingress-base.js +16 -1
  280. package/lib/utils/config-secrets-path.js +46 -0
  281. package/lib/utils/configuration-env-resolver.js +36 -0
  282. package/lib/utils/controller-url.js +88 -1
  283. package/lib/utils/credential-secrets-env-kv.js +216 -0
  284. package/lib/utils/credential-secrets-env.js +175 -257
  285. package/lib/utils/dataplane-resolver.js +18 -2
  286. package/lib/utils/declarative-url-ports.js +27 -4
  287. package/lib/utils/deployment-auth-mode.js +41 -0
  288. package/lib/utils/developer-volume-id.js +33 -0
  289. package/lib/utils/docker-build.js +1 -4
  290. package/lib/utils/env-copy.js +14 -9
  291. package/lib/utils/env-kv-orphan-lines.js +43 -0
  292. package/lib/utils/error-formatters/network-errors.js +13 -4
  293. package/lib/utils/external-env-template.js +11 -3
  294. package/lib/utils/external-system-readiness-core.js +10 -0
  295. package/lib/utils/external-system-readiness-display.js +80 -23
  296. package/lib/utils/external-system-validators.js +8 -2
  297. package/lib/utils/health-check.js +4 -1
  298. package/lib/utils/help-builder.js +13 -8
  299. package/lib/utils/keycloak-realm-ready.js +101 -0
  300. package/lib/utils/load-cip-capacity-display-config.js +61 -15
  301. package/lib/utils/manifest-source-emit.js +2 -0
  302. package/lib/utils/paths.js +25 -0
  303. package/lib/utils/pipeline-upload-auth-retry.js +82 -0
  304. package/lib/utils/platform-controller-url.js +157 -0
  305. package/lib/utils/platform-kv-ref.js +57 -0
  306. package/lib/utils/postgres-platform-bootstrap.js +199 -0
  307. package/lib/utils/postgres-wipe.js +9 -2
  308. package/lib/utils/resolve-env-mode.js +47 -0
  309. package/lib/utils/runtime-configuration-download.js +189 -0
  310. package/lib/utils/runtime-configuration-values.js +119 -0
  311. package/lib/utils/schema-loader.js +19 -4
  312. package/lib/utils/secrets-generator.js +31 -25
  313. package/lib/utils/secrets-missing-error.js +164 -0
  314. package/lib/utils/service-url-label.js +81 -0
  315. package/lib/utils/setup-quiet-output.js +25 -0
  316. package/lib/utils/template-helpers.js +15 -0
  317. package/lib/utils/token-manager-client-credentials.js +201 -0
  318. package/lib/utils/token-manager-messages.js +8 -0
  319. package/lib/utils/token-manager-refresh.js +12 -2
  320. package/lib/utils/token-manager.js +86 -105
  321. package/lib/utils/upload-pipeline-ui.js +12 -5
  322. package/lib/utils/upload-sync-options.js +42 -0
  323. package/lib/utils/url-declarative-public-base.js +21 -3
  324. package/lib/utils/url-declarative-vdir-inactive-env.js +14 -4
  325. package/lib/utils/validation-poll-ui.js +8 -0
  326. package/lib/utils/validation-run-stage.js +45 -0
  327. package/lib/utils/worker-sidecars.js +142 -0
  328. package/lib/validation/external-manifest-validator.js +2 -0
  329. package/lib/validation/runtime-configuration-rules.js +98 -0
  330. package/lib/validation/validate-display-dimensions.js +154 -0
  331. package/lib/validation/validate-display-sections.js +276 -0
  332. package/lib/validation/validate-display-steps.js +67 -0
  333. package/lib/validation/validate-display.js +24 -402
  334. package/package.json +1 -1
  335. package/templates/applications/dataplane/application.yaml +7 -1
  336. package/templates/applications/dataplane/env.template +50 -14
  337. package/templates/applications/dataplane/rbac.yaml +108 -1
  338. package/templates/applications/miso-controller/application.yaml +2 -2
  339. package/templates/applications/miso-controller/env.template +53 -122
  340. package/templates/applications/miso-controller/rbac.yaml +28 -13
  341. package/templates/channels/chatgpt/install.template.md.hbs +49 -0
  342. package/templates/channels/chatgpt/manifest.template.json.hbs +9 -0
  343. package/templates/channels/microsoft-copilot/install.template.md.hbs +49 -0
  344. package/templates/channels/microsoft-copilot/manifest.template.json.hbs +8 -0
  345. package/templates/channels/slack/install.template.md.hbs +49 -0
  346. package/templates/channels/slack/manifest.template.json.hbs +66 -0
  347. package/templates/channels/teams-bot/install.template.md.hbs +49 -0
  348. package/templates/channels/teams-bot/manifest.template.json.hbs +13 -0
  349. package/templates/channels/web-embed/install.template.md.hbs +49 -0
  350. package/templates/channels/web-embed/manifest.template.json.hbs +8 -0
  351. package/templates/external-system/README.md.hbs +74 -17
  352. package/templates/python/docker-compose.hbs +75 -18
  353. package/templates/typescript/docker-compose.hbs +70 -17
  354. package/lib/commands/test-governance-command-action.js +0 -55
  355. package/lib/commands/test-trust-command-action.js +0 -118
@@ -15,12 +15,19 @@
15
15
  */
16
16
 
17
17
  const { handleCommandError } = require('../utils/cli-utils');
18
+ const { cliOptsSkipSync } = require('../utils/cli-sync-options');
18
19
  const { cliOptsSkipCertSync } = require('../certification/cli-cert-sync-skip');
19
20
  const { TEST_INTEGRATION_HELP_AFTER } = require('./setup-app.help');
21
+ const {
22
+ UPLOAD_HELP_AFTER,
23
+ DOWNLOAD_HELP_AFTER,
24
+ DELETE_HELP_AFTER
25
+ } = require('./setup-external-system-help');
20
26
 
21
27
  function setupDownloadCommand(program) {
22
28
  program.command('download <systemKey>')
23
29
  .description('Pull external system from dataplane into integration/<key>/')
30
+ .addHelpText('after', DOWNLOAD_HELP_AFTER)
24
31
  .option('--format <format>', 'Output format: json | yaml (default: yaml or config format)')
25
32
  .option('--dry-run', 'Show what would be downloaded without actually downloading')
26
33
  .option('--force', 'Overwrite existing README.md without prompting')
@@ -43,6 +50,7 @@ function setupDownloadCommand(program) {
43
50
  function setupUploadCommand(program) {
44
51
  program.command('upload <systemKey>')
45
52
  .description('Validate, publish to dataplane, and register with controller (draft application); or upload .protection batch')
53
+ .addHelpText('after', UPLOAD_HELP_AFTER)
46
54
  .option('--dry-run', 'Validate and build payload only; no API calls')
47
55
  .option('--no-sync', 'For .protection: skip datasource sync after upload')
48
56
  .option('--json', 'For .protection: JSON output')
@@ -55,6 +63,10 @@ function setupUploadCommand(program) {
55
63
  '--no-cert-sync',
56
64
  'Skip updating the system file certification block from the dataplane active certificate after publish'
57
65
  )
66
+ .option(
67
+ '--force',
68
+ 'Bypass schema guards on active datasources during publish (dangerous; shows a warning)'
69
+ )
58
70
  .action(async(systemKey, options) => {
59
71
  try {
60
72
  const { isProtectionScope } = require('../protection/scope');
@@ -97,6 +109,7 @@ function setupUploadCommand(program) {
97
109
  function setupDeleteCommand(program) {
98
110
  program.command('delete <systemKey>')
99
111
  .description('Remove external system and its datasources from dataplane')
112
+ .addHelpText('after', DELETE_HELP_AFTER)
100
113
  .option('--type <type>', 'Application type (default: external; use "external" to target integration/<systemKey>)')
101
114
  .option('--yes', 'Skip confirmation prompt')
102
115
  .option('--force', 'Skip confirmation prompt (alias for --yes)')
@@ -168,7 +181,7 @@ async function runExternalSystemTestIntegration(appName, options) {
168
181
  environment: options.env || options.environment,
169
182
  debug: options.debug,
170
183
  perDatasource: options.perDatasource,
171
- sync: options.sync === true
184
+ noSync: cliOptsSkipSync(options)
172
185
  };
173
186
  const results = await test.testExternalSystemIntegration(appName, opts);
174
187
  test.displayIntegrationTestResults(results, options.verbose, { debug: options.debug, runType: 'integration' });
@@ -225,9 +238,17 @@ function setupExternalSystemTestCommands(program) {
225
238
  .option('-e, --env <env>', 'Environment: dev, tst, or pro (builder: dev/tst for container)', 'dev')
226
239
  .option('-v, --verbose', 'Show detailed test output')
227
240
  .option('-d, --debug', 'Include debug output and write log to integration/<systemKey>/logs/')
241
+ .option(
242
+ '--no-sync',
243
+ 'Skip publishing local integration files; use system config already on the dataplane'
244
+ )
228
245
  .option(
229
246
  '--sync',
230
- 'Publish local system and datasource files to the dataplane before running tests (same as aifabrix upload <systemKey>)'
247
+ 'Publish local system and datasource files before tests (default for external integration; same as upload)'
248
+ )
249
+ .option(
250
+ '--force',
251
+ 'With --sync, pass force to upload (bypass active-datasource schema replacement guards; same as aifabrix upload --force)'
231
252
  )
232
253
  .option('--warnings-as-errors', 'Treat aggregate warn as failure (exit 1)')
233
254
  .option('--require-cert', 'Require certification passed on every datasource (exit 2 if not)')
@@ -242,7 +263,8 @@ function setupExternalSystemTestCommands(program) {
242
263
  const envExplicit = rawArgs.includes('-e') || rawArgs.includes('--env');
243
264
  const opts = {
244
265
  ...options,
245
- env: envExplicit ? options.env : undefined
266
+ env: envExplicit ? options.env : undefined,
267
+ noSync: cliOptsSkipSync(options, cmd)
246
268
  };
247
269
  await runTestIntegrationCommand(appName, opts);
248
270
  } catch (error) {
@@ -15,7 +15,7 @@ const { handleCommandError, isAuthenticationError } = require('../utils/cli-util
15
15
  const { resolveControllerUrl } = require('../utils/controller-url');
16
16
  const { handleLogin } = require('../commands/login');
17
17
  const { handleUpDataplane } = require('../commands/up-dataplane');
18
- const { cleanBuilderAppDirs } = require('../commands/up-common');
18
+ const { cleanBuilderAppDirs, DATAPLANE_BUILDER_APP_KEYS } = require('../commands/up-common');
19
19
  const { runGuidedUpDataplane } = require('./infra-guided');
20
20
  const { recordInfraInstallationCommand } = require('./installation-log-command');
21
21
 
@@ -26,7 +26,7 @@ const { recordInfraInstallationCommand } = require('./installation-log-command')
26
26
  async function runUpDataplaneWork(options) {
27
27
  let cleanedAppKeys = [];
28
28
  if (options.force) {
29
- const c = await cleanBuilderAppDirs(['dataplane']);
29
+ const c = await cleanBuilderAppDirs([...DATAPLANE_BUILDER_APP_KEYS]);
30
30
  cleanedAppKeys = Array.isArray(c) ? c : [];
31
31
  }
32
32
  if (!options.verbose) {
@@ -19,6 +19,7 @@ const { handleUpDataplane } = require('../commands/up-dataplane');
19
19
  const {
20
20
  applyUpPlatformForceConfig,
21
21
  cleanBuilderAppDirs,
22
+ PLATFORM_BUILDER_CLEAN_APP_KEYS,
22
23
  prepareUrlsLocalRegistryForUpPlatform
23
24
  } = require('../commands/up-common');
24
25
  const { runGuidedUpPlatform } = require('./infra-guided');
@@ -35,7 +36,7 @@ async function runUpPlatformWork(options) {
35
36
  let platformForceCleanSummary = null;
36
37
  if (options.force) {
37
38
  const forceSummary = await applyUpPlatformForceConfig({ silent: !options.verbose });
38
- const cleanedApps = await cleanBuilderAppDirs(PLATFORM_APPS, {
39
+ const cleanedApps = await cleanBuilderAppDirs(PLATFORM_BUILDER_CLEAN_APP_KEYS, {
39
40
  silent: !options.verbose
40
41
  });
41
42
  cleanedAppKeys = Array.isArray(cleanedApps) ? cleanedApps : [];
@@ -134,6 +134,8 @@ async function runUpInfraCommand(options) {
134
134
  const cfg = await config.getConfig();
135
135
  await persistOptionalInfraFlagsFromCli(options, cfg);
136
136
  await maybePersistTlsFromUpInfra(options, cfg);
137
+ const { passwordBundleFromCliOptions } = require('../core/admin-secrets-bundle');
138
+ const bundle = passwordBundleFromCliOptions(options);
137
139
  const adminPass = options.adminPassword || options.adminPwd;
138
140
  const tlsEnabledEffective = cfg.tlsEnabled === true;
139
141
  const effective = computeEffectiveInfraOptionalFlags(cfg, options);
@@ -145,6 +147,8 @@ async function runUpInfraCommand(options) {
145
147
  adminPwd: adminPass,
146
148
  adminEmail: options.adminEmail,
147
149
  userPassword: options.userPassword,
150
+ passwordBundle: bundle,
151
+ syncAdminKv: options.syncAdminKv === true,
148
152
  tlsEnabled: tlsEnabledEffective
149
153
  });
150
154
  await persistMissingInfraOptionalServiceFlags(cfg, effective);
@@ -156,8 +160,12 @@ function setupUpInfraCommand(program) {
156
160
  .addHelpText('after', UP_INFRA_HELP_AFTER)
157
161
  .option('-d, --developer <id>', 'Set developer ID and start infrastructure')
158
162
  .option('--verbose', 'Show full orchestration output (default is guided summary)')
159
- .option('--adminPassword <password>', 'Override {{adminPassword}} defaults (Postgres, pgAdmin, Redis Commander, catalog literals)')
163
+ .option('--adminPassword <password>', 'Override admin password (dev: all roles; pro manual-single)')
160
164
  .option('--adminEmail <email>', 'Override {{adminEmail}} default (e.g. pgAdmin login email)')
165
+ .option('--infraAdminPassword <password>', 'Pro profile: infra DB/pgAdmin/Redis Commander password')
166
+ .option('--keycloakAdminPassword <password>', 'Pro profile: Keycloak install admin password')
167
+ .option('--platformAdminPassword <password>', 'Pro profile: platform UI login password (user admin)')
168
+ .option('--syncAdminKv', 'Also sync {{adminPassword}} catalog keys into secrets.local.yaml (legacy)')
161
169
  .option('--userPassword <password>', 'Override {{userPassword}} default (e.g. Keycloak default user password)')
162
170
  .option('--pgAdmin', 'Include pgAdmin web UI and save to config')
163
171
  .option('--no-pgAdmin', 'Exclude pgAdmin and save to config')
@@ -23,7 +23,7 @@ const { handleTeardown } = require('../commands/teardown');
23
23
 
24
24
  const SETUP_HELP_AFTER = `
25
25
  What this command does:
26
- - With no infra running: prompts for admin email/password (used for Postgres, pgAdmin, Keycloak). The email is saved as adminEmail in config.yaml so the next setup can show it as the default (you can still change it). Prompts for an AI tool (OpenAI or Azure OpenAI) only when keys are not already set, then runs up-infra and up-platform.
26
+ - With no infra running: prompts for installation profile (dev = one password for infra + Keycloak + platform UI; pro = autogen or manual split passwords). Credentials are stored in admin-secrets.env (encrypted secure:// values), not in secrets.local.yaml unless you pass --syncAdminKv on up-infra. The admin email is saved in config.yaml for the next run. Prompts for an AI tool (OpenAI or Azure OpenAI) only when keys are not already set, then runs up-infra and up-platform.
27
27
  - With infra running: shows a mode menu:
28
28
  1) Re-install — stop infra and remove all volumes, then up-infra + up-platform --force.
29
29
  2) Wipe data — drop every database and DB user, then up-infra + up-platform --force.
@@ -54,6 +54,11 @@ function registerSetup(program) {
54
54
  .command('setup')
55
55
  .description('Install or refresh the full AI Fabrix platform (infra + miso + dataplane)')
56
56
  .option('-d, --developer <id>', 'Pin developer ID before fresh install (fresh path only; ignored when infra is already up)')
57
+ .option('--platform <mode>', 'Platform mode: single, single-traefik (Traefik + TLS), or full (multi-env; advanced)')
58
+ .option('--installation <profile>', 'Installation profile: dev (one password) or pro (autogen/manual)')
59
+ .option('--pro-password-mode <mode>', 'Pro profile only: autogen or manual')
60
+ .option('--admin-email <email>', 'Admin email (non-interactive fresh install)')
61
+ .option('--admin-password <password>', 'Admin password for dev or pro manual-single (non-interactive)')
57
62
  .option('-y, --yes', 'Skip destructive confirmation prompts (re-install, wipe data, teardown)')
58
63
  .addHelpText('after', SETUP_HELP_AFTER)
59
64
  .action(async(options) => {
@@ -10,6 +10,7 @@ const { formatSuccessLine } = require('../utils/cli-test-layout-chalk');
10
10
  const { handleCommandError } = require('../utils/cli-utils');
11
11
  const { handleSecretsSet } = require('../commands/secrets-set');
12
12
  const { handleSecretsList } = require('../commands/secrets-list');
13
+ const { handleSecretsGet } = require('../commands/secrets-get');
13
14
  const { handleSecretsRemove } = require('../commands/secrets-remove');
14
15
  const { handleSecretsValidate } = require('../commands/secrets-validate');
15
16
  const { handleSecure } = require('../commands/secure');
@@ -18,7 +19,7 @@ const logger = require('../utils/logger');
18
19
 
19
20
  const SECRET_GROUP_HELP_AFTER = `
20
21
  Subcommands:
21
- list, set, remove, remove-all User secrets.local.yaml (add --shared for shared/remote)
22
+ list, get, set, remove, remove-all User secrets.local.yaml (add --shared for shared/remote)
22
23
  set-secrets-file Point config at a shared secrets file or https URL
23
24
  validate YAML structure (+ optional --naming)
24
25
 
@@ -38,6 +39,17 @@ Examples:
38
39
  Shared over https: key BASH_NPM_TOKEN --shared → NPM_TOKEN available in terminal (exported).
39
40
  `;
40
41
 
42
+ const SECRET_GET_HELP_AFTER = `
43
+ Examples:
44
+ $ aifabrix secret get hubspot-demo/token --shared --exists
45
+ $ aifabrix secret get myapp/clientSecret
46
+ $ aifabrix secret get hubspot/apiKey --shared --json
47
+
48
+ --exists Script mode: exit 0 when the key is present and non-empty; no output.
49
+ Default Local user secrets.local.yaml only (same target as secret set without --shared).
50
+ --shared aifabrix-secrets store only (team file or remote API; same as secret set --shared).
51
+ `;
52
+
41
53
  const SECRET_LIST_HELP_AFTER = `
42
54
  Examples:
43
55
  $ aifabrix secret list
@@ -168,6 +180,25 @@ function setupSecureCommand(program) {
168
180
  });
169
181
  }
170
182
 
183
+ function setupSecretGetCommand(secretCmd) {
184
+ secretCmd
185
+ .command('get <key>')
186
+ .description('Get one secret (local user file by default; --shared for team store; --exists for scripts)')
187
+ .addHelpText('after', SECRET_GET_HELP_AFTER)
188
+ .option('--shared', 'Read from shared secrets (config aifabrix-secrets or remote API)')
189
+ .option('--exists', 'Exit 0 when key is present and non-empty; print nothing (for scripts)')
190
+ .option('--json', 'Output JSON { key, exists, value }')
191
+ .action(async(key, options) => {
192
+ try {
193
+ await config.ensureSecretsEncryptionKey();
194
+ await handleSecretsGet(key, options);
195
+ } catch (error) {
196
+ handleCommandError(error, 'secret get');
197
+ process.exit(1);
198
+ }
199
+ });
200
+ }
201
+
171
202
  function setupSecretListCommand(secretCmd) {
172
203
  secretCmd
173
204
  .command('list')
@@ -196,6 +227,7 @@ function setupSecretsCommands(program) {
196
227
  .addHelpText('after', SECRET_GROUP_HELP_AFTER);
197
228
 
198
229
  setupSecretListCommand(secretCmd);
230
+ setupSecretGetCommand(secretCmd);
199
231
 
200
232
  secretCmd
201
233
  .command('set <key> <value>')
@@ -26,8 +26,11 @@ Examples:
26
26
  $ aifabrix repair hubspot-demo --dry-run
27
27
  Show what would change without writing files.
28
28
 
29
+ $ aifabrix repair hubspot-demo --auth bearerToken
30
+ Private-app style apikey: Authorization + Bearer prefix; preserves baseUrl/testEndpoint when present. Warns if testEndpoint is missing.
31
+
29
32
  $ aifabrix repair hubspot-demo --auth oauth2
30
- Set authentication method; updates the system file and env.template (oauth2, aad, apikey, basic, …).
33
+ Set authentication method; updates the system file and env.template (oauth2, aad, apikey, bearerToken, basic, …).
31
34
 
32
35
  $ aifabrix repair hubspot-demo --rbac --expose --sync --test
33
36
  Optional datasource fixes: RBAC roles/permissions, exposed.schema from attributes, default sync block, testPayload stubs.
@@ -38,8 +41,28 @@ Examples:
38
41
  Before overwriting files, repair writes timestamped backups under integration/<systemKey>/backup/ (same as datasource capability copy). Use --no-backup to skip.
39
42
  `;
40
43
 
44
+ const RESOLVE_HELP_AFTER = `
45
+ Examples:
46
+ $ aifabrix resolve hubspot-demo
47
+ External integration: resolves integration/<systemKey>/env.template to .env using local host ports (no Docker rewrite).
48
+
49
+ $ aifabrix resolve dataplane --force
50
+ Seed missing secret keys and replace the full .env from env.template (no merge with an existing file).
51
+
52
+ $ aifabrix resolve dataplane --fresh
53
+ Replace the full .env only (no merge; does not seed missing secret keys). Same .env output as --force when secrets are already set.
54
+
55
+ $ aifabrix secret set hubspot-demo/token "<your-token>"
56
+ Store a secret when resolve reports a missing kv:// reference.
57
+
58
+ If a key is not required by your system file, comment out its line in env.template instead of creating a secret.
59
+ $ aifabrix repair hubspot-demo
60
+ Align env.template with authentication.security and comment stale OAuth KV lines after --auth bearerToken.
61
+ `;
62
+
41
63
  module.exports = {
42
64
  JSON_HELP_AFTER,
43
65
  VALIDATE_HELP_AFTER,
44
- REPAIR_HELP_AFTER
66
+ REPAIR_HELP_AFTER,
67
+ RESOLVE_HELP_AFTER
45
68
  };
@@ -0,0 +1,198 @@
1
+ /**
2
+ * `aifabrix repair` command wiring and CLI output (split from setup-utility for size limits).
3
+ *
4
+ * @fileoverview Repair CLI command
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const chalk = require('chalk');
12
+ const logger = require('../utils/logger');
13
+ const { handleCommandError, logOfflinePathWhenType } = require('../utils/cli-utils');
14
+ const { detectAppType } = require('../utils/paths');
15
+ const { formatSuccessParagraph, formatWarningLine } = require('../utils/cli-test-layout-chalk');
16
+ const { REPAIR_HELP_AFTER } = require('./setup-utility-help-after');
17
+
18
+ /**
19
+ * @param {string} appName
20
+ * @param {object} options
21
+ * @param {string} format
22
+ * @returns {object}
23
+ */
24
+ function buildRepairExternalIntegrationOptions(appName, options, format) {
25
+ const all = options.all === true;
26
+ return {
27
+ auth: options.auth,
28
+ doc: options.doc || all,
29
+ dryRun: options.dryRun,
30
+ format,
31
+ rbac: options.rbac || all,
32
+ expose: options.expose || all,
33
+ sync: options.sync || all,
34
+ api: options.api || all,
35
+ test: options.test || all,
36
+ backup: options.backup,
37
+ noBackup: options.noBackup
38
+ };
39
+ }
40
+
41
+ /**
42
+ * @param {string[]} changedFiles
43
+ * @param {boolean} dryRun
44
+ */
45
+ function logRepairChangedFiles(changedFiles, dryRun) {
46
+ if (!Array.isArray(changedFiles) || changedFiles.length === 0) return;
47
+ const title = dryRun ? '\nWould change files:' : '\nChanged files:';
48
+ logger.log(chalk.white(title));
49
+ changedFiles.forEach((filePath) => logger.log(chalk.cyan(` ${filePath}`)));
50
+ }
51
+
52
+ /**
53
+ * @param {string[]} warnings
54
+ */
55
+ function logRepairWarnings(warnings) {
56
+ if (!Array.isArray(warnings) || warnings.length === 0) return;
57
+ warnings.forEach((msg) => logger.log(formatWarningLine(msg)));
58
+ }
59
+
60
+ /**
61
+ * @param {string[]} changedFiles
62
+ * @param {string[]} warnings
63
+ */
64
+ function logRepairNextActions(changedFiles, warnings) {
65
+ const hasFiles = Array.isArray(changedFiles) && changedFiles.length > 0;
66
+ const hasWarnings = Array.isArray(warnings) && warnings.length > 0;
67
+ if (!hasFiles && !hasWarnings) return;
68
+ logger.log(chalk.white('\nNext actions:'));
69
+ if (hasFiles) {
70
+ logger.log(chalk.gray(' • Open the paths above in your editor and review the diff'));
71
+ logger.log(chalk.gray(' • Run: aifabrix validate <systemKey>'));
72
+ }
73
+ if (hasWarnings) {
74
+ logger.log(chalk.gray(' • Fix warnings in the system file (especially authentication.variables.testEndpoint)'));
75
+ logger.log(chalk.gray(' • Run: aifabrix json <systemKey> && aifabrix upload <systemKey>'));
76
+ }
77
+ }
78
+
79
+ /**
80
+ * @param {object} options
81
+ * @param {object} result
82
+ * @param {string[]} changedFiles
83
+ */
84
+ function logRepairDryRunOutcome(options, result, changedFiles) {
85
+ logger.log(chalk.yellow('\nWould apply:'));
86
+ result.changes.forEach((c) => logger.log(chalk.gray(` ${c}`)));
87
+ logRepairChangedFiles(changedFiles, true);
88
+ logRepairWarnings(result.warnings);
89
+ logRepairNextActions(changedFiles, result.warnings);
90
+ }
91
+
92
+ /**
93
+ * @param {object} result
94
+ * @param {string[]} changedFiles
95
+ */
96
+ function logRepairSuccessOutcome(result, changedFiles) {
97
+ if (result.updated) {
98
+ logger.log(formatSuccessParagraph('Repaired external integration config.'));
99
+ logRepairChangedFiles(changedFiles, false);
100
+ logRepairNextActions(changedFiles, result.warnings);
101
+ return;
102
+ }
103
+ if (Array.isArray(result.changes) && result.changes.length > 0) {
104
+ logger.log(formatSuccessParagraph('Repair actions completed.'));
105
+ result.changes.forEach((c) => logger.log(chalk.gray(` ${c}`)));
106
+ logRepairChangedFiles(changedFiles, false);
107
+ logRepairNextActions(changedFiles, result.warnings);
108
+ return;
109
+ }
110
+ if (result.readmeRegenerated) {
111
+ logger.log(formatSuccessParagraph('Regenerated README.md from deployment manifest.'));
112
+ return;
113
+ }
114
+ if (Array.isArray(result.warnings) && result.warnings.length > 0) {
115
+ logRepairNextActions(changedFiles, result.warnings);
116
+ return;
117
+ }
118
+ logger.log(chalk.gray('No changes needed; config already matches files on disk.'));
119
+ }
120
+
121
+ /**
122
+ * @param {object} options
123
+ * @param {object} result
124
+ */
125
+ function logRepairResult(options, result) {
126
+ const changedFiles = result.changedFiles;
127
+ if (options.dryRun && result.updated && result.changes.length > 0) {
128
+ logRepairDryRunOutcome(options, result, changedFiles);
129
+ return;
130
+ }
131
+ if (Array.isArray(result.backupPaths) && result.backupPaths.length > 0) {
132
+ result.backupPaths.forEach((p) => logger.log(chalk.gray(`Backup: ${p}`)));
133
+ }
134
+ logRepairWarnings(result.warnings);
135
+ logRepairSuccessOutcome(result, changedFiles);
136
+ }
137
+
138
+ /**
139
+ * @param {string} appName
140
+ * @param {object} options
141
+ * @returns {Promise<void>}
142
+ */
143
+ async function handleRepairCommand(appName, options) {
144
+ const { repairExternalIntegration } = require('../commands/repair');
145
+ const { appPath } = await detectAppType(appName);
146
+ logOfflinePathWhenType(appPath);
147
+ let format = 'yaml';
148
+ try {
149
+ const config = require('../core/config');
150
+ format = (await config.getFormat()) || format;
151
+ } catch (_) {
152
+ /* default yaml when config unavailable */
153
+ }
154
+ const result = await repairExternalIntegration(
155
+ appName,
156
+ buildRepairExternalIntegrationOptions(appName, options, format)
157
+ );
158
+ logRepairResult(options, result);
159
+ }
160
+
161
+ /**
162
+ * @param {import('commander').Command} program
163
+ */
164
+ function setupRepairCommand(program) {
165
+ program.command('repair <systemKey>')
166
+ .description('Fix external integration drift (files, RBAC, manifest, …)')
167
+ .option('--all', 'Run all repair actions (api, doc, expose, rbac, sync, test)')
168
+ .option(
169
+ '--api',
170
+ 'Validate and sync API contracts needed for OpenAPI/MCP (uses local OpenAPI specs at integration/<systemKey>/openapi/*.json when present)'
171
+ )
172
+ .option(
173
+ '--auth <method>',
174
+ 'Set authentication method (oauth2, aad, apikey, bearerToken, basic, queryParam, oidc, hmac, none); updates system file and env.template'
175
+ )
176
+ .option('--doc', 'Regenerate README.md from deployment manifest')
177
+ .option('--expose', 'Set exposed.schema on each datasource from all fieldMappings.attributes keys (metadata.<key>); removes deprecated exposed.attributes if present')
178
+ .option('--rbac', 'Ensure RBAC permissions per datasource and add default Admin/Reader roles if none exist')
179
+ .option('--sync', 'Add default sync section to datasources that lack it')
180
+ .option('--test', 'Generate testPayload.payloadTemplate and testPayload.expectedResult from attributes')
181
+ .option('--no-backup', 'Skip timestamped copies under integration/<systemKey>/backup/')
182
+ .option('--dry-run', 'Report changes only; do not write')
183
+ .addHelpText('after', REPAIR_HELP_AFTER)
184
+ .action(async(appName, options) => {
185
+ try {
186
+ await handleRepairCommand(appName, options);
187
+ } catch (error) {
188
+ handleCommandError(error, 'repair');
189
+ process.exit(1);
190
+ }
191
+ });
192
+ }
193
+
194
+ module.exports = {
195
+ setupRepairCommand,
196
+ buildRepairExternalIntegrationOptions,
197
+ logRepairResult
198
+ };
@@ -8,13 +8,18 @@
8
8
 
9
9
  'use strict';
10
10
 
11
+ const path = require('path');
11
12
  const chalk = require('chalk');
12
13
  const secrets = require('../core/secrets');
14
+ const secretsEnsure = require('../core/secrets-ensure');
13
15
  const logger = require('../utils/logger');
14
16
  const { handleCommandError } = require('../utils/cli-utils');
15
17
  const coreConfig = require('../core/config');
18
+ const pathsUtil = require('../utils/paths');
16
19
  const { resolvePreferLocalEnvOutputPathFlag } = require('../utils/applications-config-defaults');
17
20
  const { getResolveAppPath } = require('../utils/paths');
21
+ const { resolveGenerateEnvEnvironment } = require('../utils/resolve-env-mode');
22
+ const { RESOLVE_HELP_AFTER } = require('./setup-utility-help-after');
18
23
 
19
24
  /**
20
25
  * @param {string} appName
@@ -50,10 +55,17 @@ async function runResolveJsonOutput(appName, appPath, envOnly, envPath, options,
50
55
  * @param {string} envPath
51
56
  * @param {boolean} envOnly
52
57
  * @param {{ skipValidation?: boolean }} options
58
+ * @param {'local'|'docker'} environment
53
59
  * @returns {Promise<void>}
54
60
  */
55
- async function runResolveHumanOutput(appName, envPath, envOnly, options) {
61
+ async function runResolveHumanOutput(appName, envPath, envOnly, options, environment) {
56
62
  logger.log(`✔ Generated .env file: ${envPath}`);
63
+ if (options.fresh || options.force) {
64
+ logger.log(chalk.gray(' Wrote full resolved content (replaced existing .env from env.template; no merge).'));
65
+ }
66
+ if (environment === 'local') {
67
+ logger.log(chalk.gray(' Resolved for local use (host ports; no Docker port rewrite).'));
68
+ }
57
69
  logger.log(chalk.gray(' Note: up-platform / up-miso / up-dataplane / register / build resolve secrets in memory only.'));
58
70
  logger.log(chalk.gray(` Re-run "aifabrix resolve ${appName}" whenever you need an on-disk .env again.`));
59
71
  if (envOnly) {
@@ -77,9 +89,26 @@ async function runResolveHumanOutput(appName, envPath, envOnly, options) {
77
89
  * @param {{ force?: boolean, skipValidation?: boolean, json?: boolean }} options
78
90
  * @returns {Promise<void>}
79
91
  */
92
+ async function ensureResolveSecretsFromEnvTemplate(appPath, appName) {
93
+ const templatePath = path.join(appPath, 'env.template');
94
+ let emptyValuesForCredentials = false;
95
+ try {
96
+ const appType = await pathsUtil.detectAppType(appName);
97
+ emptyValuesForCredentials = appType?.baseDir === 'integration';
98
+ } catch {
99
+ emptyValuesForCredentials = false;
100
+ }
101
+ await secretsEnsure.ensureSecretsFromEnvTemplate(templatePath, {
102
+ preferredFilePath: pathsUtil.getPrimaryUserSecretsLocalPath(),
103
+ placeholderContext: secretsEnsure.buildInfraPlaceholderContext({}),
104
+ emptyValuesForCredentials
105
+ });
106
+ }
107
+
80
108
  async function runResolveAppAction(appName, options) {
81
109
  const jsonMode = options.json === true;
82
110
  const { appPath, envOnly } = await getResolveAppPath(appName);
111
+ await ensureResolveSecretsFromEnvTemplate(appPath, appName);
83
112
  const manifestEmit = require('../utils/manifest-source-emit');
84
113
  manifestEmit.emitManifestMetadataLineIfTTY(logger, {
85
114
  appKey: appName,
@@ -89,24 +118,26 @@ async function runResolveAppAction(appName, options) {
89
118
  });
90
119
  const userCfg = await coreConfig.getConfig();
91
120
  const preferLocalEnvOutputPath = await resolvePreferLocalEnvOutputPathFlag(userCfg, appName);
121
+ const environment = resolveGenerateEnvEnvironment(appPath, appName);
92
122
  const envPath = await secrets.generateEnvFile(
93
123
  appName,
94
124
  undefined,
95
- 'docker',
125
+ environment,
96
126
  options.force,
97
127
  {
98
128
  appPath,
99
129
  envOnly,
100
130
  skipOutputPath: false,
101
131
  preserveFromPath: null,
102
- preferLocalEnvOutputPath
132
+ preferLocalEnvOutputPath,
133
+ freshEnv: options.fresh === true || options.force === true
103
134
  }
104
135
  );
105
136
  if (jsonMode) {
106
137
  await runResolveJsonOutput(appName, appPath, envOnly, envPath, options, manifestEmit);
107
138
  return;
108
139
  }
109
- await runResolveHumanOutput(appName, envPath, envOnly, options);
140
+ await runResolveHumanOutput(appName, envPath, envOnly, options, environment);
110
141
  }
111
142
 
112
143
  /**
@@ -116,7 +147,15 @@ async function runResolveAppAction(appName, options) {
116
147
  function setupResolveCommand(program) {
117
148
  program.command('resolve <appKey|systemKey>')
118
149
  .description('Generate .env from template (builder/<appKey>/ or integration/<systemKey>/); optional validate after')
119
- .option('-f, --force', 'Generate missing secret keys in secrets file')
150
+ .addHelpText('after', RESOLVE_HELP_AFTER)
151
+ .option(
152
+ '-f, --force',
153
+ 'Seed missing secret keys and replace .env from env.template (no merge with existing .env or envOutputPath)'
154
+ )
155
+ .option(
156
+ '--fresh',
157
+ 'Same full .env replace as --force without seeding missing secret keys in the secrets file'
158
+ )
120
159
  .option('--skip-validation', 'Skip file validation after generating .env')
121
160
  .option('--json', 'Print JSON summary (envPath, manifestSource, optional validation)')
122
161
  .action(async(appName, options) => {