@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
@@ -15,7 +15,6 @@ const config = require('./config');
15
15
  const {
16
16
  interpolateEnvVars,
17
17
  collectMissingSecrets,
18
- formatMissingSecretsFileInfo,
19
18
  replaceKvInContent,
20
19
  loadEnvTemplate,
21
20
  adjustLocalEnvPortsInContent,
@@ -43,6 +42,8 @@ const {
43
42
  rewriteDockerManifestPublicPortEnvLine
44
43
  } = require('../utils/docker-manifest-public-port');
45
44
  const { loadSecrets } = require('./secrets-load');
45
+ const { buildMissingSecretsErrorMessage } = require('../utils/secrets-missing-error');
46
+ const { commentOrphanKvEnvLines } = require('../utils/env-kv-orphan-lines');
46
47
 
47
48
  /**
48
49
  * Resolves kv:// references in environment template
@@ -54,10 +55,24 @@ const { loadSecrets } = require('./secrets-load');
54
55
  * @param {string} [environment='local'] - Environment context (docker/local)
55
56
  * @param {Object|string|null} [secretsFilePaths] - Paths object with userPath and buildPath, or string path (for backward compatibility)
56
57
  * @param {string} [appName] - Application name (optional, for error messages)
58
+ * @param {Object|null} [resolveOpts] - Scoped kv (`envKey`, `effective`) and/or `envTemplatePath` for error hints
57
59
  * @returns {Promise<string>} Resolved environment content
58
60
  * @throws {Error} If kv:// reference cannot be resolved
59
61
  */
60
- async function resolveKvReferences(envTemplate, secrets, environment = 'local', secretsFilePaths = null, appName = null, scopedKv = null) {
62
+ async function resolveKvReferences(
63
+ envTemplate,
64
+ secrets,
65
+ environment = 'local',
66
+ secretsFilePaths = null,
67
+ appName = null,
68
+ resolveOpts = null
69
+ ) {
70
+ const envTemplatePath =
71
+ resolveOpts && typeof resolveOpts === 'object' ? resolveOpts.envTemplatePath || null : null;
72
+ const scopedKv =
73
+ resolveOpts && typeof resolveOpts === 'object' && (resolveOpts.envKey !== undefined || resolveOpts.effective !== undefined)
74
+ ? { envKey: resolveOpts.envKey, effective: resolveOpts.effective }
75
+ : null;
61
76
  const os = require('os');
62
77
 
63
78
  let developerId = null;
@@ -77,9 +92,16 @@ async function resolveKvReferences(envTemplate, secrets, environment = 'local',
77
92
  const resolved = interpolateEnvVars(envTemplate, envVars);
78
93
  const missing = collectMissingSecrets(resolved, secrets, scopedKv);
79
94
  if (missing.length > 0) {
80
- const fileInfo = formatMissingSecretsFileInfo(secretsFilePaths);
81
- const resolveCommand = appName ? `aifabrix resolve ${appName}` : 'aifabrix resolve <app-name>';
82
- throw new Error(`Missing secrets: ${missing.join(', ')}${fileInfo}\n\nRun "${resolveCommand}" to generate missing secrets.`);
95
+ throw new Error(
96
+ buildMissingSecretsErrorMessage({
97
+ missing,
98
+ secrets,
99
+ secretsFilePaths,
100
+ appName,
101
+ envTemplatePath,
102
+ envTemplate
103
+ })
104
+ );
83
105
  }
84
106
  return replaceKvInContent(resolved, secrets, envVars, scopedKv);
85
107
  }
@@ -178,7 +200,11 @@ async function generateEnvContent(appName, secretsPath, environment = 'local', f
178
200
  const secrets = await loadSecrets(secretsPath, appName);
179
201
  const { runEnvKey, effective } = await buildScopedKvContext(appPath, options);
180
202
  const scopedKv = { envKey: runEnvKey, effective };
181
- let resolved = await resolveKvReferences(template, secrets, environment, secretsPaths, appName, scopedKv);
203
+ let resolved = await resolveKvReferences(template, secrets, environment, secretsPaths, appName, {
204
+ envKey: runEnvKey,
205
+ effective,
206
+ envTemplatePath: templatePath
207
+ });
182
208
  if (!secretsPath) {
183
209
  await materializeResolvedKvSecretsToUserLocal(template, secrets, scopedKv, options);
184
210
  }
@@ -227,42 +253,6 @@ function parseEnvContentToMap(content) {
227
253
  return map;
228
254
  }
229
255
 
230
- /**
231
- * Merges new .env content with existing .env: newly resolved content wins for keys it
232
- * defines (so project secrets take effect when re-running). Keys only in existing .env
233
- * are appended so manual additions are kept.
234
- *
235
- * @param {string} newContent - Newly generated .env content (from template + loadSecrets)
236
- * @param {Object.<string, string>} existingMap - Existing key-to-value map from current .env
237
- * @returns {string} Merged content: new values for keys in newContent, plus extra existing keys
238
- */
239
- function mergeEnvContentPreservingExisting(newContent, existingMap) {
240
- const lines = newContent.split(/\r?\n/);
241
- const newKeys = new Set();
242
- const out = [];
243
- for (const line of lines) {
244
- const trimmed = line.trim();
245
- if (!trimmed || trimmed.startsWith('#')) {
246
- out.push(line);
247
- continue;
248
- }
249
- const eq = trimmed.indexOf('=');
250
- if (eq > 0) {
251
- const key = trimmed.substring(0, eq).trim();
252
- newKeys.add(key);
253
- }
254
- out.push(line);
255
- }
256
- if (existingMap && Object.keys(existingMap).length > 0) {
257
- for (const key of Object.keys(existingMap)) {
258
- if (!newKeys.has(key)) {
259
- out.push(`${key}=${existingMap[key]}`);
260
- }
261
- }
262
- }
263
- return out.join('\n');
264
- }
265
-
266
256
  /**
267
257
  * Merges a key-value map into existing .env file content, preserving comments and blank lines.
268
258
  * For each KEY=value line in existing content, replaces value with newMap[KEY] when the key exists
@@ -320,15 +310,27 @@ function mergeEnvMapIntoContent(existingContent, newMap, options = {}) {
320
310
 
321
311
  /**
322
312
  * Resolves content to write for .env: merges with existing file when present.
313
+ * Uses {@link mergeEnvMapIntoContent} so new template keys are appended and comments in the
314
+ * existing file are preserved (unlike a full replace).
315
+ *
323
316
  * @param {string} resolved - Newly generated content
324
317
  * @param {string} pathToPreserve - Path to existing .env to merge from (or null)
318
+ * @param {Object} [options]
319
+ * @param {boolean} [options.freshEnv=false] - When true, write full resolved content (no merge)
325
320
  * @returns {string} Content to write
326
321
  */
327
- function resolveEnvContentToWrite(resolved, pathToPreserve) {
328
- if (!pathToPreserve || !fs.existsSync(pathToPreserve)) return resolved;
322
+ function resolveEnvContentToWrite(resolved, pathToPreserve, options = {}) {
323
+ if (options.freshEnv === true || !pathToPreserve || !fs.existsSync(pathToPreserve)) {
324
+ return resolved;
325
+ }
329
326
  const existingContent = fs.readFileSync(pathToPreserve, 'utf8');
330
- const existingMap = parseEnvContentToMap(existingContent);
331
- return mergeEnvContentPreservingExisting(resolved, existingMap);
327
+ const resolvedMap = parseEnvContentToMap(resolved);
328
+ let merged = mergeEnvMapIntoContent(existingContent, resolvedMap, { appendMissingFromNewMap: true });
329
+ if (options.pruneOrphanKv === true) {
330
+ const { content: pruned } = commentOrphanKvEnvLines(merged, new Set(Object.keys(resolvedMap)));
331
+ merged = pruned;
332
+ }
333
+ return merged;
332
334
  }
333
335
 
334
336
  /**
@@ -381,14 +383,18 @@ function resolveEnvContentToWrite(resolved, pathToPreserve) {
381
383
  async function writeResolvedEnv({ appName, envPath, resolved, variablesPath, secretsPath, opts }) {
382
384
  const preservePath = opts.preserveFromPath !== undefined && opts.preserveFromPath !== null ? opts.preserveFromPath : null;
383
385
  const pathToPreserve = preservePath !== null ? preservePath : envPath;
384
- const toWrite = resolveEnvContentToWrite(resolved, pathToPreserve);
386
+ const toWrite = resolveEnvContentToWrite(resolved, pathToPreserve, {
387
+ freshEnv: opts.freshEnv === true,
388
+ pruneOrphanKv: opts.envOnly === true && opts.freshEnv !== true
389
+ });
385
390
  fs.writeFileSync(envPath, toWrite, { mode: 0o600 });
386
391
 
387
392
  if (!opts.skipOutputPath) {
388
393
  const { processEnvVariables } = require('../utils/env-copy');
389
394
  await processEnvVariables(envPath, variablesPath, appName, secretsPath, {
390
395
  preferLocalEnvOutputPath: opts.preferLocalEnvOutputPath === true,
391
- appPath: opts.appPath || null
396
+ appPath: opts.appPath || null,
397
+ freshEnv: opts.freshEnv === true
392
398
  });
393
399
  }
394
400
  return envPath;
@@ -207,7 +207,16 @@ async function resolveAndGetEnvMap(appName, options = {}) {
207
207
  let content = await secrets.generateEnvContent(appName, secretsPath, environment, force);
208
208
  content = await injectRegistryTokens(content, secretsPath, appName);
209
209
  content = await injectBashPrefixedExportLines(content, secretsPath, appName);
210
- return parseEnvContentToMap(content);
210
+ const map = parseEnvContentToMap(content);
211
+ try {
212
+ const adminSecrets = require('./admin-secrets');
213
+ const { applyAdminSecretsPlatformOverlay } = require('./admin-secrets-env-overlay');
214
+ const adminObj = await adminSecrets.readAndDecryptAdminSecrets();
215
+ applyAdminSecretsPlatformOverlay(map, adminObj);
216
+ } catch {
217
+ // admin-secrets.env optional until up-infra/setup
218
+ }
219
+ return map;
211
220
  }
212
221
 
213
222
  module.exports = { resolveAndWriteEnvFile, resolveAndGetEnvMap };
@@ -43,6 +43,8 @@ async function syncLiteralKvSecretsFromCliOverrides(
43
43
  const val = ipc.generateValueFromCatalogEntry(key, entry, crypto, placeholderContext);
44
44
  await setSecretInStore(key, val);
45
45
  }
46
+ const { isSetupQuietOutput } = require('../utils/setup-quiet-output');
47
+ if (isSetupQuietOutput()) return;
46
48
  logger.log(
47
49
  `Updated ${keys.length} secret(s) in store (catalog literals using {{${placeholder}}}).`
48
50
  );
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Setup installation profile identifiers (`dev` / `pro`).
3
+ *
4
+ * @fileoverview Normalization for setup wizard profile (local install, not login environment)
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ /** @enum {string} */
12
+ const INSTALLATION_PROFILE = Object.freeze({
13
+ DEV: 'dev',
14
+ PRO: 'pro'
15
+ });
16
+
17
+ /**
18
+ * @param {unknown} value
19
+ * @returns {'dev'|'pro'}
20
+ */
21
+ function normalizeInstallationProfile(value) {
22
+ const raw = String(value ?? '')
23
+ .trim()
24
+ .toLowerCase();
25
+ if (raw === INSTALLATION_PROFILE.PRO || raw === 'production') {
26
+ return INSTALLATION_PROFILE.PRO;
27
+ }
28
+ return INSTALLATION_PROFILE.DEV;
29
+ }
30
+
31
+ /**
32
+ * @param {unknown} value
33
+ * @returns {boolean}
34
+ */
35
+ function isProInstallationProfile(value) {
36
+ return normalizeInstallationProfile(value) === INSTALLATION_PROFILE.PRO;
37
+ }
38
+
39
+ module.exports = {
40
+ INSTALLATION_PROFILE,
41
+ normalizeInstallationProfile,
42
+ isProInstallationProfile
43
+ };
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Setup platform topology mode (`single` | `full`).
3
+ *
4
+ * This is distinct from `setupInstallationProfile` (dev/pro password bundle) and from
5
+ * the login/run environment (`dev` | `tst` | `pro`).
6
+ *
7
+ * @fileoverview Setup platform mode normalization and defaults
8
+ * @author AI Fabrix Team
9
+ * @version 1.0.0
10
+ */
11
+
12
+ 'use strict';
13
+
14
+ /** @enum {string} */
15
+ const SETUP_PLATFORM_MODE = Object.freeze({
16
+ SINGLE: 'single',
17
+ FULL: 'full'
18
+ });
19
+
20
+ /**
21
+ * @param {unknown} value
22
+ * @returns {'single'|'full'}
23
+ */
24
+ function normalizeSetupPlatformMode(value) {
25
+ const raw = String(value ?? '')
26
+ .trim()
27
+ .toLowerCase();
28
+ if (raw === SETUP_PLATFORM_MODE.FULL) return SETUP_PLATFORM_MODE.FULL;
29
+ if (raw === 'all' || raw === 'full-platform' || raw === 'platform-full') return SETUP_PLATFORM_MODE.FULL;
30
+ return SETUP_PLATFORM_MODE.SINGLE;
31
+ }
32
+
33
+ /**
34
+ * Derived config flags for a chosen platform mode.
35
+ *
36
+ * - single: direct ports, no front door ingress
37
+ * - full: enable Traefik ingress + env-scoped resources
38
+ *
39
+ * @param {'single'|'full'} mode
40
+ * @returns {{ traefik: boolean, useEnvironmentScopedResources: boolean }}
41
+ */
42
+ function flagsForSetupPlatformMode(mode) {
43
+ const m = normalizeSetupPlatformMode(mode);
44
+ return {
45
+ traefik: m === SETUP_PLATFORM_MODE.FULL,
46
+ useEnvironmentScopedResources: m === SETUP_PLATFORM_MODE.FULL
47
+ };
48
+ }
49
+
50
+ module.exports = {
51
+ SETUP_PLATFORM_MODE,
52
+ normalizeSetupPlatformMode,
53
+ flagsForSetupPlatformMode
54
+ };
55
+
@@ -0,0 +1,45 @@
1
+ /**
2
+ * @fileoverview Debug log writer for agent trust CLI runs (plan 143).
3
+ */
4
+
5
+ 'use strict';
6
+
7
+ const chalk = require('chalk');
8
+ const path = require('path');
9
+ const logger = require('../utils/logger');
10
+ const { getIntegrationPath } = require('../utils/paths');
11
+ const { writeTestLog } = require('../utils/test-log-writer');
12
+
13
+ /**
14
+ * @async
15
+ * @param {string} appKey - Integration folder key
16
+ * @param {string} datasourceKey
17
+ * @param {Object} payload
18
+ * @returns {Promise<string|null>} Log path or null when skipped
19
+ */
20
+ async function writeTrustDebugLog(appKey, datasourceKey, payload) {
21
+ const logPath = await writeTestLog(
22
+ appKey,
23
+ payload,
24
+ `verify-trust-${datasourceKey}`,
25
+ path.dirname(getIntegrationPath(appKey))
26
+ );
27
+ return logPath;
28
+ }
29
+
30
+ /**
31
+ * @async
32
+ * @param {string} appKey
33
+ * @param {string} datasourceKey
34
+ * @param {Object} payload
35
+ */
36
+ async function writeTrustDebugLogAndPrint(appKey, datasourceKey, payload) {
37
+ const logPath = await writeTrustDebugLog(appKey, datasourceKey, payload);
38
+ logger.log(chalk.gray(` Debug log: ${logPath}`));
39
+ return logPath;
40
+ }
41
+
42
+ module.exports = {
43
+ writeTrustDebugLog,
44
+ writeTrustDebugLogAndPrint
45
+ };
@@ -0,0 +1,115 @@
1
+ /**
2
+ * @fileoverview Dataplane fetch paths for agent trust runs (POST validate / GET latest).
3
+ */
4
+
5
+ 'use strict';
6
+
7
+ const {
8
+ runAgentMetadataValidation,
9
+ getLatestAgentMetadataValidation
10
+ } = require('../api/agent-metadata-validation.api');
11
+ const { parseTrustTimeoutMs } = require('./agent-trust-timeout');
12
+ const { isAgentTrustMockEnabled, buildMockTrustRun } = require('./agent-trust-mock');
13
+ const { mapRunResponseToTrustRun, mapLatestResultToTrustRun } = require('./agent-trust-map');
14
+ const {
15
+ runWithAgentTrustWaitSpinner,
16
+ logAgentTrustWaitHintOnce
17
+ } = require('../utils/agent-trust-wait-ui');
18
+
19
+ function unwrapApiData(response) {
20
+ if (response && response.data !== undefined) return response.data;
21
+ return response;
22
+ }
23
+
24
+ /**
25
+ * @param {Object} options
26
+ * @returns {boolean}
27
+ */
28
+ function shouldPreferLatestRead(options = {}) {
29
+ if (options.revalidate === true) return false;
30
+ return options.summary === true;
31
+ }
32
+
33
+ /**
34
+ * @param {Error} err
35
+ * @returns {boolean}
36
+ */
37
+ function isLatestNotFoundError(err) {
38
+ const code = err && (err.statusCode || err.status);
39
+ if (code === 404) return true;
40
+ const msg = err && err.message ? String(err.message) : '';
41
+ return /no agent metadata validation/i.test(msg);
42
+ }
43
+
44
+ /**
45
+ * @async
46
+ * @param {Object} params
47
+ * @returns {Promise<Object>}
48
+ */
49
+ async function postValidateTrustRun(params) {
50
+ const { dataplaneUrl, datasourceKey, systemKey, authConfig, body, options } = params;
51
+ const timeoutMs = parseTrustTimeoutMs(options);
52
+ logAgentTrustWaitHintOnce(datasourceKey, timeoutMs);
53
+ const raw = await runWithAgentTrustWaitSpinner(
54
+ () =>
55
+ runAgentMetadataValidation(dataplaneUrl, datasourceKey, authConfig, body, { timeoutMs }),
56
+ { datasourceKey, timeoutMs }
57
+ );
58
+ return mapRunResponseToTrustRun({
59
+ datasourceKey,
60
+ systemKey,
61
+ runResponse: unwrapApiData(raw)
62
+ });
63
+ }
64
+
65
+ /**
66
+ * @async
67
+ * @param {Object} params
68
+ * @returns {Promise<Object>}
69
+ */
70
+ async function getLatestTrustRun(params) {
71
+ const { dataplaneUrl, datasourceKey, systemKey, authConfig, options } = params;
72
+ const timeoutMs = parseTrustTimeoutMs(options);
73
+ const raw = await getLatestAgentMetadataValidation(dataplaneUrl, datasourceKey, authConfig, {
74
+ timeoutMs
75
+ });
76
+ return mapLatestResultToTrustRun({
77
+ datasourceKey,
78
+ systemKey,
79
+ latestResult: unwrapApiData(raw)
80
+ });
81
+ }
82
+
83
+ /**
84
+ * @async
85
+ * @param {Object} params
86
+ * @returns {Promise<Object>}
87
+ */
88
+ async function fetchTrustRunFromDataplane(params) {
89
+ const { datasourceKey, systemKey, dataplaneUrl, authConfig, options } = params;
90
+ if (isAgentTrustMockEnabled()) {
91
+ return buildMockTrustRun(datasourceKey, systemKey);
92
+ }
93
+
94
+ const body = { forceRevalidate: options.revalidate === true };
95
+ if (options.peerDatasourceConfigs && typeof options.peerDatasourceConfigs === 'object') {
96
+ body.peerDatasourceConfigs = options.peerDatasourceConfigs;
97
+ }
98
+
99
+ if (!shouldPreferLatestRead(options)) {
100
+ return postValidateTrustRun({ dataplaneUrl, datasourceKey, systemKey, authConfig, body, options });
101
+ }
102
+
103
+ try {
104
+ return await getLatestTrustRun({ dataplaneUrl, datasourceKey, systemKey, authConfig, options });
105
+ } catch (err) {
106
+ if (!isLatestNotFoundError(err)) throw err;
107
+ return postValidateTrustRun({ dataplaneUrl, datasourceKey, systemKey, authConfig, body, options });
108
+ }
109
+ }
110
+
111
+ module.exports = {
112
+ shouldPreferLatestRead,
113
+ fetchTrustRunFromDataplane,
114
+ isLatestNotFoundError
115
+ };
@@ -0,0 +1,101 @@
1
+ /**
2
+ * @fileoverview Map dataplane agent metadata validation API payloads to CLI trust runs.
3
+ * @author AI Fabrix Team
4
+ * @version 1.0.0
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ /**
10
+ * @param {string} trustDecision
11
+ * @returns {'ok'|'warn'|'fail'}
12
+ */
13
+ function trustDecisionToRowStatus(trustDecision) {
14
+ const td = String(trustDecision || '').trim();
15
+ if (td === 'trusted') return 'ok';
16
+ if (td === 'usableWithWarnings') return 'warn';
17
+ return 'fail';
18
+ }
19
+
20
+ /**
21
+ * @param {Object} result - AgentMetadataValidationResult from dataplane
22
+ * @returns {string[]}
23
+ */
24
+ function highLevelWarningsFromResult(result) {
25
+ if (!result || !Array.isArray(result.findings)) return [];
26
+ return result.findings
27
+ .filter(f => f && (f.severity === 'warning' || f.severity === 'error'))
28
+ .slice(0, 8)
29
+ .map(f => {
30
+ const code = f.code ? String(f.code) : 'FINDING';
31
+ const msg = f.message ? String(f.message) : '';
32
+ return msg ? `${code} — ${msg}` : code;
33
+ });
34
+ }
35
+
36
+ /**
37
+ * @param {Object} params
38
+ * @param {string} params.datasourceKey
39
+ * @param {string} params.systemKey
40
+ * @param {Object} params.runResponse - POST run response body
41
+ * @returns {Object} AgentTrustRun-shaped object for CLI display/exit
42
+ */
43
+ function mapRunResponseToTrustRun({ datasourceKey, systemKey, runResponse }) {
44
+ const body = runResponse && typeof runResponse === 'object' ? runResponse : {};
45
+ const result = body.result && typeof body.result === 'object' ? body.result : {};
46
+ const trustDecision = result.trustDecision || 'pending';
47
+ return {
48
+ datasourceKey,
49
+ systemKey,
50
+ status: trustDecisionToRowStatus(trustDecision),
51
+ trustDecision,
52
+ validationStatus: result.status || 'pending',
53
+ confidence: typeof result.confidence === 'number' ? result.confidence : 0,
54
+ summary: result.summary || '',
55
+ validatedAt: result.validatedAt || '',
56
+ inputHash: result.inputHash || '',
57
+ contractVersion: result.contractVersion || '',
58
+ cacheHit: body.reused === true,
59
+ highLevelWarnings: highLevelWarningsFromResult(result),
60
+ findings: Array.isArray(result.findings) ? result.findings : [],
61
+ observedBusinessModel: result.observedBusinessModel || null,
62
+ runId: body.id || null
63
+ };
64
+ }
65
+
66
+ /**
67
+ * @param {Object} params
68
+ * @param {string} params.datasourceKey
69
+ * @param {string} params.systemKey
70
+ * @param {Object} params.latestResult - GET /agent-validation body
71
+ * @returns {Object}
72
+ */
73
+ function mapLatestResultToTrustRun({ datasourceKey, systemKey, latestResult }) {
74
+ const result = latestResult && typeof latestResult === 'object' ? latestResult : {};
75
+ const trustDecision = result.trustDecision || 'pending';
76
+ return {
77
+ datasourceKey,
78
+ systemKey,
79
+ status: trustDecisionToRowStatus(trustDecision),
80
+ trustDecision,
81
+ validationStatus: result.status || 'pending',
82
+ confidence: typeof result.confidence === 'number' ? result.confidence : 0,
83
+ summary: result.summary || '',
84
+ validatedAt: result.validatedAt || '',
85
+ inputHash: result.inputHash || '',
86
+ contractVersion: result.contractVersion || '',
87
+ cacheHit: true,
88
+ highLevelWarnings: highLevelWarningsFromResult(result),
89
+ findings: Array.isArray(result.findings) ? result.findings : [],
90
+ observedBusinessModel: result.observedBusinessModel || null,
91
+ runId: null,
92
+ readLatest: true
93
+ };
94
+ }
95
+
96
+ module.exports = {
97
+ trustDecisionToRowStatus,
98
+ highLevelWarningsFromResult,
99
+ mapRunResponseToTrustRun,
100
+ mapLatestResultToTrustRun
101
+ };
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @fileoverview Dev-only mock trust runs when AIFABRIX_AGENT_TRUST_MOCK=1 (plan 143).
3
+ * Not documented in user-facing CLI docs; for local CLI development without dataplane 404.5.
4
+ */
5
+
6
+ 'use strict';
7
+
8
+ /**
9
+ * @returns {boolean}
10
+ */
11
+ function isAgentTrustMockEnabled() {
12
+ return String(process.env.AIFABRIX_AGENT_TRUST_MOCK || '').trim() === '1';
13
+ }
14
+
15
+ /**
16
+ * @param {string} datasourceKey
17
+ * @param {string} systemKey
18
+ * @returns {Object}
19
+ */
20
+ function buildMockTrustRun(datasourceKey, systemKey) {
21
+ return {
22
+ datasourceKey,
23
+ systemKey,
24
+ status: 'warn',
25
+ trustDecision: 'usableWithWarnings',
26
+ validationStatus: 'warning',
27
+ confidence: 0.72,
28
+ summary: 'Mock trust run (AIFABRIX_AGENT_TRUST_MOCK=1)',
29
+ validatedAt: new Date().toISOString(),
30
+ inputHash: 'mock-input-hash',
31
+ contractVersion: '1.0.0',
32
+ cacheHit: false,
33
+ highLevelWarnings: ['MOCK_TRUST — set AIFABRIX_AGENT_TRUST_MOCK=0 for live dataplane validation'],
34
+ findings: [],
35
+ observedBusinessModel: null,
36
+ runId: 'mock-run-id',
37
+ mock: true
38
+ };
39
+ }
40
+
41
+ module.exports = {
42
+ isAgentTrustMockEnabled,
43
+ buildMockTrustRun
44
+ };