@aifabrix/builder 2.49.1 → 2.50.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 (413) hide show
  1. package/.cursor/process/README.md +9 -0
  2. package/.cursor/rules/deploy-rules/docker-image-ip-policy.mdc +49 -0
  3. package/.cursor/rules/plan-rules/application-lifecycle.mdc +30 -0
  4. package/.cursor/rules/plan-rules/plan-frontmatter.mdc +35 -0
  5. package/.cursor/rules/plan-rules/plan-lifecycle.mdc +31 -0
  6. package/.cursor/rules/plan-rules/plan-validation-gate.mdc +34 -0
  7. package/.cursor/skills/README.md +1 -0
  8. package/.dockerignore +52 -0
  9. package/.eslintignore +22 -0
  10. package/README.md +2 -0
  11. package/bin/builder-api-cleanup.js +26 -0
  12. package/bin/builder-api-nest.js +10 -0
  13. package/bin/builder-api-spike.js +19 -0
  14. package/enterprise-knowledge/README.md +50 -0
  15. package/enterprise-knowledge/enterprise-integration-lifecycle/README.md +22 -0
  16. package/enterprise-knowledge/enterprise-integration-lifecycle/application.json +15 -0
  17. package/enterprise-knowledge/enterprise-integration-lifecycle/deploy.js +69 -0
  18. package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-deploy.json +52 -0
  19. package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-system.json +29 -0
  20. package/enterprise-knowledge/enterprise-integration-lifecycle/env.template +2 -0
  21. package/integration/README.md +81 -0
  22. package/integration/github/README.md +53 -0
  23. package/integration/github/application.json +21 -0
  24. package/integration/github/deploy.js +72 -0
  25. package/integration/github/env.template +11 -0
  26. package/integration/github/github-datasource-issue-comments.json +239 -0
  27. package/integration/github/github-datasource-issues.json +399 -0
  28. package/integration/github/github-datasource-repository.json +354 -0
  29. package/integration/github/github-deploy.json +1202 -0
  30. package/integration/github/github-system.json +82 -0
  31. package/integration/hubspot-test/README.md +1 -1
  32. package/jest.isolated-projects.js +31 -1
  33. package/jest.projects.js +87 -1
  34. package/lib/api/dev-server-https.js +1 -1
  35. package/lib/api/dev.api.js +1 -0
  36. package/lib/api/enterprise-knowledge.api.js +63 -0
  37. package/lib/api/evidence.api.js +172 -0
  38. package/lib/api/external-systems.api.js +8 -2
  39. package/lib/api/host-ops.api.js +69 -0
  40. package/lib/api/resource-types.api.js +1 -0
  41. package/lib/api/types/enterprise-knowledge.types.js +46 -0
  42. package/lib/api/types/evidence.types.js +67 -0
  43. package/lib/api/types/resource-types.types.js +2 -0
  44. package/lib/app/controller-application-filter.js +36 -0
  45. package/lib/app/deploy.js +1 -1
  46. package/lib/app/list-external-systems.js +130 -0
  47. package/lib/app/list.js +20 -8
  48. package/lib/app/run.js +3 -1
  49. package/lib/app/show-display.js +8 -3
  50. package/lib/app/show-online.js +178 -0
  51. package/lib/app/show.js +37 -88
  52. package/lib/build/builder-api-docker-staging.js +47 -0
  53. package/lib/build/miso-controller-npm-sdk-guard.js +2 -2
  54. package/lib/build/standard-docker-build.js +2 -0
  55. package/lib/certification/post-unified-cert-sync.js +4 -31
  56. package/lib/certification/sync-after-external-command.js +0 -1
  57. package/lib/certification/sync-system-certification.js +0 -3
  58. package/lib/channels/add-channel.js +40 -34
  59. package/lib/channels/approval-guides/chatgpt.js +33 -0
  60. package/lib/channels/approval-guides/credential-portal.js +38 -0
  61. package/lib/channels/approval-guides/index.js +110 -0
  62. package/lib/channels/approval-guides/microsoft-copilot.js +34 -0
  63. package/lib/channels/approval-guides/slack.js +34 -0
  64. package/lib/channels/approval-guides/teams-bot.js +35 -0
  65. package/lib/channels/approval-guides/web-embed.js +32 -0
  66. package/lib/channels/channel-approval-guide.js +11 -0
  67. package/lib/channels/channel-artifact-generator.js +16 -4
  68. package/lib/channels/channel-audit.js +3 -0
  69. package/lib/channels/channel-auth-context.js +1 -1
  70. package/lib/channels/channel-description.js +59 -0
  71. package/lib/channels/channel-integration-generator.js +13 -230
  72. package/lib/channels/channel-integration-template.js +94 -0
  73. package/lib/channels/channel-runtime-resolver.js +43 -3
  74. package/lib/channels/channel-status-display.js +66 -26
  75. package/lib/channels/channel-targets.js +3 -3
  76. package/lib/cli/index.js +27 -3
  77. package/lib/cli/infra-guided.js +5 -1
  78. package/lib/cli/setup-app-external-create.js +111 -0
  79. package/lib/cli/setup-app.help.js +1 -1
  80. package/lib/cli/setup-app.js +38 -125
  81. package/lib/cli/setup-app.test-commands.js +26 -52
  82. package/lib/cli/setup-certification-commands.js +4 -4
  83. package/lib/cli/setup-certification.help.js +9 -9
  84. package/lib/cli/setup-dev-path-commands.js +24 -0
  85. package/lib/cli/setup-dev.js +115 -16
  86. package/lib/cli/setup-external-system-help.js +4 -6
  87. package/lib/cli/setup-external-system.js +58 -52
  88. package/lib/cli/setup-infra-up-builder-api-action.js +64 -0
  89. package/lib/cli/setup-infra-up-platform-action.js +3 -1
  90. package/lib/cli/setup-infra.js +15 -0
  91. package/lib/cli/setup-list.js +43 -0
  92. package/lib/cli/setup-utility-repair.js +26 -7
  93. package/lib/cli/setup-utility.js +5 -3
  94. package/lib/commands/app.js +15 -43
  95. package/lib/commands/channel-add-setup.js +110 -0
  96. package/lib/commands/channel.js +42 -8
  97. package/lib/commands/datasource-sync-display.js +96 -0
  98. package/lib/commands/datasource-sync-policy.js +210 -0
  99. package/lib/commands/datasource-test-trust-cli.js +6 -6
  100. package/lib/commands/datasource-unified-test-cli.js +2 -1
  101. package/lib/commands/datasource-unified-test-cli.options.js +33 -23
  102. package/lib/commands/deploy-gate-failure-details.js +163 -0
  103. package/lib/commands/deploy-gate-orchestrator.js +322 -0
  104. package/lib/commands/dev-cli-handlers.js +64 -61
  105. package/lib/commands/dev-host-ops-params.js +91 -0
  106. package/lib/commands/dev-host-ops-poll.js +111 -0
  107. package/lib/commands/dev-host-ops.js +252 -0
  108. package/lib/commands/dev-init.js +3 -1
  109. package/lib/commands/enterprise-knowledge.js +284 -0
  110. package/lib/commands/evidence-cli-leaves.js +250 -0
  111. package/lib/commands/evidence.js +51 -0
  112. package/lib/commands/governance-cli-shared.js +2 -2
  113. package/lib/commands/governance-command-action.js +2 -2
  114. package/lib/commands/governance-fixture-subjects.js +85 -0
  115. package/lib/commands/governance.js +1 -1
  116. package/lib/commands/lifecycle-command-action.js +2 -2
  117. package/lib/commands/lifecycle-external.js +3 -3
  118. package/lib/commands/manifest-cli-auth.js +29 -0
  119. package/lib/commands/manifest-cli-commands.js +170 -0
  120. package/lib/commands/manifest-cli-integration-path.js +63 -0
  121. package/lib/commands/manifest.js +21 -0
  122. package/lib/commands/protection-cli-leaves.js +3 -3
  123. package/lib/commands/repair-auth-apply.js +15 -1
  124. package/lib/commands/repair-authentications-454.js +169 -0
  125. package/lib/commands/repair-capability-openapi-warnings.js +126 -0
  126. package/lib/commands/repair-datasource-apply.js +135 -0
  127. package/lib/commands/repair-datasource-auto-rbac.js +62 -1
  128. package/lib/commands/repair-datasource-http-service-contract.js +239 -0
  129. package/lib/commands/repair-datasource-operation-security.js +180 -0
  130. package/lib/commands/repair-datasource-run.js +7 -2
  131. package/lib/commands/repair-datasource-sync-operations.js +177 -0
  132. package/lib/commands/repair-datasource-webhooks-sync-bridge.js +133 -0
  133. package/lib/commands/repair-datasource.js +12 -68
  134. package/lib/commands/repair-env-template.js +11 -1
  135. package/lib/commands/repair-external-run.js +121 -31
  136. package/lib/commands/repair-internal.js +1 -1
  137. package/lib/commands/repair-openapi-export.js +156 -0
  138. package/lib/commands/repair-openapi-sync.js +19 -2
  139. package/lib/commands/repair-orchestration-datasource-split.js +259 -0
  140. package/lib/commands/repair-persist.js +22 -1
  141. package/lib/commands/repair-rbac-platform-preset.js +204 -0
  142. package/lib/commands/repair-rbac-reader-roles.js +191 -0
  143. package/lib/commands/repair-rbac.js +163 -86
  144. package/lib/commands/repair-steps.js +83 -18
  145. package/lib/commands/repair-system-permissions.js +1 -0
  146. package/lib/commands/repair.js +1 -1
  147. package/lib/commands/resource-type.js +65 -26
  148. package/lib/commands/run-post-publish-data-sync.js +68 -0
  149. package/lib/commands/setup-modes.js +1 -1
  150. package/lib/commands/test-e2e-external.js +21 -8
  151. package/lib/commands/test-governance-cli-options.js +2 -2
  152. package/lib/commands/test-trust-cli-options.js +2 -2
  153. package/lib/commands/up-builder-api-bootstrap.js +71 -0
  154. package/lib/commands/up-builder-api-provision.js +241 -0
  155. package/lib/commands/up-builder-api.js +88 -0
  156. package/lib/commands/up-common.js +25 -1
  157. package/lib/commands/upload-credential-push-log.js +117 -0
  158. package/lib/commands/upload-data-sync-finalize.js +60 -0
  159. package/lib/commands/upload-probe.js +66 -0
  160. package/lib/commands/upload-publish-context.js +4 -1
  161. package/lib/commands/upload-sidecar-followups.js +55 -27
  162. package/lib/commands/upload.js +116 -157
  163. package/lib/commands/verify-governance-combined-external.js +1 -1
  164. package/lib/commands/verify-governance-db.js +2 -2
  165. package/lib/commands/verify-operations-command-action.js +2 -2
  166. package/lib/commands/verify-operations-step-plan.js +2 -2
  167. package/lib/commands/verify-operations-steps.js +2 -2
  168. package/lib/commands/verify-trust-command-action.js +1 -1
  169. package/lib/commands/wizard-core.js +1 -1
  170. package/lib/commands/wizard-headless.js +2 -1
  171. package/lib/core/admin-secrets.js +2 -6
  172. package/lib/core/secrets-env-content.js +10 -4
  173. package/lib/core/secrets-env-write.js +2 -13
  174. package/lib/datasource/agent-trust-run.js +3 -3
  175. package/lib/datasource/deploy.js +3 -1
  176. package/lib/datasource/test-e2e.js +6 -1
  177. package/lib/datasource/unified-validation-run-body.js +4 -1
  178. package/lib/datasource/unified-validation-run.js +1 -1
  179. package/lib/deployment/deploy-poll-ui.js +73 -12
  180. package/lib/deployment/deployer-poll-run.js +113 -0
  181. package/lib/deployment/deployer.js +17 -87
  182. package/lib/evidence/dataplane-context.js +21 -0
  183. package/lib/evidence/evidence-display.js +78 -0
  184. package/lib/evidence/evidence-service.js +392 -0
  185. package/lib/external-system/deploy.js +290 -112
  186. package/lib/external-system/download.js +7 -3
  187. package/lib/external-system/test-execution.js +1 -1
  188. package/lib/external-system/test-system-level.js +8 -10
  189. package/lib/external-system/test.js +12 -6
  190. package/lib/generator/deploy-script.js +73 -0
  191. package/lib/generator/external.js +2 -1
  192. package/lib/generator/index.js +17 -2
  193. package/lib/generator/wizard.js +3 -36
  194. package/lib/internal/fs-real-sync.js +22 -1
  195. package/lib/internal/node-fs.js +2 -0
  196. package/lib/lifecycle/lifecycle-governance-options.js +1 -1
  197. package/lib/lifecycle/verify-step-progress.js +1 -1
  198. package/lib/programmatic/access-log.js +26 -0
  199. package/lib/programmatic/auth-config.js +44 -0
  200. package/lib/programmatic/bearer-auth.js +176 -0
  201. package/lib/programmatic/builder-api-request.js +175 -0
  202. package/lib/programmatic/builder-api-route-dispatch.js +82 -0
  203. package/lib/programmatic/builder-api-runtime-config.js +42 -0
  204. package/lib/programmatic/builder-api-server.js +230 -0
  205. package/lib/programmatic/builder-help-authentication-catalog.js +282 -0
  206. package/lib/programmatic/builder-help-connected-system-ui.js +266 -0
  207. package/lib/programmatic/builder-help-enterprise-sync-fabrix.js +60 -0
  208. package/lib/programmatic/builder-help-envelope.js +36 -0
  209. package/lib/programmatic/builder-help-fixtures.js +200 -0
  210. package/lib/programmatic/builder-help-governance.js +172 -0
  211. package/lib/programmatic/builder-help-schema-catalog.js +92 -0
  212. package/lib/programmatic/builder-help.js +361 -0
  213. package/lib/programmatic/capability-registry.js +77 -0
  214. package/lib/programmatic/command-options.js +32 -0
  215. package/lib/programmatic/enterprise-mcp-client.js +98 -0
  216. package/lib/programmatic/http-problem-details.js +99 -0
  217. package/lib/programmatic/http-route-match.js +40 -0
  218. package/lib/programmatic/idempotency-cache.js +69 -0
  219. package/lib/programmatic/index.js +53 -0
  220. package/lib/programmatic/integration-path-scope.js +39 -0
  221. package/lib/programmatic/log-redaction.js +66 -0
  222. package/lib/programmatic/manifest-get-section.js +146 -0
  223. package/lib/programmatic/manifest-patch-section.js +252 -0
  224. package/lib/programmatic/manifest-repair.js +122 -0
  225. package/lib/programmatic/manifest-section-dependency-graph.js +160 -0
  226. package/lib/programmatic/manifest-section-io.js +225 -0
  227. package/lib/programmatic/manifest-section-quality.js +171 -0
  228. package/lib/programmatic/manifest-section-registry-data.js +269 -0
  229. package/lib/programmatic/manifest-section-registry.js +205 -0
  230. package/lib/programmatic/nest-http-bridge.js +34 -0
  231. package/lib/programmatic/openapi-component-schemas.js +68 -0
  232. package/lib/programmatic/openapi-description-enricher.js +117 -0
  233. package/lib/programmatic/openapi-descriptions.js +190 -0
  234. package/lib/programmatic/openapi-docs-serving.js +123 -0
  235. package/lib/programmatic/openapi-help-schemas.js +63 -0
  236. package/lib/programmatic/openapi-manifest-schemas.js +141 -0
  237. package/lib/programmatic/openapi-operation-bindings.js +274 -0
  238. package/lib/programmatic/openapi-request-schemas.js +155 -0
  239. package/lib/programmatic/openapi-result-schemas.js +476 -0
  240. package/lib/programmatic/openapi-schema-descriptions-certify.js +139 -0
  241. package/lib/programmatic/openapi-schema-descriptions-core.js +159 -0
  242. package/lib/programmatic/openapi-schema-descriptions-help.js +40 -0
  243. package/lib/programmatic/openapi-schema-descriptions-manifest.js +143 -0
  244. package/lib/programmatic/openapi-schema-descriptions-mcp.js +118 -0
  245. package/lib/programmatic/openapi-schema-descriptions-operations.js +281 -0
  246. package/lib/programmatic/openapi-schema-helpers.js +93 -0
  247. package/lib/programmatic/openapi-spec.js +203 -0
  248. package/lib/programmatic/orchestration-openapi-meta.js +159 -0
  249. package/lib/programmatic/platform-rbac-catalog.js +90 -0
  250. package/lib/programmatic/request-timeout.js +53 -0
  251. package/lib/programmatic/route-handler-map.js +143 -0
  252. package/lib/programmatic/route-handlers-context.js +29 -0
  253. package/lib/programmatic/route-handlers.js +33 -0
  254. package/lib/programmatic/run-certify.js +57 -0
  255. package/lib/programmatic/run-enterprise-mcp.js +32 -0
  256. package/lib/programmatic/run-lifecycle.js +29 -0
  257. package/lib/programmatic/run-repair.js +41 -0
  258. package/lib/programmatic/run-repository-emcp.js +54 -0
  259. package/lib/programmatic/run-template-workspace.js +61 -0
  260. package/lib/programmatic/run-test.js +49 -0
  261. package/lib/programmatic/run-upload.js +63 -0
  262. package/lib/programmatic/run-validate.js +53 -0
  263. package/lib/programmatic/run-wizard.js +40 -0
  264. package/lib/programmatic/system-key.js +48 -0
  265. package/lib/programmatic/wizard-config-normalize.js +118 -0
  266. package/lib/programmatic/workspace-cleanup.js +128 -0
  267. package/lib/programmatic/workspace-context.js +145 -0
  268. package/lib/programmatic/workspace-lock.js +75 -0
  269. package/lib/programmatic/workspace-meta.js +64 -0
  270. package/lib/programmatic/workspace-ops.js +149 -0
  271. package/lib/protection/run-commands-upload-sync.js +35 -0
  272. package/lib/protection/run-commands.js +2 -20
  273. package/lib/protection/upload-batch.js +11 -7
  274. package/lib/resolvers/resource-type-file.js +22 -0
  275. package/lib/schema/external-datasource.schema.json +161 -1
  276. package/lib/schema/external-system.schema.json +242 -4
  277. package/lib/schema/flag-map-validation-run.json +3 -0
  278. package/lib/schema/type/credential-field-registry.json +2 -2
  279. package/lib/schema/type/document-storage.json +9 -0
  280. package/lib/utils/agent-trust-run-display.js +1 -1
  281. package/lib/utils/app-path-resolve.js +168 -0
  282. package/lib/utils/authentication-env-template.js +222 -0
  283. package/lib/utils/cli-sync-options.js +7 -11
  284. package/lib/utils/cli-utils.js +4 -0
  285. package/lib/utils/cli-workspace-options.js +29 -0
  286. package/lib/utils/compose-generate-docker-compose.js +102 -0
  287. package/lib/utils/configuration-env-resolver.js +203 -27
  288. package/lib/utils/datasource-test-run-certificate-tty.js +28 -2
  289. package/lib/utils/datasource-test-run-certification-debug.js +130 -0
  290. package/lib/utils/datasource-test-run-debug-display.js +2 -0
  291. package/lib/utils/datasource-test-run-debug-slice.js +7 -0
  292. package/lib/utils/datasource-test-run-display.js +2 -1
  293. package/lib/utils/dev-init-ssh-merge.js +165 -23
  294. package/lib/utils/dev-pin-share-instructions.js +110 -0
  295. package/lib/utils/dev-ssh-config-helper.js +177 -33
  296. package/lib/utils/enterprise-knowledge-paths.js +142 -0
  297. package/lib/utils/env-copy.js +2 -1
  298. package/lib/utils/env-dotenv-format.js +103 -0
  299. package/lib/utils/external-env-template.js +4 -1
  300. package/lib/utils/external-system-display.js +5 -1
  301. package/lib/utils/external-system-readiness-compact-blocks.js +221 -0
  302. package/lib/utils/external-system-readiness-compact-display.js +324 -0
  303. package/lib/utils/external-system-readiness-core.js +16 -0
  304. package/lib/utils/external-system-readiness-deploy-display.js +29 -11
  305. package/lib/utils/external-system-readiness-display-internals.js +3 -1
  306. package/lib/utils/external-system-readiness-display.js +20 -30
  307. package/lib/utils/external-system-system-test-tty-certification.js +135 -0
  308. package/lib/utils/external-system-system-test-tty.js +5 -41
  309. package/lib/utils/help-builder.js +6 -1
  310. package/lib/utils/host-ops-job-labels.js +236 -0
  311. package/lib/utils/host-ops-job-result.js +61 -0
  312. package/lib/utils/host-ops-poll-ui.js +163 -0
  313. package/lib/utils/integration-path-resolve.js +112 -0
  314. package/lib/utils/paths-reload-source.js +148 -0
  315. package/lib/utils/paths-system-builder-keys.js +25 -0
  316. package/lib/utils/paths.js +151 -26
  317. package/lib/utils/runtime-configuration-values.js +64 -2
  318. package/lib/utils/secrets-helpers.js +5 -1
  319. package/lib/utils/ssh-known-hosts.js +130 -0
  320. package/lib/utils/test-target-cli-options.js +75 -0
  321. package/lib/utils/upload-sync-options.js +4 -0
  322. package/lib/utils/validation-run-request.js +11 -2
  323. package/lib/validation/external-manifest-validator.js +11 -1
  324. package/lib/validation/openapi-contract-surface-validator.js +426 -0
  325. package/lib/validation/openapi-contract-vendor-validation.js +238 -0
  326. package/lib/validation/validate-external-file.js +160 -0
  327. package/lib/validation/validate.js +6 -117
  328. package/package.json +46 -29
  329. package/packages/builder-api/README.md +120 -0
  330. package/packages/builder-api/package.json +30 -0
  331. package/packages/builder-api/src/app.module.ts +7 -0
  332. package/packages/builder-api/src/auth/auth.module.ts +5 -0
  333. package/packages/builder-api/src/external-system/external-system.module.ts +5 -0
  334. package/packages/builder-api/src/main.ts +16 -0
  335. package/packages/builder-api/tsconfig.json +15 -0
  336. package/scripts/check-builder-api-architecture-grep.js +79 -0
  337. package/scripts/docker_image_content_gate.js +47 -0
  338. package/scripts/docker_image_content_gate.sh +5 -0
  339. package/scripts/export-builder-api-evidence.js +262 -0
  340. package/scripts/lib/builder-api-docker-staging-copy.js +60 -0
  341. package/scripts/lib/builder-api-docker-staging-core.js +183 -0
  342. package/scripts/lib/docker-image-content-gate-core.js +166 -0
  343. package/scripts/lib/plan-actor.js +109 -0
  344. package/scripts/lib/plan-config.js +20 -0
  345. package/scripts/lib/plan-gates.js +154 -0
  346. package/scripts/lib/plan-meta.js +104 -0
  347. package/scripts/lib/plan-parse.js +162 -0
  348. package/scripts/lib/plan-prevalidate-gates.js +326 -0
  349. package/scripts/lib/plan-run-core.js +125 -0
  350. package/scripts/lib/plan-run-report.js +108 -0
  351. package/scripts/plan-approve.js +24 -0
  352. package/scripts/plan-archive.js +49 -0
  353. package/scripts/plan-run.js +13 -0
  354. package/scripts/plan-set-actor.js +21 -0
  355. package/scripts/plan-validate.js +80 -0
  356. package/scripts/pnpm/af.mjs +110 -0
  357. package/scripts/pnpm/check-quiet.mjs +32 -0
  358. package/scripts/pnpm/dev-install.mjs +29 -0
  359. package/scripts/pnpm/dev-reload.mjs +18 -0
  360. package/scripts/pnpm/help.mjs +55 -0
  361. package/scripts/pnpm/lib/dev-reload-core.mjs +189 -0
  362. package/scripts/pnpm/lib/dev-reload-log-capture.mjs +67 -0
  363. package/scripts/pnpm/lib/dev-reload-log-utils.mjs +32 -0
  364. package/scripts/pnpm/lib/resolve-aifabrix-bin.mjs +124 -0
  365. package/scripts/pnpm/lib/resolve-app-url.mjs +183 -0
  366. package/scripts/pnpm/lib/spinner.mjs +42 -0
  367. package/scripts/stage_builder_api_for_docker.js +65 -0
  368. package/scripts/sync-builder-api-template.js +44 -0
  369. package/templates/README.md +3 -0
  370. package/templates/applications/builder-api/Dockerfile +38 -0
  371. package/templates/applications/builder-api/application.yaml +75 -0
  372. package/templates/applications/builder-api/env.template +48 -0
  373. package/templates/applications/dataplane/application.yaml +1 -1
  374. package/templates/applications/dataplane/env.template +10 -6
  375. package/templates/applications/dataplane/rbac.yaml +21 -1
  376. package/templates/applications/miso-controller/application.yaml +1 -1
  377. package/templates/applications/miso-controller/env.template +1 -3
  378. package/templates/channels/README.md +18 -0
  379. package/templates/channels/ai-fabrix-icon.jpg +0 -0
  380. package/templates/channels/chatgpt/install.template.md.hbs +21 -24
  381. package/templates/channels/chatgpt/integration/README.md +11 -0
  382. package/templates/channels/chatgpt/integration/application.json +15 -0
  383. package/templates/channels/chatgpt/integration/chatgpt-system.json +29 -0
  384. package/templates/channels/chatgpt/integration/env.template +4 -0
  385. package/templates/channels/microsoft-copilot/install.template.md.hbs +20 -25
  386. package/templates/channels/microsoft-copilot/integration/README.md +11 -0
  387. package/templates/channels/microsoft-copilot/integration/application.json +15 -0
  388. package/templates/channels/microsoft-copilot/integration/env.template +6 -0
  389. package/templates/channels/microsoft-copilot/integration/microsoft-copilot-system.json +34 -0
  390. package/templates/channels/slack/install.template.md.hbs +48 -18
  391. package/templates/channels/slack/integration/README.md +38 -0
  392. package/templates/channels/slack/integration/application.json +18 -0
  393. package/templates/channels/slack/integration/env.template +29 -0
  394. package/templates/channels/slack/integration/slack-datasource-conversations.json +226 -0
  395. package/templates/channels/slack/integration/slack-datasource-messages.json +269 -0
  396. package/templates/channels/slack/integration/slack-system.json +86 -0
  397. package/templates/channels/slack/manifest.template.json.hbs +20 -10
  398. package/templates/channels/teams-bot/install.template.md.hbs +31 -17
  399. package/templates/channels/teams-bot/integration/README.md +18 -0
  400. package/templates/channels/teams-bot/integration/application.json +17 -0
  401. package/templates/channels/teams-bot/integration/env.template +5 -0
  402. package/templates/channels/teams-bot/integration/teams-bot-system.json +55 -0
  403. package/templates/channels/teams-bot/manifest.template.json.hbs +27 -0
  404. package/templates/channels/web-embed/install.template.md.hbs +16 -26
  405. package/templates/channels/web-embed/integration/README.md +11 -0
  406. package/templates/channels/web-embed/integration/application.json +15 -0
  407. package/templates/channels/web-embed/integration/env.template +4 -0
  408. package/templates/channels/web-embed/integration/web-embed-system.json +29 -0
  409. package/templates/openapi/redoc_page.html +86 -0
  410. package/templates/python/docker-compose.hbs +11 -0
  411. package/templates/python/requirements.txt +1 -1
  412. package/templates/typescript/docker-compose.hbs +11 -0
  413. package/lib/certification/cli-cert-sync-skip.js +0 -21
