@aifabrix/builder 2.45.0 → 2.46.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 (352) hide show
  1. package/.cursor/rules/cli-layout.mdc +2 -0
  2. package/.cursor/rules/cli-product-neutral.mdc +43 -0
  3. package/.cursor/rules/docs-rules.mdc +3 -1
  4. package/.cursor/rules/project-rules.mdc +1 -0
  5. package/README.md +43 -17
  6. package/integration/hubspot-test/wizard-hubspot-e2e.yaml +1 -1
  7. package/jest.config.default.js +2 -1
  8. package/jest.config.isolated.js +2 -1
  9. package/jest.global-live-fabrix-hooks.js +36 -0
  10. package/jest.isolated-projects.js +130 -0
  11. package/jest.projects.js +69 -121
  12. package/lib/api/agent-metadata-validation.api.js +93 -0
  13. package/lib/api/api-response-errors.js +124 -0
  14. package/lib/api/audit-api-helpers.js +68 -0
  15. package/lib/api/audit.api.js +119 -0
  16. package/lib/api/auth-cache.api.js +44 -0
  17. package/lib/api/certificates.api.js +4 -4
  18. package/lib/api/credential.api.js +2 -2
  19. package/lib/api/dataplane-health.api.js +137 -0
  20. package/lib/api/dataplane-sync.api.js +27 -0
  21. package/lib/api/datasources-core.api.js +21 -18
  22. package/lib/api/datasources-extended.api.js +22 -22
  23. package/lib/api/dimensions.api.js +3 -0
  24. package/lib/api/external-systems.api.js +13 -13
  25. package/lib/api/governance-scenario-pack.api.js +159 -0
  26. package/lib/api/governance-scenarios.api.js +39 -0
  27. package/lib/api/groups.api.js +79 -0
  28. package/lib/api/index.js +88 -5
  29. package/lib/api/lifecycle.api.js +77 -0
  30. package/lib/api/pipeline.api.js +7 -5
  31. package/lib/api/protection.api.js +157 -0
  32. package/lib/api/records-bulk.api.js +43 -0
  33. package/lib/api/records-search-parse.js +49 -0
  34. package/lib/api/records-search.api.js +29 -0
  35. package/lib/api/types/agent-metadata-validation.types.js +67 -0
  36. package/lib/api/types/audit.types.js +72 -0
  37. package/lib/api/types/dataplane-health.types.js +27 -0
  38. package/lib/api/types/dimensions.types.js +2 -0
  39. package/lib/api/types/governance-scenarios.types.js +39 -0
  40. package/lib/api/types/protection.types.js +69 -0
  41. package/lib/api/types/records-bulk.types.js +35 -0
  42. package/lib/api/types/records-search.types.js +28 -0
  43. package/lib/api/user-groups.api.js +50 -0
  44. package/lib/api/users.api.js +95 -0
  45. package/lib/api/validation-run.api.js +3 -3
  46. package/lib/api/validation-runner.js +5 -3
  47. package/lib/api/wizard-platform.api.js +3 -3
  48. package/lib/api/wizard.api.js +21 -21
  49. package/lib/app/deploy-config.js +4 -1
  50. package/lib/app/deploy.js +34 -19
  51. package/lib/app/down.js +20 -1
  52. package/lib/app/push.js +4 -5
  53. package/lib/app/register.js +7 -4
  54. package/lib/app/run-env-compose.js +84 -30
  55. package/lib/build/index.js +5 -0
  56. package/lib/certification/sync-system-certification.js +13 -6
  57. package/lib/cli/index.js +8 -2
  58. package/lib/cli/infra-guided-auth.js +109 -0
  59. package/lib/cli/infra-guided.js +91 -69
  60. package/lib/cli/setup-app.help.js +19 -2
  61. package/lib/cli/setup-app.js +58 -23
  62. package/lib/cli/setup-app.test-commands.js +28 -21
  63. package/lib/cli/setup-auth.js +55 -3
  64. package/lib/cli/setup-certification-commands.js +147 -0
  65. package/lib/cli/setup-certification.help.js +141 -0
  66. package/lib/cli/setup-environment.js +19 -2
  67. package/lib/cli/setup-external-system-help.js +62 -0
  68. package/lib/cli/setup-external-system.js +62 -6
  69. package/lib/cli/setup-infra.js +9 -1
  70. package/lib/cli/setup-platform.js +6 -1
  71. package/lib/cli/setup-secrets.js +33 -1
  72. package/lib/cli/setup-utility-help-after.js +65 -0
  73. package/lib/cli/setup-utility-repair.js +198 -0
  74. package/lib/cli/setup-utility-resolve.js +42 -6
  75. package/lib/cli/setup-utility-validate.js +197 -0
  76. package/lib/cli/setup-utility.js +41 -258
  77. package/lib/commands/auth-status-client-tokens.js +214 -0
  78. package/lib/commands/auth-status-dataplane-version.js +269 -0
  79. package/lib/commands/auth-status-display.js +94 -0
  80. package/lib/commands/auth-status.js +111 -53
  81. package/lib/commands/credential-push.js +10 -5
  82. package/lib/commands/datasource-load-export-cli.js +178 -0
  83. package/lib/commands/datasource-test-trust-cli.js +118 -0
  84. package/lib/commands/datasource-unified-test-cli.js +31 -20
  85. package/lib/commands/datasource-unified-test-cli.options.js +22 -3
  86. package/lib/commands/datasource-unified-test-e2e-cli-helpers.js +5 -5
  87. package/lib/commands/datasource-verify-audit-cli.js +96 -0
  88. package/lib/commands/datasource.js +68 -1
  89. package/lib/commands/dev-show-display.js +8 -1
  90. package/lib/commands/dimension-value.js +43 -13
  91. package/lib/commands/dimension.js +38 -7
  92. package/lib/commands/governance-cli-shared.js +94 -0
  93. package/lib/commands/governance-command-action.js +132 -0
  94. package/lib/commands/governance-download-external.js +34 -0
  95. package/lib/commands/governance-generate-external.js +71 -0
  96. package/lib/commands/governance-upload-external.js +36 -0
  97. package/lib/commands/governance-verify-external.js +64 -0
  98. package/lib/commands/governance.js +144 -0
  99. package/lib/commands/identity-apply-sync.js +131 -0
  100. package/lib/commands/identity-group-cli.js +146 -0
  101. package/lib/commands/identity-membership-role-cache.js +175 -0
  102. package/lib/commands/identity-shared.js +94 -0
  103. package/lib/commands/identity-user-cli.js +158 -0
  104. package/lib/commands/identity.js +43 -0
  105. package/lib/commands/lifecycle-command-action.js +123 -0
  106. package/lib/commands/lifecycle-external.js +268 -0
  107. package/lib/commands/login.js +56 -17
  108. package/lib/commands/protection-cli-leaves.js +286 -0
  109. package/lib/commands/protection.js +50 -0
  110. package/lib/commands/repair-auth-apply.js +127 -0
  111. package/lib/commands/repair-changed-files.js +41 -0
  112. package/lib/commands/repair-datasource-keys.js +4 -1
  113. package/lib/commands/repair-datasource-run.js +59 -0
  114. package/lib/commands/repair-datasource-test-payload.js +259 -0
  115. package/lib/commands/repair-datasource.js +1 -51
  116. package/lib/commands/repair-env-template.js +64 -13
  117. package/lib/commands/repair-external-run.js +216 -0
  118. package/lib/commands/repair-openapi-sync.js +23 -0
  119. package/lib/commands/repair-persist.js +4 -0
  120. package/lib/commands/repair-rbac.js +52 -1
  121. package/lib/commands/repair-steps.js +145 -0
  122. package/lib/commands/repair.js +29 -286
  123. package/lib/commands/secrets-get.js +184 -0
  124. package/lib/commands/secrets-remove-all.js +3 -1
  125. package/lib/commands/setup-image-refresh.js +146 -0
  126. package/lib/commands/setup-modes.js +158 -162
  127. package/lib/commands/setup-platform-auth.js +76 -0
  128. package/lib/commands/setup-prompts-admin.js +244 -0
  129. package/lib/commands/setup-prompts-platform-mode.js +67 -0
  130. package/lib/commands/setup-prompts-validators.js +36 -0
  131. package/lib/commands/setup-prompts.js +24 -76
  132. package/lib/commands/setup-run-context.js +45 -0
  133. package/lib/commands/setup-spinners.js +39 -0
  134. package/lib/commands/setup.js +27 -5
  135. package/lib/commands/teardown.js +39 -0
  136. package/lib/commands/test-e2e-external.js +61 -14
  137. package/lib/commands/test-governance-cli-options.js +47 -0
  138. package/lib/commands/test-governance-external.js +67 -0
  139. package/lib/commands/test-trust-cli-options.js +32 -0
  140. package/lib/commands/test-trust-external.js +126 -0
  141. package/lib/commands/up-common.js +25 -13
  142. package/lib/commands/up-dataplane.js +50 -13
  143. package/lib/commands/upload-publish-context.js +75 -0
  144. package/lib/commands/upload-sidecar-followups.js +89 -0
  145. package/lib/commands/upload.js +108 -105
  146. package/lib/commands/verify-governance-combined-external.js +61 -0
  147. package/lib/commands/verify-governance-command-action.js +64 -0
  148. package/lib/commands/verify-governance-db.js +102 -0
  149. package/lib/commands/verify-governance-external.js +77 -0
  150. package/lib/commands/verify-governance-result-builders.js +71 -0
  151. package/lib/commands/verify-operations-command-action.js +68 -0
  152. package/lib/commands/verify-operations-external.js +268 -0
  153. package/lib/commands/verify-operations-persist.js +75 -0
  154. package/lib/commands/verify-operations-step-plan.js +68 -0
  155. package/lib/commands/verify-operations-steps.js +111 -0
  156. package/lib/commands/verify-trust-command-action.js +70 -0
  157. package/lib/commands/verify-trust-external.js +67 -0
  158. package/lib/commands/wizard-config-normalizer.js +43 -23
  159. package/lib/commands/wizard-core.js +5 -0
  160. package/lib/core/admin-password-generator.js +38 -0
  161. package/lib/core/admin-secrets-bundle.js +111 -0
  162. package/lib/core/admin-secrets-env-overlay.js +62 -0
  163. package/lib/core/admin-secrets.js +32 -4
  164. package/lib/core/config-attach-extensions.js +3 -0
  165. package/lib/core/config-device-dataplane.js +185 -0
  166. package/lib/core/config-platform-controller.js +44 -0
  167. package/lib/core/config-setup-installation-profile.js +42 -0
  168. package/lib/core/config-setup-platform-mode.js +46 -0
  169. package/lib/core/config.js +46 -36
  170. package/lib/core/secrets-admin-env.js +6 -2
  171. package/lib/core/secrets-ensure.js +4 -0
  172. package/lib/core/secrets-env-content.js +54 -48
  173. package/lib/core/secrets-env-write.js +10 -1
  174. package/lib/core/secrets-infra-placeholder-sync.js +2 -0
  175. package/lib/core/setup-installation-profile.js +43 -0
  176. package/lib/core/setup-platform-mode.js +55 -0
  177. package/lib/datasource/agent-trust-debug-log.js +45 -0
  178. package/lib/datasource/agent-trust-fetch.js +115 -0
  179. package/lib/datasource/agent-trust-map.js +101 -0
  180. package/lib/datasource/agent-trust-mock.js +44 -0
  181. package/lib/datasource/agent-trust-run.js +95 -0
  182. package/lib/datasource/agent-trust-timeout.js +25 -0
  183. package/lib/datasource/audit-evidence-display.js +80 -0
  184. package/lib/datasource/audit-evidence-extract-debug.js +115 -0
  185. package/lib/datasource/audit-evidence-extract.js +180 -0
  186. package/lib/datasource/audit-evidence-matrix-rows.js +158 -0
  187. package/lib/datasource/audit-evidence-operation-aliases.js +63 -0
  188. package/lib/datasource/audit-evidence-poll.js +109 -0
  189. package/lib/datasource/audit-evidence-run.js +177 -0
  190. package/lib/datasource/audit-evidence-verify-helpers.js +167 -0
  191. package/lib/datasource/audit-evidence-verify-matrix.js +205 -0
  192. package/lib/datasource/audit-evidence-verify.js +108 -0
  193. package/lib/datasource/bulk-loader-run-batches.js +100 -0
  194. package/lib/datasource/bulk-loader-service-retry.js +52 -0
  195. package/lib/datasource/bulk-loader-service.js +127 -0
  196. package/lib/datasource/capability/run-capability-dimension.js +2 -1
  197. package/lib/datasource/datasource-exporter-resolve.js +82 -0
  198. package/lib/datasource/datasource-exporter-service.js +144 -0
  199. package/lib/datasource/datasource-identifier.js +148 -0
  200. package/lib/datasource/datasource-load-export-context.js +95 -0
  201. package/lib/datasource/integration-context.js +6 -4
  202. package/lib/datasource/local-data-paths.js +145 -0
  203. package/lib/datasource/log-cleaner.js +241 -0
  204. package/lib/datasource/log-viewer.js +111 -6
  205. package/lib/datasource/record-file-parser.js +85 -0
  206. package/lib/datasource/record-mapper.js +129 -0
  207. package/lib/datasource/resolve-app.js +74 -55
  208. package/lib/datasource/test-e2e.js +29 -2
  209. package/lib/datasource/unified-validation-run-body.js +3 -1
  210. package/lib/datasource/unified-validation-run-resolve.js +45 -12
  211. package/lib/datasource/unified-validation-run.js +47 -18
  212. package/lib/datasource/validate.js +37 -20
  213. package/lib/deployment/environment-poll-status.js +138 -0
  214. package/lib/deployment/environment.js +42 -34
  215. package/lib/external-system/download.js +21 -20
  216. package/lib/external-system/generator.js +5 -1
  217. package/lib/external-system/integration-auth-context.js +45 -0
  218. package/lib/external-system/test-auth.js +12 -5
  219. package/lib/external-system/test-system-level.js +25 -4
  220. package/lib/external-system/test.js +9 -7
  221. package/lib/generator/external-controller-manifest.js +15 -0
  222. package/lib/governance/governance-cli-errors.js +96 -0
  223. package/lib/governance/governance-download-display.js +38 -0
  224. package/lib/governance/governance-pack-loader.js +70 -0
  225. package/lib/governance/governance-run-display.js +309 -0
  226. package/lib/identity/identity-apply-core.js +108 -0
  227. package/lib/identity/identity-apply-phases.js +244 -0
  228. package/lib/identity/identity-apply-service.js +77 -0
  229. package/lib/identity/identity-csv-parser.js +114 -0
  230. package/lib/infrastructure/admin-secrets-apply.js +84 -0
  231. package/lib/infrastructure/admin-secrets-ensure.js +130 -0
  232. package/lib/infrastructure/admin-secrets-resolve.js +95 -0
  233. package/lib/infrastructure/admin-secrets-sync.js +91 -0
  234. package/lib/infrastructure/helpers.js +23 -129
  235. package/lib/infrastructure/index.js +5 -6
  236. package/lib/infrastructure/orphan-infra-docker-teardown.js +11 -5
  237. package/lib/internal/fs-real-sync.js +29 -1
  238. package/lib/lifecycle/certification-progress.js +231 -0
  239. package/lib/lifecycle/dataplane-ui-url.js +145 -0
  240. package/lib/lifecycle/exit-codes.js +24 -0
  241. package/lib/lifecycle/json-envelope.js +25 -0
  242. package/lib/lifecycle/lifecycle-governance-options.js +51 -0
  243. package/lib/lifecycle/logger-quiet.js +29 -0
  244. package/lib/lifecycle/open-api-published.js +59 -0
  245. package/lib/lifecycle/operations-readiness-metrics.js +101 -0
  246. package/lib/lifecycle/product-model.js +196 -0
  247. package/lib/lifecycle/report-display.js +471 -0
  248. package/lib/lifecycle/scenario-upload.js +191 -0
  249. package/lib/lifecycle/verify-step-progress.js +87 -0
  250. package/lib/parameters/infra-kv-discovery.js +27 -2
  251. package/lib/protection/auth-context.js +51 -0
  252. package/lib/protection/convert-batch.js +90 -0
  253. package/lib/protection/load.js +41 -0
  254. package/lib/protection/paths.js +158 -0
  255. package/lib/protection/preflight-datasource-ready.js +46 -0
  256. package/lib/protection/protection-create-probe-lines.js +142 -0
  257. package/lib/protection/protection-create-probes.js +95 -0
  258. package/lib/protection/protection-create-scaffold.js +281 -0
  259. package/lib/protection/protection-display-helpers.js +445 -0
  260. package/lib/protection/protection-display.js +215 -0
  261. package/lib/protection/protection-preset-registry.js +97 -0
  262. package/lib/protection/report-exit.js +62 -0
  263. package/lib/protection/resolve.js +202 -0
  264. package/lib/protection/run-commands-validate.js +130 -0
  265. package/lib/protection/run-commands.js +216 -0
  266. package/lib/protection/run-protection-create-helpers.js +134 -0
  267. package/lib/protection/run-protection-create-probes-flow.js +43 -0
  268. package/lib/protection/run-protection-create.js +191 -0
  269. package/lib/protection/scope.js +22 -0
  270. package/lib/protection/sync-after-upload.js +64 -0
  271. package/lib/protection/upload-batch.js +127 -0
  272. package/lib/protection/validate-batch.js +113 -0
  273. package/lib/protection/validate-local.js +65 -0
  274. package/lib/resolvers/dimension-file.js +29 -4
  275. package/lib/schema/application-schema.json +1 -1
  276. package/lib/schema/datasource-test-run.schema.json +89 -6
  277. package/lib/schema/external-datasource.schema.json +2636 -2588
  278. package/lib/schema/external-system.schema.json +1089 -761
  279. package/lib/schema/flag-map-validation-run.json +2 -2
  280. package/lib/schema/infra.parameter.yaml +45 -0
  281. package/lib/schema/protection.schema.json +374 -0
  282. package/lib/schema/type/credential-field-registry.json +642 -0
  283. package/lib/schema/wizard-config.schema.json +1 -1
  284. package/lib/utils/agent-trust-run-display.js +231 -0
  285. package/lib/utils/agent-trust-run-exit.js +59 -0
  286. package/lib/utils/agent-trust-wait-ui.js +94 -0
  287. package/lib/utils/aifabrix-test-runtime-guard.js +125 -0
  288. package/lib/utils/api.js +55 -31
  289. package/lib/utils/app-relative-path-env.js +112 -0
  290. package/lib/utils/cli-exit-codes.js +30 -0
  291. package/lib/utils/cli-secrets-error-format.js +83 -21
  292. package/lib/utils/cli-sync-options.js +33 -0
  293. package/lib/utils/cli-utils.js +16 -4
  294. package/lib/utils/compose-generate-docker-compose.js +4 -0
  295. package/lib/utils/compose-traefik-ingress-base.js +16 -1
  296. package/lib/utils/config-secrets-path.js +46 -0
  297. package/lib/utils/controller-url.js +88 -1
  298. package/lib/utils/credential-push-ui.js +90 -0
  299. package/lib/utils/credential-secrets-env.js +137 -9
  300. package/lib/utils/dataplane-cli-version-gate.js +202 -0
  301. package/lib/utils/dataplane-cli-version-help.js +74 -0
  302. package/lib/utils/dataplane-resolver.js +129 -2
  303. package/lib/utils/datasource-export-display.js +137 -0
  304. package/lib/utils/datasource-load-display.js +174 -0
  305. package/lib/utils/datasource-load-export-ui.js +120 -0
  306. package/lib/utils/datasource-test-run-capability-scope.js +3 -3
  307. package/lib/utils/datasource-test-run-display.js +3 -3
  308. package/lib/utils/datasource-test-run-tty-log.js +5 -1
  309. package/lib/utils/declarative-url-ports.js +3 -3
  310. package/lib/utils/deployment-auth-mode.js +41 -0
  311. package/lib/utils/developer-volume-id.js +33 -0
  312. package/lib/utils/env-copy.js +14 -9
  313. package/lib/utils/env-kv-orphan-lines.js +43 -0
  314. package/lib/utils/error-formatters/network-errors.js +13 -4
  315. package/lib/utils/external-env-template.js +1 -0
  316. package/lib/utils/external-system-readiness-core.js +10 -0
  317. package/lib/utils/external-system-readiness-display.js +80 -23
  318. package/lib/utils/health-check.js +4 -1
  319. package/lib/utils/help-builder.js +35 -26
  320. package/lib/utils/keycloak-realm-ready.js +101 -0
  321. package/lib/utils/load-cip-capacity-display-config.js +61 -15
  322. package/lib/utils/manifest-source-emit.js +24 -0
  323. package/lib/utils/pipeline-upload-auth-retry.js +82 -0
  324. package/lib/utils/platform-controller-url.js +156 -0
  325. package/lib/utils/postgres-platform-bootstrap.js +199 -0
  326. package/lib/utils/postgres-wipe.js +9 -2
  327. package/lib/utils/resolve-env-mode.js +47 -0
  328. package/lib/utils/secrets-generator.js +31 -25
  329. package/lib/utils/secrets-missing-error.js +164 -0
  330. package/lib/utils/semver-compare.js +127 -0
  331. package/lib/utils/service-url-label.js +81 -0
  332. package/lib/utils/setup-quiet-output.js +25 -0
  333. package/lib/utils/template-helpers.js +15 -0
  334. package/lib/utils/token-manager-client-credentials.js +201 -0
  335. package/lib/utils/token-manager-messages.js +8 -0
  336. package/lib/utils/token-manager-refresh.js +12 -2
  337. package/lib/utils/token-manager.js +86 -105
  338. package/lib/utils/upload-pipeline-ui.js +98 -0
  339. package/lib/utils/upload-sync-options.js +42 -0
  340. package/lib/utils/url-declarative-public-base.js +21 -3
  341. package/lib/utils/url-declarative-vdir-inactive-env.js +14 -4
  342. package/lib/utils/validation-poll-ui.js +22 -7
  343. package/lib/utils/validation-run-stage.js +45 -0
  344. package/lib/validation/wizard-config-validator.js +58 -19
  345. package/package.json +1 -1
  346. package/templates/applications/dataplane/application.yaml +2 -1
  347. package/templates/applications/dataplane/env.template +36 -1
  348. package/templates/applications/dataplane/rbac.yaml +4 -0
  349. package/templates/applications/miso-controller/env.template +16 -0
  350. package/templates/external-system/README.md.hbs +116 -11
  351. package/templates/python/docker-compose.hbs +19 -18
  352. package/templates/typescript/docker-compose.hbs +18 -17
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Comment active KV_* env lines that are not in the expected key set (stale auth vars).
3
+ *
4
+ * @fileoverview Shared orphan KV line handling for env.template repair and resolve merge
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ /**
12
+ * Comments active KV_* lines whose env key is not in the expected set.
13
+ *
14
+ * @param {string} content - .env or env.template content
15
+ * @param {Set<string>|Map<string, unknown>} expectedKeys - Keys that should stay active
16
+ * @returns {{ content: string, changed: boolean }}
17
+ */
18
+ function commentOrphanKvEnvLines(content, expectedKeys) {
19
+ const expected =
20
+ expectedKeys instanceof Set ? expectedKeys : new Set(expectedKeys.keys());
21
+ const changedRef = { value: false };
22
+ const out = (content || '').split(/\r?\n/).map((line) => {
23
+ const trimmed = line.trim();
24
+ if (!trimmed || trimmed.startsWith('#')) {
25
+ return line;
26
+ }
27
+ const eq = line.indexOf('=');
28
+ if (eq <= 0 || !/^KV_/i.test(trimmed)) {
29
+ return line;
30
+ }
31
+ const key = line.substring(0, eq).trim();
32
+ if (expected.has(key)) {
33
+ return line;
34
+ }
35
+ changedRef.value = true;
36
+ return `${line.match(/^\s*/)[0]}# ${trimmed}`;
37
+ });
38
+ const joined = out.join('\n');
39
+ const normalized = joined.length > 0 && !joined.endsWith('\n') ? `${joined}\n` : joined;
40
+ return { content: normalized, changed: changedRef.value };
41
+ }
42
+
43
+ module.exports = { commentOrphanKvEnvLines };
@@ -10,6 +10,7 @@ const { formatBlockingError } = require('../cli-test-layout-chalk');
10
10
  */
