@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
@@ -10,118 +10,30 @@
10
10
 
11
11
  const chalk = require('chalk');
12
12
  const logger = require('./logger');
13
+ const { SEP, statusGlyph } = require('./datasource-test-run-display');
14
+ const { logEnvelopeForInteractiveCli } = require('./datasource-test-run-tty-log');
15
+ const { displayLocalExternalTestPlanLayout } = require('./external-system-local-test-tty');
16
+ const {
17
+ sectionTitle,
18
+ headerKeyValue,
19
+ formatStatusKeyValue,
20
+ formatDatasourceListRow,
21
+ integrationFooterLine,
22
+ formatSuccessParagraph,
23
+ formatBlockingError,
24
+ successGlyph,
25
+ failureGlyph
26
+ } = require('./cli-test-layout-chalk');
27
+ const { displaySystemAggregateDatasourceTestRuns } = require('./external-system-system-test-tty');
13
28
 
14
29
  /**
15
- * Displays system file results
16
- * @function displaySystemResults
17
- * @param {Object[]} systemResults - System file results
18
- */
19
- function displaySystemResults(systemResults) {
20
- if (systemResults.length === 0) {
21
- return;
22
- }
23
- logger.log(chalk.blue('System Files:'));
24
- for (const systemResult of systemResults) {
25
- if (systemResult.valid) {
26
- logger.log(chalk.green(` ✓ ${systemResult.file}`));
27
- } else {
28
- logger.log(chalk.red(` ✗ ${systemResult.file}`));
29
- }
30
- }
31
- }
32
-
33
- /**
34
- * Displays verbose datasource details
35
- * @function displayVerboseDatasourceDetails
36
- * @param {Object} dsResult - Datasource result
37
- */
38
- function displayVerboseDatasourceDetails(dsResult) {
39
- if (dsResult.warnings.length > 0) {
40
- dsResult.warnings.forEach(warn => logger.log(chalk.yellow(` ⚠ ${warn}`)));
41
- }
42
-
43
- if (dsResult.fieldMappingResults) {
44
- const fm = dsResult.fieldMappingResults;
45
- logger.log(chalk.gray(` Field mappings: ${Object.keys(fm.mappedFields || {}).length} fields`));
46
- }
47
-
48
- if (dsResult.metadataSchemaResults) {
49
- const ms = dsResult.metadataSchemaResults;
50
- const statusMsg = ms.valid ? ' Metadata schema: ✓ Valid' : ' Metadata schema: ✗ Invalid';
51
- logger.log(ms.valid ? chalk.gray(statusMsg) : chalk.red(statusMsg));
52
- }
53
- }
54
-
55
- /**
56
- * Displays datasource file results
57
- * @function displayDatasourceResults
58
- * @param {Object[]} datasourceResults - Datasource file results
59
- * @param {boolean} verbose - Show detailed output
60
- */
61
- function displayDatasourceResults(datasourceResults, verbose) {
62
- if (datasourceResults.length === 0) {
63
- return;
64
- }
65
- logger.log(chalk.blue('\nDatasource Files:'));
66
- for (const dsResult of datasourceResults) {
67
- if (dsResult.valid) {
68
- logger.log(chalk.green(` ✓ ${dsResult.key} (${dsResult.file})`));
69
- } else {
70
- logger.log(chalk.red(` ✗ ${dsResult.key} (${dsResult.file})`));
71
- if (verbose && dsResult.errors.length > 0) {
72
- dsResult.errors.forEach(err => logger.log(chalk.red(` - ${err}`)));
73
- }
74
- }
75
-
76
- if (verbose) {
77
- displayVerboseDatasourceDetails(dsResult);
78
- }
79
- }
80
- }
81
-
82
- /**
83
- * Displays errors and warnings
84
- * @function displayErrorsAndWarnings
85
- * @param {string[]} errors - Error messages
86
- * @param {string[]} warnings - Warning messages
87
- */
88
- function displayErrorsAndWarnings(errors, warnings) {
89
- if (errors.length > 0) {
90
- logger.log(chalk.red('\n❌ Errors:'));
91
- errors.forEach(err => logger.log(chalk.red(` - ${err}`)));
92
- }
93
-
94
- if (warnings.length > 0) {
95
- logger.log(chalk.yellow('\n⚠ Warnings:'));
96
- warnings.forEach(warn => logger.log(chalk.yellow(` - ${warn}`)));
97
- }
98
- }
99
-
100
- /**
101
- * Displays final test status
102
- * @function displayFinalTestStatus
103
- * @param {boolean} valid - Whether all tests passed
104
- */
105
- function displayFinalTestStatus(valid) {
106
- if (valid) {
107
- logger.log(chalk.green('\n✅ All tests passed!'));
108
- } else {
109
- logger.log(chalk.red('\n❌ Some tests failed'));
110
- }
111
- }
112
-
113
- /**
114
- * Displays formatted test results
30
+ * Displays formatted test results (local external `aifabrix test` — structured report layout).
115
31
  * @param {Object} results - Test results
116
32
  * @param {boolean} verbose - Show detailed output
33
+ * @param {string} [appName] - Integration folder / app key for header
117
34
  */
