@aifabrix/builder 2.49.2 → 2.51.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 (459) hide show
  1. package/.cursor/plans/157.1-security-quality-violations-by-type.csv +374 -0
  2. package/.cursor/rules/assistant-driven-integration-build.mdc +40 -0
  3. package/.cursor/rules/deploy-rules/docker-image-ip-policy.mdc +49 -0
  4. package/.cursor/rules/plan-rules/application-lifecycle.mdc +30 -0
  5. package/.cursor/rules/plan-rules/plan-frontmatter.mdc +35 -0
  6. package/.cursor/rules/plan-rules/plan-lifecycle.mdc +31 -0
  7. package/.cursor/rules/plan-rules/plan-validation-gate.mdc +34 -0
  8. package/.cursor/skills/README.md +1 -0
  9. package/.dockerignore +52 -0
  10. package/.eslintignore +22 -0
  11. package/README.md +2 -0
  12. package/bin/builder-api-cleanup.js +26 -0
  13. package/bin/builder-api-nest.js +10 -0
  14. package/bin/builder-api-spike.js +19 -0
  15. package/enterprise-knowledge/README.md +50 -0
  16. package/enterprise-knowledge/enterprise-integration-lifecycle/README.md +22 -0
  17. package/enterprise-knowledge/enterprise-integration-lifecycle/application.json +15 -0
  18. package/enterprise-knowledge/enterprise-integration-lifecycle/deploy.js +69 -0
  19. package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-deploy.json +52 -0
  20. package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-system.json +29 -0
  21. package/enterprise-knowledge/enterprise-integration-lifecycle/env.template +2 -0
  22. package/integration/README.md +81 -0
  23. package/integration/github/README.md +53 -0
  24. package/integration/github/application.json +21 -0
  25. package/integration/github/deploy.js +72 -0
  26. package/integration/github/env.template +11 -0
  27. package/integration/github/github-datasource-issue-comments.json +239 -0
  28. package/integration/github/github-datasource-issues.json +399 -0
  29. package/integration/github/github-datasource-repository.json +354 -0
  30. package/integration/github/github-deploy.json +1202 -0
  31. package/integration/github/github-system.json +82 -0
  32. package/integration/hubspot-test/README.md +1 -1
  33. package/integration/hubspot-test/create-hubspot.js +1 -16
  34. package/jest.isolated-projects.js +31 -1
  35. package/jest.projects.js +87 -1
  36. package/lib/api/dev-server-https.js +1 -1
  37. package/lib/api/enterprise-knowledge.api.js +63 -0
  38. package/lib/api/evidence-kinds.api.js +128 -0
  39. package/lib/api/evidence.api.js +172 -0
  40. package/lib/api/external-systems.api.js +8 -2
  41. package/lib/api/pipeline.api.js +5 -1
  42. package/lib/api/resource-types.api.js +5 -4
  43. package/lib/api/roles.api.js +121 -0
  44. package/lib/api/types/enterprise-knowledge.types.js +46 -0
  45. package/lib/api/types/evidence-kinds.types.js +42 -0
  46. package/lib/api/types/evidence.types.js +67 -0
  47. package/lib/api/types/resource-types.types.js +2 -0
  48. package/lib/api/types/roles.types.js +36 -0
  49. package/lib/app/certification-verify-rows.js +1 -1
  50. package/lib/app/controller-application-filter.js +36 -0
  51. package/lib/app/deploy.js +1 -1
  52. package/lib/app/list-external-systems.js +130 -0
  53. package/lib/app/list.js +20 -8
  54. package/lib/app/run.js +3 -1
  55. package/lib/app/show-display.js +8 -3
  56. package/lib/app/show-online.js +178 -0
  57. package/lib/app/show.js +39 -90
  58. package/lib/build/builder-api-docker-staging.js +47 -0
  59. package/lib/build/miso-controller-npm-sdk-guard.js +2 -2
  60. package/lib/build/standard-docker-build.js +2 -0
  61. package/lib/certification/merge-certification-from-artifact.js +1 -1
  62. package/lib/certification/post-unified-cert-sync.js +4 -31
  63. package/lib/certification/sync-after-external-command.js +0 -1
  64. package/lib/certification/sync-system-certification.js +0 -3
  65. package/lib/channels/add-channel.js +40 -34
  66. package/lib/channels/approval-guides/chatgpt.js +33 -0
  67. package/lib/channels/approval-guides/credential-portal.js +38 -0
  68. package/lib/channels/approval-guides/index.js +110 -0
  69. package/lib/channels/approval-guides/microsoft-copilot.js +34 -0
  70. package/lib/channels/approval-guides/slack.js +34 -0
  71. package/lib/channels/approval-guides/teams-bot.js +35 -0
  72. package/lib/channels/approval-guides/web-embed.js +32 -0
  73. package/lib/channels/channel-approval-guide.js +11 -0
  74. package/lib/channels/channel-artifact-generator.js +18 -5
  75. package/lib/channels/channel-audit.js +3 -0
  76. package/lib/channels/channel-auth-context.js +1 -1
  77. package/lib/channels/channel-description.js +59 -0
  78. package/lib/channels/channel-integration-generator.js +13 -230
  79. package/lib/channels/channel-integration-template.js +94 -0
  80. package/lib/channels/channel-runtime-resolver.js +43 -3
  81. package/lib/channels/channel-status-display.js +66 -26
  82. package/lib/channels/channel-targets.js +3 -3
  83. package/lib/cli/index.js +31 -3
  84. package/lib/cli/infra-guided.js +5 -1
  85. package/lib/cli/setup-app-external-create.js +111 -0
  86. package/lib/cli/setup-app.help.js +1 -1
  87. package/lib/cli/setup-app.js +60 -130
  88. package/lib/cli/setup-app.test-commands.js +26 -52
  89. package/lib/cli/setup-certification-commands.js +4 -4
  90. package/lib/cli/setup-certification.help.js +9 -9
  91. package/lib/cli/setup-dev.js +30 -9
  92. package/lib/cli/setup-external-system-help.js +4 -6
  93. package/lib/cli/setup-external-system.js +58 -52
  94. package/lib/cli/setup-infra-up-builder-api-action.js +64 -0
  95. package/lib/cli/setup-infra-up-platform-action.js +3 -1
  96. package/lib/cli/setup-infra.js +15 -0
  97. package/lib/cli/setup-list.js +43 -0
  98. package/lib/cli/setup-utility-help-after.js +12 -0
  99. package/lib/cli/setup-utility-repair.js +26 -7
  100. package/lib/cli/setup-utility-validate.js +41 -2
  101. package/lib/cli/setup-utility.js +5 -3
  102. package/lib/commands/app.js +15 -43
  103. package/lib/commands/channel-add-setup.js +110 -0
  104. package/lib/commands/channel.js +42 -8
  105. package/lib/commands/datasource-sync-display.js +96 -0
  106. package/lib/commands/datasource-sync-policy.js +210 -0
  107. package/lib/commands/datasource-test-trust-cli.js +6 -6
  108. package/lib/commands/datasource-unified-test-cli.js +2 -1
  109. package/lib/commands/datasource-unified-test-cli.options.js +33 -23
  110. package/lib/commands/deploy-gate-failure-details.js +184 -0
  111. package/lib/commands/deploy-gate-orchestrator.js +368 -0
  112. package/lib/commands/dev-cli-handlers.js +7 -62
  113. package/lib/commands/dev-host-ops-params.js +91 -0
  114. package/lib/commands/dev-host-ops-poll.js +111 -0
  115. package/lib/commands/dev-host-ops.js +107 -94
  116. package/lib/commands/dev-init.js +6 -106
  117. package/lib/commands/dev-refresh.js +197 -0
  118. package/lib/commands/enterprise-knowledge.js +284 -0
  119. package/lib/commands/evidence-cli-leaves.js +250 -0
  120. package/lib/commands/evidence-kind.js +428 -0
  121. package/lib/commands/evidence.js +51 -0
  122. package/lib/commands/governance-cli-shared.js +2 -2
  123. package/lib/commands/governance-command-action.js +5 -3
  124. package/lib/commands/governance-fixture-subjects.js +85 -0
  125. package/lib/commands/governance.js +1 -1
  126. package/lib/commands/lifecycle-command-action.js +2 -2
  127. package/lib/commands/lifecycle-external.js +3 -3
  128. package/lib/commands/manifest-cli-auth.js +29 -0
  129. package/lib/commands/manifest-cli-commands.js +170 -0
  130. package/lib/commands/manifest-cli-integration-path.js +63 -0
  131. package/lib/commands/manifest.js +21 -0
  132. package/lib/commands/protection-cli-leaves.js +3 -3
  133. package/lib/commands/repair-auth-apply.js +15 -1
  134. package/lib/commands/repair-authentications-454.js +169 -0
  135. package/lib/commands/repair-capability-openapi-warnings.js +126 -0
  136. package/lib/commands/repair-datasource-apply.js +135 -0
  137. package/lib/commands/repair-datasource-auto-rbac.js +62 -1
  138. package/lib/commands/repair-datasource-http-service-contract.js +239 -0
  139. package/lib/commands/repair-datasource-operation-security.js +180 -0
  140. package/lib/commands/repair-datasource-run.js +7 -2
  141. package/lib/commands/repair-datasource-sync-operations.js +177 -0
  142. package/lib/commands/repair-datasource-webhooks-sync-bridge.js +133 -0
  143. package/lib/commands/repair-datasource.js +12 -68
  144. package/lib/commands/repair-env-template.js +11 -1
  145. package/lib/commands/repair-external-run.js +121 -31
  146. package/lib/commands/repair-internal.js +1 -1
  147. package/lib/commands/repair-openapi-export.js +156 -0
  148. package/lib/commands/repair-openapi-sync.js +33 -8
  149. package/lib/commands/repair-orchestration-datasource-split.js +259 -0
  150. package/lib/commands/repair-persist.js +22 -1
  151. package/lib/commands/repair-rbac-platform-preset.js +204 -0
  152. package/lib/commands/repair-rbac-reader-roles.js +191 -0
  153. package/lib/commands/repair-rbac.js +163 -86
  154. package/lib/commands/repair-steps.js +83 -18
  155. package/lib/commands/repair-system-permissions.js +1 -0
  156. package/lib/commands/repair.js +1 -1
  157. package/lib/commands/resource-type.js +166 -44
  158. package/lib/commands/role.js +452 -0
  159. package/lib/commands/run-post-publish-data-sync.js +68 -0
  160. package/lib/commands/setup-modes.js +1 -1
  161. package/lib/commands/setup.js +1 -1
  162. package/lib/commands/test-e2e-external.js +21 -8
  163. package/lib/commands/test-governance-cli-options.js +2 -2
  164. package/lib/commands/test-trust-cli-options.js +2 -2
  165. package/lib/commands/up-builder-api-bootstrap.js +71 -0
  166. package/lib/commands/up-builder-api-provision.js +241 -0
  167. package/lib/commands/up-builder-api.js +88 -0
  168. package/lib/commands/up-common.js +25 -1
  169. package/lib/commands/upload-credential-push-log.js +117 -0
  170. package/lib/commands/upload-data-sync-finalize.js +60 -0
  171. package/lib/commands/upload-probe.js +66 -0
  172. package/lib/commands/upload-publish-context.js +4 -1
  173. package/lib/commands/upload-sidecar-followups.js +55 -27
  174. package/lib/commands/upload.js +116 -157
  175. package/lib/commands/validate-json.js +230 -0
  176. package/lib/commands/verify-governance-combined-external.js +1 -1
  177. package/lib/commands/verify-governance-db.js +2 -2
  178. package/lib/commands/verify-operations-command-action.js +2 -2
  179. package/lib/commands/verify-operations-step-plan.js +79 -41
  180. package/lib/commands/verify-operations-steps.js +2 -2
  181. package/lib/commands/verify-trust-command-action.js +1 -1
  182. package/lib/commands/wizard-core.js +1 -1
  183. package/lib/commands/wizard-headless.js +2 -1
  184. package/lib/core/admin-secrets.js +2 -6
  185. package/lib/core/audit-logger.js +1 -1
  186. package/lib/core/secrets-env-content.js +10 -4
  187. package/lib/core/secrets-env-write.js +2 -13
  188. package/lib/core/secrets-load.js +1 -3
  189. package/lib/datasource/agent-trust-run.js +3 -3
  190. package/lib/datasource/capability/relate-operations.js +1 -1
  191. package/lib/datasource/deploy.js +3 -1
  192. package/lib/datasource/test-e2e.js +6 -1
  193. package/lib/datasource/unified-validation-run-body.js +4 -1
  194. package/lib/datasource/unified-validation-run.js +1 -1
  195. package/lib/deployment/deploy-poll-ui.js +73 -12
  196. package/lib/deployment/deployer-poll-run.js +113 -0
  197. package/lib/deployment/deployer.js +17 -87
  198. package/lib/evidence/dataplane-context.js +21 -0
  199. package/lib/evidence/evidence-display.js +78 -0
  200. package/lib/evidence/evidence-service.js +392 -0
  201. package/lib/external-system/deploy.js +290 -112
  202. package/lib/external-system/download.js +7 -3
  203. package/lib/external-system/test-execution.js +1 -1
  204. package/lib/external-system/test-system-level.js +8 -10
  205. package/lib/external-system/test.js +12 -6
  206. package/lib/generator/deploy-script.js +73 -0
  207. package/lib/generator/external.js +2 -1
  208. package/lib/generator/helpers.js +13 -5
  209. package/lib/generator/index.js +17 -2
  210. package/lib/generator/split-variables.js +9 -3
  211. package/lib/generator/wizard.js +3 -36
  212. package/lib/infrastructure/helpers-docker-check.js +6 -0
  213. package/lib/infrastructure/helpers.js +1 -1
  214. package/lib/internal/fs-real-sync.js +22 -1
  215. package/lib/internal/node-fs.js +2 -0
  216. package/lib/lifecycle/lifecycle-governance-options.js +1 -1
  217. package/lib/lifecycle/verify-step-progress.js +1 -1
  218. package/lib/programmatic/access-log.js +26 -0
  219. package/lib/programmatic/auth-config.js +45 -0
  220. package/lib/programmatic/bearer-auth.js +176 -0
  221. package/lib/programmatic/builder-api-request.js +175 -0
  222. package/lib/programmatic/builder-api-route-dispatch.js +82 -0
  223. package/lib/programmatic/builder-api-runtime-config.js +42 -0
  224. package/lib/programmatic/builder-api-server.js +230 -0
  225. package/lib/programmatic/builder-help-authentication-catalog.js +282 -0
  226. package/lib/programmatic/builder-help-connected-system-ui.js +266 -0
  227. package/lib/programmatic/builder-help-enterprise-sync-fabrix.js +60 -0
  228. package/lib/programmatic/builder-help-envelope.js +36 -0
  229. package/lib/programmatic/builder-help-fixtures.js +200 -0
  230. package/lib/programmatic/builder-help-governance.js +172 -0
  231. package/lib/programmatic/builder-help-schema-catalog.js +92 -0
  232. package/lib/programmatic/builder-help.js +361 -0
  233. package/lib/programmatic/capability-registry.js +77 -0
  234. package/lib/programmatic/command-options.js +32 -0
  235. package/lib/programmatic/enterprise-mcp-client.js +114 -0
  236. package/lib/programmatic/http-problem-details.js +99 -0
  237. package/lib/programmatic/http-route-match.js +40 -0
  238. package/lib/programmatic/idempotency-cache.js +69 -0
  239. package/lib/programmatic/index.js +53 -0
  240. package/lib/programmatic/integration-path-scope.js +39 -0
  241. package/lib/programmatic/log-redaction.js +66 -0
  242. package/lib/programmatic/manifest-get-section.js +146 -0
  243. package/lib/programmatic/manifest-patch-section.js +252 -0
  244. package/lib/programmatic/manifest-repair.js +122 -0
  245. package/lib/programmatic/manifest-section-dependency-graph.js +160 -0
  246. package/lib/programmatic/manifest-section-io.js +225 -0
  247. package/lib/programmatic/manifest-section-quality.js +171 -0
  248. package/lib/programmatic/manifest-section-registry-data.js +269 -0
  249. package/lib/programmatic/manifest-section-registry.js +222 -0
  250. package/lib/programmatic/nest-http-bridge.js +34 -0
  251. package/lib/programmatic/openapi-component-schemas.js +68 -0
  252. package/lib/programmatic/openapi-description-enricher.js +117 -0
  253. package/lib/programmatic/openapi-descriptions.js +190 -0
  254. package/lib/programmatic/openapi-docs-serving.js +123 -0
  255. package/lib/programmatic/openapi-help-schemas.js +63 -0
  256. package/lib/programmatic/openapi-manifest-schemas.js +141 -0
  257. package/lib/programmatic/openapi-operation-bindings.js +274 -0
  258. package/lib/programmatic/openapi-request-schemas.js +155 -0
  259. package/lib/programmatic/openapi-result-schemas.js +493 -0
  260. package/lib/programmatic/openapi-schema-descriptions-certify.js +139 -0
  261. package/lib/programmatic/openapi-schema-descriptions-core.js +162 -0
  262. package/lib/programmatic/openapi-schema-descriptions-help.js +40 -0
  263. package/lib/programmatic/openapi-schema-descriptions-manifest.js +143 -0
  264. package/lib/programmatic/openapi-schema-descriptions-mcp.js +118 -0
  265. package/lib/programmatic/openapi-schema-descriptions-operations.js +281 -0
  266. package/lib/programmatic/openapi-schema-helpers.js +108 -0
  267. package/lib/programmatic/openapi-spec.js +203 -0
  268. package/lib/programmatic/orchestration-openapi-meta.js +159 -0
  269. package/lib/programmatic/platform-rbac-catalog.js +90 -0
  270. package/lib/programmatic/request-timeout.js +53 -0
  271. package/lib/programmatic/route-handler-map.js +143 -0
  272. package/lib/programmatic/route-handlers-context.js +29 -0
  273. package/lib/programmatic/route-handlers.js +33 -0
  274. package/lib/programmatic/run-certify.js +57 -0
  275. package/lib/programmatic/run-enterprise-mcp.js +32 -0
  276. package/lib/programmatic/run-lifecycle.js +29 -0
  277. package/lib/programmatic/run-repair.js +41 -0
  278. package/lib/programmatic/run-repository-emcp.js +62 -0
  279. package/lib/programmatic/run-template-workspace.js +74 -0
  280. package/lib/programmatic/run-test.js +49 -0
  281. package/lib/programmatic/run-upload.js +63 -0
  282. package/lib/programmatic/run-validate.js +53 -0
  283. package/lib/programmatic/run-wizard.js +40 -0
  284. package/lib/programmatic/system-key.js +48 -0
  285. package/lib/programmatic/wizard-config-normalize.js +118 -0
  286. package/lib/programmatic/workspace-cleanup.js +128 -0
  287. package/lib/programmatic/workspace-context.js +145 -0
  288. package/lib/programmatic/workspace-lock.js +75 -0
  289. package/lib/programmatic/workspace-meta.js +64 -0
  290. package/lib/programmatic/workspace-ops.js +149 -0
  291. package/lib/protection/run-commands-upload-sync.js +35 -0
  292. package/lib/protection/run-commands.js +2 -20
  293. package/lib/protection/upload-batch.js +11 -7
  294. package/lib/resolvers/evidence-kind-file.js +230 -0
  295. package/lib/resolvers/resource-type-file.js +58 -1
  296. package/lib/resolvers/role-file.js +227 -0
  297. package/lib/schema/application-schema.json +22 -2
  298. package/lib/schema/external-datasource.schema.json +245 -2
  299. package/lib/schema/external-system.schema.json +259 -119
  300. package/lib/schema/flag-map-validation-run.json +3 -0
  301. package/lib/schema/infra.parameter.yaml +25 -1
  302. package/lib/schema/type/credential-field-registry.json +21 -5
  303. package/lib/schema/type/document-storage.json +9 -0
  304. package/lib/utils/agent-trust-run-display.js +1 -1
  305. package/lib/utils/api.js +8 -2
  306. package/lib/utils/app-path-resolve.js +168 -0
  307. package/lib/utils/app-register-config.js +4 -3
  308. package/lib/utils/authentication-env-template.js +222 -0
  309. package/lib/utils/cli-sync-options.js +62 -10
  310. package/lib/utils/cli-utils.js +15 -3
  311. package/lib/utils/cli-workspace-options.js +29 -0
  312. package/lib/utils/compose-generate-docker-compose.js +102 -0
  313. package/lib/utils/configuration-env-resolver.js +203 -27
  314. package/lib/utils/datasource-test-run-certificate-tty.js +28 -2
  315. package/lib/utils/datasource-test-run-certification-debug.js +130 -0
  316. package/lib/utils/datasource-test-run-debug-display.js +2 -0
  317. package/lib/utils/datasource-test-run-debug-slice.js +7 -0
  318. package/lib/utils/datasource-test-run-display.js +2 -1
  319. package/lib/utils/dev-ca-install.js +5 -6
  320. package/lib/utils/dev-config.js +2 -2
  321. package/lib/utils/dev-init-ssh-merge.js +165 -23
  322. package/lib/utils/dev-list-sort.js +145 -0
  323. package/lib/utils/dev-pin-share-instructions.js +110 -0
  324. package/lib/utils/dev-platform-tls.js +0 -63
  325. package/lib/utils/dev-ssh-config-helper.js +177 -33
  326. package/lib/utils/docker-build.js +46 -27
  327. package/lib/utils/docker-daemon-tls-ca.js +1 -1
  328. package/lib/utils/docker-exec.js +91 -6
  329. package/lib/utils/enterprise-knowledge-paths.js +142 -0
  330. package/lib/utils/env-copy.js +3 -4
  331. package/lib/utils/env-dotenv-format.js +103 -0
  332. package/lib/utils/error-formatters/error-parser.js +0 -3
  333. package/lib/utils/external-env-template.js +5 -2
  334. package/lib/utils/external-system-display.js +5 -1
  335. package/lib/utils/external-system-readiness-compact-blocks.js +248 -0
  336. package/lib/utils/external-system-readiness-compact-display.js +324 -0
  337. package/lib/utils/external-system-readiness-core.js +16 -0
  338. package/lib/utils/external-system-readiness-deploy-display.js +29 -11
  339. package/lib/utils/external-system-readiness-display-internals.js +3 -1
  340. package/lib/utils/external-system-readiness-display.js +20 -30
  341. package/lib/utils/external-system-system-test-tty-certification.js +135 -0
  342. package/lib/utils/external-system-system-test-tty.js +5 -41
  343. package/lib/utils/health-check-request.js +2 -3
  344. package/lib/utils/help-builder.js +9 -1
  345. package/lib/utils/host-ops-job-labels.js +236 -0
  346. package/lib/utils/host-ops-job-result.js +61 -0
  347. package/lib/utils/host-ops-poll-ui.js +163 -0
  348. package/lib/utils/image-name.js +22 -4
  349. package/lib/utils/integration-path-resolve.js +112 -0
  350. package/lib/utils/logger.js +37 -4
  351. package/lib/utils/manifest-source-emit.js +1 -1
  352. package/lib/utils/paths-reload-source.js +148 -0
  353. package/lib/utils/paths-system-builder-keys.js +25 -0
  354. package/lib/utils/paths.js +183 -30
  355. package/lib/utils/pipeline-upload-auth-retry.js +4 -0
  356. package/lib/utils/postgres-platform-bootstrap.js +24 -17
  357. package/lib/utils/postgres-wipe.js +5 -2
  358. package/lib/utils/remote-dev-auth.js +39 -4
  359. package/lib/utils/resolve-docker-image-ref.js +36 -6
  360. package/lib/utils/runtime-configuration-values.js +64 -2
  361. package/lib/utils/secrets-helpers.js +5 -1
  362. package/lib/utils/ssh-known-hosts.js +130 -0
  363. package/lib/utils/test-target-cli-options.js +75 -0
  364. package/lib/utils/token-manager.js +16 -0
  365. package/lib/utils/upload-sync-options.js +20 -2
  366. package/lib/utils/validation-run-request.js +11 -2
  367. package/lib/validation/external-manifest-validator.js +11 -1
  368. package/lib/validation/openapi-contract-surface-validator.js +430 -0
  369. package/lib/validation/openapi-contract-vendor-validation.js +238 -0
  370. package/lib/validation/validate-external-file.js +160 -0
  371. package/lib/validation/validate.js +6 -117
  372. package/lib/validation/validator.js +6 -5
  373. package/package.json +76 -37
  374. package/packages/builder-api/README.md +120 -0
  375. package/packages/builder-api/package.json +30 -0
  376. package/packages/builder-api/src/app.module.ts +7 -0
  377. package/packages/builder-api/src/auth/auth.module.ts +5 -0
  378. package/packages/builder-api/src/external-system/external-system.module.ts +5 -0
  379. package/packages/builder-api/src/main.ts +16 -0
  380. package/packages/builder-api/tsconfig.json +15 -0
  381. package/scripts/check-builder-api-architecture-grep.js +79 -0
  382. package/scripts/docker_image_content_gate.js +47 -0
  383. package/scripts/docker_image_content_gate.sh +5 -0
  384. package/scripts/export-builder-api-evidence.js +262 -0
  385. package/scripts/lib/builder-api-docker-staging-copy.js +60 -0
  386. package/scripts/lib/builder-api-docker-staging-core.js +183 -0
  387. package/scripts/lib/docker-image-content-gate-core.js +166 -0
  388. package/scripts/lib/plan-actor.js +109 -0
  389. package/scripts/lib/plan-config.js +20 -0
  390. package/scripts/lib/plan-gates.js +154 -0
  391. package/scripts/lib/plan-meta.js +104 -0
  392. package/scripts/lib/plan-parse.js +162 -0
  393. package/scripts/lib/plan-prevalidate-gates.js +337 -0
  394. package/scripts/lib/plan-run-core.js +125 -0
  395. package/scripts/lib/plan-run-report.js +119 -0
  396. package/scripts/plan-approve.js +24 -0
  397. package/scripts/plan-archive.js +49 -0
  398. package/scripts/plan-run.js +13 -0
  399. package/scripts/plan-set-actor.js +21 -0
  400. package/scripts/plan-validate.js +80 -0
  401. package/scripts/pnpm/af.mjs +110 -0
  402. package/scripts/pnpm/check-quiet.mjs +32 -0
  403. package/scripts/pnpm/dev-install.mjs +29 -0
  404. package/scripts/pnpm/dev-reload.mjs +18 -0
  405. package/scripts/pnpm/help.mjs +55 -0
  406. package/scripts/pnpm/lib/dev-reload-core.mjs +189 -0
  407. package/scripts/pnpm/lib/dev-reload-log-capture.mjs +67 -0
  408. package/scripts/pnpm/lib/dev-reload-log-utils.mjs +32 -0
  409. package/scripts/pnpm/lib/resolve-aifabrix-bin.mjs +124 -0
  410. package/scripts/pnpm/lib/resolve-app-url.mjs +183 -0
  411. package/scripts/pnpm/lib/spinner.mjs +42 -0
  412. package/scripts/stage_builder_api_for_docker.js +65 -0
  413. package/scripts/sync-builder-api-template.js +44 -0
  414. package/templates/README.md +3 -0
  415. package/templates/applications/builder-api/Dockerfile +38 -0
  416. package/templates/applications/builder-api/application.yaml +75 -0
  417. package/templates/applications/builder-api/env.template +48 -0
  418. package/templates/applications/dataplane/application.yaml +27 -5
  419. package/templates/applications/dataplane/env.template +38 -15
  420. package/templates/applications/dataplane/rbac.yaml +85 -3
  421. package/templates/applications/miso-controller/application.yaml +10 -1
  422. package/templates/applications/miso-controller/env.template +11 -10
  423. package/templates/applications/miso-controller/rbac.yaml +72 -0
  424. package/templates/channels/README.md +18 -0
  425. package/templates/channels/ai-fabrix-icon.jpg +0 -0
  426. package/templates/channels/chatgpt/install.template.md.hbs +21 -24
  427. package/templates/channels/chatgpt/integration/README.md +11 -0
  428. package/templates/channels/chatgpt/integration/application.json +15 -0
  429. package/templates/channels/chatgpt/integration/chatgpt-system.json +29 -0
  430. package/templates/channels/chatgpt/integration/env.template +4 -0
  431. package/templates/channels/microsoft-copilot/install.template.md.hbs +20 -25
  432. package/templates/channels/microsoft-copilot/integration/README.md +11 -0
  433. package/templates/channels/microsoft-copilot/integration/application.json +15 -0
  434. package/templates/channels/microsoft-copilot/integration/env.template +6 -0
  435. package/templates/channels/microsoft-copilot/integration/microsoft-copilot-system.json +34 -0
  436. package/templates/channels/slack/install.template.md.hbs +48 -18
  437. package/templates/channels/slack/integration/README.md +38 -0
  438. package/templates/channels/slack/integration/application.json +18 -0
  439. package/templates/channels/slack/integration/env.template +29 -0
  440. package/templates/channels/slack/integration/slack-datasource-conversations.json +226 -0
  441. package/templates/channels/slack/integration/slack-datasource-messages.json +269 -0
  442. package/templates/channels/slack/integration/slack-system.json +144 -0
  443. package/templates/channels/slack/manifest.template.json.hbs +20 -10
  444. package/templates/channels/teams-bot/install.template.md.hbs +31 -17
  445. package/templates/channels/teams-bot/integration/README.md +18 -0
  446. package/templates/channels/teams-bot/integration/application.json +17 -0
  447. package/templates/channels/teams-bot/integration/env.template +5 -0
  448. package/templates/channels/teams-bot/integration/teams-bot-system.json +55 -0
  449. package/templates/channels/teams-bot/manifest.template.json.hbs +27 -0
  450. package/templates/channels/web-embed/install.template.md.hbs +16 -26
  451. package/templates/channels/web-embed/integration/README.md +11 -0
  452. package/templates/channels/web-embed/integration/application.json +15 -0
  453. package/templates/channels/web-embed/integration/env.template +4 -0
  454. package/templates/channels/web-embed/integration/web-embed-system.json +29 -0
  455. package/templates/openapi/redoc_page.html +86 -0
  456. package/templates/python/docker-compose.hbs +11 -0
  457. package/templates/python/requirements.txt +2 -2
  458. package/templates/typescript/docker-compose.hbs +11 -0
  459. package/lib/certification/cli-cert-sync-skip.js +0 -21
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Slack manifest description limits (plan 152).
3
+ *
4
+ * @fileoverview Enforce Slack display_information.description max length
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ /** Slack manifest `display_information.description` max (api.slack.com/reference/manifests). */
12
+ const SLACK_APP_DESCRIPTION_MAX_LENGTH = 140;
13
+
14
+ /**
15
+ * @param {string} description
16
+ * @returns {string}
17
+ */
18
+ function normalizeSlackAppDescription(description) {
19
+ const text = String(description ?? '').trim();
20
+ if (!text || text.length <= SLACK_APP_DESCRIPTION_MAX_LENGTH) {
21
+ return text;
22
+ }
23
+ return `${text.slice(0, SLACK_APP_DESCRIPTION_MAX_LENGTH - 1)}…`;
24
+ }
25
+
26
+ /**
27
+ * @param {string} description
28
+ * @returns {string}
29
+ * @throws {Error}
30
+ */
31
+ function assertSlackAppDescription(description) {
32
+ const text = String(description ?? '').trim();
33
+ if (text.length > SLACK_APP_DESCRIPTION_MAX_LENGTH) {
34
+ throw new Error(
35
+ `Slack app description must be at most ${SLACK_APP_DESCRIPTION_MAX_LENGTH} characters (got ${text.length}). Provide a shorter --description.`
36
+ );
37
+ }
38
+ return text;
39
+ }
40
+
41
+ /**
42
+ * @param {string} channelTarget
43
+ * @param {string} description
44
+ * @returns {string}
45
+ */
46
+ function resolveAppDescription(channelTarget, description) {
47
+ const text = String(description ?? '').trim();
48
+ if (channelTarget === 'slack') {
49
+ return assertSlackAppDescription(text);
50
+ }
51
+ return text;
52
+ }
53
+
54
+ module.exports = {
55
+ SLACK_APP_DESCRIPTION_MAX_LENGTH,
56
+ normalizeSlackAppDescription,
57
+ assertSlackAppDescription,
58
+ resolveAppDescription
59
+ };
@@ -1,9 +1,11 @@
1
1
  /**
2
- * Generate integration/<channelTarget>/ for communication external systems (plan 152).
2
+ * Scaffold integration/<channelTarget>/ from published templates (plan 152).
3
+ * Manifest SSOT: dataplane integration/ (slack via make sync-json) → templates/channels/{target}/integration/.
4
+ * Builder generates only *-deploy.json at scaffold time.
3
5
  *
4
- * @fileoverview Builder generator for channel deploy step 1 scaffolds
6
+ * @fileoverview Channel integration scaffold — template copy + deploy JSON
5
7
  * @author AI Fabrix Team
6
- * @version 1.0.0
8
+ * @version 2.0.0
7
9
  */