11
11
 
12
12
  const chalk = require('chalk');
13
+ const { serviceLabelDisplayName } = require('../service-url-label');
13
14
 
14
15
  /**
15
16
  * Normalizes error message to string
@@ -56,9 +57,16 @@ function addControllerUrlToMessage(lines, errorData) {
56
57
  * @param {Object} errorData - Error response data
57
58
  */
58
59
  function formatConnectionRefusedError(lines, errorData) {
59
- lines.push(chalk.yellow('Cannot connect to controller.'));
60
+ const label = serviceLabelDisplayName(errorData?.serviceLabel || 'service');
61
+ lines.push(chalk.yellow(`Cannot connect to ${label}.`));
60
62
  addControllerUrlToMessage(lines, errorData);
61
- lines.push(chalk.gray('Check if the controller is running.'));
63
+ if (label === 'dataplane') {
64
+ lines.push(chalk.gray('Check if the dataplane is running (e.g. aifabrix run dataplane --reload).'));
65
+ } else if (label === 'controller') {
66
+ lines.push(chalk.gray('Check if the controller is running.'));
67
+ } else {
68
+ lines.push(chalk.gray('Check the service URL and network.'));
69
+ }
62
70
  }
63
71
 
64
72
  /**
@@ -68,9 +76,10 @@ function formatConnectionRefusedError(lines, errorData) {
68
76
  * @param {Object} errorData - Error response data
69
77
  */