@@ -9,54 +9,223 @@
9
9
 
10
10
  const path = require('path');
11
11
  const fs = require('fs');
12
- const { getIntegrationPath } = require('./paths');
12
+ const { resolveExternalSystemPath } = require('./app-path-resolve');
13
13
  const { parseEnvToMap } = require('./credential-secrets-env');
14
14
  const { loadSecrets, resolveKvReferences } = require('../core/secrets');
15
+ const { expandDeclarativeUrlsIfPresent } = require('../core/secrets-env-declarative-expand');
16
+ const { resolveApplicationConfigPath } = require('./app-config-resolver');
15
17
  const { loadEnvTemplate } = require('./secrets-helpers');
16
18
  const { getActualSecretsPath } = require('./secrets-path');
17
19
 
18
20
  const VAR_PLACEHOLDER_REGEX = /\{\{([^}]+)\}\}/g;
19
21
 
22
+ /**
23
+ * Env.template keys whose RHS uses declarative url:// (upload overlay candidates).
24
+ *
25
+ * @param {string} envTemplateContent
26
+ * @returns {Set<string>}
27
+ */
28
+ function getUrlDeclarativeEnvKeysFromTemplateContent(envTemplateContent) {
29
+ const keys = new Set();
30
+ if (!envTemplateContent || typeof envTemplateContent !== 'string') {
31
+ return keys;
32
+ }
33
+ for (const line of envTemplateContent.split(/\r?\n/)) {
34
+ const trimmed = line.trim();
35
+ if (!trimmed || trimmed.startsWith('#')) {
36
+ continue;
37
+ }
38
+ const eq = trimmed.indexOf('=');
39
+ if (eq <= 0) {
40
+ continue;
41
+ }
42
+ const key = trimmed.substring(0, eq).trim();
43
+ const value = trimmed.substring(eq + 1);
44
+ if (key && value.includes('url://')) {
45
+ keys.add(key);
46
+ }
47
+ }
48
+ return keys;
49
+ }
50
+
51
+ /**
52
+ * @param {string} systemKey
53
+ * @param {string} templateContent
54
+ * @param {Object} secrets
55
+ * @returns {Promise<Object.<string, string>>}
56
+ */
57
+ async function resolveDockerTemplateMap(systemKey, templateContent, secrets, options = {}) {
58
+ const appPath = resolveExternalSystemPath(systemKey, options);
59
+ const secretsPaths = await getActualSecretsPath(undefined, systemKey);
60
+ let resolved = await resolveKvReferences(
61
+ templateContent,
62
+ secrets,
63
+ 'docker',
64
+ secretsPaths,
65
+ systemKey,
66
+ { envTemplatePath: path.join(appPath, 'env.template') }
67
+ );
68
+
69
+ let variablesPath = null;
70
+ try {
71
+ variablesPath = resolveApplicationConfigPath(appPath);
72
+ } catch {
73
+ variablesPath = null;
74
+ }
75
+
76
+ resolved = await expandDeclarativeUrlsIfPresent(
77
+ resolved,
78
+ systemKey,
79
+ appPath,
80
+ variablesPath,
81
+ 'docker',
82
+ false
83
+ );
84
+ return parseEnvToMap(resolved);
85
+ }
86
+
87
+ /**
88
+ * @param {Object.<string, string>} envMap
89
+ * @param {Set<string>} urlKeys
90
+ * @param {Object.<string, string>} dockerMap
91
+ * @returns {Object.<string, string>}
92
+ */
93
+ function mergeUrlKeysIntoEnvMap(envMap, urlKeys, dockerMap) {
94
+ const out = { ...envMap };
95
+ for (const key of urlKeys) {
96
+ const raw = dockerMap[key];
97
+ if (raw === undefined || raw === null) {
98
+ continue;
99
+ }
100
+ const value = String(raw).trim();
101
+ if (value && !value.includes('url://')) {
102
+ out[key] = value;
103
+ }
104
+ }
105
+ return out;
106
+ }
107
+
108
+ /**
109
+ * Overlays docker-profile expansions for env.template url:// keys onto an env map.
110
+ * Host `.env` may use local profile URLs; dataplane CIP runs in Docker and needs internal service URLs.
111
+ *
112
+ * @param {string} systemKey
113
+ * @param {Object.<string, string>} envMap
114
+ * @param {Object} secrets
115
+ * @returns {Promise<Object.<string, string>>}
116
+ */
117
+ async function overlayDataplaneRuntimeEnvFromTemplate(systemKey, envMap, secrets, options = {}) {
118
+ const appPath = resolveExternalSystemPath(systemKey, options);
119
+ const envTemplatePath = path.join(appPath, 'env.template');
120
+ if (!fs.existsSync(envTemplatePath)) {
121
+ return envMap;
122
+ }
123
+
124
+ const templateContent = loadEnvTemplate(envTemplatePath);
125
+ const urlKeys = getUrlDeclarativeEnvKeysFromTemplateContent(templateContent);
126
+ if (urlKeys.size === 0) {
127
+ return envMap;
128
+ }
129
+
130
+ const dockerMap = await resolveDockerTemplateMap(systemKey, templateContent, secrets, options);
131
+ return mergeUrlKeysIntoEnvMap(envMap, urlKeys, dockerMap);
132
+ }
133
+
134
+ async function loadIntegrationSecrets(systemKey) {
135
+ try {
136
+ return await loadSecrets(undefined, systemKey);
137
+ } catch {
138
+ return {};
139
+ }
140
+ }
141
+
142
+ async function readIntegrationEnvMap(integrationPath, systemKey, secrets) {
143
+ const envPath = path.join(integrationPath, '.env');
144
+ const envTemplatePath = path.join(integrationPath, 'env.template');
145
+ if (fs.existsSync(envPath)) {
146
+ return parseEnvToMap(fs.readFileSync(envPath, 'utf8'));
147
+ }
148
+ if (!fs.existsSync(envTemplatePath)) {
149
+ return {};
150
+ }
151
+ const templateContent = loadEnvTemplate(envTemplatePath);
152
+ const secretsPaths = await getActualSecretsPath(undefined, systemKey);
153
+ const resolvedContent = await resolveKvReferences(
154
+ templateContent,
155
+ secrets,
156
+ 'local',
157
+ secretsPaths,
158
+ systemKey
159
+ );
160
+ return parseEnvToMap(resolvedContent);
161
+ }
162
+
20
163
  /**
21
164
  * Builds resolved env map and secrets for an integration app (for configuration resolution).
22
165
  * If .env exists, parses it; otherwise resolves env.template with secrets and parses the result.
23
166
  *
24
167
  * @param {string} systemKey - External system key (e.g. 'my-sharepoint')
168
+ * @param {Object} [options]
169
+ * @param {boolean} [options.dataplaneRuntime=false] - When true, overlay docker-profile url:// values from env.template for publish/runtime config push
25
170
  * @returns {Promise<{ envMap: Object.<string, string>, secrets: Object }>} envMap for {{VAR}} substitution, secrets for kv://
26
171
  * @throws {Error} If env.template is missing when .env is missing (only when building from template)
27
172
  */
