@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,101 @@
1
+ /**
2
+ * Structured audit logging for channel install (plan 152).
3
+ *
4
+ * @fileoverview Channel install audit events — no secrets in payloads
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const logger = require('../utils/logger');
12
+
13
+ /**
14
+ * @param {string} eventName
15
+ * @param {Object} payload
16
+ */
17
+ function emitChannelAuditEvent(eventName, payload) {
18
+ logger.log(
19
+ JSON.stringify({
20
+ event: eventName,
21
+ ...payload,
22
+ timestamp: new Date().toISOString()
23
+ })
24
+ );
25
+ }
26
+
27
+ /**
28
+ * @param {string} channelTarget
29
+ * @param {Object} details
30
+ */
31
+ function auditArtifactGenerated(channelTarget, details) {
32
+ emitChannelAuditEvent('channelArtifactGenerated', { channelTarget, ...details });
33
+ }
34
+
35
+ /**
36
+ * @param {string} channelTarget
37
+ * @param {Object} details
38
+ */
39
+ function auditConfigPatched(channelTarget, details) {
40
+ emitChannelAuditEvent('channelConfigPatched', { channelTarget, ...details });
41
+ }
42
+
43
+ /**
44
+ * @param {string} channelTarget
45
+ * @param {Object} details
46
+ */
47
+ function auditCredentialCreated(channelTarget, details) {
48
+ emitChannelAuditEvent('channelCredentialCreated', { channelTarget, ...details });
49
+ }
50
+
51
+ /**
52
+ * @param {string} channelTarget
53
+ * @param {Object} details
54
+ */
55
+ function auditCredentialUpdated(channelTarget, details) {
56
+ emitChannelAuditEvent('channelCredentialUpdated', { channelTarget, ...details });
57
+ }
58
+
59
+ /**
60
+ * @param {string} channelTarget
61
+ * @param {Object} details
62
+ */
63
+ function auditApprovalRequired(channelTarget, details) {
64
+ emitChannelAuditEvent('channelApprovalRequired', { channelTarget, ...details });
65
+ }
66
+
67
+ /**
68
+ * @param {string} channelTarget
69
+ * @param {Object} details
70
+ */
71
+ function auditApprovalCompleted(channelTarget, details) {
72
+ emitChannelAuditEvent('channelApprovalCompleted', { channelTarget, ...details });
73
+ }
74
+
75
+ /**
76
+ * @param {string} channelTarget
77
+ * @param {Object} details
78
+ */
79
+ function auditValidated(channelTarget, details) {
80
+ emitChannelAuditEvent('channelValidated', { channelTarget, ...details });
81
+ }
82
+
83
+ /**
84
+ * @param {string} channelTarget
85
+ * @param {Object} details
86
+ */
87
+ function auditFailed(channelTarget, details) {
88
+ emitChannelAuditEvent('channelFailed', { channelTarget, ...details });
89
+ }
90
+
91
+ module.exports = {
92
+ emitChannelAuditEvent,
93
+ auditArtifactGenerated,
94
+ auditConfigPatched,
95
+ auditCredentialCreated,
96
+ auditCredentialUpdated,
97
+ auditApprovalRequired,
98
+ auditApprovalCompleted,
99
+ auditValidated,
100
+ auditFailed
101
+ };
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Resolve controller, dataplane, and auth for channel install.
3
+ *
4
+ * @fileoverview Channel install auth context (plan 152)
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const config = require('../core/config');
12
+ const { resolveControllerUrl } = require('../utils/controller-url');
13
+ const { getDeploymentAuth } = require('../utils/token-manager');
14
+ const { resolveDataplaneUrl } = require('../utils/dataplane-resolver');
15
+
16
+ /**
17
+ * @async
18
+ * @param {string} channelTarget
19
+ * @param {{ silent?: boolean }} [opts]
20
+ * @returns {Promise<{ controllerUrl: string, environment: string, dataplaneUrl: string, authConfig: Object }>}
21
+ */
22
+ async function resolveChannelAuthContext(channelTarget, opts = {}) {
23
+ const controllerUrl = await resolveControllerUrl();
24
+ const environment = (await config.getEnvironment()) || 'dev';
25
+ const authConfig = await getDeploymentAuth(controllerUrl, environment, channelTarget);
26
+ if (!authConfig) {
27
+ throw new Error('Authentication required. Run "aifabrix login" first.');
28
+ }
29
+ const dataplaneUrl = await resolveDataplaneUrl(controllerUrl, environment, authConfig, {
30
+ silent: opts.silent === true
31
+ });
32
+ return { controllerUrl, environment, dataplaneUrl, authConfig };
33
+ }
34
+
35
+ module.exports = {
36
+ resolveChannelAuthContext
37
+ };
@@ -0,0 +1,200 @@
1
+ /**
2
+ * Channel credential matrix and provisioning (plan 152).
3
+ *
4
+ * @fileoverview Ensure channel credentials exist; push secrets from integration env
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const path = require('path');
12
+ const { listCredentials } = require('../api/credentials.api');
13
+ const { credentialSelection } = require('../api/wizard.api');
14
+ const { pushCredentialSecrets } = require('../utils/credential-secrets-env');
15
+ const { getIntegrationPath } = require('../utils/paths');
16
+ const {
17
+ auditCredentialCreated,
18
+ auditCredentialUpdated,
19
+ auditFailed
20
+ } = require('./channel-audit');
21
+
22
+ /** @type {Record<string, { method: string, displayName: string, credentialConfig: Object }>} */
23
+ const CREDENTIAL_SPECS = {
24
+ slack: {
25
+ method: 'hmac',
26
+ credentialConfig: {
27
+ type: 'hmac',
28
+ signingSecret: 'pending-channel-install',
29
+ algorithm: 'sha256',
30
+ signatureHeader: 'X-Slack-Signature',
31
+ timestampHeader: 'X-Slack-Request-Timestamp',
32
+ signaturePrefix: 'v0=',
33
+ timestampMaxAge: 300
34
+ }
35
+ },
36
+ 'teams-bot': {
37
+ method: 'oidc',
38
+ credentialConfig: {
39
+ type: 'oidc',
40
+ openIdConfigUrl: 'https://login.botframework.com/v1/.well-known/openid_configuration',
41
+ clientId: 'pending-channel-install',
42
+ validateSignature: true,
43
+ algorithms: ['RS256'],
44
+ clockSkewSeconds: 300
45
+ }
46
+ },
47
+ 'microsoft-copilot': {
48
+ method: 'oauth2',
49
+ credentialConfig: {
50
+ type: 'oauth2',
51
+ grantType: 'client_credentials',
52
+ tokenUrl: 'https://login.microsoftonline.com/common/oauth2/v2.0/token',
53
+ clientId: 'pending-channel-install',
54
+ clientSecret: 'pending-channel-install'
55
+ }
56
+ },
57
+ chatgpt: {
58
+ method: 'apiKey',
59
+ credentialConfig: {
60
+ type: 'apiKey',
61
+ apiKey: 'pending-channel-install',
62
+ headerName: 'Authorization',
63
+ prefix: 'Bearer'
64
+ }
65
+ },
66
+ 'web-embed': {
67
+ method: 'apiKey',
68
+ credentialConfig: {
69
+ type: 'apiKey',
70
+ apiKey: 'pending-channel-install',
71
+ headerName: 'Authorization',
72
+ prefix: 'Bearer'
73
+ }
74
+ }
75
+ };
76
+
77
+ /**
78
+ * @param {Object} response
79
+ * @returns {Object[]}
80
+ */
81
+ function extractCredentials(response) {
82
+ const body = response?.data ?? response;
83
+ const data = body?.data ?? body;
84
+ const items = data?.credentials ?? data?.items ?? (Array.isArray(data) ? data : []);
85
+ return Array.isArray(items) ? items : [];
86
+ }
87
+
88
+ /**
89
+ * @param {string} channelTarget
90
+ * @param {typeof import('./channel-targets').CHANNEL_TARGETS[string]} target
91
+ * @returns {{ method: ChannelCredentialMethod, displayName: string, credentialConfig: Object }}
92
+ */
93
+ function buildCredentialSpec(channelTarget, target) {
94
+ const base = CREDENTIAL_SPECS[channelTarget];
95
+ if (!base) {
96
+ throw new Error(`No credential spec for channel target "${channelTarget}"`);
97
+ }
98
+ return {
99
+ method: base.method,
100
+ displayName: `${target.key} assistant channel`,
101
+ credentialConfig: base.credentialConfig
102
+ };
103
+ }
104
+
105
+ /**
106
+ * @async
107
+ * @param {Object} ctx
108
+ * @param {string} credentialKey
109
+ * @returns {Promise<Object|null>}
110
+ */
111
+ async function findCredentialByKey(ctx, credentialKey) {
112
+ const response = await listCredentials(ctx.dataplaneUrl, ctx.authConfig, { pageSize: 200 });
113
+ const items = extractCredentials(response);
114
+ return items.find((item) => item.key === credentialKey || item.credentialKey === credentialKey) || null;
115
+ }
116
+
117
+ /**
118
+ * @async
119
+ * @param {Object} ctx
120
+ * @param {string} channelTarget
121
+ * @param {Object} target
122
+ * @returns {Promise<Object>}
123
+ */
124
+ async function createChannelCredential(ctx, channelTarget, target) {
125
+ const spec = buildCredentialSpec(channelTarget, target);
126
+ const payload = {
127
+ action: 'create',
128
+ credentialConfig: {
129
+ key: target.credentialKey,
130
+ displayName: spec.displayName,
131
+ description: 'Assistant channel credential (secrets via kv:// env.template)',
132
+ credentialConfig: spec.credentialConfig,
133
+ isActive: true
134
+ }
135
+ };
136
+ const response = await credentialSelection(ctx.dataplaneUrl, ctx.authConfig, payload);
137
+ auditCredentialCreated(channelTarget, { credentialKey: target.credentialKey, method: spec.method });
138
+ return { created: true, credentialIdOrKey: response?.data?.credentialIdOrKey || target.credentialKey };
139
+ }
140
+
141
+ /**
142
+ * @async
143
+ * @param {Object} ctx
144
+ * @param {string} channelTarget
145
+ * @returns {Promise<{ pushed: number }>}
146
+ */
147
+ async function pushIntegrationSecrets(ctx, channelTarget) {
148
+ const integrationDir = getIntegrationPath(channelTarget);
149
+ const envPath = path.join(integrationDir, '.env');
150
+ const result = await pushCredentialSecrets(ctx.dataplaneUrl, ctx.authConfig, {
151
+ envFilePath: envPath,
152
+ appName: channelTarget,
153
+ quiet: true
154
+ });
155
+ return { pushed: result?.pushed ?? 0, skipped: result?.skipped === true };
156
+ }
157
+
158
+ /**
159
+ * Ensure channel credential record exists; optionally push secrets from integration/.env.
160
+ * Does not rotate secrets when force is set (plan 152 V1).
161
+ *
162
+ * @async
163
+ * @param {Object} params
164
+ * @param {Object} params.ctx
165
+ * @param {string} params.channelTarget
166
+ * @param {Object} params.target
167
+ * @param {boolean} [params.force]
168
+ * @returns {Promise<Object>}
169
+ */
170
+ async function ensureChannelCredential(params) {
171
+ const { ctx, channelTarget, target, force = false } = params;
172
+ const existing = await findCredentialByKey(ctx, target.credentialKey);
173
+ if (existing) {
174
+ auditCredentialUpdated(channelTarget, {
175
+ credentialKey: target.credentialKey,
176
+ rotated: false,
177
+ force: force === true
178
+ });
179
+ const secretPush = await pushIntegrationSecrets(ctx, channelTarget);
180
+ return { existed: true, credentialKey: target.credentialKey, secretPush };
181
+ }
182
+
183
+ try {
184
+ const created = await createChannelCredential(ctx, channelTarget, target);
185
+ const secretPush = await pushIntegrationSecrets(ctx, channelTarget);
186
+ return { ...created, credentialKey: target.credentialKey, secretPush };
187
+ } catch (err) {
188
+ auditFailed(channelTarget, { phase: 'credential', error: err.message });
189
+ throw err;
190
+ }
191
+ }
192
+
193
+ module.exports = {
194
+ buildCredentialSpec,
195
+ extractCredentials,
196
+ findCredentialByKey,
197
+ createChannelCredential,
198
+ pushIntegrationSecrets,
199
+ ensureChannelCredential
200
+ };
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Environment-scoped assistant channel display names (plan 152).
3
+ *
4
+ * @fileoverview Base name (e.g. Elsa) → Elsa (dev) | Elsa (tst) | Elsa in production
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const ENV_SUFFIX_PATTERN = /\s+\((dev|tst|test|pro|prod|production)\)$/i;
12
+
13
+ /**
14
+ * Strip a trailing environment suffix so --name can be re-run safely.
15
+ * @param {string} name
16
+ * @returns {string}
17
+ */
18
+ function normalizeBaseChannelName(name) {
19
+ if (!name || typeof name !== 'string') {
20
+ throw new Error('Channel base name is required');
21
+ }
22
+ const trimmed = name.trim();
23
+ if (!trimmed) {
24
+ throw new Error('Channel base name is required');
25
+ }
26
+ return trimmed.replace(ENV_SUFFIX_PATTERN, '').trim();
27
+ }
28
+
29
+ /**
30
+ * @param {string} environment
31
+ * @returns {boolean}
32
+ */
33
+ function isProductionEnvironment(environment) {
34
+ const env = String(environment || '').toLowerCase();
35
+ return env === 'pro' || env === 'prod' || env === 'production';
36
+ }
37
+
38
+ /**
39
+ * Resolve customer-visible channel name for the active environment.
40
+ * @param {string} baseName - Canonical product name (e.g. Elsa)
41
+ * @param {string} environment - dev | tst | pro
42
+ * @returns {string}
43
+ */
44
+ function resolveChannelDisplayName(baseName, environment) {
45
+ const base = normalizeBaseChannelName(baseName);
46
+ const env = String(environment || 'dev').toLowerCase();
47
+
48
+ if (isProductionEnvironment(env)) {
49
+ return base;
50
+ }
51
+ if (env === 'dev') {
52
+ return `${base} (dev)`;
53
+ }
54
+ if (env === 'tst' || env === 'test') {
55
+ return `${base} (tst)`;
56
+ }
57
+ return `${base} (${env})`;
58
+ }
59
+
60
+ module.exports = {
61
+ normalizeBaseChannelName,
62
+ isProductionEnvironment,
63
+ resolveChannelDisplayName
64
+ };
@@ -0,0 +1,106 @@
1
+ /**
2
+ * External system channel config helpers (plan 152).
3
+ *
4
+ * @fileoverview Patch config.extensions.channel on deployed communication systems
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const { getExternalSystem, updateExternalSystem } = require('../api/external-systems.api');
12
+ const { unwrapApiData } = require('../utils/external-system-readiness-core');
13
+
14
+ /**
15
+ * @param {Object|null} system
16
+ * @returns {Object|null}
17
+ */
18
+ function getExistingChannelExtension(system) {
19
+ if (!system || typeof system !== 'object') return null;
20
+ const channel = system.config?.extensions?.channel;
21
+ return channel && typeof channel === 'object' ? channel : null;
22
+ }
23
+
24
+ /**
25
+ * @param {Object} params
26
+ * @param {typeof import('./channel-targets').CHANNEL_TARGETS[string]} target
27
+ * @param {string} params.name
28
+ * @param {string} params.baseName
29
+ * @param {string} params.description
30
+ * @param {string} params.artifactHash
31
+ * @param {string} params.status
32
+ * @returns {Object}
33
+ */
34
+ function buildChannelExtensionBlock(params, target) {
35
+ return {
36
+ type: target.channelType,
37
+ name: params.name,
38
+ baseName: params.baseName,
39
+ description: params.description,
40
+ capabilities: [...target.capabilities],
41
+ status: params.status,
42
+ artifactHash: params.artifactHash,
43
+ credentialKey: target.credentialKey
44
+ };
45
+ }
46
+
47
+ /**
48
+ * @param {Object} system
49
+ * @param {Object} channelBlock
50
+ * @returns {Object}
51
+ */
52
+ function mergeChannelIntoSystem(system, channelBlock) {
53
+ const config = system.config && typeof system.config === 'object' ? { ...system.config } : {};
54
+ const extensions =
55
+ config.extensions && typeof config.extensions === 'object' ? { ...config.extensions } : {};
56
+ extensions.channel = channelBlock;
57
+ config.extensions = extensions;
58
+ return { ...system, config, displayName: channelBlock.name };
59
+ }
60
+
61
+ /**
62
+ * @async
63
+ * @param {Object} ctx
64
+ * @param {string} ctx.dataplaneUrl
65
+ * @param {Object} ctx.authConfig
66
+ * @param {string} ctx.channelTarget
67
+ * @returns {Promise<Object>}
68
+ */
69
+ async function fetchCommunicationSystem(ctx) {
70
+ const res = await getExternalSystem(ctx.dataplaneUrl, ctx.channelTarget, ctx.authConfig);
71
+ const system = unwrapApiData(res);
72
+ if (!system || typeof system !== 'object') {
73
+ throw new Error(
74
+ `Communication external system "${ctx.channelTarget}" was not found. ` +
75
+ `Run: aifabrix deploy ${ctx.channelTarget}`
76
+ );
77
+ }
78
+ const kind = system.systemKind || system.systemKindKey;
79
+ if (kind && kind !== 'communication') {
80
+ throw new Error(
81
+ `External system "${ctx.channelTarget}" is not systemKind communication (found: ${kind}).`
82
+ );
83
+ }
84
+ return system;
85
+ }
86
+
87
+ /**
88
+ * @async
89
+ * @param {Object} ctx
90
+ * @param {Object} channelBlock
91
+ * @returns {Promise<Object>}
92
+ */
93
+ async function patchChannelExtension(ctx, channelBlock) {
94
+ const system = await fetchCommunicationSystem(ctx);
95
+ const merged = mergeChannelIntoSystem(system, channelBlock);
96
+ const res = await updateExternalSystem(ctx.dataplaneUrl, ctx.channelTarget, ctx.authConfig, merged);
97
+ return unwrapApiData(res) || merged;
98
+ }
99
+
100
+ module.exports = {
101
+ getExistingChannelExtension,
102
+ buildChannelExtensionBlock,
103
+ mergeChannelIntoSystem,
104
+ fetchCommunicationSystem,
105
+ patchChannelExtension
106
+ };