8
10
 
9
11
  'use strict';
@@ -12,201 +14,8 @@ const fs = require('fs');
12
14
  const path = require('path');
13
15
  const { getChannelTarget } = require('./channel-targets');
14
16
  const { getIntegrationPath } = require('../utils/paths');
15
-
16
- /** @type {Record<string, Object>} */
17
- const AUTH_BLOCKS = {
18
- slack: {
19
- authType: 'credential',
20
- credential: {
21
- credentialKey: 'slack-app',
22
- displayName: 'Slack assistant channel',
23
- method: 'hmac',
24
- variables: {},
25
- security: {
26
- signingSecret: 'kv://slack/signingSecret',
27
- clientId: 'kv://slack/clientId',
28
- clientSecret: 'kv://slack/clientSecret'
29
- },
30
- writeOnce: true
31
- }
32
- },
33
- 'teams-bot': {
34
- authType: 'credential',
35
- credential: {
36
- credentialKey: 'teams-bot',
37
- displayName: 'Microsoft Teams assistant bot',
38
- method: 'oidc',
39
- variables: {
40
- openIdConfigUrl: 'https://login.botframework.com/v1/.well-known/openid_configuration',
41
- clientId: 'kv://teams-bot/botAppId',
42
- expectedIssuer: 'https://api.botframework.com'
43
- },
44
- security: {},
45
- writeOnce: true
46
- }
47
- },
48
- 'microsoft-copilot': {
49
- authType: 'credential',
50
- credential: {
51
- credentialKey: 'microsoft-copilot-channel',
52
- displayName: 'Microsoft Copilot assistant channel',
53
- method: 'oauth2',
54
- variables: {
55
- tokenUrl: 'https://login.microsoftonline.com/common/oauth2/v2.0/token',
56
- grantType: 'client_credentials'
57
- },
58
- security: {
59
- clientId: 'kv://microsoft-copilot/clientId',
60
- clientSecret: 'kv://microsoft-copilot/clientSecret'
61
- },
62
- writeOnce: true
63
- }
64
- },
65
- chatgpt: {
66
- authType: 'credential',
67
- credential: {
68
- credentialKey: 'chatgpt-channel',
69
- displayName: 'ChatGPT assistant channel',
70
- method: 'apikey',
71
- variables: {},
72
- security: {
73
- apiKey: 'kv://chatgpt/apiKey'
74
- },
75
- writeOnce: true
76
- }
77
- },
78
- 'web-embed': {
79
- authType: 'credential',
80
- credential: {
81
- credentialKey: 'web-embed-channel',
82
- displayName: 'Web embed assistant channel',
83
- method: 'apikey',
84
- variables: {},
85
- security: {
86
- apiKey: 'kv://web-embed/apiKey'
87
- },
88
- writeOnce: true
89
- }
90
- }
91
- };
92
-
93
- /**
94
- * @param {string} channelTarget
95
- * @param {typeof import('./channel-targets').CHANNEL_TARGETS[string]} target
96
- * @returns {Object}
97
- */
98
- function buildAuthenticationBlock(channelTarget, target) {
99
- const block = AUTH_BLOCKS[channelTarget];
100
- if (!block) {
101
- throw new Error(`No authentication block for channel target "${channelTarget}"`);
102
- }
103
- const auth = JSON.parse(JSON.stringify(block));
104
- auth.credential.credentialKey = target.credentialKey;
105
- return auth;
106
- }
107
-
108
- /**
109
- * @param {string} channelTarget
110
- * @returns {Object}
111
- */
112
- function buildSystemJson(channelTarget) {
113
- const target = getChannelTarget(channelTarget);
114
- const system = {
115
- key: channelTarget,
116
- displayName: 'Microsoft Teams assistant bot',
117
- description: 'Bot Framework assistant channel (not full Teams / Graph integration)',
118
- type: 'custom',
119
- systemKind: 'communication',
120
- enabled: true,
121
- authentication: buildAuthenticationBlock(channelTarget, target),
122
- configuration: [],
123
- dataSources: []
124
- };
125
-
126
- if (channelTarget === 'teams-bot') {
127
- system.displayName = 'Microsoft Teams assistant bot';
128
- system.endpoints = [
129
- {
130
- type: 'messages',
131
- path: '/messages',
132
- router: 'teams_bot_router',
133
- description: 'Bot Framework messaging endpoint',
134
- active: true
135
- },
136
- {
137
- type: 'notifications',
138
- path: '/notifications',
139
- router: 'teams_notifications_router',
140
- description: 'Proactive notification endpoint',
141
- active: true
142
- },
143
- {
144
- type: 'config',
145
- path: '/bot-config',
146
- router: 'teams_config_router',
147
- description: 'Bot configuration endpoint',
148
- active: true
149
- }
150
- ];
151
- system.endpointsActive = true;
152
- } else {
153
- system.displayName = `${target.key} assistant channel`;
154
- system.description = 'Communication external system for assistant channel install (plan 152)';
155
- }
156
-
157
- return system;
158
- }
159
-
160
- /**
161
- * @param {string} channelTarget
162
- * @returns {Object}
163
- */
164
- function buildApplicationJson(channelTarget) {
165
- const target = getChannelTarget(channelTarget);
166
- const systemFile = `${channelTarget}-system.json`;
167
- return {
168
- app: {
169
- key: channelTarget,
170
- displayName: `${target.key} assistant channel`,
171
- description: 'Assistant communication channel — deploy then app add-channel',
172
- type: 'external'
173
- },
174
- externalIntegration: {
175
- schemaBasePath: './',
176
- systems: [systemFile],
177
- dataSources: [],
178
- autopublish: true,
179
- version: '1.0.0'
180
- }
181
- };
182
- }
183
-
184
- /**
185
- * @param {string} channelTarget
186
- * @returns {string}
187
- */
188
- function buildEnvTemplate(channelTarget) {
189
- const kvPrefix = channelTarget === 'web-embed' ? 'web-embed' : channelTarget;
190
- const lines = [
191
- `# ${channelTarget} assistant channel — resolve secrets before deploy/add-channel`,
192
- '# kv:// paths are pushed via aifabrix credential push or add-channel secret sync',
193
- ''
194
- ];
195
- if (channelTarget === 'slack') {
196
- lines.push('KV_SLACK_SIGNINGSECRET=kv://slack/signingSecret');
197
- lines.push('KV_SLACK_CLIENTID=kv://slack/clientId');
198
- lines.push('KV_SLACK_CLIENTSECRET=kv://slack/clientSecret');
199
- } else if (channelTarget === 'teams-bot') {
200
- lines.push('KV_TEAMS_BOT_BOTAPPID=kv://teams-bot/botAppId');
201
- } else if (channelTarget === 'microsoft-copilot') {
202
- lines.push('KV_MICROSOFT_COPILOT_CLIENTID=kv://microsoft-copilot/clientId');
203
- lines.push('KV_MICROSOFT_COPILOT_CLIENTSECRET=kv://microsoft-copilot/clientSecret');
204
- } else {
205
- lines.push(`KV_${kvPrefix.toUpperCase().replace(/-/g, '_')}_APIKEY=kv://${kvPrefix}/apiKey`);
206
- }
207
- lines.push('');
208
- return lines.join('\n');
209
- }
17
+ const { copyChannelIntegrationTemplate } = require('./channel-integration-template');
18
+ const { generateDeployJson } = require('../generator/index');
210
19
 
