@aifabrix/builder 2.43.0 → 2.44.1

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 (371) hide show
  1. package/.cursor/rules/anchor-docs.mdc +15 -0
  2. package/.cursor/rules/cli-layout.mdc +75 -0
  3. package/.cursor/rules/project-rules.mdc +8 -0
  4. package/.npmrc.token +1 -0
  5. package/.nyc_output/55e9d034-ddab-4579-a706-e02a91d75c91.json +1 -0
  6. package/.nyc_output/processinfo/55e9d034-ddab-4579-a706-e02a91d75c91.json +1 -0
  7. package/.nyc_output/processinfo/index.json +1 -0
  8. package/README.md +1 -1
  9. package/anchor-docs/README.md +10 -0
  10. package/anchor-docs/_TEMPLATE +24 -0
  11. package/bin/aifabrix.js +13 -4
  12. package/integration/hubspot-test/README.md +31 -0
  13. package/integration/hubspot-test/create-hubspot.js +5 -5
  14. package/integration/hubspot-test/hubspot-test-datasource-company.json +58 -462
  15. package/integration/hubspot-test/hubspot-test-datasource-contact.json +61 -555
  16. package/integration/hubspot-test/hubspot-test-datasource-deal.json +63 -506
  17. package/integration/hubspot-test/hubspot-test-datasource-users.json +42 -83
  18. package/integration/hubspot-test/hubspot-test-deploy.json +3 -3
  19. package/integration/hubspot-test/test-dataplane-down-tests.js +1 -7
  20. package/integration/hubspot-test/test-dataplane-down.js +3 -3
  21. package/integration/hubspot-test/test.js +35 -43
  22. package/integration/hubspot-test/wizard-hubspot-test-headless.yaml +23 -0
  23. package/integration/roundtrip-test-local/README.md +144 -0
  24. package/integration/roundtrip-test-local/application.yaml +13 -0
  25. package/integration/roundtrip-test-local/env.template +15 -0
  26. package/integration/roundtrip-test-local/roundtrip-test-local-datasource-roundtrip-test-company.yaml +14 -0
  27. package/integration/roundtrip-test-local/roundtrip-test-local-deploy.json +61 -0
  28. package/integration/roundtrip-test-local/roundtrip-test-local-system.yaml +25 -0
  29. package/integration/roundtrip-test-local2/README.md +144 -0
  30. package/integration/roundtrip-test-local2/application.yaml +13 -0
  31. package/integration/roundtrip-test-local2/env.template +15 -0
  32. package/integration/roundtrip-test-local2/roundtrip-test-local2-datasource-company.yaml +31 -0
  33. package/integration/roundtrip-test-local2/roundtrip-test-local2-deploy.json +86 -0
  34. package/integration/roundtrip-test-local2/roundtrip-test-local2-system.yaml +25 -0
  35. package/integration/test/wizard.yaml +8 -0
  36. package/jest.config.default.js +10 -0
  37. package/jest.config.integration.fixtures.js +22 -0
  38. package/jest.config.integration.js +21 -18
  39. package/jest.config.isolated.js +10 -0
  40. package/jest.projects.js +301 -0
  41. package/lib/api/certificates.api.js +62 -0
  42. package/lib/api/datasources-core.api.js +3 -3
  43. package/lib/api/dev-mtls-request.js +110 -0
  44. package/lib/api/dev-server-https.js +145 -0
  45. package/lib/api/dev.api.js +133 -144
  46. package/lib/api/index.js +11 -3
  47. package/lib/api/pipeline.api.js +67 -20
  48. package/lib/api/types/certificates.types.js +48 -0
  49. package/lib/api/types/dev.types.js +4 -3
  50. package/lib/api/types/pipeline.types.js +8 -5
  51. package/lib/api/types/validation-run.types.js +56 -0
  52. package/lib/api/validation-run.api.js +111 -0
  53. package/lib/api/validation-runner.js +109 -0
  54. package/lib/app/certification-show-enrich.js +129 -0
  55. package/lib/app/certification-verify-rows.js +60 -0
  56. package/lib/app/config.js +1 -1
  57. package/lib/app/deploy-status-display.js +2 -2
  58. package/lib/app/deploy.js +7 -6
  59. package/lib/app/display.js +2 -1
  60. package/lib/app/dockerfile.js +3 -2
  61. package/lib/app/down.js +2 -1
  62. package/lib/app/helpers.js +6 -5
  63. package/lib/app/index.js +27 -8
  64. package/lib/app/list.js +7 -6
  65. package/lib/app/push.js +4 -3
  66. package/lib/app/register.js +16 -7
  67. package/lib/app/rotate-secret.js +14 -13
  68. package/lib/app/run-container-start.js +184 -0
  69. package/lib/app/run-docker-fallback.js +108 -0
  70. package/lib/app/run-env-compose.js +30 -42
  71. package/lib/app/run-helpers.js +49 -126
  72. package/lib/app/run-infra-requirements.js +30 -0
  73. package/lib/app/run-resolve-image.js +21 -0
  74. package/lib/app/run.js +74 -21
  75. package/lib/app/show-display.js +44 -1
  76. package/lib/app/show.js +93 -9
  77. package/lib/build/index.js +13 -10
  78. package/lib/certification/cli-cert-sync-skip.js +21 -0
  79. package/lib/certification/merge-certification-from-artifact.js +185 -0
  80. package/lib/certification/post-unified-cert-sync.js +33 -0
  81. package/lib/certification/sync-after-external-command.js +52 -0
  82. package/lib/certification/sync-system-certification.js +197 -0
  83. package/lib/cli/index.js +2 -0
  84. package/lib/cli/setup-app.help.js +67 -0
  85. package/lib/cli/setup-app.js +61 -121
  86. package/lib/cli/setup-app.test-commands.js +195 -0
  87. package/lib/cli/setup-auth.js +19 -5
  88. package/lib/cli/setup-credential-deployment.js +22 -8
  89. package/lib/cli/setup-dev-path-commands.js +124 -0
  90. package/lib/cli/setup-dev.js +170 -113
  91. package/lib/cli/setup-environment.js +7 -1
  92. package/lib/cli/setup-external-system.js +84 -23
  93. package/lib/cli/setup-infra.js +126 -47
  94. package/lib/cli/setup-parameters.js +32 -0
  95. package/lib/cli/setup-secrets.js +137 -18
  96. package/lib/cli/setup-service-user.js +1 -1
  97. package/lib/cli/setup-utility.js +54 -22
  98. package/lib/commands/app-down.js +5 -7
  99. package/lib/commands/app-install.js +14 -7
  100. package/lib/commands/app-logs.js +13 -10
  101. package/lib/commands/app-shell.js +4 -1
  102. package/lib/commands/app-test.js +25 -19
  103. package/lib/commands/app.js +32 -11
  104. package/lib/commands/auth-config.js +6 -6
  105. package/lib/commands/auth-status.js +4 -3
  106. package/lib/commands/credential-env.js +4 -3
  107. package/lib/commands/credential-list.js +5 -4
  108. package/lib/commands/credential-push.js +4 -3
  109. package/lib/commands/datasource-unified-test-cli.js +428 -0
  110. package/lib/commands/datasource-unified-test-cli.options.js +191 -0
  111. package/lib/commands/datasource-unified-test-e2e-cli-helpers.js +106 -0
  112. package/lib/commands/datasource-validation-cli.js +143 -0
  113. package/lib/commands/datasource.js +125 -95
  114. package/lib/commands/deployment-list.js +6 -5
  115. package/lib/commands/dev-cli-handlers.js +122 -18
  116. package/lib/commands/dev-down.js +4 -3
  117. package/lib/commands/dev-init.js +231 -116
  118. package/lib/commands/dev-show-display.js +473 -0
  119. package/lib/commands/login-credentials.js +3 -2
  120. package/lib/commands/login-device.js +4 -3
  121. package/lib/commands/login.js +5 -4
  122. package/lib/commands/logout.js +8 -7
  123. package/lib/commands/parameters-validate.js +54 -0
  124. package/lib/commands/repair-datasource.js +314 -68
  125. package/lib/commands/repair-env-template.js +2 -2
  126. package/lib/commands/repair.js +21 -3
  127. package/lib/commands/secrets-list.js +23 -12
  128. package/lib/commands/secrets-remove-all.js +220 -0
  129. package/lib/commands/secrets-remove.js +21 -12
  130. package/lib/commands/secrets-set.js +21 -12
  131. package/lib/commands/secrets-validate.js +4 -4
  132. package/lib/commands/secure.js +10 -9
  133. package/lib/commands/service-user.js +26 -25
  134. package/lib/commands/test-e2e-external.js +27 -1
  135. package/lib/commands/up-common.js +3 -2
  136. package/lib/commands/up-dataplane.js +29 -16
  137. package/lib/commands/up-miso.js +19 -29
  138. package/lib/commands/upload.js +149 -39
  139. package/lib/commands/wizard-core-helpers.js +1 -1
  140. package/lib/commands/wizard-dataplane.js +4 -3
  141. package/lib/commands/wizard-helpers.js +3 -3
  142. package/lib/commands/wizard.js +2 -2
  143. package/lib/core/admin-secrets.js +14 -5
  144. package/lib/core/audit-logger.js +12 -4
  145. package/lib/core/config-attach-extensions.js +46 -0
  146. package/lib/core/config-runtime-paths.js +29 -0
  147. package/lib/core/config.js +55 -56
  148. package/lib/core/diff.js +3 -2
  149. package/lib/core/ensure-encryption-key.js +1 -1
  150. package/lib/core/secrets-ensure-infra.js +77 -0
  151. package/lib/core/secrets-ensure.js +120 -64
  152. package/lib/core/secrets-env-write.js +35 -7
  153. package/lib/core/secrets-infra-placeholder-sync.js +61 -0
  154. package/lib/core/secrets.js +200 -37
  155. package/lib/core/templates-env.js +4 -3
  156. package/lib/datasource/abac-validator.js +1 -10
  157. package/lib/datasource/deploy.js +75 -53
  158. package/lib/datasource/field-reference-validator.js +9 -6
  159. package/lib/datasource/integration-context.js +63 -0
  160. package/lib/datasource/list.js +8 -7
  161. package/lib/datasource/log-viewer.js +189 -67
  162. package/lib/datasource/resolve-app.js +4 -4
  163. package/lib/datasource/test-e2e.js +113 -146
  164. package/lib/datasource/test-integration.js +114 -122
  165. package/lib/datasource/unified-validation-run-body.js +68 -0
  166. package/lib/datasource/unified-validation-run-post.js +23 -0
  167. package/lib/datasource/unified-validation-run-resolve.js +43 -0
  168. package/lib/datasource/unified-validation-run.js +93 -0
  169. package/lib/datasource/validate.js +157 -13
  170. package/lib/deployment/deployer.js +4 -3
  171. package/lib/deployment/environment.js +7 -6
  172. package/lib/deployment/push.js +17 -8
  173. package/lib/external-system/delete.js +4 -3
  174. package/lib/external-system/deploy.js +166 -53
  175. package/lib/external-system/download-helpers.js +1 -1
  176. package/lib/external-system/download.js +7 -6
  177. package/lib/external-system/generator.js +92 -6
  178. package/lib/external-system/integration-test-dispatch.js +26 -0
  179. package/lib/external-system/test-execution.js +5 -1
  180. package/lib/external-system/test-helpers.js +0 -4
  181. package/lib/external-system/test-system-level-helpers.js +110 -0
  182. package/lib/external-system/test-system-level.js +83 -44
  183. package/lib/external-system/test.js +59 -8
  184. package/lib/generator/builders.js +23 -11
  185. package/lib/generator/deploy-manifest-azure-kv.js +81 -0
  186. package/lib/generator/external.js +16 -4
  187. package/lib/generator/helpers.js +58 -3
  188. package/lib/generator/index.js +4 -0
  189. package/lib/generator/split-readme.js +12 -7
  190. package/lib/generator/split-variables.js +2 -1
  191. package/lib/generator/split.js +1 -1
  192. package/lib/generator/wizard-readme.js +3 -3
  193. package/lib/generator/wizard.js +8 -8
  194. package/lib/infrastructure/compose.js +70 -7
  195. package/lib/infrastructure/helpers-docker-check.js +67 -0
  196. package/lib/infrastructure/helpers.js +203 -42
  197. package/lib/infrastructure/index.js +31 -18
  198. package/lib/infrastructure/services.js +21 -67
  199. package/lib/internal/fs-real-sync.js +104 -0
  200. package/lib/internal/node-fs.js +98 -0
  201. package/lib/parameters/database-secret-values.js +173 -0
  202. package/lib/parameters/infra-kv-discovery.js +121 -0
  203. package/lib/parameters/infra-parameter-catalog.js +458 -0
  204. package/lib/parameters/infra-parameter-validate.js +64 -0
  205. package/lib/schema/application-schema.json +37 -17
  206. package/lib/schema/datasource-test-run.schema.json +493 -0
  207. package/lib/schema/deployment-rules.yaml +102 -63
  208. package/lib/schema/external-datasource.schema.json +1200 -442
  209. package/lib/schema/external-system.schema.json +203 -5
  210. package/lib/schema/flag-map-validation-run.json +31 -0
  211. package/lib/schema/infra-parameter.schema.json +106 -0
  212. package/lib/schema/infra.parameter.yaml +421 -0
  213. package/lib/schema/type/credential-auth-templates.json +40 -0
  214. package/lib/schema/type/document-storage.json +226 -0
  215. package/lib/schema/type/message-service.json +123 -0
  216. package/lib/schema/type/vector-store.json +88 -0
  217. package/lib/utils/aifabrix-runtime-config-dir.js +132 -0
  218. package/lib/utils/api-error-handler.js +2 -2
  219. package/lib/utils/api.js +77 -17
  220. package/lib/utils/app-register-api.js +3 -2
  221. package/lib/utils/app-register-auth.js +1 -1
  222. package/lib/utils/app-register-config.js +4 -4
  223. package/lib/utils/app-register-display.js +3 -2
  224. package/lib/utils/app-register-validator.js +3 -2
  225. package/lib/utils/app-run-containers.js +26 -22
  226. package/lib/utils/app-scoped-config.js +31 -0
  227. package/lib/utils/app-service-env-from-builder.js +164 -0
  228. package/lib/utils/build-copy.js +1 -1
  229. package/lib/utils/build-helpers.js +20 -20
  230. package/lib/utils/build-resolve-image.js +165 -0
  231. package/lib/utils/cli-layout-chalk.js +8 -0
  232. package/lib/utils/cli-test-layout-chalk.js +267 -0
  233. package/lib/utils/cli-utils.js +88 -11
  234. package/lib/utils/compose-db-passwords.js +138 -0
  235. package/lib/utils/compose-generate-docker-compose.js +216 -0
  236. package/lib/utils/compose-generator.js +197 -291
  237. package/lib/utils/compose-miso-env.js +18 -0
  238. package/lib/utils/compose-traefik-ingress-base.js +158 -0
  239. package/lib/utils/config-paths.js +166 -7
  240. package/lib/utils/config-scoped-resources-preference.js +41 -0
  241. package/lib/utils/configuration-env-resolver.js +11 -8
  242. package/lib/utils/controller-deployment-outcome.js +68 -0
  243. package/lib/utils/credential-display.js +2 -2
  244. package/lib/utils/credential-secrets-env.js +5 -5
  245. package/lib/utils/dataplane-pipeline-warning.js +4 -3
  246. package/lib/utils/datasource-test-run-capability-scope.js +43 -0
  247. package/lib/utils/datasource-test-run-certificate-tty.js +82 -0
  248. package/lib/utils/datasource-test-run-debug-display.js +137 -0
  249. package/lib/utils/datasource-test-run-debug-slice.js +93 -0
  250. package/lib/utils/datasource-test-run-display.js +459 -0
  251. package/lib/utils/datasource-test-run-exit.js +83 -0
  252. package/lib/utils/datasource-test-run-legacy-adapter.js +93 -0
  253. package/lib/utils/datasource-test-run-report-version.js +51 -0
  254. package/lib/utils/datasource-test-run-schema-sync.js +59 -0
  255. package/lib/utils/datasource-test-run-tty-log.js +81 -0
  256. package/lib/utils/datasource-validation-watch.js +266 -0
  257. package/lib/utils/declarative-url-ports.js +47 -0
  258. package/lib/utils/derive-env-key-from-client-id.js +41 -0
  259. package/lib/utils/dev-ca-install.js +185 -23
  260. package/lib/utils/dev-cert-helper.js +266 -17
  261. package/lib/utils/dev-hosts-helper.js +307 -0
  262. package/lib/utils/dev-init-cert-hints.js +37 -0
  263. package/lib/utils/dev-init-health-messages.js +52 -0
  264. package/lib/utils/dev-init-resolve.js +86 -0
  265. package/lib/utils/dev-init-ssh-merge.js +65 -0
  266. package/lib/utils/dev-ssh-config-helper.js +196 -0
  267. package/lib/utils/dev-user-groups.js +93 -0
  268. package/lib/utils/docker-build.js +42 -17
  269. package/lib/utils/docker-exec.js +28 -0
  270. package/lib/utils/docker-manifest-public-port.js +116 -0
  271. package/lib/utils/docker-not-running-hint.js +52 -0
  272. package/lib/utils/docker.js +98 -11
  273. package/lib/utils/ensure-dev-certs-for-remote-docker.js +192 -0
  274. package/lib/utils/env-config-loader.js +10 -91
  275. package/lib/utils/env-copy.js +19 -10
  276. package/lib/utils/env-map.js +35 -8
  277. package/lib/utils/env-template.js +2 -2
  278. package/lib/utils/environment-scoped-resources.js +144 -0
  279. package/lib/utils/error-formatter.js +92 -13
  280. package/lib/utils/error-formatters/http-status-errors.js +6 -5
  281. package/lib/utils/error-formatters/network-errors.js +2 -1
  282. package/lib/utils/error-formatters/permission-errors.js +2 -1
  283. package/lib/utils/error-formatters/validation-errors.js +2 -1
  284. package/lib/utils/external-readme.js +8 -1
  285. package/lib/utils/external-system-display.js +242 -136
  286. package/lib/utils/external-system-local-test-tty.js +389 -0
  287. package/lib/utils/external-system-readiness-core.js +377 -0
  288. package/lib/utils/external-system-readiness-deploy-display.js +270 -0
  289. package/lib/utils/external-system-readiness-display-internals.js +150 -0
  290. package/lib/utils/external-system-readiness-display.js +186 -0
  291. package/lib/utils/external-system-system-test-tty-overview.js +120 -0
  292. package/lib/utils/external-system-system-test-tty.js +417 -0
  293. package/lib/utils/external-system-test-helpers.js +24 -6
  294. package/lib/utils/external-system-validators.js +30 -12
  295. package/lib/utils/health-check-url.js +119 -0
  296. package/lib/utils/health-check.js +59 -25
  297. package/lib/utils/help-builder.js +11 -8
  298. package/lib/utils/image-version.js +4 -8
  299. package/lib/utils/infra-containers.js +4 -7
  300. package/lib/utils/infra-env-defaults.js +162 -0
  301. package/lib/utils/infra-status-display.js +167 -0
  302. package/lib/utils/infra-status.js +16 -8
  303. package/lib/utils/local-secrets.js +3 -4
  304. package/lib/utils/paths.js +148 -47
  305. package/lib/utils/port-resolver.js +10 -23
  306. package/lib/utils/redis-env-scope.js +62 -0
  307. package/lib/utils/register-aifabrix-shell-env.js +204 -0
  308. package/lib/utils/remote-builder-validation.js +99 -0
  309. package/lib/utils/remote-dev-auth.js +117 -21
  310. package/lib/utils/remote-docker-env.js +67 -15
  311. package/lib/utils/remote-secrets-loader.js +13 -4
  312. package/lib/utils/resolve-docker-image-ref.js +124 -0
  313. package/lib/utils/schema-loader.js +22 -9
  314. package/lib/utils/secrets-bash-kv.js +25 -0
  315. package/lib/utils/secrets-generator.js +169 -49
  316. package/lib/utils/secrets-helpers.js +70 -59
  317. package/lib/utils/secrets-kv-scope.js +60 -0
  318. package/lib/utils/secrets-utils.js +32 -38
  319. package/lib/utils/secrets-validation.js +3 -1
  320. package/lib/utils/secrets-yaml-preserve.js +109 -0
  321. package/lib/utils/ssh-key-helper.js +4 -2
  322. package/lib/utils/template-helpers.js +2 -2
  323. package/lib/utils/test-log-writer.js +3 -3
  324. package/lib/utils/token-manager.js +1 -2
  325. package/lib/utils/url-declarative-public-base.js +188 -0
  326. package/lib/utils/url-declarative-resolve-build.js +493 -0
  327. package/lib/utils/url-declarative-resolve-load-doc.js +51 -0
  328. package/lib/utils/url-declarative-resolve.js +220 -0
  329. package/lib/utils/url-declarative-token-parse.js +74 -0
  330. package/lib/utils/url-declarative-url-flags.js +50 -0
  331. package/lib/utils/url-declarative-vdir-inactive-env.js +99 -0
  332. package/lib/utils/url-public-path-prefix.js +34 -0
  333. package/lib/utils/urls-local-registry.js +220 -0
  334. package/lib/utils/validation-report-tty-kit.js +77 -0
  335. package/lib/utils/validation-run-poll.js +112 -0
  336. package/lib/utils/validation-run-post-retry.js +85 -0
  337. package/lib/utils/validation-run-request.js +116 -0
  338. package/lib/utils/variable-transformer.js +21 -4
  339. package/lib/utils/yaml-preserve.js +33 -14
  340. package/lib/validation/datasource-warnings.js +56 -0
  341. package/lib/validation/env-template-auth.js +1 -1
  342. package/lib/validation/external-manifest-validator.js +27 -7
  343. package/lib/validation/validate-display.js +37 -31
  344. package/lib/validation/validate-external-cert-sync.js +23 -0
  345. package/lib/validation/validate.js +8 -14
  346. package/lib/validation/validator-unresolved-placeholders.js +98 -0
  347. package/lib/validation/validator.js +22 -65
  348. package/lib/validation/wizard-config-validator.js +2 -1
  349. package/package.json +9 -4
  350. package/scripts/check-datasource-test-run-schema-sync.js +34 -0
  351. package/scripts/diagnose-cli.js +150 -0
  352. package/scripts/install-local.js +307 -55
  353. package/scripts/pnpm-global-remove.js +48 -0
  354. package/templates/README.md +15 -2
  355. package/templates/applications/dataplane/application.yaml +52 -2
  356. package/templates/applications/dataplane/env.template +79 -17
  357. package/templates/applications/dataplane/rbac.yaml +8 -0
  358. package/templates/applications/keycloak/application.yaml +9 -1
  359. package/templates/applications/keycloak/env.template +15 -6
  360. package/templates/applications/miso-controller/application.yaml +10 -2
  361. package/templates/applications/miso-controller/env.template +42 -12
  362. package/templates/applications/miso-controller/rbac.yaml +5 -0
  363. package/templates/external-system/README.md.hbs +20 -7
  364. package/templates/external-system/deploy.js.hbs +5 -5
  365. package/templates/external-system/external-datasource.yaml.hbs +197 -118
  366. package/templates/infra/compose.yaml.hbs +33 -16
  367. package/templates/infra/servers.json.hbs +3 -1
  368. package/templates/python/docker-compose.hbs +16 -0
  369. package/templates/typescript/docker-compose.hbs +16 -0
  370. package/lib/api/external-test.api.js +0 -111
  371. package/lib/schema/env-config.yaml +0 -60