70
78
  function formatHostnameNotFoundError(lines, errorData) {
71
- lines.push(chalk.yellow('Controller hostname not found.'));
79
+ const label = serviceLabelDisplayName(errorData?.serviceLabel || 'service');
80
+ lines.push(chalk.yellow(`${label.charAt(0).toUpperCase()}${label.slice(1)} hostname not found.`));
72
81
  addControllerUrlToMessage(lines, errorData);
73
- lines.push(chalk.gray('Check your controller URL.'));
82
+ lines.push(chalk.gray(`Check your ${label} URL (see aifabrix auth status).`));
74
83
  }
75
84
 
76
85
  /**
@@ -43,6 +43,7 @@ const FALLBACK_SECURITY_BY_AUTH = {
43
43
  aad: ['clientId', 'clientSecret'],
44
44
  apikey: ['apiKey'],
45
45
  apiKey: ['apiKey'],
46
+ bearertoken: ['token'],
46
47
  basic: ['username', 'password'],
47
48
  queryParam: ['paramValue'],
48
49
  oidc: [],
@@ -28,6 +28,15 @@ function isPublicationResultShape(obj) {
28
28
  return !!(obj && typeof obj === 'object' && (obj.uploadId || obj.system) && Array.isArray(obj.datasources));
29
29
  }
30
30
 
31
+ /**
32
+ * True when dataplane skipped publish because manifest matches running config.
33
+ * @param {*} publication - Parsed PublicationResult
34
+ * @returns {boolean}
35
+ */
36
+ function isPublicationUnchanged(publication) {
37
+ return !!(publication && publication.uploadStatus === 'unchanged');
38
+ }
39
+
31
40
  /**
32
41
  * Returns publication payload from upload API response.
33
42
  * @param {*} res - Response from uploadApplicationViaPipeline
@@ -432,6 +441,7 @@ module.exports = {
432
441
  unwrapApiData,
433
442
  unwrapPublicationResult,
434
443
  isPublicationResultShape,
444
+ isPublicationUnchanged,
435
445
  classifyDatasourceTierADetail,
436
446
  classifyDatasourceTierA,
437
447
  formatTierAPartialHint,
@@ -128,25 +128,94 @@ function logServerValidationWarnings(validationBody) {
128
128
  }
129
129
  }
130
130
 
131
+ /**
132
+ * @param {Object[]} results - Probe result rows
133
+ * @returns {boolean}
134
+ */
135
+ function connectivityCheckFailed(results) {
136
+ return results.some(
137
+ row =>
138
+ row?.endpointTestResults?.success === false
139
+ || row?.endpointTestResults?.endpointReachable === false
140
+ );
141
+ }
142
+
131
143
  /**
132
144
  * @param {Object} results - Probe result rows
133
145
  * @param {Object} summary - summarizeProbeResults output
134
146
  */
