@aifabrix/builder 2.42.1 → 2.44.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 (392) hide show
  1. package/.cursor/rules/anchor-docs.mdc +15 -0
  2. package/README.md +2 -2
  3. package/anchor-docs/README.md +10 -0
  4. package/anchor-docs/_TEMPLATE +24 -0
  5. package/bin/aifabrix.js +13 -4
  6. package/integration/hubspot-test/README.md +157 -0
  7. package/integration/{hubspot → hubspot-test}/application.json +6 -6
  8. package/integration/{hubspot → hubspot-test}/create-hubspot.js +10 -10
  9. package/integration/hubspot-test/env.template +4 -0
  10. package/integration/hubspot-test/hubspot-test-datasource-company.json +138 -0
  11. package/integration/hubspot-test/hubspot-test-datasource-contact.json +146 -0
  12. package/integration/hubspot-test/hubspot-test-datasource-deal.json +146 -0
  13. package/integration/hubspot-test/hubspot-test-datasource-users.json +76 -0
  14. package/integration/{hubspot/hubspot-deploy.json → hubspot-test/hubspot-test-deploy.json} +201 -24
  15. package/integration/{hubspot/hubspot-system.json → hubspot-test/hubspot-test-system.json} +8 -7
  16. package/integration/hubspot-test/rbac.json +166 -0
  17. package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-hubspot-credential-real.yaml +3 -3
  18. package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-hubspot-env-vars.yaml +2 -2
  19. package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-add-datasource.yaml +1 -1
  20. package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-credential-create.yaml +1 -1
  21. package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-credential-select.yaml +1 -1
  22. package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-known-platform.yaml +1 -1
  23. package/integration/hubspot-test/test-artifacts/wizard-invalid-missing-source.yaml +2 -0
  24. package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-mode.yaml +1 -1
  25. package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-openapi-file.yaml +1 -1
  26. package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-openapi-url.yaml +1 -1
  27. package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-source.yaml +1 -1
  28. package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-valid-for-dimension-array-test.yaml +1 -1
  29. package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-key-test.yaml +5 -0
  30. package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-path-test.yaml +5 -0
  31. package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-valid-for-dimension-test.yaml +1 -1
  32. package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-valid-for-rbac-test.yaml +1 -1
  33. package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-valid-for-rbac-yaml-test.yaml +1 -1
  34. package/integration/{hubspot → hubspot-test}/test-dataplane-down-tests.js +1 -7
  35. package/integration/{hubspot → hubspot-test}/test-dataplane-down.js +3 -3
  36. package/integration/{hubspot → hubspot-test}/test.js +137 -102
  37. package/integration/{hubspot → hubspot-test}/wizard-hubspot-e2e.yaml +2 -2
  38. package/integration/{hubspot → hubspot-test}/wizard-hubspot-platform.yaml +1 -1
  39. package/integration/hubspot-test/wizard-hubspot-test-headless.yaml +23 -0
  40. package/integration/roundtrip-test-local/README.md +144 -0
  41. package/integration/roundtrip-test-local/application.yaml +13 -0
  42. package/integration/roundtrip-test-local/env.template +15 -0
  43. package/integration/roundtrip-test-local/roundtrip-test-local-datasource-roundtrip-test-company.yaml +14 -0
  44. package/integration/roundtrip-test-local/roundtrip-test-local-deploy.json +61 -0
  45. package/integration/roundtrip-test-local/roundtrip-test-local-system.yaml +25 -0
  46. package/integration/roundtrip-test-local2/README.md +144 -0
  47. package/integration/roundtrip-test-local2/application.yaml +13 -0
  48. package/integration/roundtrip-test-local2/env.template +15 -0
  49. package/integration/roundtrip-test-local2/roundtrip-test-local2-datasource-company.yaml +31 -0
  50. package/integration/roundtrip-test-local2/roundtrip-test-local2-deploy.json +86 -0
  51. package/integration/roundtrip-test-local2/roundtrip-test-local2-system.yaml +25 -0
  52. package/integration/test/wizard.yaml +8 -0
  53. package/jest.config.default.js +10 -0
  54. package/jest.config.integration.fixtures.js +22 -0
  55. package/jest.config.integration.js +21 -18
  56. package/jest.config.isolated.js +10 -0
  57. package/jest.projects.js +288 -0
  58. package/lib/api/datasources-core.api.js +3 -3
  59. package/lib/api/dev-mtls-request.js +110 -0
  60. package/lib/api/dev-server-https.js +145 -0
  61. package/lib/api/dev.api.js +133 -144
  62. package/lib/api/index.js +0 -1
  63. package/lib/api/pipeline.api.js +67 -20
  64. package/lib/api/service-users.api.js +111 -2
  65. package/lib/api/types/dev.types.js +4 -3
  66. package/lib/api/types/pipeline.types.js +8 -5
  67. package/lib/api/types/service-users.types.js +41 -0
  68. package/lib/api/types/validation-run.types.js +56 -0
  69. package/lib/api/validation-run.api.js +99 -0
  70. package/lib/api/validation-runner.js +99 -0
  71. package/lib/app/config.js +1 -1
  72. package/lib/app/deploy-status-display.js +2 -2
  73. package/lib/app/deploy.js +7 -6
  74. package/lib/app/display.js +2 -1
  75. package/lib/app/dockerfile.js +3 -2
  76. package/lib/app/down.js +2 -1
  77. package/lib/app/helpers.js +6 -5
  78. package/lib/app/index.js +27 -8
  79. package/lib/app/list.js +7 -6
  80. package/lib/app/push.js +4 -3
  81. package/lib/app/register.js +19 -8
  82. package/lib/app/rotate-secret.js +17 -13
  83. package/lib/app/run-container-start.js +184 -0
  84. package/lib/app/run-docker-fallback.js +108 -0
  85. package/lib/app/run-env-compose.js +30 -42
  86. package/lib/app/run-helpers.js +49 -126
  87. package/lib/app/run-infra-requirements.js +30 -0
  88. package/lib/app/run-resolve-image.js +21 -0
  89. package/lib/app/run.js +74 -21
  90. package/lib/app/show-display.js +1 -1
  91. package/lib/app/show.js +1 -1
  92. package/lib/build/index.js +13 -10
  93. package/lib/cli/index.js +2 -0
  94. package/lib/cli/setup-app.help.js +67 -0
  95. package/lib/cli/setup-app.js +59 -123
  96. package/lib/cli/setup-app.test-commands.js +179 -0
  97. package/lib/cli/setup-auth.js +36 -14
  98. package/lib/cli/setup-credential-deployment.js +22 -8
  99. package/lib/cli/setup-dev-path-commands.js +124 -0
  100. package/lib/cli/setup-dev.js +190 -103
  101. package/lib/cli/setup-environment.js +11 -20
  102. package/lib/cli/setup-external-system.js +62 -22
  103. package/lib/cli/setup-infra.js +139 -47
  104. package/lib/cli/setup-parameters.js +32 -0
  105. package/lib/cli/setup-secrets.js +147 -10
  106. package/lib/cli/setup-service-user.js +146 -20
  107. package/lib/cli/setup-utility.js +47 -19
  108. package/lib/commands/app-down.js +5 -7
  109. package/lib/commands/app-install.js +14 -7
  110. package/lib/commands/app-logs.js +13 -10
  111. package/lib/commands/app-shell.js +4 -1
  112. package/lib/commands/app-test.js +25 -19
  113. package/lib/commands/app.js +22 -10
  114. package/lib/commands/auth-config.js +10 -14
  115. package/lib/commands/auth-status.js +4 -3
  116. package/lib/commands/credential-env.js +4 -3
  117. package/lib/commands/credential-list.js +5 -4
  118. package/lib/commands/credential-push.js +4 -3
  119. package/lib/commands/datasource-unified-test-cli.js +495 -0
  120. package/lib/commands/datasource-unified-test-cli.options.js +149 -0
  121. package/lib/commands/datasource-validation-cli.js +129 -0
  122. package/lib/commands/datasource.js +123 -71
  123. package/lib/commands/deployment-list.js +6 -5
  124. package/lib/commands/dev-cli-handlers.js +122 -18
  125. package/lib/commands/dev-down.js +4 -3
  126. package/lib/commands/dev-init.js +231 -116
  127. package/lib/commands/dev-show-display.js +473 -0
  128. package/lib/commands/login-credentials.js +3 -2
  129. package/lib/commands/login-device.js +4 -3
  130. package/lib/commands/login.js +5 -4
  131. package/lib/commands/logout.js +8 -7
  132. package/lib/commands/parameters-validate.js +54 -0
  133. package/lib/commands/repair-datasource.js +314 -68
  134. package/lib/commands/repair-env-template.js +16 -10
  135. package/lib/commands/repair-rbac.js +25 -19
  136. package/lib/commands/repair.js +116 -32
  137. package/lib/commands/secrets-list.js +23 -12
  138. package/lib/commands/secrets-remove-all.js +220 -0
  139. package/lib/commands/secrets-remove.js +22 -13
  140. package/lib/commands/secrets-set.js +21 -12
  141. package/lib/commands/secrets-validate.js +20 -7
  142. package/lib/commands/secure.js +10 -9
  143. package/lib/commands/service-user.js +243 -13
  144. package/lib/commands/test-e2e-external.js +27 -1
  145. package/lib/commands/up-common.js +28 -2
  146. package/lib/commands/up-dataplane.js +31 -18
  147. package/lib/commands/up-miso.js +19 -29
  148. package/lib/commands/upload.js +138 -39
  149. package/lib/commands/wizard-core-helpers.js +1 -1
  150. package/lib/commands/wizard-dataplane.js +4 -3
  151. package/lib/commands/wizard-helpers.js +3 -3
  152. package/lib/commands/wizard.js +2 -2
  153. package/lib/core/admin-secrets.js +16 -5
  154. package/lib/core/audit-logger.js +12 -4
  155. package/lib/core/config-attach-extensions.js +46 -0
  156. package/lib/core/config-runtime-paths.js +29 -0
  157. package/lib/core/config.js +59 -58
  158. package/lib/core/diff.js +3 -2
  159. package/lib/core/ensure-encryption-key.js +2 -4
  160. package/lib/core/secrets-ensure-infra.js +77 -0
  161. package/lib/core/secrets-ensure.js +120 -64
  162. package/lib/core/secrets-env-write.js +35 -7
  163. package/lib/core/secrets-infra-placeholder-sync.js +61 -0
  164. package/lib/core/secrets.js +228 -42
  165. package/lib/core/templates-env.js +4 -3
  166. package/lib/core/templates.js +1 -1
  167. package/lib/datasource/abac-validator.js +148 -0
  168. package/lib/datasource/deploy.js +75 -53
  169. package/lib/datasource/field-reference-validator.js +77 -36
  170. package/lib/datasource/integration-context.js +63 -0
  171. package/lib/datasource/list.js +8 -7
  172. package/lib/datasource/log-viewer.js +252 -0
  173. package/lib/datasource/resolve-app.js +109 -0
  174. package/lib/datasource/test-e2e.js +95 -155
  175. package/lib/datasource/test-integration.js +121 -109
  176. package/lib/datasource/unified-validation-run-body.js +65 -0
  177. package/lib/datasource/unified-validation-run-post.js +23 -0
  178. package/lib/datasource/unified-validation-run-resolve.js +43 -0
  179. package/lib/datasource/unified-validation-run.js +92 -0
  180. package/lib/datasource/validate.js +162 -15
  181. package/lib/deployment/deployer.js +4 -3
  182. package/lib/deployment/environment.js +7 -6
  183. package/lib/deployment/push.js +17 -8
  184. package/lib/external-system/delete.js +4 -3
  185. package/lib/external-system/deploy.js +131 -53
  186. package/lib/external-system/download-helpers.js +1 -1
  187. package/lib/external-system/download.js +7 -6
  188. package/lib/external-system/generator.js +104 -14
  189. package/lib/external-system/integration-test-dispatch.js +26 -0
  190. package/lib/external-system/test-execution.js +5 -1
  191. package/lib/external-system/test-helpers.js +0 -4
  192. package/lib/external-system/test-system-level-helpers.js +110 -0
  193. package/lib/external-system/test-system-level.js +83 -44
  194. package/lib/external-system/test.js +59 -8
  195. package/lib/generator/builders.js +23 -11
  196. package/lib/generator/deploy-manifest-azure-kv.js +81 -0
  197. package/lib/generator/external-controller-manifest.js +3 -3
  198. package/lib/generator/external.js +23 -11
  199. package/lib/generator/helpers.js +71 -12
  200. package/lib/generator/index.js +8 -4
  201. package/lib/generator/split-readme.js +12 -7
  202. package/lib/generator/split-variables.js +2 -1
  203. package/lib/generator/split.js +46 -11
  204. package/lib/generator/wizard-readme.js +3 -3
  205. package/lib/generator/wizard.js +16 -13
  206. package/lib/infrastructure/compose.js +60 -6
  207. package/lib/infrastructure/helpers.js +238 -51
  208. package/lib/infrastructure/index.js +64 -37
  209. package/lib/infrastructure/services.js +21 -15
  210. package/lib/internal/fs-real-sync.js +104 -0
  211. package/lib/internal/node-fs.js +98 -0
  212. package/lib/parameters/database-secret-values.js +173 -0
  213. package/lib/parameters/infra-kv-discovery.js +121 -0
  214. package/lib/parameters/infra-parameter-catalog.js +458 -0
  215. package/lib/parameters/infra-parameter-validate.js +64 -0
  216. package/lib/schema/application-schema.json +37 -17
  217. package/lib/schema/datasource-test-run.schema.json +493 -0
  218. package/lib/schema/deployment-rules.yaml +102 -63
  219. package/lib/schema/external-datasource.schema.json +1201 -433
  220. package/lib/schema/external-system.schema.json +181 -5
  221. package/lib/schema/flag-map-validation-run.json +31 -0
  222. package/lib/schema/infra-parameter.schema.json +106 -0
  223. package/lib/schema/infra.parameter.yaml +421 -0
  224. package/lib/schema/type/credential-auth-templates.json +40 -0
  225. package/lib/schema/type/document-storage.json +213 -0
  226. package/lib/schema/type/message-service.json +123 -0
  227. package/lib/schema/type/vector-store.json +88 -0
  228. package/lib/utils/aifabrix-runtime-config-dir.js +132 -0
  229. package/lib/utils/api-error-handler.js +2 -2
  230. package/lib/utils/api.js +49 -14
  231. package/lib/utils/app-config-resolver.js +23 -1
  232. package/lib/utils/app-register-api.js +3 -2
  233. package/lib/utils/app-register-auth.js +1 -1
  234. package/lib/utils/app-register-config.js +4 -4
  235. package/lib/utils/app-register-display.js +3 -2
  236. package/lib/utils/app-register-validator.js +3 -2
  237. package/lib/utils/app-run-containers.js +26 -22
  238. package/lib/utils/app-scoped-config.js +31 -0
  239. package/lib/utils/app-service-env-from-builder.js +164 -0
  240. package/lib/utils/build-copy.js +1 -1
  241. package/lib/utils/build-helpers.js +20 -20
  242. package/lib/utils/build-resolve-image.js +165 -0
  243. package/lib/utils/cli-layout-chalk.js +8 -0
  244. package/lib/utils/cli-test-layout-chalk.js +267 -0
  245. package/lib/utils/cli-utils.js +88 -11
  246. package/lib/utils/compose-db-passwords.js +138 -0
  247. package/lib/utils/compose-generate-docker-compose.js +216 -0
  248. package/lib/utils/compose-generator.js +197 -291
  249. package/lib/utils/compose-miso-env.js +18 -0
  250. package/lib/utils/compose-traefik-ingress-base.js +158 -0
  251. package/lib/utils/config-paths.js +209 -6
  252. package/lib/utils/config-scoped-resources-preference.js +41 -0
  253. package/lib/utils/controller-deployment-outcome.js +68 -0
  254. package/lib/utils/credential-display.js +2 -2
  255. package/lib/utils/credential-secrets-env.js +16 -1
  256. package/lib/utils/dataplane-pipeline-warning.js +4 -3
  257. package/lib/utils/datasource-test-run-capability-scope.js +43 -0
  258. package/lib/utils/datasource-test-run-debug-display.js +137 -0
  259. package/lib/utils/datasource-test-run-debug-slice.js +93 -0
  260. package/lib/utils/datasource-test-run-display.js +442 -0
  261. package/lib/utils/datasource-test-run-exit.js +58 -0
  262. package/lib/utils/datasource-test-run-legacy-adapter.js +93 -0
  263. package/lib/utils/datasource-test-run-report-version.js +51 -0
  264. package/lib/utils/datasource-test-run-schema-sync.js +59 -0
  265. package/lib/utils/datasource-test-run-tty-log.js +81 -0
  266. package/lib/utils/datasource-validation-watch.js +266 -0
  267. package/lib/utils/declarative-url-ports.js +47 -0
  268. package/lib/utils/derive-env-key-from-client-id.js +41 -0
  269. package/lib/utils/dev-ca-install.js +185 -23
  270. package/lib/utils/dev-cert-helper.js +266 -17
  271. package/lib/utils/dev-hosts-helper.js +307 -0
  272. package/lib/utils/dev-init-cert-hints.js +37 -0
  273. package/lib/utils/dev-init-health-messages.js +52 -0
  274. package/lib/utils/dev-init-resolve.js +86 -0
  275. package/lib/utils/dev-init-ssh-merge.js +65 -0
  276. package/lib/utils/dev-ssh-config-helper.js +196 -0
  277. package/lib/utils/dev-user-groups.js +93 -0
  278. package/lib/utils/docker-build.js +42 -17
  279. package/lib/utils/docker-exec.js +28 -0
  280. package/lib/utils/docker-manifest-public-port.js +116 -0
  281. package/lib/utils/docker-not-running-hint.js +52 -0
  282. package/lib/utils/docker.js +98 -11
  283. package/lib/utils/ensure-dev-certs-for-remote-docker.js +192 -0
  284. package/lib/utils/env-config-loader.js +10 -91
  285. package/lib/utils/env-copy.js +19 -10
  286. package/lib/utils/env-map.js +42 -11
  287. package/lib/utils/env-template.js +2 -2
  288. package/lib/utils/environment-scoped-resources.js +144 -0
  289. package/lib/utils/error-formatter.js +125 -9
  290. package/lib/utils/error-formatters/http-status-errors.js +6 -5
  291. package/lib/utils/error-formatters/network-errors.js +2 -1
  292. package/lib/utils/error-formatters/permission-errors.js +2 -1
  293. package/lib/utils/error-formatters/validation-errors.js +2 -1
  294. package/lib/utils/external-env-template.js +180 -0
  295. package/lib/utils/external-readme.js +8 -1
  296. package/lib/utils/external-system-display.js +277 -136
  297. package/lib/utils/external-system-local-test-tty.js +389 -0
  298. package/lib/utils/external-system-readiness-core.js +377 -0
  299. package/lib/utils/external-system-readiness-deploy-display.js +270 -0
  300. package/lib/utils/external-system-readiness-display-internals.js +150 -0
  301. package/lib/utils/external-system-readiness-display.js +186 -0
  302. package/lib/utils/external-system-test-helpers.js +24 -6
  303. package/lib/utils/external-system-validators.js +32 -14
  304. package/lib/utils/health-check-url.js +119 -0
  305. package/lib/utils/health-check.js +59 -25
  306. package/lib/utils/help-builder.js +14 -13
  307. package/lib/utils/image-version.js +4 -8
  308. package/lib/utils/infra-containers.js +4 -7
  309. package/lib/utils/infra-env-defaults.js +162 -0
  310. package/lib/utils/infra-status-display.js +167 -0
  311. package/lib/utils/infra-status.js +16 -8
  312. package/lib/utils/local-secrets.js +29 -7
  313. package/lib/utils/paths.js +136 -48
  314. package/lib/utils/port-resolver.js +10 -23
  315. package/lib/utils/redis-env-scope.js +62 -0
  316. package/lib/utils/register-aifabrix-shell-env.js +204 -0
  317. package/lib/utils/remote-builder-validation.js +99 -0
  318. package/lib/utils/remote-dev-auth.js +117 -21
  319. package/lib/utils/remote-docker-env.js +67 -15
  320. package/lib/utils/remote-secrets-loader.js +13 -4
  321. package/lib/utils/resolve-docker-image-ref.js +124 -0
  322. package/lib/utils/schema-loader.js +22 -9
  323. package/lib/utils/secrets-bash-kv.js +25 -0
  324. package/lib/utils/secrets-generator.js +171 -51
  325. package/lib/utils/secrets-helpers.js +70 -59
  326. package/lib/utils/secrets-kv-scope.js +60 -0
  327. package/lib/utils/secrets-utils.js +35 -37
  328. package/lib/utils/secrets-validation.js +3 -1
  329. package/lib/utils/secrets-yaml-preserve.js +109 -0
  330. package/lib/utils/secure-file-permissions.js +91 -0
  331. package/lib/utils/ssh-key-helper.js +4 -2
  332. package/lib/utils/template-helpers.js +2 -2
  333. package/lib/utils/test-log-writer.js +3 -3
  334. package/lib/utils/token-manager.js +37 -5
  335. package/lib/utils/url-declarative-public-base.js +188 -0
  336. package/lib/utils/url-declarative-resolve-build.js +493 -0
  337. package/lib/utils/url-declarative-resolve-load-doc.js +51 -0
  338. package/lib/utils/url-declarative-resolve.js +220 -0
  339. package/lib/utils/url-declarative-token-parse.js +74 -0
  340. package/lib/utils/url-declarative-url-flags.js +50 -0
  341. package/lib/utils/url-declarative-vdir-inactive-env.js +99 -0
  342. package/lib/utils/url-public-path-prefix.js +34 -0
  343. package/lib/utils/urls-local-registry.js +220 -0
  344. package/lib/utils/validation-report-tty-kit.js +77 -0
  345. package/lib/utils/validation-run-poll.js +89 -0
  346. package/lib/utils/validation-run-post-retry.js +73 -0
  347. package/lib/utils/validation-run-request.js +98 -0
  348. package/lib/utils/variable-transformer.js +21 -4
  349. package/lib/utils/yaml-preserve.js +78 -1
  350. package/lib/validation/datasource-warnings.js +56 -0
  351. package/lib/validation/env-template-auth.js +50 -2
  352. package/lib/validation/external-manifest-validator.js +35 -7
  353. package/lib/validation/validate-display.js +37 -31
  354. package/lib/validation/validate.js +9 -10
  355. package/lib/validation/validator-unresolved-placeholders.js +98 -0
  356. package/lib/validation/validator.js +32 -78
  357. package/lib/validation/wizard-config-validator.js +2 -1
  358. package/package.json +11 -3
  359. package/scripts/check-datasource-test-run-schema-sync.js +34 -0
  360. package/scripts/diagnose-cli.js +150 -0
  361. package/scripts/install-local.js +304 -55
  362. package/templates/README.md +15 -2
  363. package/templates/applications/dataplane/application.yaml +52 -2
  364. package/templates/applications/dataplane/env.template +80 -18
  365. package/templates/applications/dataplane/rbac.yaml +8 -0
  366. package/templates/applications/keycloak/application.yaml +9 -1
  367. package/templates/applications/keycloak/env.template +15 -6
  368. package/templates/applications/miso-controller/application.yaml +10 -2
  369. package/templates/applications/miso-controller/env.template +55 -14
  370. package/templates/applications/miso-controller/rbac.yaml +5 -0
  371. package/templates/external-system/README.md.hbs +20 -7
  372. package/templates/external-system/deploy.js.hbs +5 -5
  373. package/templates/external-system/env.template.hbs +22 -0
  374. package/templates/external-system/external-datasource.yaml.hbs +197 -118
  375. package/templates/infra/compose.yaml.hbs +20 -4
  376. package/templates/python/docker-compose.hbs +16 -0
  377. package/templates/typescript/docker-compose.hbs +16 -0
  378. package/integration/hubspot/README.md +0 -102
  379. package/integration/hubspot/env.template +0 -4
  380. package/integration/hubspot/hubspot-datasource-company.json +0 -541
  381. package/integration/hubspot/hubspot-datasource-contact.json +0 -639
  382. package/integration/hubspot/hubspot-datasource-deal.json +0 -588
  383. package/integration/hubspot/hubspot-datasource-users.json +0 -116
  384. package/integration/hubspot/test-artifacts/wizard-invalid-missing-source.yaml +0 -2
  385. package/integration/hubspot/test-artifacts/wizard-valid-for-dimension-key-test.yaml +0 -5
  386. package/integration/hubspot/test-artifacts/wizard-valid-for-dimension-path-test.yaml +0 -5
  387. package/lib/api/external-test.api.js +0 -111
  388. package/lib/schema/env-config.yaml +0 -43
  389. /package/integration/{hubspot → hubspot-test}/companies.json +0 -0
  390. /package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-app-name.yaml +0 -0
  391. /package/integration/{hubspot → hubspot-test}/test-artifacts/wizard-invalid-missing-app.yaml +0 -0
  392. /package/integration/{hubspot → hubspot-test}/test-dataplane-down-helpers.js +0 -0