@@ -1,3 +1,4 @@
1
+ const { formatSuccessLine } = require('../utils/cli-test-layout-chalk');
1
2
  /**
2
3
  * CLI infrastructure command setup (up-infra, up-platform, up-miso, up-dataplane, down-infra, doctor, status, restart).
3
4
  *
@@ -18,6 +19,22 @@ const { handleLogin } = require('../commands/login');
18
19
  const { handleUpMiso } = require('../commands/up-miso');
19
20
  const { handleUpDataplane } = require('../commands/up-dataplane');
20
21
  const { cleanBuilderAppDirs } = require('../commands/up-common');
22
+ const {
23
+ loadInfraStatusSummary,
24
+ formatInfraStatusTitleLine,
25
+ logInfraStatusConfigurationSummary,
26
+ logPaddedFieldRow
27
+ } = require('../utils/infra-status-display');
28
+
29
+ const UP_INFRA_HELP_AFTER = `
30
+ Typical sequence:
31
+ $ aifabrix up-infra
32
+ $ aifabrix up-platform
33
+ Or: aifabrix up-miso, then aifabrix up-dataplane (login required for dataplane)
34
+
35
+ Full bootstrap example (Traefik, TLS flag, pgAdmin, catalog overrides — matches shipped defaults in infra.parameter.yaml):
36
+ $ aifabrix up-infra --traefik --tls --adminPassword admin123 --adminEmail admin@aifabrix.dev --userPassword user123 --pgAdmin
37
+ `;
21
38
 
22
39
  /**
23
40
  * Persists optional service flag to config when explicitly set.
@@ -29,7 +46,29 @@ const { cleanBuilderAppDirs } = require('../commands/up-common');
29
46
  async function persistOptionalServiceFlag(cfg, key, value, label) {
30
47
  cfg[key] = value;
31
48
  await config.saveConfig(cfg);
32
- logger.log(chalk.green(`✓ ${label} ${value ? 'enabled' : 'disabled'} and saved to config`));
49
+ logger.log(formatSuccessLine(`${label} ${value ? 'enabled' : 'disabled'} and saved to config`));
50
+ }
51
+
52
+ /**
53
+ * Persists TLS mode for ${TLS_ENABLED} / ${HTTP_ENABLED} in application.yaml / deployment manifest interpolation.
54
+ * @param {Object} cfg - Config object (mutated)
55
+ * @param {boolean} value - Whether TLS mode is on
56
+ */
57
+ async function persistTlsEnabledFlag(cfg, value) {
58
+ cfg.tlsEnabled = value;
59
+ await config.saveConfig(cfg);
60
+ const tlsStr = value ? 'true' : 'false';
61
+ const httpStr = value ? 'false' : 'true';
62
+ logger.log(
63
+ chalk.green(
64
+ `✔ TLS mode ${value ? 'enabled' : 'disabled'} and saved to config (` +
65
+ '${TLS_ENABLED}=' +
66
+ tlsStr +
67
+ ', ${HTTP_ENABLED}=' +
68
+ httpStr +
69
+ ' when generating deployment JSON)'
70
+ )
71
+ );
33
72
  }
