@aifabrix/builder 2.45.5 → 2.47.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 (355) 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/project-rules.mdc +1 -0
  4. package/.npmrc.token +1 -0
  5. package/.temp/jest-protection-convert/run-IFN2nv/.protection/hubspot-companies.json +1 -0
  6. package/.temp/jest-protection-convert/run-IvmKLO/.protection/hubspot-companies.yaml +17 -0
  7. package/.temp/jest-protection-convert/run-SdvblF/.protection/hubspot-companies.json +1 -0
  8. package/.temp/jest-protection-convert/run-b51TsW/.protection/hubspot-companies.json +1 -0
  9. package/.temp/jest-protection-convert/run-fiLmb1/.protection/hubspot-companies.json +1 -0
  10. package/.temp/jest-protection-convert/run-qYGHMU/.protection/hubspot-companies.yaml +17 -0
  11. package/.temp/jest-protection-fixtures/hubspot-Mq5re8/hubspot-companies.yaml +17 -0
  12. package/.temp/jest-protection-fixtures/hubspot-f3u4YL/hubspot-companies.yaml +17 -0
  13. package/.temp/jest-protection-fixtures/hubspot-iQtd1O/hubspot-companies.yaml +17 -0
  14. package/.temp/jest-protection-fixtures/hubspot-mdmz5M/hubspot-companies.yaml +17 -0
  15. package/.temp/jest-protection-fixtures/hubspot-qbKYxQ/hubspot-companies.yaml +17 -0
  16. package/.temp/jest-protection-fixtures/hubspot-yzlJy6/hubspot-companies.yaml +17 -0
  17. package/.temp/validation/summary.txt +5 -0
  18. package/README.md +43 -17
  19. package/integration/hubspot-test/test-artifacts/wizard-hubspot-credential-real.yaml +1 -1
  20. package/integration/hubspot-test/test-artifacts/wizard-hubspot-env-vars.yaml +1 -1
  21. package/jest.config.default.js +2 -1
  22. package/jest.config.isolated.js +2 -1
  23. package/jest.global-live-fabrix-hooks.js +36 -0
  24. package/jest.isolated-projects.js +146 -0
  25. package/jest.projects.js +65 -136
  26. package/lib/api/api-response-errors.js +124 -0
  27. package/lib/api/dataplane-health.api.js +19 -7
  28. package/lib/api/governance-scenario-pack.api.js +159 -0
  29. package/lib/api/index.js +43 -3
  30. package/lib/api/lifecycle.api.js +98 -0
  31. package/lib/api/pipeline.api.js +3 -1
  32. package/lib/api/records-bulk.api.js +14 -1
  33. package/lib/api/resource-types.api.js +107 -0
  34. package/lib/api/runtime-configuration.api.js +72 -0
  35. package/lib/api/types/resource-types.types.js +45 -0
  36. package/lib/api/user-groups.api.js +9 -9
  37. package/lib/api/users.api.js +8 -8
  38. package/lib/api/validation-runner.js +3 -1
  39. package/lib/api/wizard.api.js +10 -2
  40. package/lib/app/deploy-config.js +4 -1
  41. package/lib/app/down.js +78 -27
  42. package/lib/app/index.js +2 -2
  43. package/lib/app/push.js +4 -5
  44. package/lib/app/register.js +7 -4
  45. package/lib/app/run-env-compose.js +84 -30
  46. package/lib/app/run-resolve-image.js +2 -1
  47. package/lib/app/run-stop-containers.js +113 -0
  48. package/lib/app/run.js +1 -31
  49. package/lib/app/show-display.js +35 -0
  50. package/lib/app/show.js +32 -1
  51. package/lib/build/index.js +22 -5
  52. package/lib/build/miso-controller-npm-sdk-guard.js +25 -0
  53. package/lib/certification/sync-system-certification.js +13 -6
  54. package/lib/channels/add-channel.js +348 -0
  55. package/lib/channels/channel-artifact-generator.js +141 -0
  56. package/lib/channels/channel-audit.js +101 -0
  57. package/lib/channels/channel-auth-context.js +37 -0
  58. package/lib/channels/channel-credential.js +200 -0
  59. package/lib/channels/channel-display-name.js +64 -0
  60. package/lib/channels/channel-external-system.js +106 -0
  61. package/lib/channels/channel-integration-generator.js +274 -0
  62. package/lib/channels/channel-probe.js +89 -0
  63. package/lib/channels/channel-runtime-resolver.js +152 -0
  64. package/lib/channels/channel-status-display.js +141 -0
  65. package/lib/channels/channel-targets.js +115 -0
  66. package/lib/cli/index.js +20 -4
  67. package/lib/cli/infra-guided-auth.js +109 -0
  68. package/lib/cli/infra-guided.js +84 -81
  69. package/lib/cli/setup-app.help.js +0 -31
  70. package/lib/cli/setup-app.js +82 -5
  71. package/lib/cli/setup-app.test-commands.js +5 -57
  72. package/lib/cli/setup-auth.js +25 -0
  73. package/lib/cli/setup-certification-commands.js +147 -0
  74. package/lib/cli/setup-certification.help.js +141 -0
  75. package/lib/cli/setup-environment.js +19 -2
  76. package/lib/cli/setup-external-system-help.js +62 -0
  77. package/lib/cli/setup-external-system.js +25 -3
  78. package/lib/cli/setup-infra-up-dataplane-action.js +2 -2
  79. package/lib/cli/setup-infra-up-platform-action.js +2 -1
  80. package/lib/cli/setup-infra.js +9 -1
  81. package/lib/cli/setup-platform.js +6 -1
  82. package/lib/cli/setup-secrets.js +33 -1
  83. package/lib/cli/setup-utility-help-after.js +25 -2
  84. package/lib/cli/setup-utility-repair.js +198 -0
  85. package/lib/cli/setup-utility-resolve.js +44 -5
  86. package/lib/cli/setup-utility-validate.js +197 -0
  87. package/lib/cli/setup-utility.js +4 -239
  88. package/lib/commands/app-logs.js +54 -26
  89. package/lib/commands/app.js +41 -0
  90. package/lib/commands/auth-status-client-tokens.js +214 -0
  91. package/lib/commands/auth-status-dataplane-version.js +142 -68
  92. package/lib/commands/auth-status.js +43 -54
  93. package/lib/commands/channel.js +58 -0
  94. package/lib/commands/datasource-test-trust-cli.js +27 -23
  95. package/lib/commands/datasource-unified-test-cli.js +6 -3
  96. package/lib/commands/datasource-unified-test-cli.options.js +5 -1
  97. package/lib/commands/datasource.js +8 -8
  98. package/lib/commands/dev-show-display.js +8 -1
  99. package/lib/commands/governance-cli-shared.js +94 -0
  100. package/lib/commands/governance-command-action.js +132 -0
  101. package/lib/commands/governance-download-external.js +34 -0
  102. package/lib/commands/governance-generate-external.js +71 -0
  103. package/lib/commands/governance-upload-external.js +36 -0
  104. package/lib/commands/governance-verify-external.js +64 -0
  105. package/lib/commands/governance.js +144 -0
  106. package/lib/commands/identity-apply-sync.js +49 -8
  107. package/lib/commands/identity-group-cli.js +66 -26
  108. package/lib/commands/identity-membership-role-cache.js +58 -37
  109. package/lib/commands/identity-shared.js +22 -1
  110. package/lib/commands/identity-user-cli.js +80 -34
  111. package/lib/commands/lifecycle-command-action.js +123 -0
  112. package/lib/commands/lifecycle-external.js +268 -0
  113. package/lib/commands/login.js +11 -2
  114. package/lib/commands/repair-auth-apply.js +153 -0
  115. package/lib/commands/repair-auth-config.js +8 -13
  116. package/lib/commands/repair-changed-files.js +41 -0
  117. package/lib/commands/repair-datasource-com-v2.js +15 -0
  118. package/lib/commands/repair-datasource-keys.js +4 -1
  119. package/lib/commands/repair-datasource-run.js +59 -0
  120. package/lib/commands/repair-datasource-service-contract.js +206 -0
  121. package/lib/commands/repair-datasource-test-payload.js +259 -0
  122. package/lib/commands/repair-datasource.js +49 -64
  123. package/lib/commands/repair-env-template.js +76 -25
  124. package/lib/commands/repair-external-run.js +216 -0
  125. package/lib/commands/repair-openapi-sync.js +49 -4
  126. package/lib/commands/repair-persist.js +4 -0
  127. package/lib/commands/repair-rbac.js +52 -1
  128. package/lib/commands/repair-steps.js +160 -0
  129. package/lib/commands/repair-system-alignment.js +7 -4
  130. package/lib/commands/repair.js +29 -296
  131. package/lib/commands/resource-type.js +371 -0
  132. package/lib/commands/secrets-get.js +184 -0
  133. package/lib/commands/secrets-remove-all.js +3 -1
  134. package/lib/commands/setup-image-refresh.js +146 -0
  135. package/lib/commands/setup-modes.js +158 -162
  136. package/lib/commands/setup-platform-auth.js +76 -0
  137. package/lib/commands/setup-prompts-admin.js +244 -0
  138. package/lib/commands/setup-prompts-platform-mode.js +70 -0
  139. package/lib/commands/setup-prompts-validators.js +36 -0
  140. package/lib/commands/setup-prompts.js +24 -76
  141. package/lib/commands/setup-run-context.js +45 -0
  142. package/lib/commands/setup-spinners.js +39 -0
  143. package/lib/commands/setup.js +27 -5
  144. package/lib/commands/teardown.js +39 -0
  145. package/lib/commands/test-e2e-external.js +24 -8
  146. package/lib/commands/test-governance-external.js +3 -24
  147. package/lib/commands/test-trust-external.js +48 -100
  148. package/lib/commands/up-common.js +57 -13
  149. package/lib/commands/up-dataplane.js +56 -15
  150. package/lib/commands/upload-publish-context.js +75 -0
  151. package/lib/commands/upload-sidecar-followups.js +89 -0
  152. package/lib/commands/upload.js +113 -110
  153. package/lib/commands/verify-governance-combined-external.js +61 -0
  154. package/lib/commands/verify-governance-command-action.js +64 -0
  155. package/lib/commands/verify-governance-db.js +102 -0
  156. package/lib/commands/verify-governance-external.js +77 -0
  157. package/lib/commands/verify-governance-result-builders.js +71 -0
  158. package/lib/commands/verify-operations-command-action.js +68 -0
  159. package/lib/commands/verify-operations-external.js +268 -0
  160. package/lib/commands/verify-operations-persist.js +75 -0
  161. package/lib/commands/verify-operations-step-plan.js +68 -0
  162. package/lib/commands/verify-operations-steps.js +111 -0
  163. package/lib/commands/verify-trust-command-action.js +73 -0
  164. package/lib/commands/verify-trust-external.js +59 -0
  165. package/lib/commands/wizard-config-normalizer.js +43 -23
  166. package/lib/commands/wizard-core.js +2 -0
  167. package/lib/core/admin-password-generator.js +38 -0
  168. package/lib/core/admin-secrets-bundle.js +111 -0
  169. package/lib/core/admin-secrets-env-overlay.js +62 -0
  170. package/lib/core/admin-secrets.js +32 -4
  171. package/lib/core/config-attach-extensions.js +3 -0
  172. package/lib/core/config-platform-controller.js +44 -0
  173. package/lib/core/config-setup-installation-profile.js +42 -0
  174. package/lib/core/config-setup-platform-mode.js +46 -0
  175. package/lib/core/config.js +46 -36
  176. package/lib/core/secrets-admin-env.js +6 -2
  177. package/lib/core/secrets-ensure.js +4 -0
  178. package/lib/core/secrets-env-content.js +54 -48
  179. package/lib/core/secrets-env-write.js +10 -1
  180. package/lib/core/secrets-infra-placeholder-sync.js +2 -0
  181. package/lib/core/setup-installation-profile.js +43 -0
  182. package/lib/core/setup-platform-mode.js +90 -0
  183. package/lib/datasource/agent-trust-debug-log.js +1 -1
  184. package/lib/datasource/agent-trust-run.js +5 -3
  185. package/lib/datasource/audit-evidence-extract-debug.js +30 -18
  186. package/lib/datasource/audit-evidence-extract.js +7 -4
  187. package/lib/datasource/audit-evidence-verify-matrix.js +54 -26
  188. package/lib/datasource/bulk-loader-run-batches.js +15 -3
  189. package/lib/datasource/capability/capability-diff-slice.js +2 -2
  190. package/lib/datasource/capability/capability-manifest.js +254 -0
  191. package/lib/datasource/capability/capability-resolve.js +3 -4
  192. package/lib/datasource/capability/copy-operations.js +5 -3
  193. package/lib/datasource/capability/remove-operations.js +2 -1
  194. package/lib/datasource/capability/run-capability-copy.js +32 -4
  195. package/lib/datasource/capability/run-capability-diff.js +3 -3
  196. package/lib/datasource/capability/run-capability-dimension.js +2 -4
  197. package/lib/datasource/capability/run-capability-edit.js +4 -7
  198. package/lib/datasource/capability/run-capability-relate.js +2 -4
  199. package/lib/datasource/capability/run-capability-remove.js +2 -4
  200. package/lib/datasource/capability/validate-capability-slice.js +2 -1
  201. package/lib/datasource/datasource-identifier.js +2 -1
  202. package/lib/datasource/datasource-load-export-context.js +3 -0
  203. package/lib/datasource/datasource-validate-display.js +1 -1
  204. package/lib/datasource/field-reference-validator.js +24 -3
  205. package/lib/datasource/log-cleaner.js +2 -2
  206. package/lib/datasource/log-viewer.js +8 -8
  207. package/lib/datasource/orphan-profiles-validator.js +98 -0
  208. package/lib/datasource/test-e2e.js +4 -1
  209. package/lib/datasource/unified-validation-run-body.js +3 -1
  210. package/lib/datasource/unified-validation-run.js +5 -2
  211. package/lib/datasource/validate.js +41 -23
  212. package/lib/deployment/environment-poll-status.js +138 -0
  213. package/lib/deployment/environment.js +42 -34
  214. package/lib/external-system/download-helpers.js +87 -0
  215. package/lib/external-system/download.js +78 -138
  216. package/lib/external-system/generator.js +1 -55
  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.js +16 -21
  220. package/lib/generator/builders.js +11 -1
  221. package/lib/generator/external-controller-manifest.js +18 -0
  222. package/lib/generator/split.js +3 -1
  223. package/lib/generator/wizard.js +1 -28
  224. package/lib/governance/governance-cli-errors.js +96 -0
  225. package/lib/governance/governance-download-display.js +38 -0
  226. package/lib/governance/governance-run-display.js +215 -25
  227. package/lib/identity/fk-reference.js +65 -0
  228. package/lib/identity/identity-apply-core.js +13 -58
  229. package/lib/identity/identity-apply-phases.js +5 -1
  230. package/lib/identity/identity-display.js +243 -0
  231. package/lib/identity/identity-response-helpers.js +52 -0
  232. package/lib/identity/identity-sync-errors.js +62 -0
  233. package/lib/identity/resolve-user-id.js +129 -0
  234. package/lib/identity/username-default.js +31 -0
  235. package/lib/infrastructure/admin-secrets-apply.js +84 -0
  236. package/lib/infrastructure/admin-secrets-ensure.js +130 -0
  237. package/lib/infrastructure/admin-secrets-resolve.js +95 -0
  238. package/lib/infrastructure/admin-secrets-sync.js +91 -0
  239. package/lib/infrastructure/helpers.js +23 -129
  240. package/lib/infrastructure/index.js +5 -6
  241. package/lib/infrastructure/orphan-infra-docker-teardown.js +11 -5
  242. package/lib/lifecycle/certification-progress.js +231 -0
  243. package/lib/lifecycle/dataplane-ui-url.js +145 -0
  244. package/lib/lifecycle/exit-codes.js +24 -0
  245. package/lib/lifecycle/json-envelope.js +25 -0
  246. package/lib/lifecycle/lifecycle-governance-options.js +51 -0
  247. package/lib/lifecycle/logger-quiet.js +29 -0
  248. package/lib/lifecycle/open-api-published.js +59 -0
  249. package/lib/lifecycle/operations-readiness-metrics.js +101 -0
  250. package/lib/lifecycle/product-model.js +196 -0
  251. package/lib/lifecycle/report-display-trust.js +70 -0
  252. package/lib/lifecycle/report-display.js +472 -0
  253. package/lib/lifecycle/scenario-upload.js +191 -0
  254. package/lib/lifecycle/verify-step-progress.js +87 -0
  255. package/lib/parameters/infra-kv-discovery.js +27 -2
  256. package/lib/protection/auth-context.js +10 -4
  257. package/lib/resolvers/datasource-resolver.js +2 -3
  258. package/lib/resolvers/resource-type-file.js +159 -0
  259. package/lib/schema/application-schema.json +17 -1
  260. package/lib/schema/datasource-test-run.schema.json +89 -6
  261. package/lib/schema/deployment-rules.yaml +2 -1
  262. package/lib/schema/external-datasource.schema.json +2947 -2619
  263. package/lib/schema/external-system.schema.json +1418 -761
  264. package/lib/schema/infra.parameter.yaml +45 -0
  265. package/lib/schema/type/credential-field-registry.json +103 -97
  266. package/lib/schema/type/document-storage.json +9 -5
  267. package/lib/utils/aifabrix-test-runtime-guard.js +125 -0
  268. package/lib/utils/api.js +55 -31
  269. package/lib/utils/app-relative-path-env.js +112 -0
  270. package/lib/utils/app-run-containers.js +25 -2
  271. package/lib/utils/authentication-shape.js +224 -0
  272. package/lib/utils/build-copy.js +36 -5
  273. package/lib/utils/build-resolve-image.js +66 -12
  274. package/lib/utils/celery-companion-apps.js +53 -0
  275. package/lib/utils/cli-secrets-error-format.js +83 -21
  276. package/lib/utils/cli-utils.js +20 -4
  277. package/lib/utils/compose-celery-worker.js +23 -0
  278. package/lib/utils/compose-generate-docker-compose.js +13 -1
  279. package/lib/utils/compose-traefik-ingress-base.js +16 -1
  280. package/lib/utils/config-secrets-path.js +46 -0
  281. package/lib/utils/configuration-env-resolver.js +36 -0
  282. package/lib/utils/controller-url.js +88 -1
  283. package/lib/utils/credential-secrets-env-kv.js +216 -0
  284. package/lib/utils/credential-secrets-env.js +175 -257
  285. package/lib/utils/dataplane-resolver.js +18 -2
  286. package/lib/utils/declarative-url-ports.js +27 -4
  287. package/lib/utils/deployment-auth-mode.js +41 -0
  288. package/lib/utils/developer-volume-id.js +33 -0
  289. package/lib/utils/docker-build.js +1 -4
  290. package/lib/utils/env-copy.js +14 -9
  291. package/lib/utils/env-kv-orphan-lines.js +43 -0
  292. package/lib/utils/error-formatters/network-errors.js +13 -4
  293. package/lib/utils/external-env-template.js +11 -3
  294. package/lib/utils/external-system-readiness-core.js +10 -0
  295. package/lib/utils/external-system-readiness-display.js +80 -23
  296. package/lib/utils/external-system-validators.js +8 -2
  297. package/lib/utils/health-check.js +4 -1
  298. package/lib/utils/help-builder.js +13 -8
  299. package/lib/utils/keycloak-realm-ready.js +101 -0
  300. package/lib/utils/load-cip-capacity-display-config.js +61 -15
  301. package/lib/utils/manifest-source-emit.js +2 -0
  302. package/lib/utils/paths.js +25 -0
  303. package/lib/utils/pipeline-upload-auth-retry.js +82 -0
  304. package/lib/utils/platform-controller-url.js +157 -0
  305. package/lib/utils/platform-kv-ref.js +57 -0
  306. package/lib/utils/postgres-platform-bootstrap.js +199 -0
  307. package/lib/utils/postgres-wipe.js +9 -2
  308. package/lib/utils/resolve-env-mode.js +47 -0
  309. package/lib/utils/runtime-configuration-download.js +189 -0
  310. package/lib/utils/runtime-configuration-values.js +119 -0
  311. package/lib/utils/schema-loader.js +19 -4
  312. package/lib/utils/secrets-generator.js +31 -25
  313. package/lib/utils/secrets-missing-error.js +164 -0
  314. package/lib/utils/service-url-label.js +81 -0
  315. package/lib/utils/setup-quiet-output.js +25 -0
  316. package/lib/utils/template-helpers.js +15 -0
  317. package/lib/utils/token-manager-client-credentials.js +201 -0
  318. package/lib/utils/token-manager-messages.js +8 -0
  319. package/lib/utils/token-manager-refresh.js +12 -2
  320. package/lib/utils/token-manager.js +86 -105
  321. package/lib/utils/upload-pipeline-ui.js +12 -5
  322. package/lib/utils/upload-sync-options.js +42 -0
  323. package/lib/utils/url-declarative-public-base.js +21 -3
  324. package/lib/utils/url-declarative-vdir-inactive-env.js +14 -4
  325. package/lib/utils/validation-poll-ui.js +8 -0
  326. package/lib/utils/validation-run-stage.js +45 -0
  327. package/lib/utils/worker-sidecars.js +142 -0
  328. package/lib/validation/external-manifest-validator.js +2 -0
  329. package/lib/validation/runtime-configuration-rules.js +98 -0
  330. package/lib/validation/validate-display-dimensions.js +154 -0
  331. package/lib/validation/validate-display-sections.js +276 -0
  332. package/lib/validation/validate-display-steps.js +67 -0
  333. package/lib/validation/validate-display.js +24 -402
  334. package/package.json +1 -1
  335. package/templates/applications/dataplane/application.yaml +7 -1
  336. package/templates/applications/dataplane/env.template +50 -14
  337. package/templates/applications/dataplane/rbac.yaml +108 -1
  338. package/templates/applications/miso-controller/application.yaml +2 -2
  339. package/templates/applications/miso-controller/env.template +53 -122
  340. package/templates/applications/miso-controller/rbac.yaml +28 -13
  341. package/templates/channels/chatgpt/install.template.md.hbs +49 -0
  342. package/templates/channels/chatgpt/manifest.template.json.hbs +9 -0
  343. package/templates/channels/microsoft-copilot/install.template.md.hbs +49 -0
  344. package/templates/channels/microsoft-copilot/manifest.template.json.hbs +8 -0
  345. package/templates/channels/slack/install.template.md.hbs +49 -0
  346. package/templates/channels/slack/manifest.template.json.hbs +66 -0
  347. package/templates/channels/teams-bot/install.template.md.hbs +49 -0
  348. package/templates/channels/teams-bot/manifest.template.json.hbs +13 -0
  349. package/templates/channels/web-embed/install.template.md.hbs +49 -0
  350. package/templates/channels/web-embed/manifest.template.json.hbs +8 -0
  351. package/templates/external-system/README.md.hbs +74 -17
  352. package/templates/python/docker-compose.hbs +75 -18
  353. package/templates/typescript/docker-compose.hbs +70 -17
  354. package/lib/commands/test-governance-command-action.js +0 -55
  355. package/lib/commands/test-trust-command-action.js +0 -118
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Channel CLI commands (plan 152).
3
+ *
4
+ * @fileoverview Scaffold communication external systems for channel deploy step 1
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const chalk = require('chalk');
12
+ const logger = require('../utils/logger');
13
+ const { formatSuccessLine, formatBlockingError, sectionTitle, metadata } = require('../utils/cli-test-layout-chalk');
14
+ const { CHANNEL_TARGET_KEYS, isChannelTargetKey } = require('../channels/channel-targets');
15
+ const { scaffoldChannelIntegration } = require('../channels/channel-integration-generator');
16
+
17
+ /**
18
+ * @param {import('commander').Command} program
19
+ */
20
+ function setupChannelCommands(program) {
21
+ const channel = program
22
+ .command('channel')
23
+ .description('Assistant channel integration scaffolds (plan 152)');
24
+
25
+ channel
26
+ .command('scaffold <channelTarget>')
27
+ .description('Generate integration/<target>/ communication external system for deploy step 1')
28
+ .option('--force', 'Overwrite generated scaffold files when folder exists')
29
+ .option('--allow-experimental', 'Allow web-embed scaffold')
30
+ .action(async(channelTarget, options) => {
31
+ try {
32
+ if (!isChannelTargetKey(channelTarget)) {
33
+ throw new Error(
34
+ `Unknown channel target "${channelTarget}". Expected: ${CHANNEL_TARGET_KEYS.join(', ')}`
35
+ );
36
+ }
37
+ const result = scaffoldChannelIntegration(channelTarget, {
38
+ force: options.force === true,
39
+ allowExperimental: options.allowExperimental === true
40
+ });
41
+ logger.log(sectionTitle(`${channelTarget} channel scaffold`));
42
+ logger.log('');
43
+ logger.log(formatSuccessLine(`Created integration at ${result.integrationDir}`));
44
+ for (const file of result.files) {
45
+ logger.log(metadata(file));
46
+ }
47
+ logger.log('');
48
+ logger.log(chalk.white('Next steps:'));
49
+ logger.log(chalk.gray(` aifabrix deploy ${channelTarget}`));
50
+ logger.log(chalk.gray(` aifabrix app add-channel ${channelTarget} --name "Your Assistant"`));
51
+ } catch (error) {
52
+ logger.error(formatBlockingError(error.message || String(error)));
53
+ process.exit(1);
54
+ }
55
+ });
56
+ }
57
+
58
+ module.exports = { setupChannelCommands };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @fileoverview CLI wiring for `datasource test-trust` (404.5 / plan 143).
2
+ * @fileoverview CLI wiring for `datasource verify-trust` (404.5 / plan 143).
3
3
  * @author AI Fabrix Team