@@ -7,8 +7,8 @@
7
7
  */
8
8
 
9
9
  const { spawn } = require('child_process');
10
- const chalk = require('chalk');
11
10
  const logger = require('../utils/logger');
11
+ const { infoLine, formatSuccessLine } = require('../utils/cli-test-layout-chalk');
12
12
  const config = require('../core/config');
13
13
  const containerHelpers = require('../utils/app-run-containers');
14
14
  const composeGenerator = require('../utils/compose-generator');
@@ -97,9 +97,9 @@ async function runTestsInDev(appName, developerId, testCmd) {
97
97
  `Container ${containerName} is not running.\nRun 'aifabrix run ${appName}' first.`
98
98
  );
99
99
  }
100
- logger.log(chalk.blue(`Running tests in container ${containerName}: ${testCmd}\n`));
100
+ logger.log(infoLine(`ℹ Running tests in container ${containerName}: ${testCmd}\n`));
101
101
  const envFilePath = await secretsEnvWrite.resolveAndWriteEnvFile(appName, {});
102
- return runDockerExec(containerName, testCmd, envFilePath);
102
+ return await runDockerExec(containerName, testCmd, envFilePath);
103
103
  }
104
104
 
105
105
  /**
@@ -123,14 +123,14 @@ async function runAppTest(appName, options = {}) {
123
123
  if (env === 'dev') {
124
124
  const code = await runTestsInDev(appName, developerId, testCmd);
125
125
  if (code !== 0) process.exit(code);
126
- logger.log(chalk.green('Tests completed'));
126
+ logger.log(formatSuccessLine('Tests completed.'));
127
127
  return;
128
128
  }
129
- logger.log(chalk.blue(`Running tests in ephemeral container (${fullImage}): ${testCmd}\n`));
129
+ logger.log(infoLine(`ℹ Running tests in ephemeral container (${fullImage}): ${testCmd}\n`));
130
130
  const envFilePath = await secretsEnvWrite.resolveAndWriteEnvFile(appName, {});
131
131
  const code = await runDockerRunEphemeral(fullImage, testCmd, envFilePath);
132
132
  if (code !== 0) process.exit(code);
133
- logger.log(chalk.green('Tests completed'));
133
+ logger.log(formatSuccessLine('Tests completed.'));
134
134
  }
135
135
 
136
136
  /**
@@ -141,14 +141,17 @@ async function runAppTest(appName, options = {}) {
141
141
  * @param {string|null} [envFilePath] - Path to resolved .env for --env-file (optional)
142
142
  * @returns {Promise<number>} Exit code
143
143
  */