135
147
  function logProbeCredentialLine(results, summary) {
136
148
  logSeparator();
137
- logSectionTitle('Credential Test:');
138
- const anyEndpointFail = results.some(row => row?.endpointTestResults?.success === false);
139
- if (anyEndpointFail) {
149
+ logSectionTitle('Connectivity check:');
150
+ if (connectivityCheckFailed(results)) {
140
151
  logger.log(formatBlockingError('Failed (see Key Issues / endpoint test)'));
141
- } else if (summary.failed > 0) {
142
- logger.log(formatBlockingError('Some datasource checks failed'));
143
- } else if (summary.partial > 0) {
144
- logger.log(chalk.yellow('⚠ Completed with warnings'));
145
152
  } else {
146
- logger.log(formatSuccessLine('Passed'));
153
+ logger.log(formatSuccessLine('Passed (system credential / testEndpoint)'));
154
+ }
155
+ if (summary.partial > 0 || summary.failed > 0) {
156
+ logSeparator();
157
+ logSectionTitle('Datasource readiness:');
158
+ if (summary.failed > 0) {
159
+ logger.log(formatBlockingError('Some datasource checks failed'));
160
+ } else {
161
+ logger.log(
162
+ chalk.yellow(
163
+ '⚠ Partial — validation or certification warnings (not a failed credential test)'
164
+ )
165
+ );
166
+ }
167
+ logger.log(
168
+ chalk.gray(
169
+ ' Upload --probe runs structural validation + certification tiers; live .env connectivity is separate.'
170
+ )
171
+ );
172
+ }
173
+ }
174
+
175
+ /**
176
+ * @param {Object[]} results
177
+ */
178
+ function logProbeEmptyResultsWarningIfNeeded(results) {
179
+ if (results.length === 0) {
180
+ logger.log(chalk.yellow('⚠ No runtime datasource results were returned by the dataplane probe.'));
181
+ logger.log(chalk.gray(' Endpoint credential test may still pass even if datasource checks were not reported.'));
147
182
  }
148
183
  }
149
184
 
185
+ /**
186
+ * @param {Array<{ key: string, lines: string[] }>} issues
187
+ */
188
+ function logProbeKeyIssues(issues) {
189
+ if (issues.length === 0) return;
190
+ logSeparator();
191
+ logSectionTitle('Key Issues:');
192
+ for (const { key, lines } of issues) {
193
+ logger.log(chalk.white(key));
194
+ for (const line of lines) {
195
+ logger.log(chalk.red(`- ${line}`));
196
+ }
197
+ }
198
+ }
199
+
200
+ /**
201
+ * @param {Object[]} results
202
+ * @param {Object} summary
203
+ * @returns {string[]}
204
+ */
205
+ function buildProbeNextActionHints(results, summary) {
206
+ const hints = [];
207
+ if (connectivityCheckFailed(results)) {
208
+ hints.push('Fix API credentials or permissions (connectivity check failed)');
209
+ }
210
+ if (summary.failed > 0) {
211
+ hints.push('Fix datasource errors listed under Key Issues');
212
+ }
213
+ if (summary.partial > 0 && summary.failed === 0) {
214
+ hints.push('Review Key Issues for certification/validation warnings (ICC, MCP, dimensions)');
215
+ }
216
+ return hints;
217
+ }
218
+
150
219
  /**
151
220
  * @param {Object} probeRaw - Unwrapped POST /validation/run body
152
221
  * @param {string} systemKey
@@ -156,25 +225,13 @@ function logProbeRuntimeBlock(probeRaw, systemKey) {
156
225
  const summary = summarizeProbeResults(results);
157
226
  logSeparator();
158
227
  logger.log(chalk.bold('Runtime Readiness:'));
159
- if (results.length === 0) {
160
- logger.log(chalk.yellow('⚠ No runtime datasource results were returned by the dataplane probe.'));
161
- logger.log(chalk.gray(' Endpoint credential test may still pass even if datasource checks were not reported.'));
162
- }
228
+ logProbeEmptyResultsWarningIfNeeded(results);
163
229
  logDatasourceTable(summary.rows, summary);
164
- if (summary.issues.length > 0) {
165
- logSeparator();
166
- logSectionTitle('Key Issues:');
167
- for (const { key, lines } of summary.issues) {
168
- logger.log(chalk.white(key));
169
- for (const line of lines) {
170
- logger.log(chalk.red(`- ${line}`));
171
- }
172
- }
173
- }
230
+ logProbeKeyIssues(summary.issues);
174
231
  logProbeCredentialLine(results, summary);
175
232
  logSeparator();
176
233
  logNextActions(
177
- ['Fix API credentials or permissions if endpoint tests failed'],
234
+ buildProbeNextActionHints(results, summary),
178
235
  `Run: aifabrix datasource test-e2e <datasourceKey> --app ${systemKey}`
179
236
  );
180
237
  }
@@ -357,7 +357,10 @@ async function performHealthCheckAttempt(healthCheckUrl, attempt, maxAttempts, d
357
357
  }
358
358
  const healthCheckPassed = await checkHealthEndpoint(healthCheckUrl, debug);
359
359
  if (healthCheckPassed) {
360
- logger.log(formatSuccessLine('Application is healthy'));
360
+ const { isSetupQuietOutput } = require('./setup-quiet-output');
361
+ if (!isSetupQuietOutput()) {
362
+ logger.log(formatSuccessLine('Application is healthy'));
363
+ }
361
364
  if (debug) {
362
365
  logger.log(chalk.gray(`[DEBUG] Health check passed after ${attempt + 1} attempt(s)`));
363
366
  }
@@ -26,10 +26,10 @@ const CATEGORIES = [
26
26
  { name: 'up-platform' },
27
27
  { name: 'up-miso' },
28
28
  { name: 'up-dataplane' },
29
- { name: 'down-infra', term: 'down-infra [service|app]' },
29
+ { name: 'down-infra', term: 'down-infra [service|appKey]' },
30
30
  { name: 'doctor' },
31
31
  { name: 'status' },
32
- { name: 'restart', term: 'restart <service|app>' }
32
+ { name: 'restart', term: 'restart <service|appKey>' }
33
33
  ]
34
34
  },
35
35
  {
@@ -43,23 +43,22 @@ const CATEGORIES = [
43
43
  {
44
44
  name: 'Applications (Create & Develop)',
45
45
  commands: [
46
- { name: 'create', term: 'create <app>' },
47
- { name: 'wizard' },
48
- { name: 'build', term: 'build <app>' },
49
- { name: 'run', term: 'run <app>' },
50
- { name: 'shell', term: 'shell <app>' },
51
- { name: 'install', term: 'install <app>' },
52
- { name: 'lint', term: 'lint <app>' },
53
- { name: 'logs', term: 'logs <app>' },
54
- { name: 'stop', term: 'stop <app>' },
55
- { name: 'dockerfile', term: 'dockerfile <app>' }
46
+ { name: 'create', term: 'create <appKey|systemKey>' },
47
+ { name: 'build', term: 'build <appKey>' },
48
+ { name: 'run', term: 'run <appKey>' },
49
+ { name: 'shell', term: 'shell <appKey>' },
50
+ { name: 'install', term: 'install <appKey>' },
51
+ { name: 'lint', term: 'lint <appKey>' },
52
+ { name: 'logs', term: 'logs <appKey>' },
53
+ { name: 'stop', term: 'stop <appKey>' },
54
+ { name: 'dockerfile', term: 'dockerfile <appKey>' }
56
55
  ]
57
56
  },
58
57
  {
59
58
  name: 'Deployment',
60
59
  commands: [
61
- { name: 'push', term: 'push <app>' },
62
- { name: 'deploy', term: 'deploy <app>' }
60
+ { name: 'push', term: 'push <appKey>' },
61
+ { name: 'deploy', term: 'deploy <appKey|systemKey>' }
63
62
  ]
64
63
  },
65
64
  {
@@ -74,18 +73,22 @@ const CATEGORIES = [
74
73
  { name: 'app' },
75
74
  { name: 'credential' },
76
75
  { name: 'deployment' },
77
- { name: 'integration-client' }
76
+ { name: 'integration-client' },
77
+ { name: 'dimension' },
78
+ { name: 'dimension value', term: 'dimension value <command>' },
79
+ { name: 'identity' },
80
+ { name: 'protection' }
78
81
  ]
79
82
  },
80
83
  {
81
84
  name: 'Configuration & Validation',
82
85
  commands: [
83
- { name: 'resolve', term: 'resolve <app>' },
84
- { name: 'json', term: 'json <app>' },
85
- { name: 'split-json', term: 'split-json <app>' },
86
- { name: 'convert', term: 'convert <app>' },
87
- { name: 'show', term: 'show <app>' },
88
- { name: 'validate', term: 'validate <appOrFile>' },
86
+ { name: 'resolve', term: 'resolve <appKey|systemKey>' },
87
+ { name: 'json', term: 'json <appKey|systemKey>' },
88
+ { name: 'split-json', term: 'split-json <appKey|systemKey>' },
89
+ { name: 'convert', term: 'convert <appKey|systemKey>' },
90
+ { name: 'show', term: 'show <appKey|systemKey>' },
91
+ { name: 'validate', term: 'validate [appKey|systemKey|file]' },
89
92
  { name: 'parameters', term: 'parameters validate' },
90
93
  { name: 'diff', term: 'diff <file1> <file2>' }
91
94
  ]
@@ -93,16 +96,22 @@ const CATEGORIES = [
93
96
  {
94
97
  name: 'External Systems',
95
98
  commands: [
99
+ { name: 'wizard', term: 'wizard [systemKey]' },
96
100
  { name: 'download', term: 'download <systemKey>' },
97
101
  { name: 'upload', term: 'upload <systemKey>' },
98
102
  { name: 'delete', term: 'delete <systemKey>' },
99
103
  { name: 'repair', term: 'repair <systemKey>' },
100
104
  { name: 'datasource' },
101
- { name: 'dimension' },
102
- { name: 'dimension-value' },
103
- { name: 'test', term: 'test <app>' },
104
- { name: 'test-e2e', term: 'test-e2e <app>' },
105
- { name: 'test-integration', term: 'test-integration <app>' }
105
+ { name: 'datasource load', term: 'datasource load <datasourceKey>' },
106
+ { name: 'datasource export', term: 'datasource export <datasourceKey>' },
107
+ { name: 'test', term: 'test <appKey|systemKey>' },
108
+ { name: 'test-integration', term: 'test-integration <appKey|systemKey>' },
109
+ { name: 'test-e2e', term: 'test-e2e <appKey|systemKey>' },
110
+ { name: 'verify-operations', term: 'verify-operations <systemKey>' },
111
+ { name: 'verify-trust', term: 'verify-trust <systemKey>' },
112
+ { name: 'verify-governance', term: 'verify-governance <systemKey>' },
113
+ { name: 'governance', term: 'governance <generate|verify|download|upload> <systemKey>' },
114
+ { name: 'lifecycle', term: 'lifecycle <systemKey>' }
106
115
  ]
107
116
  },
108
117
  {
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Poll Keycloak until the `aifabrix` realm is available (post-wipe / fresh install).
3
+ *
4
+ * @fileoverview Keycloak realm readiness for setup auth
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const { computeAppBaseUrl } = require('./platform-controller-url');
12
+ const config = require('../core/config');
13
+ const { readUrlsLocalRegistrySync } = require('./urls-local-registry');
14
+ const { normalizeFrontDoorPatternForHealth } = require('./health-check-url');
15
+
16
+ /**
17
+ * @param {string} keycloakBase
18
+ * @returns {string}
19
+ */
20
+ function buildRealmWellKnownUrl(keycloakBase) {
21
+ const base = String(keycloakBase || '').replace(/\/+$/, '');
22
+ return `${base}/realms/aifabrix/.well-known/openid-configuration`;
23
+ }
24
+
25
+ /**
26
+ * @async
27
+ * @param {string} url
28
+ * @returns {Promise<boolean>}
29
+ */
30
+ async function probeRealmWellKnown(url) {
31
+ const controller = new AbortController();
32
+ const timer = setTimeout(() => controller.abort(), 8000);
33
+ try {
34
+ const res = await fetch(url, { method: 'GET', signal: controller.signal });
35
+ return res.ok;
36
+ } catch {
37
+ return false;
38
+ } finally {
39
+ clearTimeout(timer);
40
+ }
41
+ }
42
+
43
+ function computeKeycloakDirectBaseUrlFromRegistry(registry, developerIdNum) {
44
+ const portRaw = registry && registry['keycloak-port'];
45
+ const port =
46
+ typeof portRaw === 'number'
47
+ ? portRaw
48
+ : typeof portRaw === 'string' && /^\d+$/.test(portRaw.trim())
49
+ ? parseInt(portRaw.trim(), 10)
50
+ : null;
51
+ if (!port || port <= 0) {
52
+ return null;
53
+ }
54
+ const patternRaw = registry && registry['keycloak-pattern'];
55
+ const pattern = typeof patternRaw === 'string' && patternRaw.trim() ? patternRaw.trim() : null;
56
+ const mount = pattern ? normalizeFrontDoorPatternForHealth(pattern) : null;
57
+ const adjusted = port + (Number.isFinite(developerIdNum) ? developerIdNum : 0) * 100;
58
+ return `http://localhost:${adjusted}${mount || ''}`;
59
+ }
60
+
61
+ /**
62
+ * Wait until Keycloak serves the aifabrix realm OIDC metadata.
63
+ *
64
+ * @async
65
+ * @param {{ timeoutSeconds?: number, intervalMs?: number }} [opts]
66
+ * @returns {Promise<void>}
67
+ * @throws {Error} On timeout
68
+ */
69
+ async function waitForKeycloakRealmReady(opts = {}) {
70
+ const timeoutSeconds = Number.isFinite(opts.timeoutSeconds) ? opts.timeoutSeconds : 180;
71
+ const intervalMs = Number.isFinite(opts.intervalMs) ? opts.intervalMs : 3000;
72
+ const keycloakBase = await computeAppBaseUrl('keycloak');
73
+ const url = buildRealmWellKnownUrl(keycloakBase);
74
+ const registry = readUrlsLocalRegistrySync();
75
+ const developerIdRaw = await config.getDeveloperId();
76
+ const developerIdNum = typeof developerIdRaw === 'string' ? parseInt(developerIdRaw, 10) : developerIdRaw;
77
+ const directBase = computeKeycloakDirectBaseUrlFromRegistry(registry, developerIdNum);
78
+ const directUrl = directBase ? buildRealmWellKnownUrl(directBase) : null;
79
+ const deadline = Date.now() + timeoutSeconds * 1000;
80
+
81
+ while (Date.now() < deadline) {
82
+ if (await probeRealmWellKnown(url)) {
83
+ return;
84
+ }
85
+ if (directUrl && (await probeRealmWellKnown(directUrl))) {
86
+ return;
87
+ }
88
+ await new Promise((resolve) => setTimeout(resolve, intervalMs));
89
+ }
90
+
91
+ throw new Error(
92
+ `Keycloak realm "aifabrix" was not ready within ${timeoutSeconds}s (checked ${url}${directUrl ? ` and ${directUrl}` : ''}). ` +
93
+ 'Ensure Miso Controller finished onboarding after the database wipe.'
94
+ );
95
+ }
96
+
97
+ module.exports = {
98
+ buildRealmWellKnownUrl,
99
+ waitForKeycloakRealmReady,
100
+ computeKeycloakDirectBaseUrlFromRegistry
101
+ };
@@ -8,8 +8,8 @@
8
8
 
9
9
  'use strict';
10
10
 
11
- const fs = require('fs');
12
11
  const path = require('path');
12
+ const { existsSync, readFileSync } = require('../internal/fs-real-sync');
13
13
 
14
14
  /**
15
15
  * @param {object|null} schema - Parsed external-datasource.schema.json
@@ -33,8 +33,8 @@ function extractStandardOperationOrderFromSchema(schema) {
33
33
  */
34
34
  function tryReadJsonFile(p) {
35
35
  try {
36
- if (!p || !fs.existsSync(p)) return null;
37
- return JSON.parse(fs.readFileSync(p, 'utf8'));
36
+ if (!p || !existsSync(p)) return null;
37
+ return JSON.parse(readFileSync(p, 'utf8'));
38
38
  } catch {
39
39
  return null;
40
40
  }
@@ -48,25 +48,74 @@ function tryReadJsonFile(p) {
48
48
  function resolveExternalDatasourceSchemaPath() {
49
49
  if (process.env.AIFABRIX_EXTERNAL_DATASOURCE_SCHEMA) {
50
50
  const envPath = String(process.env.AIFABRIX_EXTERNAL_DATASOURCE_SCHEMA).trim();
51
- if (envPath && fs.existsSync(envPath)) return envPath;
51
+ if (envPath && existsSync(envPath)) return envPath;
52
52
  }
53
53
  const candidates = [
54
+ path.join(__dirname, '../schema/external-datasource.schema.json'),
54
55
  path.join(process.cwd(), 'app/schemas/json/external-datasource.schema.json'),
55
56
  path.join(process.cwd(), 'aifabrix-dataplane/app/schemas/json/external-datasource.schema.json'),
56
57
  path.join(process.cwd(), '..', 'aifabrix-dataplane', 'app/schemas/json/external-datasource.schema.json'),
57
58
  path.join(__dirname, '../../../aifabrix-dataplane/app/schemas/json/external-datasource.schema.json')
58
59
  ];
59
60
  for (const c of candidates) {
60
- if (c && fs.existsSync(c)) return c;
61
+ if (c && existsSync(c)) return c;
61
62
  }
62
63
  return null;
63
64
  }
64
65
 
65
66
  const FALLBACK_PATH = path.join(__dirname, '../schema/cip-capacity-display.fallback.json');
66
67
 
68
+ /**
69
+ * When schema/fallback JSON cannot be read (missing file, parse error, or Jest fs mocks in a shared worker).
70
+ * Must stay aligned with `cip-capacity-display.fallback.json` and dataplane `cipDefinition.operations`.
71
+ */
72
+ const HARDCODED_STANDARD_OPERATION_ORDER = ['list', 'get', 'create', 'update', 'delete'];
73
+ const HARDCODED_DISPLAY_ALIASES = { create: 'insert (create)' };
74
+
67
75
  /** @type {{ standardOrder: string[], aliases: Record<string, string> }|null} */
68
76
  let _cache = null;
69
77
 
78
+ /**
79
+ * @returns {{ standardOperationOrder: string[], displayAliases: Record<string, string> }}
80
+ */
81
+ function readFallbackDisplayConfig() {
82
+ const fromFile = tryReadJsonFile(FALLBACK_PATH);
83
+ const order =
84
+ fromFile && Array.isArray(fromFile.standardOperationOrder) && fromFile.standardOperationOrder.length
85
+ ? fromFile.standardOperationOrder
86
+ : HARDCODED_STANDARD_OPERATION_ORDER;
87
+ const aliases =
88
+ fromFile && fromFile.displayAliases && typeof fromFile.displayAliases === 'object'
89
+ ? fromFile.displayAliases
90
+ : HARDCODED_DISPLAY_ALIASES;
91
+ return { standardOperationOrder: order, displayAliases: aliases };
92
+ }
93
+
94
+ /**
95
+ * Prefer schema key order, then append any fallback standard ops missing from the schema
96
+ * (guards partial/stale schema files and cross-test cache pollution in Jest).
97
+ * @param {string[]|null} fromSchema
98
+ * @param {string[]} fbOrder
99
+ * @returns {string[]}
100
+ */
101
+ function mergeStandardOperationOrders(fromSchema, fbOrder) {
102
+ const schemaOps = Array.isArray(fromSchema)
103
+ ? fromSchema.map(op => String(op).trim().toLowerCase()).filter(Boolean)
104
+ : [];
105
+ const fallbackOps = Array.isArray(fbOrder)
106
+ ? fbOrder.map(op => String(op).trim().toLowerCase()).filter(Boolean)
107
+ : [];
108
+ if (!schemaOps.length) return fallbackOps;
109
+ const seen = new Set(schemaOps);
110
+ const merged = [...schemaOps];
111
+ for (const op of fallbackOps) {
112
+ if (seen.has(op)) continue;
113
+ seen.add(op);
114
+ merged.push(op);
115
+ }
116
+ return merged;
117
+ }
118
+
70
119
  /**
71
120
  * @returns {{ standardOrder: string[], aliases: Record<string, string> }}
72
121
  */
@@ -75,16 +124,12 @@ function getCipCapacityDisplayConfig() {
75
124
  const schemaPath = resolveExternalDatasourceSchemaPath();
76
125
  const schema = schemaPath ? tryReadJsonFile(schemaPath) : null;
77
126
  const fromSchema = extractStandardOperationOrderFromSchema(schema);
78
- const fallback = tryReadJsonFile(FALLBACK_PATH) || {};
79
- const fbOrder = Array.isArray(fallback.standardOperationOrder)
80
- ? fallback.standardOperationOrder
81
- : [];
82
- const standardOrder = fromSchema && fromSchema.length ? fromSchema : fbOrder;
83
- const aliases =
84
- fallback.displayAliases && typeof fallback.displayAliases === 'object'
85
- ? fallback.displayAliases
86
- : { create: 'insert (create)' };
87
- _cache = { standardOrder, aliases };
127
+ const fallback = readFallbackDisplayConfig();
128
+ const standardOrder = mergeStandardOperationOrders(
129
+ fromSchema,
130
+ fallback.standardOperationOrder
131
+ );
132
+ _cache = { standardOrder, aliases: fallback.displayAliases };
88
133
  return _cache;
89
134
  }
90
135
 
@@ -122,6 +167,7 @@ function clearCipCapacityDisplayConfigCacheForTests() {
122
167
 
123
168
  module.exports = {
124
169
  extractStandardOperationOrderFromSchema,
170
+ mergeStandardOperationOrders,
125
171
  resolveExternalDatasourceSchemaPath,
126
172
  getCipCapacityDisplayConfig,
127
173
  standardOperationRank,
@@ -104,6 +104,8 @@ function isStdoutTty() {
104
104
  function emitManifestMetadataLineIfTTY(logger, opts) {
105
105
  if (!logger || typeof logger.log !== 'function') return;
106
106
  if (!opts || opts.json || opts.envOnly) return;
107
+ const { isSetupQuietOutput } = require('./setup-quiet-output');
108
+ if (isSetupQuietOutput()) return;
107
109
  if (!isStdoutTty()) return;
108
110
  const appKey = opts.appKey && typeof opts.appKey === 'string' ? opts.appKey.trim() : '';
109
111
  const appPath = opts.appPath && typeof opts.appPath === 'string' ? opts.appPath.trim() : '';
@@ -151,8 +153,30 @@ function emitAllPlatformSystemManifestLinesIfTTY(logger, opts = {}) {
151
153
  }
152
154
  }
153
155
 
156
+ /**
157
+ * Integration load/export manifest line (plan 144).
158
+ *
159
+ * @param {{ tier?: string, configPath?: string, labelPrefix?: string }} opts
160
+ * @returns {void}
161
+ */
162
+ function emitManifestSourceMetadata(opts = {}) {
163
+ if (!isStdoutTty()) return;
164
+ const log = require('./logger');
165
+ const tier = opts.tier && typeof opts.tier === 'string' ? opts.tier : 'resolved';
166
+ const configPath =
167
+ opts.configPath && typeof opts.configPath === 'string' ? opts.configPath : '';
168
+ const labelPrefix =
169
+ opts.labelPrefix && typeof opts.labelPrefix === 'string' ? opts.labelPrefix : '';
170
+ const tierLabel = tier === 'int' ? 'integration' : humanTierLabel(tier);
171
+ const line = labelPrefix
172
+ ? metadata(`${labelPrefix} — ${tierLabel} — ${configPath}`)
173
+ : formatManifestSourceMetadataLine({ tier: tierLabel, configPath });
174
+ log.log(line);
175
+ }
176
+
154
177
  module.exports = {
155
178
  emitManifestMetadataLineIfTTY,
179
+ emitManifestSourceMetadata,
156
180
  emitSystemBuilderAppManifestLineIfTTY,
157
181
  emitAllPlatformSystemManifestLinesIfTTY,
158
182
  formatManifestSourceMetadataLine,