118
- function displayTestResults(results, verbose = false) {
119
- logger.log(chalk.blue('\n📊 Test Results\n'));
120
-
121
- displaySystemResults(results.systemResults);
122
- displayDatasourceResults(results.datasourceResults, verbose);
123
- displayErrorsAndWarnings(results.errors, results.warnings);
124
- displayFinalTestStatus(results.valid);
35
+ function displayTestResults(results, verbose = false, appName = '') {
36
+ displayLocalExternalTestPlanLayout(results, verbose, appName || results.appName || results.systemKey || 'unknown');
125
37
  }
126
38
 
127
39
  /**
@@ -131,9 +43,9 @@ function displayTestResults(results, verbose = false) {
131
43
  */
132
44
  function displayVerboseValidationResults(vr) {
133
45
  if (vr.isValid) {
134
- logger.log(chalk.gray(' Validation: Valid'));
46
+ logger.log(chalk.gray(' Validation: Valid'));
135
47
  } else {
136
- logger.log(chalk.red(' Validation: Invalid'));
48
+ logger.log(chalk.red(' Validation: Invalid'));
137
49
  }
138
50
  if (vr.errors && vr.errors.length > 0) {
139
51
  vr.errors.forEach(err => logger.log(chalk.red(` - ${err}`)));
@@ -163,7 +75,7 @@ function displayVerboseFieldMappingResults(fmr) {
163
75
  */
164
76
  function displayVerboseEndpointResults(etr) {
165
77
  if (etr.endpointConfigured) {
166
- logger.log(chalk.gray(' Endpoint: Configured'));
78
+ logger.log(chalk.gray(' Endpoint: Configured'));
167
79
  } else {
168
80
  logger.log(chalk.gray(' Endpoint: Not configured'));
169
81
  }
@@ -191,54 +103,244 @@ function displayVerboseIntegrationDetails(dsResult) {
191
103
  }
192
104
 
193
105
  /**
194
- * Displays a single datasource integration test result
195
- * @function displayDatasourceIntegrationResult
106
+ * @param {Object} dsResult
107
+ * @returns {'ok'|'warn'|'fail'|'skipped'}
108
+ */
109
+ function legacyIntegrationRowStatus(dsResult) {
110
+ if (dsResult.skipped) return 'skipped';
111
+ if (!dsResult.success) return 'fail';
112
+ const w = dsResult.validationResults && dsResult.validationResults.warnings;
113
+ if (Array.isArray(w) && w.length > 0) return 'warn';
114
+ return 'ok';
115
+ }
116
+
117
+ function legacyIntegrationRowHint(dsResult) {
118
+ if (dsResult.skipped) return dsResult.reason || 'Skipped';
119
+ if (!dsResult.success) return 'Failed';
120
+ return legacyIntegrationRowStatus(dsResult) === 'warn' ? 'Partial' : 'Ready';
121
+ }
122
+
123
+ /**
124
+ * Displays a single datasource integration test result (legacy pipeline row).
196
125
  * @param {Object} dsResult - Datasource result
197
126
  * @param {boolean} verbose - Show detailed output
198
127
  */
199
128
  function displayDatasourceIntegrationResult(dsResult, verbose) {
129
+ const rowSt = legacyIntegrationRowStatus(dsResult);
130
+ const hint = legacyIntegrationRowHint(dsResult);
131
+ logger.log(formatDatasourceListRow(rowSt, dsResult.key, hint));
132
+
133
+ if (!dsResult.skipped && !dsResult.success && dsResult.error) {
134
+ logger.log(chalk.red(` Error: ${dsResult.error}`));
135
+ }
136
+
137
+ if (verbose) {
138
+ displayVerboseIntegrationDetails(dsResult);
139
+ }
140
+ }
141
+
142
+ /**
143
+ * Worst status across server runs (envelope.status or transport failure).
144
+ * @param {Object} results
145
+ * @returns {'ok'|'warn'|'fail'}
146
+ */
147
+ function serverRowFails(r) {
148
+ if (r.skipped) return false;
149
+ if (r.datasourceTestRun && r.datasourceTestRun.status === 'fail') return true;
150
+ return !r.datasourceTestRun && r.success === false;
151
+ }
152
+
153
+ function serverRowWarns(r) {
154
+ if (r.skipped) return false;
155
+ return !!(r.datasourceTestRun && r.datasourceTestRun.status === 'warn');
156
+ }
157
+
158
+ function deriveAggregateServerStatus(results) {
159
+ const ds = results.datasourceResults || [];
160
+ if (ds.length === 0) {
161
+ return results.success === false ? 'fail' : 'ok';
162
+ }
163
+ if (ds.some(serverRowFails)) return 'fail';
164
+ if (ds.some(serverRowWarns)) return 'warn';
165
+ return results.success === false ? 'fail' : 'ok';
166
+ }
167
+
168
+ /**
169
+ * Aggregate status for legacy pipeline integration results (no DatasourceTestRun envelope).
170
+ * @param {Object} results
171
+ * @returns {'ok'|'warn'|'fail'}
172
+ */
173
+ function deriveAggregateLegacyIntegrationStatus(results) {
174
+ const ds = results.datasourceResults || [];
175
+ if (ds.length === 0) {
176
+ return results.success === false ? 'fail' : 'ok';
177
+ }
178
+ if (ds.some(r => !r.skipped && r.success === false)) return 'fail';
179
+ if (ds.some(r => legacyIntegrationRowStatus(r) === 'warn')) return 'warn';
180
+ return results.success === false ? 'fail' : 'ok';
181
+ }
182
+
183
+ function integrationResultsHaveEnvelope(results) {
184
+ return (results.datasourceResults || []).some(
185
+ r => r.datasourceTestRun && typeof r.datasourceTestRun === 'object'
186
+ );
187
+ }
188
+
189
+ /**
190
+ * One datasource with DatasourceTestRun — same display path as `aifabrix datasource test` (no server wrapper).
191
+ * @param {Object} results
192
+ * @returns {boolean}
193
+ */
194
+ function isSingleUnskippedEnvelopeRun(results) {
195
+ const rows = results.datasourceResults || [];
196
+ if (rows.length !== 1) return false;
197
+ const r = rows[0];
198
+ return Boolean(
199
+ r && !r.skipped && r.datasourceTestRun && typeof r.datasourceTestRun === 'object'
200
+ );
201
+ }
202
+
203
+ function runLabelForServerRun(runType) {
204
+ return runType === 'e2e' ? 'test-e2e (dataplane)' : 'test-integration (dataplane)';
205
+ }
206
+
207
+ function renderOneServerDatasourceRow(dsResult, verbose, opts) {
208
+ logger.log('');
209
+ if (!dsResult.datasourceTestRun) {
210
+ logger.log(headerKeyValue('Datasource:', dsResult.key));
211
+ }
200
212
  if (dsResult.skipped) {
201
- logger.log(chalk.yellow(` ⚠ ${dsResult.key}: ${dsResult.reason}`));
213
+ logger.log(formatDatasourceListRow('skipped', dsResult.key, dsResult.reason || 'Skipped'));
202
214
  return;
203
215
  }
216
+ if (dsResult.datasourceTestRun) {
217
+ logEnvelopeForInteractiveCli(dsResult.datasourceTestRun, {
218
+ json: false,
219
+ summary: false,
220
+ debug: opts.debug,
221
+ requestedCapabilityKey: opts.requestedCapabilityKey
222
+ });
223
+ return;
224
+ }
225
+ displayDatasourceIntegrationResult(dsResult, verbose);
226
+ }
204
227
 
205
- if (dsResult.success) {
206
- logger.log(chalk.green(` ✓ ${dsResult.key}`));
207
- } else {
208
- logger.log(chalk.red(` ✗ ${dsResult.key}`));
209
- if (dsResult.error) {
210
- logger.log(chalk.red(` Error: ${dsResult.error}`));
211
- }
228
+ function logServerDatasourceTestRunHeader(results, runType, agg) {
229
+ logger.log('');
230
+ logger.log(sectionTitle('Server test results'));
231
+ logger.log('');
232
+ logger.log(headerKeyValue('System:', results.systemKey));
233
+ logger.log(headerKeyValue('Run:', runLabelForServerRun(runType)));
234
+ logger.log(formatStatusKeyValue(agg, statusGlyph(agg)));
235
+ logger.log('');
236
+ logger.log(chalk.gray(SEP));
237
+ }
238
+
239
+ function logServerDatasourceTestRunFooter(success, agg) {
240
+ logger.log(
241
+ integrationFooterLine(
242
+ success,
243
+ agg,
244
+ 'All server tests passed.',
245
+ 'Server tests completed with warnings.',
246
+ 'Some server tests failed.'
247
+ )
248
+ );
249
+ }
250
+
251
+ /**
252
+ * Dataplane DatasourceTestRun layout (multi- or single-datasource).
253
+ * @param {Object} results
254
+ * @param {boolean} verbose
255
+ * @param {Object} opts
256
+ * @param {boolean|string} [opts.debug]
257
+ * @param {'integration'|'e2e'} [opts.runType]
258
+ */
259
+ function displayServerDatasourceTestRunResults(results, verbose, opts = {}) {
260
+ const runType = opts.runType === 'e2e' ? 'e2e' : 'integration';
261
+
262
+ if (isSingleUnskippedEnvelopeRun(results)) {
263
+ const row = results.datasourceResults[0];
264
+ logEnvelopeForInteractiveCli(row.datasourceTestRun, {
265
+ json: false,
266
+ summary: false,
267
+ debug: opts.debug,
268
+ requestedCapabilityKey: opts.requestedCapabilityKey
269
+ });
270
+ return;
212
271
  }
213
272
 
214
- if (verbose) {
215
- displayVerboseIntegrationDetails(dsResult);
273
+ // Plan §17: system-level overview for multi-datasource results (no full §16 dump per datasource by default).
274
+ // Keep legacy per-datasource full envelope available only via datasource commands.
275
+ if (integrationResultsHaveEnvelope(results)) {
276
+ displaySystemAggregateDatasourceTestRuns(results, { runType, verbose: Boolean(verbose) });
277
+ return;
278
+ }
279
+
280
+ const agg = deriveAggregateServerStatus(results);
281
+ logServerDatasourceTestRunHeader(results, runType, agg);
282
+
283
+ if (results.datasourceResults.length === 0) {
284
+ logger.log('');
285
+ logger.log(chalk.yellow('No datasources tested'));
286
+ logger.log('');
287
+ return;
288
+ }
289
+
290
+ for (const dsResult of results.datasourceResults) {
291
+ renderOneServerDatasourceRow(dsResult, verbose, opts);
292
+ logger.log('');
293
+ logger.log(chalk.gray(SEP));
216
294
  }
295
+
296
+ logServerDatasourceTestRunFooter(results.success, agg);
217
297
  }
218
298
 
219
299
  /**
220
- * Displays formatted integration test results
300
+ * Displays formatted integration / E2E test results (legacy or DatasourceTestRun TTY).
221
301
  * @param {Object} results - Integration test results
222
302
  * @param {boolean} verbose - Show detailed output
303
+ * @param {Object} [displayOpts]
304
+ * @param {boolean|string} [displayOpts.debug] - Debug appendix for each envelope
305
+ * @param {'integration'|'e2e'} [displayOpts.runType]
306
+ * @param {string} [displayOpts.requestedCapabilityKey]
223
307
  */
224
- function displayIntegrationTestResults(results, verbose = false) {
225
- logger.log(chalk.blue('\n📊 Integration Test Results\n'));
226
- logger.log(chalk.blue(`System: ${results.systemKey}`));
308
+ function displayIntegrationTestResults(results, verbose = false, displayOpts = {}) {
309
+ if (integrationResultsHaveEnvelope(results)) {
310
+ displayServerDatasourceTestRunResults(results, verbose, displayOpts);
311
+ return;
312
+ }
313
+
314
+ const agg = deriveAggregateLegacyIntegrationStatus(results);
315
+ logger.log('');
316
+ logger.log(sectionTitle('Integration test results'));
317
+ logger.log('');
318
+ logger.log(headerKeyValue('System:', results.systemKey));
319
+ logger.log(headerKeyValue('Run:', 'test-integration (pipeline)'));
320
+ logger.log(formatStatusKeyValue(agg, statusGlyph(agg)));
321
+ logger.log('');
322
+ logger.log(chalk.gray(SEP));
227
323
 
228
324
  if (results.datasourceResults.length === 0) {
325
+ logger.log('');
229
326
  logger.log(chalk.yellow('No datasources tested'));
230
327
  return;
231
328
  }
232
329
 
330
+ logger.log('');
233
331
  for (const dsResult of results.datasourceResults) {
234
332
  displayDatasourceIntegrationResult(dsResult, verbose);
235
333
  }
236
334
 
237
- if (results.success) {
238
- logger.log(chalk.green('\n✅ All integration tests passed!'));
239
- } else {
240
- logger.log(chalk.red('\n❌ Some integration tests failed'));
241
- }
335
+ logger.log(
336
+ integrationFooterLine(
337
+ results.success,
338
+ agg,
339
+ 'All integration tests passed.',
340
+ 'Integration tests completed with warnings.',
341
+ 'Some integration tests failed.'
342
+ )
343
+ );
242
344
  }
243
345
 
244
346
  /**
@@ -256,7 +358,9 @@ function displayIntegrationTestResults(results, verbose = false) {
256
358
  */
257
359
  /* eslint-disable max-statements,complexity -- Step iteration and status display */
258
360
  function displayE2EResults(data, verbose = false) {
259
- logger.log(chalk.blue('\n📊 E2E Test Results\n'));
361
+ logger.log('');
362
+ logger.log(sectionTitle('E2E test results'));
363
+ logger.log('');
260
364
  if (data.status) {
261
365
  const statusLabel = data.status === 'running'
262
366
  ? chalk.yellow('running')
@@ -265,12 +369,12 @@ function displayE2EResults(data, verbose = false) {
265
369
  : data.status === 'failed'
266
370
  ? chalk.red('failed')
267
371
  : data.status;
268
- logger.log(`Status: ${statusLabel}`);
372
+ logger.log(`${chalk.gray('Status:')} ${statusLabel}`);
269
373
  }
270
374
  const steps = data.steps || data.completedActions || [];
271
375
  if (steps.length === 0) {
272
376
  if (data.success === false) {
273
- logger.log(chalk.red('E2E test failed'));
377
+ logger.log(formatBlockingError('E2E test failed.'));
274
378
  if (data.error) logger.log(chalk.red(` Error: ${data.error}`));
275
379
  } else if (data.status === 'running') {
276
380
  logger.log(chalk.gray(' No steps completed yet'));
@@ -286,7 +390,7 @@ function displayE2EResults(data, verbose = false) {
286
390
  for (const step of steps) {
287
391
  const name = step.name || step.step || 'unknown';
288
392
  const ok = step.success !== false && !step.error;
289
- logger.log(` ${ok ? chalk.green('✓') : chalk.red('✗')} ${name}`);
393
+ logger.log(` ${ok ? successGlyph() : failureGlyph()} ${chalk.white(name)}`);
290
394
  if (!ok && (step.error || step.message)) logger.log(chalk.red(` ${step.error || step.message}`));
291
395
  if (verbose && step.message && ok) logger.log(chalk.gray(` ${step.message}`));
292
396
  if (verbose && ok && (name === 'sync' || step.step === 'sync') && step.evidence && step.evidence.jobs) {
@@ -308,7 +412,9 @@ function displayE2EResults(data, verbose = false) {
308
412
  return;
309
413
  }
310
414
  const allPassed = steps.every(s => s.success !== false && !s.error);
311
- logger.log(allPassed ? chalk.green('\n✅ E2E test passed!') : chalk.red('\n❌ E2E test failed'));
415
+ logger.log(
416
+ allPassed ? formatSuccessParagraph('E2E test passed.') : `\n${formatBlockingError('E2E test failed.')}`
417
+ );
312
418
  }
313
419
 
314
420
  /**