144
- function runDockerExec(containerName, testCmd, envFilePath = null) {
144
+ async function runDockerExec(containerName, testCmd, envFilePath = null) {
145
+ const { getDockerExecEnv } = require('../utils/remote-docker-env');
146
+ const dockerEnv = await getDockerExecEnv();
145
147
  return new Promise((resolve) => {
146
148
  const args = ['exec'];
147
149
  if (envFilePath) args.push('--env-file', envFilePath);
148
150
  args.push(containerName, 'sh', '-c', testCmd);
149
151
  const proc = spawn('docker', args, {
150
152
  stdio: 'inherit',
151
- shell: false
153
+ shell: false,
154
+ env: dockerEnv
152
155
  });
153
156
  proc.on('close', code => resolve(code !== null ? code : 1));
154
157
  proc.on('error', () => resolve(1));
@@ -162,14 +165,17 @@ function runDockerExec(containerName, testCmd, envFilePath = null) {
162
165
  * @param {string|null} [envFilePath] - Path to .env for docker run --env-file (optional)
163
166
  * @returns {Promise<number>} Exit code
164
167
  */
165
- function runDockerRunEphemeral(fullImage, testCmd, envFilePath = null) {
168
+ async function runDockerRunEphemeral(fullImage, testCmd, envFilePath = null) {
169
+ const { getDockerExecEnv } = require('../utils/remote-docker-env');
170
+ const dockerEnv = await getDockerExecEnv();
166
171
  return new Promise((resolve) => {
167
172
  const args = ['run', '--rm'];
168
173
  if (envFilePath) args.push('--env-file', envFilePath);
169
174
  args.push(fullImage, 'sh', '-c', testCmd);
170
175
  const proc = spawn('docker', args, {
171
176
  stdio: 'inherit',
172
- shell: false
177
+ shell: false,
178
+ env: dockerEnv
173
179
  });
174
180
  proc.on('close', code => resolve(code !== null ? code : 1));
175
181
  proc.on('error', () => resolve(1));
@@ -197,14 +203,14 @@ async function runAppTestE2e(appName, options = {}) {
197
203
  if (env === 'dev') {
198
204
  const code = await runTestsInDev(appName, developerId, cmd);
199
205
  if (code !== 0) process.exit(code);
200
- logger.log(chalk.green('Test-e2e completed'));
206
+ logger.log(formatSuccessLine('Test-e2e completed.'));
201
207
  return;
202
208
  }
203
- logger.log(chalk.blue(`Running test-e2e in ephemeral container (${fullImage}): ${cmd}\n`));
209
+ logger.log(infoLine(`ℹ Running test-e2e in ephemeral container (${fullImage}): ${cmd}\n`));
204
210
  const envFilePath = await secretsEnvWrite.resolveAndWriteEnvFile(appName, {});
205
211
  const code = await runDockerRunEphemeral(fullImage, cmd, envFilePath);
206
212
  if (code !== 0) process.exit(code);
207
- logger.log(chalk.green('Test-e2e completed'));
213
+ logger.log(formatSuccessLine('Test-e2e completed.'));
208
214
  }
209
215
 
210
216
  /**
@@ -229,14 +235,14 @@ async function runAppTestIntegration(appName, options = {}) {
229
235
  if (env === 'dev') {
230
236
  const code = await runTestsInDev(appName, developerId, cmd);
231
237
  if (code !== 0) process.exit(code);
232
- logger.log(chalk.green('Test-integration completed'));
238
+ logger.log(formatSuccessLine('Test-integration completed.'));
233
239
  return;
234
240
  }
235
- logger.log(chalk.blue(`Running test-integration in ephemeral container (${fullImage}): ${cmd}\n`));
241
+ logger.log(infoLine(`ℹ Running test-integration in ephemeral container (${fullImage}): ${cmd}\n`));
236
242
  const envFilePath = await secretsEnvWrite.resolveAndWriteEnvFile(appName, {});
237
243
  const code = await runDockerRunEphemeral(fullImage, cmd, envFilePath);
238
244
  if (code !== 0) process.exit(code);
239
- logger.log(chalk.green('Test-integration completed'));
245
+ logger.log(formatSuccessLine('Test-integration completed.'));
240
246
  }
241
247
 
242
248
  /**
@@ -260,14 +266,14 @@ async function runAppLint(appName, options = {}) {
260
266
  if (env === 'dev') {
261
267
  const code = await runTestsInDev(appName, developerId, cmd);
262
268
  if (code !== 0) process.exit(code);
263
- logger.log(chalk.green('Lint completed'));
269
+ logger.log(formatSuccessLine('Lint completed.'));
264
270
  return;
265
271
  }
266
- logger.log(chalk.blue(`Running lint in ephemeral container (${fullImage}): ${cmd}\n`));
272
+ logger.log(infoLine(`ℹ Running lint in ephemeral container (${fullImage}): ${cmd}\n`));
267
273
  const envFilePath = await secretsEnvWrite.resolveAndWriteEnvFile(appName, {});
268
274
  const code = await runDockerRunEphemeral(fullImage, cmd, envFilePath);
269
275
  if (code !== 0) process.exit(code);
270
- logger.log(chalk.green('Lint completed'));
276
+ logger.log(formatSuccessLine('Lint completed.'));
271
277
  }
272
278
 
273
279
  module.exports = {
@@ -1,3 +1,4 @@
1
+ const { formatBlockingError } = require('../utils/cli-test-layout-chalk');
1
2
  /**
2
3
  * AI Fabrix Builder - Application Registration Commands
3
4
  *
@@ -17,9 +18,20 @@ const { rotateSecret } = require('../app/rotate-secret');
17
18
  const { showApp } = require('../app/show');
18
19
  const { runAppDeploymentList } = require('./deployment-list');
19
20
 
21
+ const APP_HELP_AFTER = `
22
+ Subcommands:
23
+ register <appKey> Register app; get pipeline client id/secret
24
+ list Applications in current environment
25
+ rotate-secret <key> New ClientSecret (shown once)
26
+ show <key> From controller (like show --online)
27
+ deployment <key> Deployment history for app
28
+
29
+ Requires: aifabrix login
30
+ `;
31
+
20
32
  function setupAppRegisterCommand(app) {
21
33
  app.command('register <appKey>')
22
- .description('Register application and get pipeline credentials')
34
+ .description('Register app; receive pipeline credentials')
23
35
  .option('-p, --port <port>', 'Application port (default: from application.yaml)')
24
36
  .option('-u, --url <url>', 'Application URL. If omitted: app.url, deployment.dataplaneUrl or deployment.appUrl in application.yaml; else http://localhost:{port})')
25
37
  .option('-n, --name <name>', 'Override display name')
@@ -28,7 +40,7 @@ function setupAppRegisterCommand(app) {
28
40
  try {
29
41
  await registerApplication(appKey, options);
30
42
  } catch (error) {
31
- logger.error(chalk.red('Registration failed:'), error.message);
43
+ logger.error(formatBlockingError('Registration failed:'), error.message);
32
44
  process.exit(1);
33
45
  }
34
46
  });
@@ -36,12 +48,12 @@ function setupAppRegisterCommand(app) {
36
48
 
37
49
  function setupAppListCommand(app) {
38
50
  app.command('list')
39
- .description('List applications')
51
+ .description('List apps in current environment')
40
52
  .action(async(options) => {
41
53
  try {
42
54
  await listApplications(options);
43
55
  } catch (error) {
44
- logger.error(chalk.red('Failed to list applications:'), error.message);
56
+ logger.error(formatBlockingError('Failed to list applications:'), error.message);
45
57
  process.exit(1);
46
58
  }
47
59
  });
@@ -49,20 +61,20 @@ function setupAppListCommand(app) {
49
61
 
50
62
  function setupAppRotateSecretCommand(app) {
51
63
  app.command('rotate-secret <appKey>')
52
- .description('Rotate pipeline ClientSecret for an application')
64
+ .description('Rotate pipeline ClientSecret (one-time display)')
53
65
  .action(async(appKey, options) => {
54
66
  try {
55
67
  await rotateSecret(appKey, options);
56
68
  } catch (error) {
57
- logger.error(chalk.red('Rotation failed:'), error.message);
69
+ logger.error(formatBlockingError('Rotation failed:'), error.message);
58
70
  process.exit(1);
59
71
  }
60
72
  });
61
73
  }
62
74
 
63
75
  function setupAppShowCommand(app) {
64
- app.command('show <appKey>')
65
- .description('Show application from controller (online). Same as aifabrix show <appKey> --online')
76
+ app.command('show <app>')
77
+ .description('App details from controller (same as show --online)')
66
78
  .option('--online', 'Fetch from controller (default for this command)')
67
79
  .option('--json', 'Output as JSON')
68
80
  .option('--permissions', 'Show only list of permissions')
@@ -78,7 +90,7 @@ function setupAppShowCommand(app) {
78
90
 
79
91
  function setupAppDeploymentCommand(app) {
80
92
  app.command('deployment <appKey>')
81
- .description('List last N deployments for an application in current environment (default pageSize=50)')
93
+ .description('List recent deployments for app in current environment')
82
94
  .option('--controller <url>', 'Controller URL (default: from config)')
83
95
  .option('--environment <env>', 'Environment key (default: from config)')
84
96
  .option('--page-size <n>', 'Items per page', '50')
@@ -102,7 +114,7 @@ function setupAppDeploymentCommand(app) {
102
114
  * @param {Command} program - Commander program instance
103
115
  */
104
116
  function setupAppCommands(program) {
105
- const app = program.command('app').description('Manage applications');
117
+ const app = program.command('app').description('Controller apps: register, list, secrets, deploy history').addHelpText('after', APP_HELP_AFTER);
106
118
  setupAppRegisterCommand(app);
107
119
  setupAppListCommand(app);
108
120
  setupAppRotateSecretCommand(app);
@@ -8,7 +8,7 @@
8
8
  * @version 2.0.0
9
9
  */
10
10
 
11
- const chalk = require('chalk');
11
+ const { formatBlockingError, formatSuccessLine } = require('../utils/cli-test-layout-chalk');
12
12
  const {
13
13
  setControllerUrl,
14
14
  setCurrentEnvironment,
@@ -42,23 +42,23 @@ async function handleSetController(url) {
42
42
  if (!loggedInControllerUrl) {
43
43
  // No stored credentials: allow setting controller so "aifabrix login" opens the right place
44
44
  await setControllerUrl(url);
45
- logger.log(chalk.green(`✓ Controller URL set to: ${url}`));
45
+ logger.log(formatSuccessLine(`Controller URL set to: ${url}`));
46
46
  return;
47
47
  }
48
48
 
49
49
  const normalizedLoggedIn = loggedInControllerUrl.trim().replace(/\/+$/, '');
50
50
  if (normalizedLoggedIn === normalizedUrl) {
51
51
  await setControllerUrl(url);
52
- logger.log(chalk.green(`✓ Controller URL set to: ${url}`));
52
+ logger.log(formatSuccessLine(`Controller URL set to: ${url}`));
53
53
  return;
54
54
  }
55
55
 
56
56
  throw new Error(
57
57
  `You have credentials for another controller (${loggedInControllerUrl}).\n` +
58
- `To use ${url} either run "aifabrix login" with that controller, or run "aifabrix logout" first to clear credentials, then set the new controller with --set-controller.`
58
+ 'To use a different controller either run "aifabrix login" with that controller, or run "aifabrix logout" first to clear credentials, then set the new controller with "aifabrix auth --set-controller <url>".'
59
59
  );
60
60
  } catch (error) {
61
- logger.error(chalk.red(`✗ Failed to set controller URL: ${error.message}`));
61
+ logger.error(formatBlockingError(`Failed to set controller URL: ${error.message}`));
62
62
  throw error;
63
63
  }
64
64
  }
@@ -80,8 +80,7 @@ async function handleSetEnvironment(environment) {
80
80
  const controllerUrl = await getControllerUrl();
81
81
  if (!controllerUrl) {
82
82
  throw new Error(
83
- 'No controller URL found in config.\n' +
84
- 'Please run "aifabrix login" first to set the controller URL.'
83
+ 'No controller URL found in config. Run "aifabrix login" first, or set the controller with "aifabrix auth --set-controller <url>".'
85
84
  );
86
85
  }
87
86
 
@@ -89,17 +88,16 @@ async function handleSetEnvironment(environment) {
89
88
  const isLoggedIn = await checkUserLoggedIn(controllerUrl);
90
89
  if (!isLoggedIn) {
91
90
  throw new Error(
92
- `You are not logged in to controller ${controllerUrl}.\n` +
93
- 'Please run "aifabrix login" first to authenticate with this controller.'
91
+ `You are not logged in to controller ${controllerUrl}. Run "aifabrix login" first to authenticate.`
94
92
  );
95
93
  }
96
94
 
97
95
  // Save environment
98
96
  await setCurrentEnvironment(environment);
99
97
 
100
- logger.log(chalk.green(`✓ Environment set to: ${environment}`));
98
+ logger.log(formatSuccessLine(`Environment set to: ${environment}`));
101
99
  } catch (error) {
102
- logger.error(chalk.red(`✗ Failed to set environment: ${error.message}`));
100
+ logger.error(formatBlockingError(`Failed to set environment: ${error.message}`));
103
101
  throw error;
104
102
  }
105
103
  }
@@ -117,9 +115,7 @@ async function handleSetEnvironment(environment) {
117
115
  async function handleAuthConfig(options) {
118
116
  if (!options.setController && !options.setEnvironment) {
119
117
  throw new Error(
120
- 'No action specified. Use one of:\n' +
121
- ' --set-controller <url>\n' +
122
- ' --set-environment <env>'
118
+ 'No action specified. Use "aifabrix auth --set-controller <url>" or "aifabrix auth --set-environment <env>".'
123
119
  );
124
120
  }
125
121
  if (options.setController) {
@@ -9,6 +9,7 @@
9
9
  */
10
10
 
11
11
  const chalk = require('chalk');
12
+ const { failureGlyph, successGlyph } = require('../utils/cli-test-layout-chalk');
12
13
  const logger = require('../utils/logger');
13
14
  const config = require('../core/config');
14
15
  const { getConfig } = config;
@@ -194,7 +195,7 @@ function displayUserInfo(user) {
194
195
  * @param {Object} tokenInfo - Token information
195
196
  */
196
197
  function displayTokenInfo(tokenInfo) {
197
- const statusIcon = tokenInfo.authenticated ? chalk.green('✓') : chalk.red('✗');
198
+ const statusIcon = tokenInfo.authenticated ? successGlyph() : failureGlyph();
198
199
  const statusText = tokenInfo.authenticated ? 'Authenticated' : 'Not authenticated';
199
200
 
200
201
  logger.log(` Status: ${statusIcon} ${statusText}`);
@@ -244,7 +245,7 @@ function displayDataplaneSection(dataplaneUrl, dataplaneConnected) {
244
245
  logger.log('');
245
246
  if (dataplaneUrl) {
246
247
  logger.log(`Dataplane: ${chalk.cyan(dataplaneUrl)}`);
247
- const statusIcon = dataplaneConnected ? chalk.green('✓') : chalk.red('✗');
248
+ const statusIcon = dataplaneConnected ? successGlyph() : failureGlyph();
248
249
  const statusText = dataplaneConnected ? 'Connected' : 'Not reachable';
249
250
  displayOpenApiDocs(null, dataplaneUrl);
250
251
  logger.log('');
@@ -297,7 +298,7 @@ function displayStatus(controllerUrl, environment, tokenInfo, dataplaneInfo) {
297
298
  logger.log(` Environment: ${chalk.cyan(environment || 'Not specified')}\n`);
298
299
 
299
300
  if (!tokenInfo) {
300
- logger.log(` Status: ${chalk.red('Not authenticated')}`);
301
+ logger.log(` Status: ${failureGlyph()} ${chalk.red('Not authenticated')}`);
301
302
  logger.log(` Token Type: ${chalk.gray('None')}\n`);
302
303
  logger.log(chalk.yellow('💡 Run "aifabrix login" to authenticate\n'));
303
304
  return;
@@ -1,6 +1,7 @@
1
+ const { formatSuccessLine } = require('../utils/cli-test-layout-chalk');
1
2
  /**
2
3
  * Credential env command – prompts for KV_* values and writes .env.
3
- * Used by `aifabrix credential env <system-key>`.
4
+ * Used by `aifabrix credential env <systemKey>`.
4
5
  *
5
6
  * @fileoverview Credential env command – interactive credential capture to .env
6
7
  * @author AI Fabrix Team
@@ -120,7 +121,7 @@ function buildEnvContent(templateContent, promptValues) {
120
121
  /**
121
122
  * Runs credential env command: prompt for KV_* values and write .env.
122
123
  * @async
123
- * @param {string} systemKey - External system key (integration/<system-key>/)
124
+ * @param {string} systemKey - External system key (integration/<systemKey>/)
124
125
  * @returns {Promise<string>} Path to written .env file
125
126
  * @throws {Error} If env.template missing or write fails
126
127
  */
@@ -155,7 +156,7 @@ async function runCredentialEnv(systemKey) {
155
156
  const dir = path.dirname(envPath);
156
157
  if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
157
158
  fs.writeFileSync(envPath, content, { mode: 0o600 });
158
- logger.log(chalk.green(`✓ Wrote ${envPath}`));
159
+ logger.log(formatSuccessLine(`Wrote ${envPath}`));
159
160
  return envPath;
160
161
  }
161
162
 
@@ -1,3 +1,4 @@
1
+ const { formatBlockingError } = require('../utils/cli-test-layout-chalk');
1
2
  /**
2
3
  * Credential list command – list credentials from Dataplane
3
4
  * GET /api/v1/credential. Used by `aifabrix credential list`.
@@ -78,12 +79,12 @@ function displayCredentialList(list, baseUrl) {
78
79
  async function ensureControllerAndAuth(options = {}) {
79
80
  const controllerUrl = options.controller || (await resolveControllerUrl());
80
81
  if (!controllerUrl) {
81
- logger.error(chalk.red('Controller URL is required. Run "aifabrix login" first.'));
82
+ logger.error(formatBlockingError('Controller URL is required. Run "aifabrix login" first.'));
82
83
  process.exit(1);
83
84
  }
84
85
  const authResult = await getCredentialListAuth(controllerUrl);
85
86
  if (!authResult || !authResult.token) {
86
- logger.error(chalk.red(`❌ No authentication token for controller: ${controllerUrl}`));
87
+ logger.error(formatBlockingError(`No authentication token for controller: ${controllerUrl}`));
87
88
  logger.error(chalk.gray('Run: aifabrix login'));
88
89
  process.exit(1);
89
90
  }
@@ -129,7 +130,7 @@ async function resolveDataplaneUrlOrExit(controllerUrl, authConfig) {
129
130
  try {
130
131
  return await resolveCredentialListDataplaneUrl(controllerUrl, authConfig);
131
132
  } catch (err) {
132
- logger.error(chalk.red(`❌ Could not resolve Dataplane URL: ${err.message}`));
133
+ logger.error(formatBlockingError(`Could not resolve Dataplane URL: ${err.message}`));
133
134
  process.exit(1);
134
135
  }
135
136
  }
@@ -152,7 +153,7 @@ async function runCredentialList(options = {}) {
152
153
  try {
153
154
  await fetchAndDisplayCredentials(dataplaneUrl, authConfig, listOptions);
154
155
  } catch (error) {
155
- logger.error(chalk.red(`❌ Failed to list credentials: ${error.message}`));
156
+ logger.error(formatBlockingError(`Failed to list credentials: ${error.message}`));
156
157
  process.exit(1);
157
158
  }
158
159
  }
@@ -1,6 +1,7 @@
1
+ const { formatSuccessLine } = require('../utils/cli-test-layout-chalk');
1
2
  /**
2
3
  * Credential push command – pushes KV_* from .env to dataplane.
3
- * Used by `aifabrix credential push <system-key>`.
4
+ * Used by `aifabrix credential push <systemKey>`.
4
5
  *
5
6
  * @fileoverview Credential push command – push credential secrets to dataplane
6
7
  * @author AI Fabrix Team
@@ -55,7 +56,7 @@ async function buildPayload(systemKey) {
55
56
  function logPushResult(pushResult) {
56
57
  if (pushResult.pushed > 0) {
57
58
  const keyList = pushResult.keys?.length ? ` (${pushResult.keys.join(', ')})` : '';
58
- logger.log(chalk.green(`✓ Pushed ${pushResult.pushed} credential secret(s) to dataplane${keyList}.`));
59
+ logger.log(formatSuccessLine(`Pushed ${pushResult.pushed} credential secret(s) to dataplane${keyList}.`));
59
60
  } else if (pushResult.skipped) {
60
61
  logger.log(chalk.yellow('No credential secrets to push (empty .env or no KV_* vars with values).'));
61
62
  } else {
@@ -75,7 +76,7 @@ async function runCredentialPush(systemKey) {
75
76
  const authConfig = await getDeploymentAuth(controllerUrl, environment, systemKey);
76
77
 
77
78
  if (!authConfig.token && !authConfig.clientId) {
78
- throw new Error('Authentication required. Run "aifabrix login" or "aifabrix app register <system-key>" first.');
79
+ throw new Error('Authentication required. Run "aifabrix login" or "aifabrix app register <systemKey>" first.');
79
80
  }
80
81
 
81
82
  requireBearerForDataplanePipeline(authConfig);