28
- async function buildResolvedEnvMapForIntegration(systemKey) {
173
+ async function buildResolvedEnvMapForIntegration(systemKey, options = {}) {
29
174
  if (!systemKey || typeof systemKey !== 'string') {
30
175
  throw new Error('systemKey is required and must be a string');
31
176
  }
32
- const integrationPath = getIntegrationPath(systemKey);
33
- const envPath = path.join(integrationPath, '.env');
34
- const envTemplatePath = path.join(integrationPath, 'env.template');
177
+ const integrationPath = resolveExternalSystemPath(systemKey, options);
178
+ const secrets = await loadIntegrationSecrets(systemKey);
179
+ let envMap = await readIntegrationEnvMap(integrationPath, systemKey, secrets);
180
+ if (options.dataplaneRuntime === true) {
181
+ envMap = await overlayDataplaneRuntimeEnvFromTemplate(systemKey, envMap, secrets);
182
+ }
183
+ applyPathParamEnvAliases(envMap);
184
+ return { envMap, secrets };
185
+ }
35
186
 
36
- let secrets = {};
37
- try {
38
- secrets = await loadSecrets(undefined, systemKey);
39
- } catch {
40
- secrets = {};
187
+ function applyPathParamEnvAliases(envMap) {
188
+ if (!envMap || typeof envMap !== 'object') {
189
+ return envMap;
190
+ }
191
+ const systemKey = envMap.systemKey;
192
+ if (
193
+ (!systemKey || String(systemKey).includes('{{')) &&
194
+ envMap.E2E_SYSTEM_KEY &&
195
+ !String(envMap.E2E_SYSTEM_KEY).includes('{{')
196
+ ) {
197
+ envMap.systemKey = String(envMap.E2E_SYSTEM_KEY).trim();
198
+ }
199
+ const pillar = envMap.pillar;
200
+ if (
201
+ (!pillar || String(pillar).includes('{{')) &&
202
+ envMap.E2E_CERTIFY_PILLAR &&
203
+ !String(envMap.E2E_CERTIFY_PILLAR).includes('{{')
204
+ ) {
205
+ envMap.pillar = String(envMap.E2E_CERTIFY_PILLAR).trim();
41
206
  }
207
+ return envMap;
208
+ }
42
209
 
43
- let envMap = {};
44
- if (fs.existsSync(envPath)) {
45
- const content = fs.readFileSync(envPath, 'utf8');
46
- envMap = parseEnvToMap(content);
47
- } else if (fs.existsSync(envTemplatePath)) {
48
- const templateContent = loadEnvTemplate(envTemplatePath);
49
- const secretsPaths = await getActualSecretsPath(undefined, systemKey);
50
- const resolvedContent = await resolveKvReferences(
51
- templateContent,
52
- secrets,
53
- 'local',
54
- secretsPaths,
55
- systemKey
56
- );
57
- envMap = parseEnvToMap(resolvedContent);
210
+ /**
211
+ * True when value is `{{pathParam}}` pointing at an OpenAPI path segment (camelCase), not env self-ref.
212
+ * @param {string} value
213
+ * @param {string} [configName]
214
+ * @returns {boolean}
215
+ */
216
+ function isOpenApiPathParamAliasTemplate(value, configName) {
217
+ if (typeof value !== 'string') {
218
+ return false;
58
219
  }
59
- return { envMap, secrets };
220
+ const match = value.trim().match(/^\{\{(\w+)\}\}$/);
221
+ if (!match) {
222
+ return false;
223
+ }
224
+ const alias = match[1];
225
+ if (!alias || alias === configName) {
226
+ return false;
227
+ }
228
+ return /^[a-z]/.test(alias);
60
229
  }
61
230
 
62
231
  /**
@@ -99,6 +268,9 @@ function resolveConfigurationValues(configArray, envMap, secrets, systemKey) {
99
268
  if (item.value.trim().startsWith('kv://')) {
100
269
  throw new Error(`Configuration entry '${item.name || 'unknown'}' has location 'variable' but value is kv://. Use location 'keyvault' for secrets.`);
101
270
  }
271
+ if (isOpenApiPathParamAliasTemplate(item.value, item.name)) {
272
+ continue;
273
+ }
102
274
  item.value = substituteVarPlaceholders(item.value, envMap, systemKey);
103
275
  } else if (location === 'keyvault') {
104
276
  if (!item.value.trim().startsWith('kv://')) {
@@ -234,7 +406,7 @@ function retemplateDatasourceConfigurationOverrides(configArray) {
234
406
  */
235
407
  async function retemplateConfigurationForDownload(systemKey, configArray) {
236
408
  if (!systemKey || typeof systemKey !== 'string' || !Array.isArray(configArray)) return false;
237
- const integrationPath = getIntegrationPath(systemKey);
409
+ const integrationPath = resolveExternalSystemPath(systemKey, {});
238
410
  const envTemplatePath = path.join(integrationPath, 'env.template');
239
411
  if (!fs.existsSync(envTemplatePath)) return false;
240
412
  const content = fs.readFileSync(envTemplatePath, 'utf8');
@@ -245,6 +417,10 @@ async function retemplateConfigurationForDownload(systemKey, configArray) {
245
417
 
246
418
  module.exports = {
247
419
  buildResolvedEnvMapForIntegration,
420
+ getUrlDeclarativeEnvKeysFromTemplateContent,
421
+ overlayDataplaneRuntimeEnvFromTemplate,
422
+ applyPathParamEnvAliases,
423
+ isOpenApiPathParamAliasTemplate,
248
424
  resolveConfigurationValues,
249
425
  collectResolvedVariableConfigurationNames,
250
426
  getEnvTemplateVariableNames,
@@ -50,14 +50,39 @@ function appendCertificateBlockerLines(lines, blockers, maxVisible) {
50
50
  const cap = Math.min(maxVisible, blockers.length);
51
51
  for (let i = 0; i < cap; i += 1) {
52
52
  const b = blockers[i];
53
+ const code = b && b.code ? String(b.code) : '';
53
54
  const msg = b && b.message ? String(b.message) : '';
54
- if (msg) lines.push(chalk.yellow(` • ${msg}`));
55
+ const tail = [code, msg].filter(Boolean).join(' — ');
56
+ if (tail) lines.push(chalk.yellow(` • ${tail}`));
55
57
  }
56
58
  if (blockers.length > cap) {
57
59
  lines.push(chalk.gray(` … and ${blockers.length - cap} more`));
58
60
  }
59
61
  }
60
62
 
63
+ /**
64
+ * Auto-issue outcome when dataplane could not write an integration certificate.
65
+ * @param {string[]} lines
66
+ * @param {Object} envelope
67
+ */
68
+ function appendCertificateIssuanceTTY(lines, envelope) {
69
+ const issuance = envelope && envelope.certificateIssuance;
70
+ if (!issuance || typeof issuance !== 'object') return;
71
+ const status = issuance.status !== undefined && issuance.status !== null ? String(issuance.status) : '';
72
+ if (!status || status === 'issued' || status === 'reusedActive' || status === 'skipped') return;
73
+
74
+ lines.push('');
75
+ lines.push(sectionTitle('Certificate issuance:'));
76
+ const reason = issuance.reasonCode ? String(issuance.reasonCode) : '';
77
+ lines.push(chalk.white(` ✖ ${status}${reason ? ` (${reason})` : ''}`));
78
+ if (issuance.message) {
79
+ lines.push(chalk.yellow(` ${String(issuance.message)}`));
80
+ }
81
+ if (issuance.validationHint) {
82
+ lines.push(chalk.gray(` ${String(issuance.validationHint)}`));
83
+ }
84
+ }
85
+
61
86
  /**
62
87
  * Certification / certificate tier (integration engine or E2E envelope after active cert attach).
63
88
  * @param {string[]} lines
@@ -78,5 +103,6 @@ function appendCertificateTTY(lines, envelope) {
78
103
  }
79
104
 
80
105
  module.exports = {
81
- appendCertificateTTY
106
+ appendCertificateTTY,
107
+ appendCertificateIssuanceTTY
82
108
  };
@@ -0,0 +1,130 @@
1
+ /**
2
+ * @fileoverview Certification / certificate issuance debug helpers for DatasourceTestRun.
3
+ * @author AI Fabrix Team
4
+ * @version 2.0.0
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const chalk = require('chalk');
10
+ const { sectionTitle } = require('./cli-test-layout-chalk');
11
+
12
+ /**
13
+ * @param {Object|undefined|null} output
14
+ * @returns {Object|undefined}
15
+ */
16
+ function sliceCertificationOutput(output) {
17
+ if (!output || typeof output !== 'object') return undefined;
18
+ return {
19
+ summaryText: output.summaryText,
20
+ summaryLines: Array.isArray(output.summaryLines) ? output.summaryLines.slice(0, 40) : undefined,
21
+ explainText: output.explainText,
22
+ explainLines: Array.isArray(output.explainLines) ? output.explainLines.slice(0, 80) : undefined,
23
+ passed: output.passed,
24
+ level: output.level,
25
+ blockers: Array.isArray(output.blockers) ? output.blockers.slice(0, 30) : undefined
26
+ };
27
+ }
28
+
29
+ /**
30
+ * @param {Object|undefined|null} issuance
31
+ * @returns {Object|undefined}
32
+ */
33
+ function sliceCertificateIssuance(issuance) {
34
+ if (!issuance || typeof issuance !== 'object') return undefined;
35
+ return {
36
+ status: issuance.status,
37
+ reasonCode: issuance.reasonCode,
38
+ message: issuance.message,
39
+ validationHint: issuance.validationHint,
40
+ systemKey: issuance.systemKey,
41
+ datasourceKey: issuance.datasourceKey
42
+ };
43
+ }
44
+
45
+ function certificationOutputFromEnvelope(envelope) {
46
+ const v = envelope && envelope.validation;
47
+ return v && typeof v === 'object' ? v.certificationOutput : null;
48
+ }
49
+
50
+ function blockerCode(blocker) {
51
+ if (!blocker || typeof blocker !== 'object') return '';
52
+ const code = blocker.code;
53
+ return code !== undefined && code !== null ? String(code).trim() : '';
54
+ }
55
+
56
+ function blockerMessage(blocker) {
57
+ if (!blocker || typeof blocker !== 'object') return '';
58
+ const msg = blocker.message;
59
+ return msg !== undefined && msg !== null ? String(msg).trim() : '';
60
+ }
61
+
62
+ /**
63
+ * @param {string[]} lines
64
+ * @param {Object} output
65
+ * @param {number} maxBlockers
66
+ */
67
+ function pushCertificationOutputSummary(lines, output, maxBlockers) {
68
+ const passed = output.passed === true;
69
+ const level = output.level !== undefined && output.level !== null ? String(output.level) : '';
70
+ const glyph = passed ? '✔' : '✖';
71
+ const tier = level ? ` tier ${level}` : '';
72
+ lines.push(`Certification engine: ${glyph} ${passed ? 'passed' : 'not passed'}${tier}`);
73
+ const blockers = Array.isArray(output.blockers) ? output.blockers : [];
74
+ const cap = Math.min(maxBlockers, blockers.length);
75
+ for (let i = 0; i < cap; i += 1) {
76
+ const code = blockerCode(blockers[i]);
77
+ const msg = blockerMessage(blockers[i]);
78
+ const tail = [code, msg].filter(Boolean).join(' — ');
79
+ if (tail) lines.push(` • ${tail}`);
80
+ }
81
+ if (blockers.length > cap) {
82
+ lines.push(` … and ${blockers.length - cap} more blocker(s)`);
83
+ }
84
+ const summaryLines = Array.isArray(output.summaryLines) ? output.summaryLines : [];
85
+ const summaryCap = Math.min(6, summaryLines.length);
86
+ for (let i = 0; i < summaryCap; i += 1) {
87
+ const line = String(summaryLines[i] || '').trim();
88
+ if (line) lines.push(chalk.gray(` ${line}`));
89
+ }
90
+ }
91
+
92
+ /**
93
+ * @param {string[]} lines
94
+ * @param {Object} issuance
95
+ */
96
+ function pushCertificateIssuanceSummary(lines, issuance) {
97
+ const status = issuance.status !== undefined && issuance.status !== null ? String(issuance.status) : '';
98
+ const reason = issuance.reasonCode ? String(issuance.reasonCode) : '';
99
+ const msg = issuance.message ? String(issuance.message) : '';
100
+ lines.push(`Certificate issuance: ${status || 'unknown'}${reason ? ` (${reason})` : ''}`);
101
+ if (msg) lines.push(chalk.yellow(` ${msg}`));
102
+ if (issuance.validationHint) {
103
+ lines.push(chalk.gray(` Hint: ${String(issuance.validationHint)}`));
104
+ }
105
+ }
106
+
107
+ /**
108
+ * Summary debug lines for certification + issuance (plan §3.7 debug appendix).
109
+ * @param {string[]} lines
110
+ * @param {Object|null|undefined} envelope
111
+ */
112
+ function pushCertificationDebugSummaryLines(lines, envelope) {
113
+ if (!envelope || typeof envelope !== 'object') return;
114
+ const output = certificationOutputFromEnvelope(envelope);
115
+ const issuance = envelope.certificateIssuance;
116
+ const hasOutput = output && typeof output === 'object';
117
+ const hasIssuance = issuance && typeof issuance === 'object';
118
+ if (!hasOutput && !hasIssuance) return;
119
+
120
+ lines.push(sectionTitle('Certification debug:'));
121
+ if (hasOutput) pushCertificationOutputSummary(lines, output, 5);
122
+ if (hasIssuance) pushCertificateIssuanceSummary(lines, issuance);
123
+ }
124
+
125
+ module.exports = {
126
+ sliceCertificationOutput,
127
+ sliceCertificateIssuance,
128
+ pushCertificationDebugSummaryLines,
129
+ certificationOutputFromEnvelope
130
+ };
@@ -12,6 +12,7 @@ const {
12
12
  parseCapacityDetailKey,
13
13
  formatCapacityOperationLabel
14
14
  } = require('./datasource-test-run-capacity-operations');
15
+ const { pushCertificationDebugSummaryLines } = require('./datasource-test-run-certification-debug');
15
16
 
16
17
  const FULL_MAX_BYTES_PER_STRING = 8192;
17
18
  const RAW_MAX_STRING_TTY = 65536;
@@ -210,6 +211,7 @@ function pushSummaryRefLines(lines, envelope) {
210
211
  try {
211
212
  pushSyncSummaryLines(lines, envelope);
212
213
  pushE2eTimingSummaryLines(lines, envelope);
214
+ pushCertificationDebugSummaryLines(lines, envelope);
213
215
  } catch {
214
216
  // ignore best-effort debug summary extraction
215
217
  }
@@ -4,6 +4,11 @@
4
4
 
5
5
  'use strict';
6
6
 
7
+ const {
8
+ sliceCertificationOutput,
9
+ sliceCertificateIssuance
10
+ } = require('./datasource-test-run-certification-debug');
11
+
7
12
  /**
8
13
  * @param {Object|undefined|null} v
9
14
  * @returns {Object|undefined}
@@ -15,6 +20,7 @@ function sliceValidationLayer(v) {
15
20
  summary: v.summary,
16
21
  dataReadiness: v.dataReadiness,
17
22
  metricsOutput: v.metricsOutput,
23
+ certificationOutput: sliceCertificationOutput(v.certificationOutput),
18
24
  issues: Array.isArray(v.issues) ? v.issues.slice(0, 50) : undefined
19
25
  };
20
26
  }
@@ -85,6 +91,7 @@ function buildDebugEnvelopeSlice(envelope) {
85
91
  validation: sliceValidationLayer(envelope.validation),
86
92
  integration: sliceIntegration(envelope.integration),
87
93
  certificate: sliceCertificate(envelope.certificate),
94
+ certificateIssuance: sliceCertificateIssuance(envelope.certificateIssuance),
88
95
  capabilitySummary: envelope.capabilitySummary,
89
96
  capabilities: sliceCapabilities(envelope.capabilities)
90
97
  };
@@ -6,7 +6,7 @@
6
6
 
7
7
  const chalk = require('chalk');
8
8
  const { sectionTitle, headerKeyValue, colorAggregateGlyph, successGlyph, failureGlyph } = require('./cli-test-layout-chalk');
9
- const { appendCertificateTTY } = require('./datasource-test-run-certificate-tty');
9
+ const { appendCertificateTTY, appendCertificateIssuanceTTY } = require('./datasource-test-run-certificate-tty');
10
10
  const { buildTtyMetaLines: buildTtyMetaLinesCore } = require('./datasource-test-run-tty-meta-lines');
11
11
 
12
12
  const SEP = '────────────────────────────────';
@@ -444,6 +444,7 @@ function formatDatasourceTestRunTTY(envelope, options = {}) {
444
444
  lines.push(sectionTitle('Verdict:'));
445
445
  lines.push(chalk.white(pickExecutiveVerdictLine(envelope)));
446
446
  appendCertificateTTY(lines, envelope);
447
+ appendCertificateIssuanceTTY(lines, envelope);
447
448
  appendRefsSectionIfEnabled(lines, envelope, options);
448
449
  appendValidationIssueLines(lines, envelope);
449
450
  appendIntegrationStepLines(lines, envelope);