34
73
 
35
74
  /**
@@ -46,24 +85,26 @@ function resolveFlag(optValue, cfgValue, defaultWhenUndef = true) {
46
85
  }
47
86
 
48
87
  /**
49
- * Runs the up-infra command: resolves developer ID, traefik, pgAdmin, redisAdmin, and starts infra.
50
- * @param {Object} options - Commander options (developer, traefik, pgAdmin, redisAdmin)
51
- * @returns {Promise<void>}
88
+ * @param {Object} options - Commander options
89
+ * @returns {Promise<number|null>} Developer ID or null
52
90
  */
53
- async function runUpInfraCommand(options) {
54
- await config.ensureSecretsEncryptionKey();
55
- let developerId = null;
56
- if (options.developer) {
57
- const id = parseInt(options.developer, 10);
58
- if (isNaN(id) || id < 0) {
59
- throw new Error('Developer ID must be a non-negative number (0 = default infra, > 0 = developer-specific)');
60
- }
61
- await config.setDeveloperId(id);
62
- process.env.AIFABRIX_DEVELOPERID = id.toString();
63
- developerId = id;
64
- logger.log(chalk.green(`✓ Developer ID set to ${id}`));
91
+ async function applyDeveloperIdFromUpInfra(options) {
92
+ if (!options.developer) return null;
93
+ const id = parseInt(options.developer, 10);
94
+ if (isNaN(id) || id < 0) {
95
+ throw new Error('Developer ID must be a non-negative number (0 = default infra, > 0 = developer-specific)');
65
96
  }
66
- const cfg = await config.getConfig();
97
+ await config.setDeveloperId(id);
98
+ process.env.AIFABRIX_DEVELOPERID = id.toString();
99
+ logger.log(formatSuccessLine(`Developer ID set to ${id}`));
100
+ return id;
101
+ }
102
+
103
+ /**
104
+ * @param {Object} options
105
+ * @param {Object} cfg - Mutable config from getConfig()
106
+ */
107
+ async function persistOptionalInfraFlagsFromCli(options, cfg) {
67
108
  const flagSpecs = [
68
109
  { opt: options.traefik, key: 'traefik', label: 'Traefik' },
69
110
  { opt: options.pgAdmin, key: 'pgadmin', label: 'pgAdmin' },
@@ -74,25 +115,59 @@ async function runUpInfraCommand(options) {
74
115
  await persistOptionalServiceFlag(cfg, key, opt, label);
75
116
  }
76
117
  }
118
+ }
119
+
120
+ /**
121
+ * @param {Object} options
122
+ * @param {Object} cfg
123
+ */
124
+ async function maybePersistTlsFromUpInfra(options, cfg) {
125
+ // Commander maps --no-tls to options.tls === false (not a separate notls flag).
126
+ if (options.tls === true) await persistTlsEnabledFlag(cfg, true);
127
+ else if (options.tls === false) await persistTlsEnabledFlag(cfg, false);
128
+ }
129
+
130
+ /**
131
+ * Runs the up-infra command: resolves developer ID, traefik, pgAdmin, redisAdmin, and starts infra.
132
+ * @param {Object} options - Commander options (developer, traefik, pgAdmin, redisAdmin)
133
+ * @returns {Promise<void>}
134
+ */
135
+ async function runUpInfraCommand(options) {
136
+ await config.ensureSecretsEncryptionKey();
137
+ const developerId = await applyDeveloperIdFromUpInfra(options);
138
+ const cfg = await config.getConfig();
139
+ await persistOptionalInfraFlagsFromCli(options, cfg);
140
+ await maybePersistTlsFromUpInfra(options, cfg);
141
+ const adminPass = options.adminPassword || options.adminPwd;
142
+ const tlsEnabledEffective = cfg.tlsEnabled === true;
77
143
  await infra.startInfra(developerId, {
78
144
  traefik: resolveFlag(options.traefik, cfg.traefik, false),
79
145
  pgadmin: resolveFlag(options.pgAdmin, cfg.pgadmin, true),
80
146
  redisCommander: resolveFlag(options.redisAdmin, cfg.redisCommander, true),
81
- adminPwd: options.adminPwd
147
+ adminPassword: adminPass,
148
+ adminPwd: adminPass,
149
+ adminEmail: options.adminEmail,
150
+ userPassword: options.userPassword,
151
+ tlsEnabled: tlsEnabledEffective
82
152
  });
83
153
  }
84
154
 
85
155
  function setupUpInfraCommand(program) {
86
156
  program.command('up-infra')
87
- .description('Start local infrastructure: Postgres, Redis, optional pgAdmin, Redis Commander, Traefik')
157
+ .description('Start Postgres, Redis; optional pgAdmin, Redis Commander, Traefik')
158
+ .addHelpText('after', UP_INFRA_HELP_AFTER)
88
159
  .option('-d, --developer <id>', 'Set developer ID and start infrastructure')
89
- .option('--adminPwd <password>', 'Override default admin password for new install (Postgres, pgAdmin, Redis Commander)')
160
+ .option('--adminPassword <password>', 'Override {{adminPassword}} defaults (Postgres, pgAdmin, Redis Commander, catalog literals)')
161
+ .option('--adminEmail <email>', 'Override {{adminEmail}} default (e.g. pgAdmin login email)')
162
+ .option('--userPassword <password>', 'Override {{userPassword}} default (e.g. Keycloak default user password)')
90
163
  .option('--pgAdmin', 'Include pgAdmin web UI and save to config')
91
164
  .option('--no-pgAdmin', 'Exclude pgAdmin and save to config')
92
165
  .option('--redisAdmin', 'Include Redis Commander web UI and save to config')
93
166
  .option('--no-redisAdmin', 'Exclude Redis Commander and save to config')
94
167
  .option('--traefik', 'Include Traefik reverse proxy and save to config')
95
168
  .option('--no-traefik', 'Exclude Traefik and save to config')
169
+ .option('--tls', 'Enable TLS mode; save tlsEnabled (${TLS_ENABLED}=true, ${HTTP_ENABLED}=false in application.yaml)')
170
+ .option('--no-tls', 'Disable TLS mode (${TLS_ENABLED}=false, ${HTTP_ENABLED}=true)')
96
171
  .action(async(options) => {
97
172
  try {
98
173
  await runUpInfraCommand(options);
@@ -105,7 +180,7 @@ function setupUpInfraCommand(program) {
105
180
 
106
181
  function setupUpPlatformCommand(program) {
107
182
  program.command('up-platform')
108
- .description('Start platform (Keycloak, Miso Controller, Dataplane) from community images; infra must be up')
183
+ .description('Start Keycloak, Miso Controller, dataplane from images (needs up-infra)')
109
184
  .option('-r, --registry <url>', 'Override registry for all apps (e.g. myacr.azurecr.io)')
110
185
  .option('--registry-mode <mode>', 'Override registry mode (acr|external)')
111
186
  .option('-i, --image <key>=<value>', 'Override image (e.g. keycloak=myreg/k:v1, miso-controller=myreg/m:v1, dataplane=myreg/d:v1); can be repeated', (v, prev) => (prev || []).concat([v]))
@@ -138,7 +213,7 @@ function setupUpPlatformCommand(program) {
138
213
 
139
214
  function setupUpMisoCommand(program) {
140
215
  program.command('up-miso')
141
- .description('Install keycloak and miso-controller from images (no build). Infra must be up. For dataplane use up-dataplane. Uses auto-generated secrets for testing.')
216
+ .description('Start Keycloak + Miso Controller from images only (no dataplane; needs up-infra)')
142
217
  .option('-r, --registry <url>', 'Override registry for all apps (e.g. myacr.azurecr.io)')
143
218
  .option('--registry-mode <mode>', 'Override registry mode (acr|external)')
144
219
  .option('-i, --image <key>=<value>', 'Override image (e.g. keycloak=myreg/k:v1, miso-controller=myreg/m:v1); can be repeated', (v, prev) => (prev || []).concat([v]))
@@ -158,7 +233,7 @@ function setupUpMisoCommand(program) {
158
233
 
159
234
  function setupUpDataplaneCommand(program) {
160
235
  program.command('up-dataplane')
161
- .description('Register, deploy, then run dataplane app locally in dev (always local deployment; requires login, environment must be dev)')
236
+ .description('Register, deploy, run dataplane locally (dev env; login required)')
162
237
  .option('-r, --registry <url>', 'Override registry for dataplane image')
163
238
  .option('--registry-mode <mode>', 'Override registry mode (acr|external)')
164
239
  .option('-i, --image <ref>', 'Override dataplane image reference (e.g. myreg/dataplane:latest)')
@@ -189,8 +264,8 @@ function setupUpDataplaneCommand(program) {
189
264
  }
190
265
 
191
266
  function setupDownInfraCommand(program) {
192
- program.command('down-infra [app]')
193
- .description('Stop and remove local infrastructure services or a specific application')
267
+ program.command('down-infra [service|app]')
268
+ .description('Stop all infra, or stop one app; use -v to remove volumes')
194
269
  .option('-v, --volumes', 'Remove volumes (deletes all data)')
195
270
  .action(async(appName, options) => {
196
271
  try {
@@ -209,14 +284,14 @@ function setupDownInfraCommand(program) {
209
284
 
210
285
  function setupDoctorCommand(program) {
211
286
  program.command('doctor')
212
- .description('Check environment and configuration')
287
+ .description('Check Docker, ports, secrets, and infra health')
213
288
  .action(async() => {
214
289
  try {
215
290
  const result = await validator.checkEnvironment();
216
291
  logger.log('\n🔍 AI Fabrix Environment Check\n');
217
- logger.log(`Docker: ${result.docker === 'ok' ? ' Running' : ' Not available'}`);
218
- logger.log(`Ports: ${result.ports === 'ok' ? ' Available' : '⚠️ Some ports in use'}`);
219
- logger.log(`Secrets: ${result.secrets === 'ok' ? ' Configured' : ' Missing'}`);
292
+ logger.log(`Docker: ${result.docker === 'ok' ? ' Running' : ' Not available'}`);
293
+ logger.log(`Ports: ${result.ports === 'ok' ? ' Available' : ' Some ports in use'}`);
294
+ logger.log(`Secrets: ${result.secrets === 'ok' ? ' Configured' : ' Missing'}`);
220
295
  if (result.recommendations.length > 0) {
221
296
  logger.log('\n📋 Recommendations:');
222
297
  result.recommendations.forEach(rec => logger.log(` • ${rec}`));
@@ -231,7 +306,7 @@ function setupDoctorCommand(program) {
231
306
  });
232
307
  logger.log('\n🏥 Infrastructure Health:');
233
308
  Object.entries(health).forEach(([service, status]) => {
234
- const icon = status === 'healthy' ? '' : status === 'unknown' ? '❓' : '';
309
+ const icon = status === 'healthy' ? '' : status === 'unknown' ? '❓' : '';
235
310
  logger.log(` ${icon} ${service}: ${status}`);
236
311
  });
237
312
  } catch (error) {
@@ -248,17 +323,21 @@ function setupDoctorCommand(program) {
248
323
 
249
324
  function setupStatusCommand(program) {
250
325
  program.command('status')
251
- .description('Show detailed infrastructure service status and running applications')
326
+ .description('Show infra services and running apps (ports, URLs)')
252
327
  .action(async() => {
253
328
  try {
329
+ const summary = await loadInfraStatusSummary();
254
330
  const status = await infra.getInfraStatus();
255
- logger.log('\n📊 Infrastructure Status\n');
331
+ logger.log('');
332
+ logger.log(formatInfraStatusTitleLine(summary.devIdStr, summary.remoteServer));
333
+ logger.log('');
334
+ logInfraStatusConfigurationSummary(summary);
256
335
  Object.entries(status).forEach(([service, info]) => {
257
- const icon = String(info.status).trim().toLowerCase() === 'running' ? '' : '';
258
- logger.log(`${icon} ${service}:`);
259
- logger.log(` Status: ${info.status}`);
260
- logger.log(` Port: ${info.port}`);
261
- logger.log(` URL: ${info.url}`);
336
+ const icon = String(info.status).trim().toLowerCase() === 'running' ? '' : '';
337
+ logger.log(`${icon} ${service}`);
338
+ logPaddedFieldRow('Status', info.status);
339
+ logPaddedFieldRow('Port', info.port);
340
+ logPaddedFieldRow('URL', info.url);
262
341
  logger.log('');
263
342
  });
264
343
  const apps = await infra.getAppStatus();
@@ -266,12 +345,12 @@ function setupStatusCommand(program) {
266
345
  logger.log('📱 Running Applications\n');
267
346
  apps.forEach((appInfo) => {
268
347
  const s = String(appInfo.status).trim().toLowerCase();
269
- const icon = s.includes('running') || s.includes('up') ? '' : '';
270
- logger.log(`${icon} ${appInfo.name}:`);
271
- logger.log(` Container: ${appInfo.container}`);
272
- logger.log(` Port: ${appInfo.port}`);
273
- logger.log(` Status: ${appInfo.status}`);
274
- logger.log(` URL: ${appInfo.url}`);
348
+ const icon = s.includes('running') || s.includes('up') ? '' : '';
349
+ logger.log(`${icon} ${appInfo.name}`);
350
+ logPaddedFieldRow('Container', appInfo.container);
351
+ logPaddedFieldRow('Port', appInfo.port);
352
+ logPaddedFieldRow('Status', appInfo.status);
353
+ logPaddedFieldRow('URL', appInfo.url);
275
354
  logger.log('');
276
355
  });
277
356
  }
@@ -285,16 +364,16 @@ function setupStatusCommand(program) {
285
364
  const INFRA_SERVICES = ['postgres', 'redis', 'pgadmin', 'redis-commander', 'traefik'];
286
365
 
287
366
  function setupRestartCommand(program) {
288
- program.command('restart <service>')
289
- .description('Restart an infrastructure service or a Docker application (builder/<app>)')
367
+ program.command('restart <service|app>')
368
+ .description('Restart infra service (postgres, redis, …) or a builder/<app> container')
290
369
  .action(async(service) => {
291
370
  try {
292
371
  if (INFRA_SERVICES.includes(service)) {
293
372
  await infra.restartService(service);
294
- logger.log(`✅ ${service} service restarted successfully`);
373
+ logger.log(`✔ ${service} service restarted successfully`);
295
374
  } else {
296
375
  await appLib.restartApp(service);
297
- logger.log(`✅ ${service} restarted successfully`);
376
+ logger.log(`✔ ${service} restarted successfully`);
298
377
  }
299
378
  } catch (error) {
300
379
  handleCommandError(error, 'restart');
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @fileoverview parameters subcommand (validate kv:// catalog coverage)
3
+ * @author AI Fabrix Team
4
+ * @version 2.0.0
5
+ */
6
+
7
+ const { handleCommandError } = require('../utils/cli-utils');
8
+ const { handleParametersValidate } = require('../commands/parameters-validate');
9
+
10
+ /**
11
+ * @param {import('commander').Command} program - Commander program
12
+ */
13
+ function setupParametersCommands(program) {
14
+ const parameters = program
15
+ .command('parameters')
16
+ .description('Infra parameter catalog (kv:// keys, generators, Azure naming hints)');
17
+
18
+ parameters
19
+ .command('validate')
20
+ .description('Check env.template kv:// references against lib/schema/infra.parameter.yaml')
21
+ .option('--catalog <path>', 'Override path to infra.parameter.yaml')
22
+ .action(async(opts) => {
23
+ try {
24
+ const result = await handleParametersValidate({ catalogPath: opts.catalog });
25
+ if (!result.valid) process.exit(1);
26
+ } catch (error) {
27
+ handleCommandError(error, 'parameters validate');
28
+ }
29
+ });
30
+ }
31
+
32
+ module.exports = { setupParametersCommands };
@@ -6,7 +6,7 @@
6
6
  * @version 2.0.0
7
7
  */
8
8
 
9
- const chalk = require('chalk');
9
+ 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');
@@ -16,10 +16,113 @@ const { handleSecure } = require('../commands/secure');
16
16
  const config = require('../core/config');
17
17
  const logger = require('../utils/logger');
18
18
 
19
+ const SECRET_GROUP_HELP_AFTER = `
20
+ Subcommands:
21
+ list, set, remove, remove-all User secrets.local.yaml (add --shared for shared/remote)
22
+ set-secrets-file Point config at a shared secrets file or https URL
23
+ validate YAML structure (+ optional --naming)
24
+
25
+ Also: aifabrix secure Encrypt secrets.local.yaml (ISO 27001)
26
+
27
+ Default "secret set" (no --shared): writes only to your user secrets.local.yaml next to
28
+ config.yaml (typically ~/.aifabrix/secrets.local.yaml). Use --shared to write the
29
+ shared store from config aifabrix-secrets (another file or https), not that user file.
30
+
31
+ Examples:
32
+ $ aifabrix secret list
33
+ $ aifabrix secret set myapp/clientSecret "your-value"
34
+ $ aifabrix secret remove old-key
35
+ $ aifabrix secret remove-all
36
+ $ aifabrix secret validate
37
+
38
+ Shared over https: key BASH_NPM_TOKEN --shared → NPM_TOKEN available in terminal (exported).
39
+ `;
40
+
41
+ const SECRET_LIST_HELP_AFTER = `
42
+ Examples:
43
+ $ aifabrix secret list
44
+ $ aifabrix secret list --shared
45
+ `;
46
+
47
+ const SECRET_SET_HELP_AFTER = `
48
+ Where the value is stored:
49
+ No --shared User file secrets.local.yaml in your aifabrix config directory (same
50
+ folder as config.yaml; often ~/.aifabrix/). Used for app/integration
51
+ secrets and kv:// resolution on your machine.
52
+ --shared The store set in config.yaml as aifabrix-secrets: a YAML file path or
53
+ an https secrets API (never the user-only file above unless you point
54
+ aifabrix-secrets at that path deliberately).
55
+
56
+ Examples:
57
+ $ aifabrix secret set myapp/clientSecret "your-secret"
58
+ $ aifabrix secret set hubspot/apiKey "$HUBSPOT_KEY"
59
+ $ aifabrix secret set team/shared-token "value" --shared
60
+ $ aifabrix secret set BASH_NPM_TOKEN "$NPM_TOKEN" --shared
61
+
62
+ With https aifabrix-secrets: keys named BASH_<NAME> --shared expose <NAME> in your
63
+ terminal as an exported env var (e.g. BASH_NPM_TOKEN → NPM_TOKEN).
64
+ `;
65
+
66
+ const SECRET_REMOVE_HELP_AFTER = `
67
+ Examples:
68
+ $ aifabrix secret remove deprecated-key
69
+ $ aifabrix secret remove shared-key --shared
70
+ `;
71
+
72
+ const SECRET_REMOVE_ALL_HELP_AFTER = `
73
+ You will be asked to type "yes" to confirm unless you pass --yes.
74
+
75
+ Examples:
76
+ $ aifabrix secret remove-all
77
+ $ aifabrix secret remove-all --yes
78
+ $ aifabrix secret remove-all --shared
79
+ $ aifabrix secret remove-all --shared --yes
80
+ `;
81
+
82
+ const SECRET_SET_SECRETS_FILE_HELP_AFTER = `
83
+ Examples:
84
+ $ aifabrix secret set-secrets-file ./shared-secrets.yaml
85
+ $ aifabrix secret set-secrets-file https://dev.example.com/api/secrets
86
+ $ aifabrix secret set-secrets-file ""
87
+ `;
88
+
89
+ const SECRET_VALIDATE_HELP_AFTER = `
90
+ Examples:
91
+ $ aifabrix secret validate
92
+ $ aifabrix secret validate ./secrets.local.yaml
93
+ $ aifabrix secret validate --naming
94
+ `;
95
+
96
+ const SECURE_HELP_AFTER = `
97
+ Examples:
98
+ $ aifabrix secure
99
+ $ aifabrix secure --secrets-encryption <32-byte-hex-or-base64>
100
+ `;
101
+
102
+ function setupSecretRemoveAllCommand(secretCmd) {
103
+ const { handleSecretsRemoveAll } = require('../commands/secrets-remove-all');
104
+ secretCmd
105
+ .command('remove-all')
106
+ .description('Remove all secret keys (requires typing "yes" unless --yes)')
107
+ .addHelpText('after', SECRET_REMOVE_ALL_HELP_AFTER)
108
+ .option('--shared', 'Remove all from shared secrets (file or remote API)')
109
+ .option('-y, --yes', 'Skip confirmation prompt (non-interactive / scripts)')
110
+ .action(async options => {
111
+ try {
112
+ await config.ensureSecretsEncryptionKey();
113
+ await handleSecretsRemoveAll(options);
114
+ } catch (error) {
115
+ handleCommandError(error, 'secret remove-all');
116
+ process.exit(1);
117
+ }
118
+ });
119
+ }
120
+
19
121
  function setupSecretValidateCommand(secretCmd) {
20
122
  secretCmd
21
123
  .command('validate [path]')
22
124
  .description('Validate secrets file (YAML structure and optional naming convention)')
125
+ .addHelpText('after', SECRET_VALIDATE_HELP_AFTER)
23
126
  .option('--naming', 'Check key names against *KeyVault convention')
24
127
  .action(async(pathArg, options) => {
25
128
  try {
@@ -39,7 +142,8 @@ function setupSecretValidateCommand(secretCmd) {
39
142
  */
40
143
  function setupSecureCommand(program) {
41
144
  program.command('secure')
42
- .description('Encrypt secrets in secrets.local.yaml files for ISO 27001 compliance')
145
+ .description('Encrypt secrets.local.yaml at rest (ISO 27001)')
146
+ .addHelpText('after', SECURE_HELP_AFTER)
43
147
  .option('--secrets-encryption <key>', 'Encryption key (32 bytes, hex or base64)')
44
148
  .action(async(options) => {
45
149
  try {
@@ -52,20 +156,13 @@ function setupSecureCommand(program) {
52
156
  });
53
157
  }
54
158
 
55
- /**
56
- * Sets up secrets and security commands
57
- * @param {Command} program - Commander program instance
58
- */
59
- function setupSecretsCommands(program) {
60
- const secretCmd = program
61
- .command('secret')
62
- .description('Manage secrets in secrets files');
63
-
159
+ function setupSecretListCommand(secretCmd) {
64
160
  secretCmd
65
161
  .command('list')
66
- .description('List secret keys (user or shared; use --shared for shared)')
162
+ .description('List secret keys (--shared for shared/remote)')
163
+ .addHelpText('after', SECRET_LIST_HELP_AFTER)
67
164
  .option('--shared', 'List shared secrets (from config aifabrix-secrets or remote API)')
68
- .action(async(options) => {
165
+ .action(async options => {
69
166
  try {
70
167
  await config.ensureSecretsEncryptionKey();
71
168
  await handleSecretsList(options);
@@ -74,11 +171,30 @@ function setupSecretsCommands(program) {
74
171
  process.exit(1);
75
172
  }
76
173
  });
174
+ }
175
+
176
+ /**
177
+ * Sets up secrets and security commands
178
+ * @param {Command} program - Commander program instance
179
+ */
180
+ function setupSecretsCommands(program) {
181
+ const secretCmd = program
182
+ .command('secret')
183
+ .description('User and shared secrets (list, set, remove, remove-all, validate)')
184
+ .addHelpText('after', SECRET_GROUP_HELP_AFTER);
185
+
186
+ setupSecretListCommand(secretCmd);
77
187
 
78
188
  secretCmd
79
189
  .command('set <key> <value>')
80
- .description('Set a secret value in secrets file')
81
- .option('--shared', 'Save to general secrets file (from config.yaml aifabrix-secrets) instead of user secrets')
190
+ .description(
191
+ 'Set a secret (default: user secrets.local.yaml beside config; --shared → aifabrix-secrets store)'
192
+ )
193
+ .addHelpText('after', SECRET_SET_HELP_AFTER)
194
+ .option(
195
+ '--shared',
196
+ 'Write to shared secrets (config aifabrix-secrets: YAML path or https), not user secrets.local.yaml'
197
+ )
82
198
  .action(async(key, value, options) => {
83
199
  try {
84
200
  await config.ensureSecretsEncryptionKey();
@@ -91,7 +207,8 @@ function setupSecretsCommands(program) {
91
207
 
92
208
  secretCmd
93
209
  .command('remove <key>')
94
- .description('Remove a secret by key')
210
+ .description('Remove a secret key')
211
+ .addHelpText('after', SECRET_REMOVE_HELP_AFTER)
95
212
  .option('--shared', 'Remove from shared secrets (file or remote API)')
96
213
  .action(async(key, options) => {
97
214
  try {
@@ -103,6 +220,7 @@ function setupSecretsCommands(program) {
103
220
  }
104
221
  });
105
222
 
223
+ setupSecretRemoveAllCommand(secretCmd);
106
224
  setupSecretSetSecretsFileCommand(secretCmd);
107
225
  setupSecretValidateCommand(secretCmd);
108
226
  setupSecureCommand(program);
@@ -115,7 +233,8 @@ function setupSecretsCommands(program) {
115
233
  function setupSecretSetSecretsFileCommand(secretCmd) {
116
234
  secretCmd
117
235
  .command('set-secrets-file <path>')
118
- .description('Set aifabrix-secrets path in config (local file or https URL; pass empty to clear; path/URL is not checked for existence)')
236
+ .description('Set shared secrets path in config (file or https; empty clears; not validated)')
237
+ .addHelpText('after', SECRET_SET_SECRETS_FILE_HELP_AFTER)
119
238
  .action(async(secretsPath) => {
120
239
  try {
121
240
  const trimmed = (secretsPath || '').trim();
@@ -123,7 +242,7 @@ function setupSecretSetSecretsFileCommand(secretCmd) {
123
242
  throw new Error('Only https URLs are allowed for remote secrets');
124
243
  }
125
244
  await config.setSecretsPath(trimmed);
126
- logger.log(trimmed === '' ? chalk.green('Secrets file path cleared') : chalk.green(`✓ Secrets file path set to ${trimmed}`));
245
+ logger.log(trimmed === '' ? formatSuccessLine('Secrets file path cleared') : formatSuccessLine(`Secrets file path set to ${trimmed}`));
127
246
  } catch (error) {
128
247
  handleCommandError(error, 'secret set-secrets-file');
129
248
  process.exit(1);
@@ -174,7 +174,7 @@ function addUpdateRedirectUrisCommand(serviceUser) {
174
174
  function setupServiceUserCommands(program) {
175
175
  const serviceUser = program
176
176
  .command('service-user')
177
- .description('Create and manage service users (API clients) for integrations and CI')
177
+ .description('OAuth service users on Controller (integrations, CI)')
178
178
  .addHelpText('after', HELP_AFTER);
179
179
  addCreateCommand(serviceUser);
180
180
  addListCommand(serviceUser);