211
20
  /**
212
21
  * @param {string} channelTarget
@@ -214,9 +23,9 @@ function buildEnvTemplate(channelTarget) {
214
23
  * @param {boolean} [options.force]
215
24
  * @param {boolean} [options.allowExperimental]
216
25
  * @param {string} [options.projectRoot]
217
- * @returns {{ integrationDir: string, files: string[] }}
26
+ * @returns {Promise<{ integrationDir: string, files: string[] }>}
218
27
  */
219
- function scaffoldChannelIntegration(channelTarget, options = {}) {
28
+ async function scaffoldChannelIntegration(channelTarget, options = {}) {
220
29
  const target = getChannelTarget(channelTarget);
221
30
  if (target.experimental && !options.allowExperimental) {
222
31
  throw new Error(
@@ -233,42 +42,16 @@ function scaffoldChannelIntegration(channelTarget, options = {}) {
233
42
  );
234
43
  }
235
44
 
236
- fs.mkdirSync(integrationDir, { recursive: true });
237
- const systemPath = path.join(integrationDir, `${channelTarget}-system.json`);
238
- const appPath = path.join(integrationDir, 'application.json');
239
- const envPath = path.join(integrationDir, 'env.template');
240
- const readmePath = path.join(integrationDir, 'README.md');
241
-
242
- fs.writeFileSync(systemPath, `${JSON.stringify(buildSystemJson(channelTarget), null, 2)}\n`, 'utf8');
243
- fs.writeFileSync(appPath, `${JSON.stringify(buildApplicationJson(channelTarget), null, 2)}\n`, 'utf8');
244
- fs.writeFileSync(envPath, buildEnvTemplate(channelTarget), 'utf8');
245
- fs.writeFileSync(
246
- readmePath,
247
- [
248
- `# ${channelTarget} assistant channel`,
249
- '',
250
- '## Two-step install',
251
- '',
252
- '```bash',
253
- `aifabrix deploy ${channelTarget}`,
254
- `aifabrix app add-channel ${channelTarget} --name "Your Assistant"`,
255
- '```',
256
- '',
257
- 'Generated by `aifabrix channel scaffold`. Secrets belong in kv:// env.template only.',
258
- ''
259
- ].join('\n'),
260
- 'utf8'
261
- );
45
+ const copied = copyChannelIntegrationTemplate(channelTarget, integrationDir);
46
+ const deployPath = await generateDeployJson(channelTarget, { appPath: integrationDir });
47
+ const files = [...copied, deployPath];
262
48
 
263
49
  return {
264
50
  integrationDir,
265
- files: [systemPath, appPath, envPath, readmePath]
51
+ files
266
52
  };
267
53
  }
268
54
 
269
55
  module.exports = {
270
- buildSystemJson,
271
- buildApplicationJson,
272
- buildEnvTemplate,
273
56
  scaffoldChannelIntegration
274
57
  };
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Channel integration templates — copied from templates/channels/<target>/integration/.
3
+ * SSOT for slack: aifabrix-dataplane/integration/slack (make sync-json in dataplane).
4
+ *
5
+ * @fileoverview Template resolution and copy for channel scaffold (plan 152)
6
+ * @author AI Fabrix Team
7
+ * @version 2.0.0
8
+ */
9
+
10
+ 'use strict';
11
+
12
+ const { nodeFs } = require('../internal/node-fs');
13
+ const fs = nodeFs();
14
+ const path = require('path');
15
+ const { getChannelTarget } = require('./channel-targets');
16
+
17
+ const BUILDER_ROOT = path.join(__dirname, '..', '..');
18
+
19
+ /** @type {RegExp[]} */
20
+ const SKIP_TEMPLATE_FILE = [
21
+ /^\./,
22
+ /-deploy\.json$/,
23
+ /^INTEGRATION_CHANGELOG\.md$/i
24
+ ];
25
+
26
+ /**
27
+ * @param {string} channelTarget
28
+ * @returns {string}
29
+ */
30
+ function getChannelIntegrationTemplateDir(channelTarget) {
31
+ const target = getChannelTarget(channelTarget);
32
+ return path.join(BUILDER_ROOT, 'templates', 'channels', target.templateDir, 'integration');
33
+ }
34
+
35
+ /**
36
+ * @param {string} name
37
+ * @returns {boolean}
38
+ */
39
+ function shouldCopyTemplateFile(name) {
40
+ return !SKIP_TEMPLATE_FILE.some((pattern) => pattern.test(name));
41
+ }
42
+
43
+ /**
44
+ * @param {string} templateDir
45
+ * @returns {string[]}
46
+ */
47
+ function listChannelIntegrationTemplateFiles(templateDir) {
48
+ if (!fs.existsSync(templateDir)) {
49
+ return [];
50
+ }
51
+ return fs
52
+ .readdirSync(templateDir)
53
+ .filter((name) => {
54
+ const full = path.join(templateDir, name);
55
+ return fs.statSync(full).isFile() && shouldCopyTemplateFile(name);
56
+ })
57
+ .sort();
58
+ }
59
+
60
+ /**
61
+ * @param {string} channelTarget
62
+ * @param {string} integrationDir
63
+ * @returns {string[]} Copied file paths
64
+ */
65
+ function copyChannelIntegrationTemplate(channelTarget, integrationDir) {
66
+ const templateDir = getChannelIntegrationTemplateDir(channelTarget);
67
+ const names = listChannelIntegrationTemplateFiles(templateDir);
68
+ if (names.length === 0) {
69
+ throw new Error(
70
+ `Channel integration template missing for "${channelTarget}" (${templateDir}). ` +
71
+ 'For slack: edit aifabrix-dataplane/integration/slack and run make sync-json. ' +
72
+ 'For other targets: add templates/channels/<target>/integration/ until dataplane SSOT exists.'
73
+ );
74
+ }
75
+
76
+ fs.mkdirSync(integrationDir, { recursive: true });
77
+ const copied = [];
78
+ for (const name of names) {
79
+ const src = path.join(templateDir, name);
80
+ const dest = path.join(integrationDir, name);
81
+ fs.copyFileSync(src, dest);
82
+ copied.push(dest);
83
+ }
84
+ return copied;
85
+ }
86
+
87
+ module.exports = {
88
+ BUILDER_ROOT,
89
+ SKIP_TEMPLATE_FILE,
90
+ getChannelIntegrationTemplateDir,
91
+ shouldCopyTemplateFile,
92
+ listChannelIntegrationTemplateFiles,
93
+ copyChannelIntegrationTemplate
94
+ };
@@ -9,6 +9,10 @@
9
9
  'use strict';
10
10
 
11
11
  const { getChannelTarget } = require('./channel-targets');
12
+ const { normalizeSlackAppDescription } = require('./channel-description');
13
+
14
+ /** Default Slack slash prefix — matches dataplane `templates/slack/command_catalog.yaml`. */
15
+ const DEFAULT_SLACK_COMMAND_PREFIX = 'af';
12
16
 
13
17
  /**
14
18
  * Normalize dataplane base URL (no trailing slash).
@@ -50,7 +54,6 @@ function getEndpointPathSuffixes(channelTarget) {
50
54
  slack: {
51
55
  eventsUrl: '/events',
52
56
  interactionUrl: '/interactive',
53
- oauthCallbackUrl: '/oauth/callback',
54
57
  commandUrl: '/commands'
55
58
  },
56
59
  'teams-bot': {
@@ -97,6 +100,26 @@ function getLegacyApiPaths(channelTarget) {
97
100
  return legacy[channelTarget] || {};
98
101
  }
99
102
 
103
+ /**
104
+ * Slack token rotation requires OAuth redirect URLs (api.slack.com app manifest).
105
+ * @param {string|undefined} oauthCallbackUrl
106
+ * @returns {{ oauthCallbackUrl?: string, slackRedirectUrlsJson: string, slackTokenRotationEnabled: boolean }}
107
+ */
108
+ function resolveSlackOAuthManifestFields(oauthCallbackUrl) {
109
+ const url = typeof oauthCallbackUrl === 'string' ? oauthCallbackUrl.trim() : '';
110
+ if (!url) {
111
+ return {
112
+ slackRedirectUrlsJson: '[]',
113
+ slackTokenRotationEnabled: false
114
+ };
115
+ }
116
+ return {
117
+ oauthCallbackUrl: url,
118
+ slackRedirectUrlsJson: JSON.stringify([url]),
119
+ slackTokenRotationEnabled: true
120
+ };
121
+ }
122
+
100
123
  /**
101
124
  * @param {Object} params
102
125
  * @param {string} params.dataplaneBaseUrl
@@ -106,6 +129,7 @@ function getLegacyApiPaths(channelTarget) {
106
129
  * @param {string} [params.environment]
107
130
  * @param {string} params.appDescription
108
131
  * @param {string} [params.icon]
132
+ * @param {string} [params.commandPrefix] Slack slash alias prefix (default `af`)
109
133
  * @returns {Object}
110
134
  */
111
135
  function resolveChannelRuntimeValues(params) {
@@ -123,9 +147,13 @@ function resolveChannelRuntimeValues(params) {
123
147
  appName: params.appName,
124
148
  baseName: params.baseName || params.appName,
125
149
  environment: params.environment || 'dev',
126
- appDescription: params.appDescription,
150
+ appDescription:
151
+ params.channelTarget === 'slack'
152
+ ? normalizeSlackAppDescription(params.appDescription)
153
+ : params.appDescription,
127
154
  icon: params.icon || '',
128
155
  credentialKey: target.credentialKey,
156
+ credentialPortalUrl: joinUrl(base, `/connected-systems/${params.channelTarget}?tab=authentication`),
129
157
  assistantCatalogUrl: joinUrl(base, '/api/v1/workers/available'),
130
158
  scopes: []
131
159
  };
@@ -140,6 +168,16 @@ function resolveChannelRuntimeValues(params) {
140
168
  }
141
169
  }
142
170
 
171
+ if (params.channelTarget === 'slack') {
172
+ const oauthCallbackUrl = params.oauthCallbackUrl || resolved.oauthCallbackUrl;
173
+ Object.assign(resolved, resolveSlackOAuthManifestFields(oauthCallbackUrl));
174
+ const prefix =
175
+ typeof params.commandPrefix === 'string' && params.commandPrefix.trim()
176
+ ? params.commandPrefix.trim()
177
+ : DEFAULT_SLACK_COMMAND_PREFIX;
178
+ resolved.commandPrefix = prefix;
179
+ }
180
+
143
181
  return resolved;
144
182
  }
145
183
 
@@ -148,5 +186,7 @@ module.exports = {
148
186
  joinUrl,
149
187
  externalSystemsPrefix,
150
188
  getEndpointPathSuffixes,
151
- resolveChannelRuntimeValues
189
+ resolveSlackOAuthManifestFields,
190
+ resolveChannelRuntimeValues,
191
+ DEFAULT_SLACK_COMMAND_PREFIX
152
192
  };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * TTY output for app add-channel (plan 152).
2
+ * TTY output for channel add (plan 152).
3
3
  *
4
4
  * @fileoverview Channel install status display — customer language: Assistant
5
5
  * @author AI Fabrix Team
@@ -26,32 +26,79 @@ function separatorLine() {
26
26
  : '────────────────────────────────────────';
27
27
  }
28
28
 
29
+ /**
30
+ * @param {Object|null} approvalGuide
31
+ */
32
+ function displayApprovalGuideOptionalLinks(approvalGuide) {
33
+ if (approvalGuide.artifactPath) {
34
+ logger.log('');
35
+ logger.log(metadata('Manifest file:'));
36
+ logger.log(chalk.white(approvalGuide.artifactPath));
37
+ }
38
+ if (approvalGuide.credentialPortalUrl) {
39
+ logger.log('');
40
+ logger.log(metadata('AI Fabrix authentication:'));
41
+ logger.log(chalk.cyan(approvalGuide.credentialPortalUrl));
42
+ }
43
+ if (approvalGuide.installGuidePath) {
44
+ logger.log('');
45
+ logger.log(metadata(`Full guide: ${approvalGuide.installGuidePath}`));
46
+ }
47
+ }
48
+
49
+ /**
50
+ * @param {Object|null} approvalGuide
51
+ */
52
+ function displayApprovalGuideSection(approvalGuide) {
53
+ if (!approvalGuide?.steps?.length) return;
54
+ logger.log('');
55
+ const heading =
56
+ approvalGuide.approvalRequired === false
57
+ ? 'Go-live steps'
58
+ : 'Platform admin approval required';
59
+ logger.log(formatWarningLine(heading));
60
+ if (approvalGuide.portalUrl) {
61
+ logger.log(metadata('Admin console:'));
62
+ logger.log(chalk.cyan(approvalGuide.portalUrl));
63
+ }
64
+ logger.log('');
65
+ logger.log(metadata('Next steps:'));
66
+ approvalGuide.steps.forEach((step, index) => {
67
+ logger.log(chalk.white(` ${index + 1}. ${step}`));
68
+ });
69
+ displayApprovalGuideOptionalLinks(approvalGuide);
70
+ }
71
+
29
72
  /**
30
73
  * @param {Object} params
31
74
  * @param {string} params.channelTarget
32
75
  * @param {string} params.name
33
76
  * @param {Object|null} params.channelExt
34
- * @param {string} [params.approvalUrl]
77
+ * @param {Object|null} [params.approvalGuide]
35
78
  */
36
79
  function displayExistingChannelStatus(params) {
37
- logger.log(sectionTitle(`${params.channelTarget} channel: ${params.name}`));
38
- logger.log('');
39
- logger.log(metadata(`Status: ${params.channelExt?.status || 'unknown'}`));
40
- if (params.channelExt?.baseName && params.channelExt.baseName !== params.name) {
41
- logger.log(metadata(`Base name: ${params.channelExt.baseName}`));
42
- }
43
- logger.log(metadata(`External System: ${params.channelTarget}`));
44
- logger.log(metadata(`Credential: ${params.channelExt?.credentialKey || '—'}`));
45
- if (params.channelExt?.capabilities?.length) {
46
- logger.log(metadata('Capabilities:'));
47
- for (const cap of params.channelExt.capabilities) {
48
- logger.log(` - ${cap}`);
49
- }
80
+ const status = params.channelExt?.status || 'unknown';
81
+ displayChannelCoreFields({
82
+ channelTarget: params.channelTarget,
83
+ name: params.name,
84
+ statusLabel: status,
85
+ baseName: params.channelExt?.baseName,
86
+ credentialKey: params.channelExt?.credentialKey,
87
+ capabilities: params.channelExt?.capabilities
88
+ });
89
+
90
+ if (status === 'approvalRequired' && params.approvalGuide) {
91
+ displayApprovalGuideSection(params.approvalGuide);
92
+ logger.log(separatorLine());
93
+ return;
50
94
  }
95
+
51
96
  logger.log('');
52
- logger.log(formatWarningLine('Channel install already configured. Use --force to regenerate artifacts.'));
53
- if (params.approvalUrl) {
54
- logger.log(metadata(`Approval URL: ${params.approvalUrl}`));
97
+ if (status === 'installed' || status === 'validated') {
98
+ logger.log(formatSuccessLine('Channel install is complete.'));
99
+ logger.log(metadata('Use --force to regenerate artifacts and patch config.'));
100
+ } else {
101
+ logger.log(formatWarningLine('Channel install already configured. Use --force to regenerate artifacts.'));
55
102
  }
56
103
  logger.log(separatorLine());
57
104
  }
@@ -107,14 +154,7 @@ function displayValidationSection(validation) {
107
154
  * @param {Object} result
108
155
  */
109
156
  function displayApprovalSection(result) {
110
- if (!result.approvalUrl) return;
111
- logger.log('');
112
- logger.log(formatWarningLine('Approval required'));
113
- logger.log(metadata('Open this URL as platform admin:'));
114
- logger.log(chalk.cyan(result.approvalUrl));
115
- logger.log('');
116
- logger.log(metadata('After approval, run:'));
117
- logger.log(chalk.white(` aifabrix app add-channel ${result.channelTarget} --name "${result.name}"`));
157
+ displayApprovalGuideSection(result.approvalGuide);
118
158
  }
119
159
 
120
160
  /**
@@ -10,7 +10,7 @@
10
10
 
11
11
  /** @typedef {'teams-bot'|'slack'|'microsoft-copilot'|'chatgpt'|'web-embed'} ChannelTargetKey */
12
12
 
13
- const DEFAULT_CAPABILITIES = ['chat', 'notify'];
13
+ const DEFAULT_CAPABILITIES = ['chat', 'notify', 'documentApproval'];
14
14
 
15
15
  const CHANNEL_TARGETS = {
16
16
  'teams-bot': {
@@ -101,8 +101,8 @@ function getChannelTarget(channelTarget) {
101
101
  */
102
102
  function getDefaultChannelDescription() {
103
103
  return (
104
- 'Enterprise AI assistant for employees. Provides access to approved assistants, ' +
105
- 'enterprise knowledge, business workflows, and governed actions through AI Fabrix.'
104
+ 'Enterprise AI assistant for employees. Approved assistants, enterprise knowledge, ' +
105
+ 'workflows, and governed actions via AI Fabrix.'
106
106
  );
107
107
  }
108
108