4
4
  * @version 1.0.0
5
5
  */
@@ -15,26 +15,27 @@ const { computeExitCodeFromTrustRun } = require('../utils/agent-trust-run-exit')
15
15
  const { attachDatasourceTestCommonOptions } = require('./datasource-unified-test-cli.options');
16
16
  const { cliOptsSkipSync } = require('../utils/cli-sync-options');
17
17
 
18
- function datasourceTestTrustHelpAfter() {
18
+ function datasourceVerifyTrustHelpAfter() {
19
19
  return `
20
20
  Examples:
21
- $ aifabrix datasource test-trust hubspot-companies
22
- $ aifabrix datasource test-trust hubspot-companies --app test-e2e-hubspot -v
23
- $ aifabrix datasource test-trust hubspot-companies --revalidate --strict
24
- $ aifabrix test-trust test-e2e-hubspot
21
+ $ aifabrix datasource verify-trust hubspot-companies
22
+ $ aifabrix datasource verify-trust hubspot-companies --app test-e2e-hubspot -v
23
+ $ aifabrix datasource verify-trust hubspot-companies --revalidate --strict
24
+ $ aifabrix verify-trust test-e2e-hubspot
25
25
 
26
26
  Notes:
27
27
  - Semantic trust only (agent metadata validation). For live API proof use test-e2e.
28
28
  - Local files are published before run unless --no-sync.
29
- - With --debug, JSON is saved under integration/<app>/logs/ (test-trust-<key>-*.json). View with: aifabrix datasource log-trust <key>
29
+ - With --debug, JSON is saved under integration/<app>/logs/ (verify-trust-<key>-*.json). View with: aifabrix datasource log-trust <key>
30
30
  `;
31
31
  }
32
32
 
33
- async function runDatasourceTestTrustOnce(datasourceKey, options) {
33
+ async function runDatasourceVerifyTrustOnce(datasourceKey, options) {
34
34
  const { trustRun, apiError } = await runDatasourceAgentTrust(datasourceKey, {
35
35
  app: options.app,
36
36
  environment: options.env,
37
37
  noSync: options.noSync === true,
38
+ force: options.force === true,
38
39
  revalidate: options.revalidate === true,
39
40
  summary: options.summary === true,
40
41
  timeout: options.timeout
@@ -42,7 +43,7 @@ async function runDatasourceTestTrustOnce(datasourceKey, options) {
42
43
  return { trustRun, apiError };
43
44
  }
44
45
 
45
- async function finalizeDatasourceTestTrust(datasourceKey, options, result) {
46
+ async function finalizeDatasourceVerifyTrust(datasourceKey, options, result) {
46
47
  const displayOpts = {
47
48
  json: options.json,
48
49
  verbose: options.verbose,
@@ -67,10 +68,10 @@ async function finalizeDatasourceTestTrust(datasourceKey, options, result) {
67
68
  return computeExitCodeFromTrustRun(result.trustRun, exitOpts);
68
69
  }
69
70
 
70
- async function datasourceTestTrustAction(datasourceKey, options, cmd) {
71
+ async function datasourceVerifyTrustAction(datasourceKey, options, cmd) {
71
72
  try {
72
73
  const merged = { ...options, noSync: cliOptsSkipSync(options, cmd) };
73
- const result = await runDatasourceTestTrustOnce(datasourceKey, merged);
74
+ const result = await runDatasourceVerifyTrustOnce(datasourceKey, merged);
74
75
  const { resolveAppKeyForDatasource } = require('../datasource/resolve-app');
75
76
  const { appKey } = await resolveAppKeyForDatasource(datasourceKey, options.app);
76
77
  if (options.debug) {
@@ -80,7 +81,7 @@ async function datasourceTestTrustAction(datasourceKey, options, cmd) {
80
81
  error: result.apiError ? result.apiError.message : null
81
82
  });
82
83
  }
83
- const exitCode = await finalizeDatasourceTestTrust(datasourceKey, merged, result);
84
+ const exitCode = await finalizeDatasourceVerifyTrust(datasourceKey, merged, result);
84
85
  process.exit(exitCode);
85
86
  } catch (err) {
86
87
  logger.error(formatBlockingError('Agent trust validation failed:'), err.message);
@@ -88,10 +89,7 @@ async function datasourceTestTrustAction(datasourceKey, options, cmd) {
88
89
  }
89
90
  }
90
91
 
91
- function setupDatasourceTestTrustCommand(datasource) {
92
- const cmd = datasource
93
- .command('test-trust <datasourceKey>')
94
- .description('Semantic agent metadata validation for one datasource (dataplane 404.5)');
92
+ function attachDatasourceTrustOptions(cmd) {
95
93
  attachDatasourceTestCommonOptions(cmd, {
96
94
  includeNoAsync: false,
97
95
  includePayload: false,
@@ -101,14 +99,20 @@ function setupDatasourceTestTrustCommand(datasource) {
101
99
  cmd
102
100
  .option('--no-sync', 'Skip publishing local integration files before validate')
103
101
  .option('--revalidate', 'Force new validation (ignore inputHash cache)')
104
- .option('--strict', 'Exit 1 unless trustDecision is trusted')
105
- .addHelpText('after', datasourceTestTrustHelpAfter())
106
- .action(datasourceTestTrustAction);
102
+ .option('--strict', 'Exit 1 unless trustDecision is trusted');
103
+ }
104
+
105
+ function setupDatasourceVerifyTrustCommand(datasource) {
106
+ const cmd = datasource
107
+ .command('verify-trust <datasourceKey>')
108
+ .description('Semantic agent metadata validation for one datasource');
109
+ attachDatasourceTrustOptions(cmd);
110
+ cmd.addHelpText('after', datasourceVerifyTrustHelpAfter()).action(datasourceVerifyTrustAction);
107
111
  }
108
112
 
109
113
  module.exports = {
110
- setupDatasourceTestTrustCommand,
111
- runDatasourceTestTrustOnce,
112
- finalizeDatasourceTestTrust,
113
- datasourceTestTrustAction
114
+ setupDatasourceVerifyTrustCommand,
115
+ runDatasourceVerifyTrustOnce,
116
+ finalizeDatasourceVerifyTrust,
117
+ datasourceVerifyTrustAction
114
118
  };
@@ -77,7 +77,8 @@ function buildDatasourceTestRunOpts(options) {
77
77
  timeout: options.timeout,
78
78
  async: options.async !== false,
79
79
  noAsync: options.async === false,
80
- sync: options.sync === true
80
+ sync: options.sync === true,
81
+ force: options.force === true
81
82
  };
82
83
  }
83
84
 
@@ -174,7 +175,8 @@ function buildIntegrationTestOpts(options) {
174
175
  debug: options.debug,
175
176
  verbose: options.verbose,
176
177
  timeout: options.timeout,
177
- sync: options.sync === true
178
+ sync: options.sync === true,
179
+ force: options.force === true
178
180
  };
179
181
  }
180
182
 
@@ -335,7 +337,8 @@ async function runDatasourceTestE2ECliOnce(datasourceKey, options) {
335
337
  minRecordCount: options.minRecordCount,
336
338
  timeout: options.timeout,
337
339
  capabilityKey: options.capabilityKey,
338
- sync: options.sync === true
340
+ sync: options.sync === true,
341
+ force: options.force === true
339
342
  });
340
343
  const unifiedModes =
341
344
  options.json || options.summary || options.warningsAsErrors || options.requireCert;
@@ -44,7 +44,7 @@ Examples:
44
44
  $ aifabrix datasource test-e2e hubspot-users --app test-e2e-hubspot -v --debug
45
45
  $ aifabrix datasource test-e2e my-documents-ds --min-vector-hits 7 -v --debug
46
46
  $ aifabrix datasource test-e2e hubspot-users -a test-e2e-hubspot --no-async
47
- $ aifabrix datasource test-e2e hubspot-users --sync --verify-audit -v
47
+ $ aifabrix datasource test-e2e hubspot-users --sync --force --verify-audit -v
48
48
  $ aifabrix datasource test-e2e hubspot-users read
49
49
 
50
50
  Notes:
@@ -129,6 +129,10 @@ function attachDatasourceTestCommonOptions(cmd, opts) {
129
129
  '--sync',
130
130
  'Publish local integration config to the dataplane before running the test (same as aifabrix upload <systemKey>; requires login)'
131
131
  )
132
+ .option(
133
+ '--force',
134
+ 'With --sync, pass force to upload (bypass active-datasource schema replacement guards; same as aifabrix upload --force)'
135
+ )
132
136
  .option('--json', 'Print raw DatasourceTestRun JSON to stdout')
133
137
  .option('--summary', 'Print compact summary line')
134
138
  .option('--warnings-as-errors', 'Exit 1 when root status is warn')
@@ -2,7 +2,7 @@
2
2
  * AI Fabrix Builder - Datasource Commands
3
3
  *
4
4
  * Handles datasource validation, listing, comparison, deployment, and online validation runs.
5
- * Subcommands `test`, `test-integration`, `test-e2e`, and `test-trust` call the dataplane; `log-*` read saved debug JSON locally; `clean-logs` removes those files. Permissions are summarized in `docs/commands/permissions.md`.
5
+ * Subcommands `test`, `test-integration`, `test-e2e`, and `verify-trust` call the dataplane; `log-*` read saved debug JSON locally; `clean-logs` removes those files. Permissions are summarized in `docs/commands/permissions.md`.
6
6
  *
7
7
  * @fileoverview Datasource management commands for AI Fabrix Builder
8
8
  * @author AI Fabrix Team
@@ -24,7 +24,7 @@ const {
24
24
  setupDatasourceTestIntegrationCommand,
25
25
  setupDatasourceTestE2ECommand
26
26
  } = require('./datasource-unified-test-cli');
27
- const { setupDatasourceTestTrustCommand } = require('./datasource-test-trust-cli');
27
+ const { setupDatasourceVerifyTrustCommand } = require('./datasource-test-trust-cli');
28
28
  const { setupDatasourceVerifyAuditCommand } = require('./datasource-verify-audit-cli');
29
29
  const { setupDatasourceLoadExportCommands } = require('./datasource-load-export-cli');
30
30
  const { setupDatasourceCapabilityCommands } = require('./datasource-capability');
@@ -44,7 +44,7 @@ Examples:
44
44
  $ af ds test-e2e <datasourceKey> --app <integrationFolder> -v
45
45
  $ af ds test-e2e <datasourceKey> --verify-audit
46
46
  $ af ds verify-audit <datasourceKey>
47
- $ af ds test-trust <datasourceKey> --app <integrationFolder> -v
47
+ $ af ds verify-trust <datasourceKey> --app <integrationFolder> -v
48
48
  $ af ds load <datasourceKey> --app <integrationFolder> --dry-run
49
49
  $ af ds export <datasourceKey> --app <integrationFolder> --format ndjson -v
50
50
  $ aifabrix datasource capability copy <file-or-key> --from create --as createBasicTrial --dry-run
@@ -97,7 +97,7 @@ Omit [prefix] to list all datasources for the active environment.
97
97
 
98
98
  function setupDatasourceValidateCommand(datasource) {
99
99
  datasource.command('validate <file-or-key>')
100
- .description('Validate datasource JSON (file path or datasource key under integration/<app>/)')
100
+ .description('Validate datasource YAML/JSON (file path or datasource key under integration/<app>/)')
101
101
  .addHelpText('after', DATASOURCE_VALIDATE_HELP_AFTER)
102
102
  .action(async(fileOrKey) => {
103
103
  try {
@@ -262,18 +262,18 @@ function setupDatasourceCleanLogsCommand(datasource) {
262
262
 
263
263
  function setupDatasourceLogTrustCommand(datasource) {
264
264
  datasource.command('log-trust <datasourceKey>')
265
- .description('Show agent trust log from datasource test-trust (latest test-trust-*.json or --file)')
265
+ .description('Show agent trust log from datasource verify-trust (latest verify-trust-*.json or --file)')
266
266
  .option(
267
267
  '-a, --app <app>',
268
268
  'Integration folder name (optional: resolve from cwd or datasource key if single match)'
269
269
  )
270
- .option('-f, --file <path>', 'Path to log file (default: latest test-trust log in app logs folder)')
270
+ .option('-f, --file <path>', 'Path to log file (default: latest verify-trust log in app logs folder)')
271
271
  .action(async(datasourceKey, options) => {
272
272
  try {
273
273
  await runLogViewer(datasourceKey, {
274
274
  app: options.app,
275
275
  file: options.file,
276
- logType: 'test-trust'
276
+ logType: 'verify-trust'
277
277
  });
278
278
  } catch (error) {
279
279
  logger.error(formatBlockingError('log-trust failed:'), error.message);
@@ -304,7 +304,7 @@ function setupDatasourceCommands(program) {
304
304
  setupDatasourceTestIntegrationCommand(datasource);
305
305
  setupDatasourceTestE2ECommand(datasource);
306
306
  setupDatasourceVerifyAuditCommand(datasource);
307
- setupDatasourceTestTrustCommand(datasource);
307
+ setupDatasourceVerifyTrustCommand(datasource);
308
308
  setupDatasourceLogE2ECommand(datasource);
309
309
  setupDatasourceLogIntegrationCommand(datasource);
310
310
  setupDatasourceLogTestCommand(datasource);
@@ -336,6 +336,8 @@ function logConfigurationSection(p) {
336
336
  logRow('Environment', p.environment);
337
337
  logRow('Controller', p.controller);
338
338
  logRow('Format', p.formatVal);
339
+ logRow('Platform mode', p.setupPlatformMode);
340
+ logRow('Traefik', p.traefikEnabled ? 'on' : 'off');
339
341
  logRow('Scoped resources', p.scopedResourcesLabel);
340
342
  logRow('URLs registry', p.urlsLocalPath);
341
343
  if (!p.hasRemote) {
@@ -386,11 +388,12 @@ async function loadDevShowData(devIdStr) {
386
388
  const devIdNum = parseInt(devIdStr, 10);
387
389
  const ports = devConfig.getDevPorts(Number.isNaN(devIdNum) ? 0 : devIdNum);
388
390
  const [
389
- environment, tlsEnabled, controller, formatRaw, useScoped, secretsRaw,
391
+ environment, tlsEnabled, controller, formatRaw, useScoped, secretsRaw, setupPlatformMode, traefikEnabled,
390
392
  remoteServer, dockerEndpoint, dockerTlsSkipVerify, mutagenFolder, syncSshUser, syncSshHost
391
393
  ] = await Promise.all([
392
394
  config.getCurrentEnvironment(), config.getTlsEnabled(), config.getControllerUrl(),
393
395
  config.getFormat(), config.getUseEnvironmentScopedResources(), config.getAifabrixSecretsPath(),
396
+ config.getSetupPlatformMode(), config.getTraefikEnabled(),
394
397
  config.getRemoteServer(), config.getDockerEndpoint(), config.getDockerTlsSkipVerify(),
395
398
  config.getUserMutagenFolder(), config.getSyncSshUser(), config.getSyncSshHost()
396
399
  ]);
@@ -410,6 +413,8 @@ async function loadDevShowData(devIdStr) {
410
413
  controller,
411
414
  formatVal: formatRaw ?? null,
412
415
  scopedResourcesLabel,
416
+ setupPlatformMode,
417
+ traefikEnabled,
413
418
  workResolved,
414
419
  homeResolved,
415
420
  secretsMain,
@@ -446,6 +451,8 @@ function renderDevShow(data) {
446
451
  tlsEnabled: data.tlsEnabled,
447
452
  controller: data.controller,
448
453
  formatVal: data.formatVal,
454
+ setupPlatformMode: data.setupPlatformMode,
455
+ traefikEnabled: data.traefikEnabled,
449
456
  scopedResourcesLabel: data.scopedResourcesLabel,
450
457
  urlsLocalPath: data.urlsLocalPath,
451
458
  hasRemote: data.hasRemote,
@@ -0,0 +1,94 @@
1
+ /**
2
+ * @fileoverview Shared helpers for governance * CLI commands (424.0).
3
+ */
4
+
5
+ 'use strict';
6
+
7
+ const {
8
+ resolveExternalIntegrationContext,
9
+ syncLocalIfRequested
10
+ } = require('./test-e2e-external');
11
+ const { resolveIntegrationAuth } = require('../external-system/integration-auth-context');
12
+ const { cliOptsSkipSync } = require('../utils/cli-sync-options');
13
+ const { fetchDataplaneGeneralHealth } = require('../api/dataplane-health.api');
14
+ const { formatNetworkError } = require('../utils/api-error-handler');
15
+
16
+ /**
17
+ * @param {Object} options
18
+ * @param {string[]} [options.subjectUserIds]
19
+ * @param {string[]} [options.subjectEmails]
20
+ * @returns {Array<{ subjectUserId?: string, subjectEmail?: string }>}
21
+ */
22
+ function buildSubjectsFromOptions(options) {
23
+ const subjects = [];
24
+ const userIds = options.subjectUserIds || [];
25
+ const emails = options.subjectEmails || [];
26
+ for (const subjectUserId of userIds) {
27
+ const id = String(subjectUserId || '').trim();
28
+ if (id) subjects.push({ subjectUserId: id });
29
+ }
30
+ for (const subjectEmail of emails) {
31
+ const email = String(subjectEmail || '').trim();
32
+ if (email) subjects.push({ subjectEmail: email });
33
+ }
34
+ return subjects;
35
+ }
36
+
37
+ /**
38
+ * Fail fast when dataplane health is unreachable (avoids misleading API validation errors).
39
+ * @async
40
+ * @param {string} dataplaneUrl
41
+ * @returns {Promise<void>}
42
+ */
43
+ async function assertDataplaneReachable(dataplaneUrl) {
44
+ const base = String(dataplaneUrl || '').replace(/\/$/, '');
45
+ const snapshot = await fetchDataplaneGeneralHealth(base, { timeoutMs: 8000 });
46
+ if (snapshot) {
47
+ return;
48
+ }
49
+ const endpointUrl = `${base}/api/v1/health`;
50
+ const err = new Error(`Cannot reach dataplane at ${base}`);
51
+ err.network = true;
52
+ err.serviceLabel = 'dataplane';
53
+ err.endpointUrl = endpointUrl;
54
+ err.formatted = formatNetworkError(err.message, {
55
+ endpointUrl,
56
+ serviceLabel: 'dataplane'
57
+ });
58
+ throw err;
59
+ }
60
+
61
+ /**
62
+ * @async
63
+ * @param {string} systemKey
64
+ * @param {Object} options
65
+ * @returns {Promise<{ resolvedKey: string, keys: string[], authConfig: Object, dataplaneUrl: string }>}
66
+ */
67
+ async function resolveGovernanceIntegrationContext(systemKey, options) {
68
+ const { systemKey: resolvedKey, keys } = resolveExternalIntegrationContext(systemKey);
69
+ if (options.authConfig && options.dataplaneUrl) {
70
+ return {
71
+ resolvedKey,
72
+ keys,
73
+ authConfig: options.authConfig,
74
+ dataplaneUrl: options.dataplaneUrl
75
+ };
76
+ }
77
+ if (!cliOptsSkipSync(options)) {
78
+ const uploadCtx = await syncLocalIfRequested(resolvedKey, options);
79
+ if (uploadCtx?.authConfig && uploadCtx?.dataplaneUrl) {
80
+ options.authConfig = uploadCtx.authConfig;
81
+ options.dataplaneUrl = uploadCtx.dataplaneUrl;
82
+ options.silentResolve = true;
83
+ }
84
+ }
85
+ const { authConfig, dataplaneUrl } = await resolveIntegrationAuth(resolvedKey, options);
86
+ await assertDataplaneReachable(dataplaneUrl);
87
+ return { resolvedKey, keys, authConfig, dataplaneUrl };
88
+ }
89
+
90
+ module.exports = {
91
+ buildSubjectsFromOptions,
92
+ assertDataplaneReachable,
93
+ resolveGovernanceIntegrationContext
94
+ };
@@ -0,0 +1,132 @@
1
+ /**
2
+ * @fileoverview CLI actions for `aifabrix governance *` (424.0).
3
+ */
4
+
5
+ 'use strict';
6
+
7
+ const logger = require('../utils/logger');
8
+ const { handleCommandError } = require('../utils/cli-utils');
9
+ const { runGovernanceGenerateForExternalSystem } = require('./governance-generate-external');
10
+ const { runGovernanceVerifyForExternalSystem } = require('./governance-verify-external');
11
+ const { runGovernanceUploadForExternalSystem } = require('./governance-upload-external');
12
+ const { runGovernanceDownloadForExternalSystem } = require('./governance-download-external');
13
+ const { displayVerifyGovernanceTTY } = require('../lifecycle/report-display');
14
+ const { exitCodeFromVerdict } = require('../lifecycle/exit-codes');
15
+ const { buildJsonEnvelope } = require('../lifecycle/json-envelope');
16
+ const { formatSuccessLine } = require('../utils/cli-test-layout-chalk');
17
+
18
+ /**
19
+ * Commander repeatable-option collector. Splits comma-separated values so both
20
+ * `--flag a --flag b` and `--flag a,b` work.
21
+ * @param {string} value
22
+ * @param {string[]} previous
23
+ * @returns {string[]}
24
+ */
25
+ function collectString(value, previous) {
26
+ const parts = String(value)
27
+ .split(',')
28
+ .map(entry => entry.trim())
29
+ .filter(Boolean);
30
+ return previous.concat(parts.length > 0 ? parts : [String(value).trim()].filter(Boolean));
31
+ }
32
+
33
+ function normalizeGovernanceOptions(options, cmd) {
34
+ const parent = cmd && cmd.parent ? cmd.parent.opts() : {};
35
+ return {
36
+ env: options.env || parent.env || 'dev',
37
+ verbose: options.verbose === true || parent.verbose === true,
38
+ noSync: options.noSync === true || parent.noSync === true,
39
+ force: options.force === true || parent.force === true,
40
+ json: options.json === true || parent.json === true,
41
+ pack: options.pack,
42
+ app: options.app,
43
+ scenarioIds: options.scenario || [],
44
+ certificationProfile: options.certificationProfile || 'bronze',
45
+ subjectUserIds: options.subjectUserId || [],
46
+ subjectEmails: options.subjectEmail || [],
47
+ maxSamplesPerPartition: options.maxSamplesPerPartition
48
+ };
49
+ }
50
+
51
+ async function governanceGenerateHandler(systemKey, options, cmd) {
52
+ try {
53
+ const opts = normalizeGovernanceOptions(options, cmd);
54
+ const result = await runGovernanceGenerateForExternalSystem(systemKey, opts);
55
+ if (opts.json) {
56
+ logger.log(JSON.stringify(buildJsonEnvelope(result, opts.verbose), null, 2));
57
+ return;
58
+ }
59
+ for (const row of result.results || []) {
60
+ logger.log(
61
+ formatSuccessLine(
62
+ `${row.datasourceKey}: pack v${row.packVersion} (${row.scenarioCount} scenarios)`
63
+ )
64
+ );
65
+ }
66
+ } catch (error) {
67
+ handleCommandError(error, 'governance generate');
68
+ process.exit(3);
69
+ }
70
+ }
71
+
72
+ async function governanceVerifyHandler(systemKey, options, cmd) {
73
+ try {
74
+ const opts = normalizeGovernanceOptions(options, cmd);
75
+ const result = await runGovernanceVerifyForExternalSystem(systemKey, opts);
76
+ if (opts.json) {
77
+ logger.log(JSON.stringify(buildJsonEnvelope(result, opts.verbose), null, 2));
78
+ } else {
79
+ displayVerifyGovernanceTTY(result.systemKey, result, { details: opts.verbose });
80
+ }
81
+ const exitCode = exitCodeFromVerdict(result.verdict);
82
+ if (exitCode !== 0) {
83
+ process.exit(exitCode);
84
+ }
85
+ } catch (error) {
86
+ handleCommandError(error, 'governance verify');
87
+ process.exit(3);
88
+ }
89
+ }
90
+
91
+ async function governanceUploadHandler(systemKey, options, cmd) {
92
+ try {
93
+ const opts = normalizeGovernanceOptions(options, cmd);
94
+ const result = await runGovernanceUploadForExternalSystem(systemKey, opts);
95
+ if (opts.json) {
96
+ logger.log(JSON.stringify(buildJsonEnvelope(result, opts.verbose), null, 2));
97
+ return;
98
+ }
99
+ logger.log(formatSuccessLine(`Uploaded ${result.uploaded} scenario pack(s)`));
100
+ } catch (error) {
101
+ if (error.friendlyHint) {
102
+ logger.log(error.friendlyHint);
103
+ }
104
+ handleCommandError(error, 'governance upload');
105
+ process.exit(3);
106
+ }
107
+ }
108
+
109
+ async function governanceDownloadHandler(systemKey, options, cmd) {
110
+ try {
111
+ const opts = normalizeGovernanceOptions(options, cmd);
112
+ opts.noSync = true;
113
+ const result = await runGovernanceDownloadForExternalSystem(systemKey, opts);
114
+ if (opts.json) {
115
+ logger.log(JSON.stringify(buildJsonEnvelope(result, opts.verbose), null, 2));
116
+ return;
117
+ }
118
+ logger.log(formatSuccessLine(`Downloaded ${result.written} scenario pack(s)`));
119
+ } catch (error) {
120
+ handleCommandError(error, 'governance download');
121
+ process.exit(3);
122
+ }
123
+ }
124
+
125
+ module.exports = {
126
+ collectString,
127
+ normalizeGovernanceOptions,
128
+ governanceGenerateHandler,
129
+ governanceVerifyHandler,
130
+ governanceUploadHandler,
131
+ governanceDownloadHandler
132
+ };
@@ -0,0 +1,34 @@
1
+ /**
2
+ * @fileoverview governance download — pull packs to integration/<systemKey>/scenarios/ (424.0).
3
+ */
4
+
5
+ 'use strict';
6
+
7
+ const { downloadGovernanceScenarioPacks } = require('../lifecycle/scenario-upload');
8
+ const { resolveGovernanceIntegrationContext } = require('./governance-cli-shared');
9
+
10
+ /**
11
+ * @async
12
+ * @param {string} systemKey
13
+ * @param {Object} options
14
+ * @returns {Promise<Object>}
15
+ */
16
+ async function runGovernanceDownloadForExternalSystem(systemKey, options = {}) {
17
+ const { resolvedKey, keys, authConfig, dataplaneUrl } =
18
+ await resolveGovernanceIntegrationContext(systemKey, options);
19
+ const written = await downloadGovernanceScenarioPacks(
20
+ resolvedKey,
21
+ keys,
22
+ dataplaneUrl,
23
+ authConfig
24
+ );
25
+ return {
26
+ systemKey: resolvedKey,
27
+ command: 'governance download',
28
+ written
29
+ };
30
+ }
31
+
32
+ module.exports = {
33
+ runGovernanceDownloadForExternalSystem
34
+ };
@@ -0,0 +1,71 @@
1
+ /**
2
+ * @fileoverview governance generate — dataplane POST generate per datasource (424.0).
3
+ */
4
+
5
+ 'use strict';
6
+
7
+ const { generateDatasourceGovernancePack } = require('../api/governance-scenario-pack.api');
8
+ const {
9
+ buildSubjectsFromOptions,
10
+ resolveGovernanceIntegrationContext
11
+ } = require('./governance-cli-shared');
12
+ const { runWithVerifyStepProgress } = require('../lifecycle/verify-step-progress');
13
+
14
+ /**
15
+ * @async
16
+ * @param {string} systemKey
17
+ * @param {Object} options
18
+ * @returns {Promise<Object>}
19
+ */
20
+ async function runGovernanceGenerateForExternalSystem(systemKey, options = {}) {
21
+ const subjects = buildSubjectsFromOptions(options);
22
+ if (subjects.length === 0) {
23
+ throw new Error(
24
+ 'At least one --subject-user-id or --subject-email is required for governance generate'
25
+ );
26
+ }
27
+
28
+ const { resolvedKey, keys, authConfig, dataplaneUrl } =
29
+ await resolveGovernanceIntegrationContext(systemKey, options);
30
+
31
+ const profile = (options.certificationProfile || 'bronze').trim().toLowerCase();
32
+ const maxSamples = Number(options.maxSamplesPerPartition) || 25;
33
+
34
+ const results = await runWithVerifyStepProgress(
35
+ 'Generating governance scenario packs',
36
+ async progress => {
37
+ const rows = [];
38
+ for (let index = 0; index < keys.length; index += 1) {
39
+ const dsKey = keys[index];
40
+ if (typeof progress.setLabel === 'function') {
41
+ progress.setLabel(`Generating pack: ${dsKey} (${index + 1}/${keys.length})`);
42
+ }
43
+ const row = await generateDatasourceGovernancePack(
44
+ dataplaneUrl,
45
+ authConfig,
46
+ dsKey,
47
+ {
48
+ certificationProfile: profile,
49
+ subjects,
50
+ systemKey: resolvedKey,
51
+ maxSamplesPerPartition: maxSamples
52
+ }
53
+ );
54
+ rows.push({ datasourceKey: dsKey, ...row });
55
+ }
56
+ return rows;
57
+ },
58
+ options
59
+ );
60
+
61
+ return {
62
+ systemKey: resolvedKey,
63
+ command: 'governance generate',
64
+ generated: results.length,
65
+ results
66
+ };
67
+ }
68
+
69
+ module.exports = {
70
+ runGovernanceGenerateForExternalSystem
71
+ };