@aifabrix/builder 2.49.2 → 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 (409) hide show
  1. package/.cursor/rules/deploy-rules/docker-image-ip-policy.mdc +49 -0
  2. package/.cursor/rules/plan-rules/application-lifecycle.mdc +30 -0
  3. package/.cursor/rules/plan-rules/plan-frontmatter.mdc +35 -0
  4. package/.cursor/rules/plan-rules/plan-lifecycle.mdc +31 -0
  5. package/.cursor/rules/plan-rules/plan-validation-gate.mdc +34 -0
  6. package/.cursor/skills/README.md +1 -0
  7. package/.dockerignore +52 -0
  8. package/.eslintignore +22 -0
  9. package/README.md +2 -0
  10. package/bin/builder-api-cleanup.js +26 -0
  11. package/bin/builder-api-nest.js +10 -0
  12. package/bin/builder-api-spike.js +19 -0
  13. package/enterprise-knowledge/README.md +50 -0
  14. package/enterprise-knowledge/enterprise-integration-lifecycle/README.md +22 -0
  15. package/enterprise-knowledge/enterprise-integration-lifecycle/application.json +15 -0
  16. package/enterprise-knowledge/enterprise-integration-lifecycle/deploy.js +69 -0
  17. package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-deploy.json +52 -0
  18. package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-system.json +29 -0
  19. package/enterprise-knowledge/enterprise-integration-lifecycle/env.template +2 -0
  20. package/integration/README.md +81 -0
  21. package/integration/github/README.md +53 -0
  22. package/integration/github/application.json +21 -0
  23. package/integration/github/deploy.js +72 -0
  24. package/integration/github/env.template +11 -0
  25. package/integration/github/github-datasource-issue-comments.json +239 -0
  26. package/integration/github/github-datasource-issues.json +399 -0
  27. package/integration/github/github-datasource-repository.json +354 -0
  28. package/integration/github/github-deploy.json +1202 -0
  29. package/integration/github/github-system.json +82 -0
  30. package/integration/hubspot-test/README.md +1 -1
  31. package/jest.isolated-projects.js +31 -1
  32. package/jest.projects.js +87 -1
  33. package/lib/api/dev-server-https.js +1 -1
  34. package/lib/api/enterprise-knowledge.api.js +63 -0
  35. package/lib/api/evidence.api.js +172 -0
  36. package/lib/api/external-systems.api.js +8 -2
  37. package/lib/api/resource-types.api.js +1 -0
  38. package/lib/api/types/enterprise-knowledge.types.js +46 -0
  39. package/lib/api/types/evidence.types.js +67 -0
  40. package/lib/api/types/resource-types.types.js +2 -0
  41. package/lib/app/controller-application-filter.js +36 -0
  42. package/lib/app/deploy.js +1 -1
  43. package/lib/app/list-external-systems.js +130 -0
  44. package/lib/app/list.js +20 -8
  45. package/lib/app/run.js +3 -1
  46. package/lib/app/show-display.js +8 -3
  47. package/lib/app/show-online.js +178 -0
  48. package/lib/app/show.js +37 -88
  49. package/lib/build/builder-api-docker-staging.js +47 -0
  50. package/lib/build/miso-controller-npm-sdk-guard.js +2 -2
  51. package/lib/build/standard-docker-build.js +2 -0
  52. package/lib/certification/post-unified-cert-sync.js +4 -31
  53. package/lib/certification/sync-after-external-command.js +0 -1
  54. package/lib/certification/sync-system-certification.js +0 -3
  55. package/lib/channels/add-channel.js +40 -34
  56. package/lib/channels/approval-guides/chatgpt.js +33 -0
  57. package/lib/channels/approval-guides/credential-portal.js +38 -0
  58. package/lib/channels/approval-guides/index.js +110 -0
  59. package/lib/channels/approval-guides/microsoft-copilot.js +34 -0
  60. package/lib/channels/approval-guides/slack.js +34 -0
  61. package/lib/channels/approval-guides/teams-bot.js +35 -0
  62. package/lib/channels/approval-guides/web-embed.js +32 -0
  63. package/lib/channels/channel-approval-guide.js +11 -0
  64. package/lib/channels/channel-artifact-generator.js +16 -4
  65. package/lib/channels/channel-audit.js +3 -0
  66. package/lib/channels/channel-auth-context.js +1 -1
  67. package/lib/channels/channel-description.js +59 -0
  68. package/lib/channels/channel-integration-generator.js +13 -230
  69. package/lib/channels/channel-integration-template.js +94 -0
  70. package/lib/channels/channel-runtime-resolver.js +43 -3
  71. package/lib/channels/channel-status-display.js +66 -26
  72. package/lib/channels/channel-targets.js +3 -3
  73. package/lib/cli/index.js +27 -3
  74. package/lib/cli/infra-guided.js +5 -1
  75. package/lib/cli/setup-app-external-create.js +111 -0
  76. package/lib/cli/setup-app.help.js +1 -1
  77. package/lib/cli/setup-app.js +38 -125
  78. package/lib/cli/setup-app.test-commands.js +26 -52
  79. package/lib/cli/setup-certification-commands.js +4 -4
  80. package/lib/cli/setup-certification.help.js +9 -9
  81. package/lib/cli/setup-dev.js +7 -2
  82. package/lib/cli/setup-external-system-help.js +4 -6
  83. package/lib/cli/setup-external-system.js +58 -52
  84. package/lib/cli/setup-infra-up-builder-api-action.js +64 -0
  85. package/lib/cli/setup-infra-up-platform-action.js +3 -1
  86. package/lib/cli/setup-infra.js +15 -0
  87. package/lib/cli/setup-list.js +43 -0
  88. package/lib/cli/setup-utility-repair.js +26 -7
  89. package/lib/cli/setup-utility.js +5 -3
  90. package/lib/commands/app.js +15 -43
  91. package/lib/commands/channel-add-setup.js +110 -0
  92. package/lib/commands/channel.js +42 -8
  93. package/lib/commands/datasource-sync-display.js +96 -0
  94. package/lib/commands/datasource-sync-policy.js +210 -0
  95. package/lib/commands/datasource-test-trust-cli.js +6 -6
  96. package/lib/commands/datasource-unified-test-cli.js +2 -1
  97. package/lib/commands/datasource-unified-test-cli.options.js +33 -23
  98. package/lib/commands/deploy-gate-failure-details.js +163 -0
  99. package/lib/commands/deploy-gate-orchestrator.js +322 -0
  100. package/lib/commands/dev-cli-handlers.js +1 -59
  101. package/lib/commands/dev-host-ops-params.js +91 -0
  102. package/lib/commands/dev-host-ops-poll.js +111 -0
  103. package/lib/commands/dev-host-ops.js +107 -94
  104. package/lib/commands/dev-init.js +3 -1
  105. package/lib/commands/enterprise-knowledge.js +284 -0
  106. package/lib/commands/evidence-cli-leaves.js +250 -0
  107. package/lib/commands/evidence.js +51 -0
  108. package/lib/commands/governance-cli-shared.js +2 -2
  109. package/lib/commands/governance-command-action.js +2 -2
  110. package/lib/commands/governance-fixture-subjects.js +85 -0
  111. package/lib/commands/governance.js +1 -1
  112. package/lib/commands/lifecycle-command-action.js +2 -2
  113. package/lib/commands/lifecycle-external.js +3 -3
  114. package/lib/commands/manifest-cli-auth.js +29 -0
  115. package/lib/commands/manifest-cli-commands.js +170 -0
  116. package/lib/commands/manifest-cli-integration-path.js +63 -0
  117. package/lib/commands/manifest.js +21 -0
  118. package/lib/commands/protection-cli-leaves.js +3 -3
  119. package/lib/commands/repair-auth-apply.js +15 -1
  120. package/lib/commands/repair-authentications-454.js +169 -0
  121. package/lib/commands/repair-capability-openapi-warnings.js +126 -0
  122. package/lib/commands/repair-datasource-apply.js +135 -0
  123. package/lib/commands/repair-datasource-auto-rbac.js +62 -1
  124. package/lib/commands/repair-datasource-http-service-contract.js +239 -0
  125. package/lib/commands/repair-datasource-operation-security.js +180 -0
  126. package/lib/commands/repair-datasource-run.js +7 -2
  127. package/lib/commands/repair-datasource-sync-operations.js +177 -0
  128. package/lib/commands/repair-datasource-webhooks-sync-bridge.js +133 -0
  129. package/lib/commands/repair-datasource.js +12 -68
  130. package/lib/commands/repair-env-template.js +11 -1
  131. package/lib/commands/repair-external-run.js +121 -31
  132. package/lib/commands/repair-internal.js +1 -1
  133. package/lib/commands/repair-openapi-export.js +156 -0
  134. package/lib/commands/repair-openapi-sync.js +19 -2
  135. package/lib/commands/repair-orchestration-datasource-split.js +259 -0
  136. package/lib/commands/repair-persist.js +22 -1
  137. package/lib/commands/repair-rbac-platform-preset.js +204 -0
  138. package/lib/commands/repair-rbac-reader-roles.js +191 -0
  139. package/lib/commands/repair-rbac.js +163 -86
  140. package/lib/commands/repair-steps.js +83 -18
  141. package/lib/commands/repair-system-permissions.js +1 -0
  142. package/lib/commands/repair.js +1 -1
  143. package/lib/commands/resource-type.js +65 -26
  144. package/lib/commands/run-post-publish-data-sync.js +68 -0
  145. package/lib/commands/setup-modes.js +1 -1
  146. package/lib/commands/test-e2e-external.js +21 -8
  147. package/lib/commands/test-governance-cli-options.js +2 -2
  148. package/lib/commands/test-trust-cli-options.js +2 -2
  149. package/lib/commands/up-builder-api-bootstrap.js +71 -0
  150. package/lib/commands/up-builder-api-provision.js +241 -0
  151. package/lib/commands/up-builder-api.js +88 -0
  152. package/lib/commands/up-common.js +25 -1
  153. package/lib/commands/upload-credential-push-log.js +117 -0
  154. package/lib/commands/upload-data-sync-finalize.js +60 -0
  155. package/lib/commands/upload-probe.js +66 -0
  156. package/lib/commands/upload-publish-context.js +4 -1
  157. package/lib/commands/upload-sidecar-followups.js +55 -27
  158. package/lib/commands/upload.js +116 -157
  159. package/lib/commands/verify-governance-combined-external.js +1 -1
  160. package/lib/commands/verify-governance-db.js +2 -2
  161. package/lib/commands/verify-operations-command-action.js +2 -2
  162. package/lib/commands/verify-operations-step-plan.js +2 -2
  163. package/lib/commands/verify-operations-steps.js +2 -2
  164. package/lib/commands/verify-trust-command-action.js +1 -1
  165. package/lib/commands/wizard-core.js +1 -1
  166. package/lib/commands/wizard-headless.js +2 -1
  167. package/lib/core/admin-secrets.js +2 -6
  168. package/lib/core/secrets-env-content.js +10 -4
  169. package/lib/core/secrets-env-write.js +2 -13
  170. package/lib/datasource/agent-trust-run.js +3 -3
  171. package/lib/datasource/deploy.js +3 -1
  172. package/lib/datasource/test-e2e.js +6 -1
  173. package/lib/datasource/unified-validation-run-body.js +4 -1
  174. package/lib/datasource/unified-validation-run.js +1 -1
  175. package/lib/deployment/deploy-poll-ui.js +73 -12
  176. package/lib/deployment/deployer-poll-run.js +113 -0
  177. package/lib/deployment/deployer.js +17 -87
  178. package/lib/evidence/dataplane-context.js +21 -0
  179. package/lib/evidence/evidence-display.js +78 -0
  180. package/lib/evidence/evidence-service.js +392 -0
  181. package/lib/external-system/deploy.js +290 -112
  182. package/lib/external-system/download.js +7 -3
  183. package/lib/external-system/test-execution.js +1 -1
  184. package/lib/external-system/test-system-level.js +8 -10
  185. package/lib/external-system/test.js +12 -6
  186. package/lib/generator/deploy-script.js +73 -0
  187. package/lib/generator/external.js +2 -1
  188. package/lib/generator/index.js +17 -2
  189. package/lib/generator/wizard.js +3 -36
  190. package/lib/internal/fs-real-sync.js +22 -1
  191. package/lib/internal/node-fs.js +2 -0
  192. package/lib/lifecycle/lifecycle-governance-options.js +1 -1
  193. package/lib/lifecycle/verify-step-progress.js +1 -1
  194. package/lib/programmatic/access-log.js +26 -0
  195. package/lib/programmatic/auth-config.js +44 -0
  196. package/lib/programmatic/bearer-auth.js +176 -0
  197. package/lib/programmatic/builder-api-request.js +175 -0
  198. package/lib/programmatic/builder-api-route-dispatch.js +82 -0
  199. package/lib/programmatic/builder-api-runtime-config.js +42 -0
  200. package/lib/programmatic/builder-api-server.js +230 -0
  201. package/lib/programmatic/builder-help-authentication-catalog.js +282 -0
  202. package/lib/programmatic/builder-help-connected-system-ui.js +266 -0
  203. package/lib/programmatic/builder-help-enterprise-sync-fabrix.js +60 -0
  204. package/lib/programmatic/builder-help-envelope.js +36 -0
  205. package/lib/programmatic/builder-help-fixtures.js +200 -0
  206. package/lib/programmatic/builder-help-governance.js +172 -0
  207. package/lib/programmatic/builder-help-schema-catalog.js +92 -0
  208. package/lib/programmatic/builder-help.js +361 -0
  209. package/lib/programmatic/capability-registry.js +77 -0
  210. package/lib/programmatic/command-options.js +32 -0
  211. package/lib/programmatic/enterprise-mcp-client.js +98 -0
  212. package/lib/programmatic/http-problem-details.js +99 -0
  213. package/lib/programmatic/http-route-match.js +40 -0
  214. package/lib/programmatic/idempotency-cache.js +69 -0
  215. package/lib/programmatic/index.js +53 -0
  216. package/lib/programmatic/integration-path-scope.js +39 -0
  217. package/lib/programmatic/log-redaction.js +66 -0
  218. package/lib/programmatic/manifest-get-section.js +146 -0
  219. package/lib/programmatic/manifest-patch-section.js +252 -0
  220. package/lib/programmatic/manifest-repair.js +122 -0
  221. package/lib/programmatic/manifest-section-dependency-graph.js +160 -0
  222. package/lib/programmatic/manifest-section-io.js +225 -0
  223. package/lib/programmatic/manifest-section-quality.js +171 -0
  224. package/lib/programmatic/manifest-section-registry-data.js +269 -0
  225. package/lib/programmatic/manifest-section-registry.js +205 -0
  226. package/lib/programmatic/nest-http-bridge.js +34 -0
  227. package/lib/programmatic/openapi-component-schemas.js +68 -0
  228. package/lib/programmatic/openapi-description-enricher.js +117 -0
  229. package/lib/programmatic/openapi-descriptions.js +190 -0
  230. package/lib/programmatic/openapi-docs-serving.js +123 -0
  231. package/lib/programmatic/openapi-help-schemas.js +63 -0
  232. package/lib/programmatic/openapi-manifest-schemas.js +141 -0
  233. package/lib/programmatic/openapi-operation-bindings.js +274 -0
  234. package/lib/programmatic/openapi-request-schemas.js +155 -0
  235. package/lib/programmatic/openapi-result-schemas.js +476 -0
  236. package/lib/programmatic/openapi-schema-descriptions-certify.js +139 -0
  237. package/lib/programmatic/openapi-schema-descriptions-core.js +159 -0
  238. package/lib/programmatic/openapi-schema-descriptions-help.js +40 -0
  239. package/lib/programmatic/openapi-schema-descriptions-manifest.js +143 -0
  240. package/lib/programmatic/openapi-schema-descriptions-mcp.js +118 -0
  241. package/lib/programmatic/openapi-schema-descriptions-operations.js +281 -0
  242. package/lib/programmatic/openapi-schema-helpers.js +93 -0
  243. package/lib/programmatic/openapi-spec.js +203 -0
  244. package/lib/programmatic/orchestration-openapi-meta.js +159 -0
  245. package/lib/programmatic/platform-rbac-catalog.js +90 -0
  246. package/lib/programmatic/request-timeout.js +53 -0
  247. package/lib/programmatic/route-handler-map.js +143 -0
  248. package/lib/programmatic/route-handlers-context.js +29 -0
  249. package/lib/programmatic/route-handlers.js +33 -0
  250. package/lib/programmatic/run-certify.js +57 -0
  251. package/lib/programmatic/run-enterprise-mcp.js +32 -0
  252. package/lib/programmatic/run-lifecycle.js +29 -0
  253. package/lib/programmatic/run-repair.js +41 -0
  254. package/lib/programmatic/run-repository-emcp.js +54 -0
  255. package/lib/programmatic/run-template-workspace.js +61 -0
  256. package/lib/programmatic/run-test.js +49 -0
  257. package/lib/programmatic/run-upload.js +63 -0
  258. package/lib/programmatic/run-validate.js +53 -0
  259. package/lib/programmatic/run-wizard.js +40 -0
  260. package/lib/programmatic/system-key.js +48 -0
  261. package/lib/programmatic/wizard-config-normalize.js +118 -0
  262. package/lib/programmatic/workspace-cleanup.js +128 -0
  263. package/lib/programmatic/workspace-context.js +145 -0
  264. package/lib/programmatic/workspace-lock.js +75 -0
  265. package/lib/programmatic/workspace-meta.js +64 -0
  266. package/lib/programmatic/workspace-ops.js +149 -0
  267. package/lib/protection/run-commands-upload-sync.js +35 -0
  268. package/lib/protection/run-commands.js +2 -20
  269. package/lib/protection/upload-batch.js +11 -7
  270. package/lib/resolvers/resource-type-file.js +22 -0
  271. package/lib/schema/external-datasource.schema.json +161 -1
  272. package/lib/schema/external-system.schema.json +244 -118
  273. package/lib/schema/flag-map-validation-run.json +3 -0
  274. package/lib/schema/type/credential-field-registry.json +2 -2
  275. package/lib/schema/type/document-storage.json +9 -0
  276. package/lib/utils/agent-trust-run-display.js +1 -1
  277. package/lib/utils/app-path-resolve.js +168 -0
  278. package/lib/utils/authentication-env-template.js +222 -0
  279. package/lib/utils/cli-sync-options.js +7 -11
  280. package/lib/utils/cli-utils.js +4 -0
  281. package/lib/utils/cli-workspace-options.js +29 -0
  282. package/lib/utils/compose-generate-docker-compose.js +102 -0
  283. package/lib/utils/configuration-env-resolver.js +203 -27
  284. package/lib/utils/datasource-test-run-certificate-tty.js +28 -2
  285. package/lib/utils/datasource-test-run-certification-debug.js +130 -0
  286. package/lib/utils/datasource-test-run-debug-display.js +2 -0
  287. package/lib/utils/datasource-test-run-debug-slice.js +7 -0
  288. package/lib/utils/datasource-test-run-display.js +2 -1
  289. package/lib/utils/dev-init-ssh-merge.js +165 -23
  290. package/lib/utils/dev-pin-share-instructions.js +110 -0
  291. package/lib/utils/dev-ssh-config-helper.js +177 -33
  292. package/lib/utils/enterprise-knowledge-paths.js +142 -0
  293. package/lib/utils/env-copy.js +2 -1
  294. package/lib/utils/env-dotenv-format.js +103 -0
  295. package/lib/utils/external-env-template.js +4 -1
  296. package/lib/utils/external-system-display.js +5 -1
  297. package/lib/utils/external-system-readiness-compact-blocks.js +221 -0
  298. package/lib/utils/external-system-readiness-compact-display.js +324 -0
  299. package/lib/utils/external-system-readiness-core.js +16 -0
  300. package/lib/utils/external-system-readiness-deploy-display.js +29 -11
  301. package/lib/utils/external-system-readiness-display-internals.js +3 -1
  302. package/lib/utils/external-system-readiness-display.js +20 -30
  303. package/lib/utils/external-system-system-test-tty-certification.js +135 -0
  304. package/lib/utils/external-system-system-test-tty.js +5 -41
  305. package/lib/utils/help-builder.js +6 -1
  306. package/lib/utils/host-ops-job-labels.js +236 -0
  307. package/lib/utils/host-ops-job-result.js +61 -0
  308. package/lib/utils/host-ops-poll-ui.js +163 -0
  309. package/lib/utils/integration-path-resolve.js +112 -0
  310. package/lib/utils/paths-reload-source.js +148 -0
  311. package/lib/utils/paths-system-builder-keys.js +25 -0
  312. package/lib/utils/paths.js +151 -26
  313. package/lib/utils/runtime-configuration-values.js +64 -2
  314. package/lib/utils/secrets-helpers.js +5 -1
  315. package/lib/utils/ssh-known-hosts.js +130 -0
  316. package/lib/utils/test-target-cli-options.js +75 -0
  317. package/lib/utils/upload-sync-options.js +4 -0
  318. package/lib/utils/validation-run-request.js +11 -2
  319. package/lib/validation/external-manifest-validator.js +11 -1
  320. package/lib/validation/openapi-contract-surface-validator.js +426 -0
  321. package/lib/validation/openapi-contract-vendor-validation.js +238 -0
  322. package/lib/validation/validate-external-file.js +160 -0
  323. package/lib/validation/validate.js +6 -117
  324. package/package.json +46 -29
  325. package/packages/builder-api/README.md +120 -0
  326. package/packages/builder-api/package.json +30 -0
  327. package/packages/builder-api/src/app.module.ts +7 -0
  328. package/packages/builder-api/src/auth/auth.module.ts +5 -0
  329. package/packages/builder-api/src/external-system/external-system.module.ts +5 -0
  330. package/packages/builder-api/src/main.ts +16 -0
  331. package/packages/builder-api/tsconfig.json +15 -0
  332. package/scripts/check-builder-api-architecture-grep.js +79 -0
  333. package/scripts/docker_image_content_gate.js +47 -0
  334. package/scripts/docker_image_content_gate.sh +5 -0
  335. package/scripts/export-builder-api-evidence.js +262 -0
  336. package/scripts/lib/builder-api-docker-staging-copy.js +60 -0
  337. package/scripts/lib/builder-api-docker-staging-core.js +183 -0
  338. package/scripts/lib/docker-image-content-gate-core.js +166 -0
  339. package/scripts/lib/plan-actor.js +109 -0
  340. package/scripts/lib/plan-config.js +20 -0
  341. package/scripts/lib/plan-gates.js +154 -0
  342. package/scripts/lib/plan-meta.js +104 -0
  343. package/scripts/lib/plan-parse.js +162 -0
  344. package/scripts/lib/plan-prevalidate-gates.js +326 -0
  345. package/scripts/lib/plan-run-core.js +125 -0
  346. package/scripts/lib/plan-run-report.js +108 -0
  347. package/scripts/plan-approve.js +24 -0
  348. package/scripts/plan-archive.js +49 -0
  349. package/scripts/plan-run.js +13 -0
  350. package/scripts/plan-set-actor.js +21 -0
  351. package/scripts/plan-validate.js +80 -0
  352. package/scripts/pnpm/af.mjs +110 -0
  353. package/scripts/pnpm/check-quiet.mjs +32 -0
  354. package/scripts/pnpm/dev-install.mjs +29 -0
  355. package/scripts/pnpm/dev-reload.mjs +18 -0
  356. package/scripts/pnpm/help.mjs +55 -0
  357. package/scripts/pnpm/lib/dev-reload-core.mjs +189 -0
  358. package/scripts/pnpm/lib/dev-reload-log-capture.mjs +67 -0
  359. package/scripts/pnpm/lib/dev-reload-log-utils.mjs +32 -0
  360. package/scripts/pnpm/lib/resolve-aifabrix-bin.mjs +124 -0
  361. package/scripts/pnpm/lib/resolve-app-url.mjs +183 -0
  362. package/scripts/pnpm/lib/spinner.mjs +42 -0
  363. package/scripts/stage_builder_api_for_docker.js +65 -0
  364. package/scripts/sync-builder-api-template.js +44 -0
  365. package/templates/README.md +3 -0
  366. package/templates/applications/builder-api/Dockerfile +38 -0
  367. package/templates/applications/builder-api/application.yaml +75 -0
  368. package/templates/applications/builder-api/env.template +48 -0
  369. package/templates/applications/dataplane/application.yaml +1 -1
  370. package/templates/applications/dataplane/env.template +10 -6
  371. package/templates/applications/dataplane/rbac.yaml +21 -1
  372. package/templates/applications/miso-controller/application.yaml +1 -1
  373. package/templates/applications/miso-controller/env.template +1 -3
  374. package/templates/channels/README.md +18 -0
  375. package/templates/channels/ai-fabrix-icon.jpg +0 -0
  376. package/templates/channels/chatgpt/install.template.md.hbs +21 -24
  377. package/templates/channels/chatgpt/integration/README.md +11 -0
  378. package/templates/channels/chatgpt/integration/application.json +15 -0
  379. package/templates/channels/chatgpt/integration/chatgpt-system.json +29 -0
  380. package/templates/channels/chatgpt/integration/env.template +4 -0
  381. package/templates/channels/microsoft-copilot/install.template.md.hbs +20 -25
  382. package/templates/channels/microsoft-copilot/integration/README.md +11 -0
  383. package/templates/channels/microsoft-copilot/integration/application.json +15 -0
  384. package/templates/channels/microsoft-copilot/integration/env.template +6 -0
  385. package/templates/channels/microsoft-copilot/integration/microsoft-copilot-system.json +34 -0
  386. package/templates/channels/slack/install.template.md.hbs +48 -18
  387. package/templates/channels/slack/integration/README.md +38 -0
  388. package/templates/channels/slack/integration/application.json +18 -0
  389. package/templates/channels/slack/integration/env.template +29 -0
  390. package/templates/channels/slack/integration/slack-datasource-conversations.json +226 -0
  391. package/templates/channels/slack/integration/slack-datasource-messages.json +269 -0
  392. package/templates/channels/slack/integration/slack-system.json +86 -0
  393. package/templates/channels/slack/manifest.template.json.hbs +20 -10
  394. package/templates/channels/teams-bot/install.template.md.hbs +31 -17
  395. package/templates/channels/teams-bot/integration/README.md +18 -0
  396. package/templates/channels/teams-bot/integration/application.json +17 -0
  397. package/templates/channels/teams-bot/integration/env.template +5 -0
  398. package/templates/channels/teams-bot/integration/teams-bot-system.json +55 -0
  399. package/templates/channels/teams-bot/manifest.template.json.hbs +27 -0
  400. package/templates/channels/web-embed/install.template.md.hbs +16 -26
  401. package/templates/channels/web-embed/integration/README.md +11 -0
  402. package/templates/channels/web-embed/integration/application.json +15 -0
  403. package/templates/channels/web-embed/integration/env.template +4 -0
  404. package/templates/channels/web-embed/integration/web-embed-system.json +29 -0
  405. package/templates/openapi/redoc_page.html +86 -0
  406. package/templates/python/docker-compose.hbs +11 -0
  407. package/templates/python/requirements.txt +1 -1
  408. package/templates/typescript/docker-compose.hbs +11 -0
  409. package/lib/certification/cli-cert-sync-skip.js +0 -21
@@ -9,50 +9,30 @@ const chalk = require('chalk');
9
9
  const logger = require('../utils/logger');
10
10
  const { formatSuccessLine } = require('../utils/cli-test-layout-chalk');
11
11
  const { getRemoteDevAuth } = require('../utils/remote-dev-auth');
12
+ const { createHostOpsPollHandlers } = require('../utils/host-ops-poll-ui');
13
+ const { buildHostOpsActionLabel, resolveHostOpsTargetLabel } = require('../utils/host-ops-job-labels');
14
+ const { pollHostOpsJobUntilTerminal } = require('./dev-host-ops-poll');
15
+ const { buildJobParams } = require('./dev-host-ops-params');
12
16
  const hostOpsApi = require('../api/host-ops.api');
17
+ const { assertHostOpsJobSucceeded } = require('../utils/host-ops-job-result');
13
18
 
14
19
  const REMOTE_NOT_CONFIGURED_MSG =
15
20
  'Remote server is not configured. Set remote-server and run "aifabrix dev init" first.';
16
21
 
17
- const POLL_INTERVAL_MS = 3000;
18
- const POLL_TIMEOUT_MS = 3 * 60 * 60 * 1000;
19
-
20
- function sleep(ms) {
21
- return new Promise((resolve) => setTimeout(resolve, ms));
22
- }
23
-
24
22
  /**
25
- * Build job params from Commander options.
23
+ * @param {string} type
24
+ * @param {Object} params
26
25
  * @param {Object} options
27
- * @param {string} [developerId]
28
26
  * @returns {Object}
29
27
  */
30
- function buildJobParams(options, developerId) {
31
- const params = {};
32
- const id = developerId || options.developerId || options['developer-id'];
33
- if (id) params.developerId = String(id).trim();
34
- if (options.include) params.include = options.include;
35
- if (options.exclude) params.exclude = options.exclude;
36
- if (options.builderVersion || options['builder-version']) {
37
- params.builderVersion = options.builderVersion || options['builder-version'];
38
- }
39
- if (options.adminEmail || options['admin-email']) {
40
- params.adminEmail = options.adminEmail || options['admin-email'];
41
- }
42
- if (options.adminPassword || options['admin-password']) {
43
- params.adminPassword = options.adminPassword || options['admin-password'];
44
- }
45
- if (options.platform) params.platform = options.platform;
46
- if (options.installation) params.installation = options.installation;
47
- if (options.skipCert || options['skip-cert']) params.skipCert = true;
48
- if (options.skipPlatform || options['skip-platform']) params.skipPlatform = true;
49
- if (options.skipCli || options['skip-cli']) params.skipCli = true;
50
- if (options.check) params.check = true;
51
- if (options.failOnBlocked) params.failOnBlocked = true;
52
- if (options.timeoutMinutes || options['timeout-minutes']) {
53
- params.timeoutMinutes = parseInt(options.timeoutMinutes || options['timeout-minutes'], 10);
54
- }
55
- return params;
28
+ function buildHostOpsWaitOpts(type, params, options) {
29
+ return {
30
+ wait: options.wait !== false,
31
+ json: Boolean(options.json),
32
+ jobType: type,
33
+ targetLabel: resolveHostOpsTargetLabel(params),
34
+ params
35
+ };
56
36
  }
57
37
 
58
38
  /**
@@ -70,26 +50,20 @@ async function waitForHostOpsJob(auth, jobId, opts = {}) {
70
50
  if (!wait) {
71
51
  return { jobId, status: 'pending' };
72
52
  }
73
- const started = Date.now();
74
- while (Date.now() - started < POLL_TIMEOUT_MS) {
75
- const job = await hostOpsApi.getHostOpsJob(
76
- auth.serverUrl,
77
- auth.clientCertPem,
78
- jobId,
79
- auth.serverCaPem || undefined
80
- );
81
- if (!json) {
82
- logger.log(chalk.gray(` host-ops job ${jobId}: ${job.status}`));
83
- }
84
- if (job.status === 'completed' || job.status === 'failed') {
85
- if (job.status === 'failed') {
86
- throw new Error(job.error || `Host-ops job ${jobId} failed`);
87
- }
88
- return job;
89
- }
90
- await sleep(POLL_INTERVAL_MS);
53
+ const pollContext = {
54
+ jobType: opts.jobType,
55
+ targetLabel: opts.targetLabel,
56
+ params: opts.params,
57
+ startedAt: Date.now()
58
+ };
59
+ const pollUi = json
60
+ ? { onPollProgress: () => {}, onTransientError: () => {}, finish: () => {} }
61
+ : createHostOpsPollHandlers(jobId, pollContext);
62
+ try {
63
+ return await pollHostOpsJobUntilTerminal(auth, jobId, pollUi, json);
64
+ } finally {
65
+ pollUi.finish();
91
66
  }
92
- throw new Error(`Timed out waiting for host-ops job ${jobId}`);
93
67
  }
94
68
 
95
69
  /**
@@ -135,13 +109,26 @@ async function runHostOpsJob(type, params, options = {}) {
135
109
  { type, params },
136
110
  auth.serverCaPem || undefined
137
111
  );
112
+ const waitOpts = buildHostOpsWaitOpts(type, params, options);
113
+ if (options.wait === false) {
114
+ if (options.json) {
115
+ logger.log(JSON.stringify({ jobId, status: 'pending', type }, null, 2));
116
+ } else {
117
+ const action = buildHostOpsActionLabel(type, waitOpts.targetLabel);
118
+ logger.log(formatSuccessLine(`${action} queued (job ${jobId}).`));
119
+ }
120
+ return { jobId, status: 'pending' };
121
+ }
138
122
  if (options.json) {
139
- const job = await waitForHostOpsJob(auth, jobId, { wait: options.wait !== false, json: true });
123
+ const job = await waitForHostOpsJob(auth, jobId, waitOpts);
124
+ assertHostOpsJobSucceeded(job);
140
125
  logger.log(JSON.stringify(job, null, 2));
141
126
  return job;
142
127
  }
143
- const job = await waitForHostOpsJob(auth, jobId, { wait: options.wait !== false, json: false });
144
- logger.log(formatSuccessLine(`Host-ops job ${jobId} completed (${type}).`));
128
+ const job = await waitForHostOpsJob(auth, jobId, waitOpts);
129
+ assertHostOpsJobSucceeded(job);
130
+ const action = buildHostOpsActionLabel(type, waitOpts.targetLabel);
131
+ logger.log(formatSuccessLine(`${action} completed.`));
145
132
  return job;
146
133
  }
147
134
 
@@ -161,6 +148,63 @@ async function handlePlatformUpdate(developerId, options) {
161
148
  await runHostOpsJob('update-dev-platform', params, options);
162
149
  }
163
150
 
151
+ function logPlatformInstallOutcomes(developerId, job, json) {
152
+ if (json) {
153
+ logger.log(JSON.stringify(job, null, 2));
154
+ return;
155
+ }
156
+ if (!Array.isArray(job.outcomes)) {
157
+ return;
158
+ }
159
+ job.outcomes.forEach((row) => {
160
+ logger.log(` ${row.linuxUser || developerId}: ${row.overall || row.status}${row.detail ? ` — ${row.detail}` : ''}`);
161
+ });
162
+ }
163
+
164
+ async function runPlatformInstallPreflight(auth, params) {
165
+ const { jobId } = await hostOpsApi.preflightHostOps(
166
+ auth.serverUrl,
167
+ auth.clientCertPem,
168
+ { type: 'install-dev-platform', params },
169
+ auth.serverCaPem || undefined
170
+ );
171
+ return waitForHostOpsJob(auth, jobId, buildHostOpsWaitOpts('install-dev-platform', params, {}));
172
+ }
173
+
174
+ async function handlePlatformInstallCheck(developerId, params, options) {
175
+ const auth = await getRemoteDevAuth();
176
+ if (!auth) throw new Error(REMOTE_NOT_CONFIGURED_MSG);
177
+ params.check = true;
178
+ const { jobId } = await hostOpsApi.preflightHostOps(
179
+ auth.serverUrl,
180
+ auth.clientCertPem,
181
+ { type: 'install-dev-platform', params },
182
+ auth.serverCaPem || undefined
183
+ );
184
+ const job = await waitForHostOpsJob(auth, jobId, buildHostOpsWaitOpts('install-dev-platform', params, options));
185
+ logPlatformInstallOutcomes(developerId, job, options.json);
186
+ assertHostOpsJobSucceeded(job);
187
+ return job;
188
+ }
189
+
190
+ async function confirmPlatformReinstall(developerId, params, options) {
191
+ const auth = await getRemoteDevAuth();
192
+ if (!auth) throw new Error(REMOTE_NOT_CONFIGURED_MSG);
193
+ const preflight = await runPlatformInstallPreflight(auth, { ...params, developerId });
194
+ if (!platformAlreadyInstalled(preflight.outcomes)) {
195
+ return null;
196
+ }
197
+ const ok = await promptYesNo(
198
+ `Platform already installed for dev${String(developerId).padStart(2, '0')}. Re-install?`
199
+ );
200
+ if (!ok) {
201
+ logger.log(chalk.gray('Cancelled.'));
202
+ return preflight;
203
+ }
204
+ await runHostOpsJob('reinstall-dev-platform', params, options);
205
+ return undefined;
206
+ }
207
+
164
208
  async function handlePlatformInstall(developerId, options) {
165
209
  if (!developerId) {
166
210
  throw new Error('Developer ID is required (positional argument).');
@@ -168,46 +212,13 @@ async function handlePlatformInstall(developerId, options) {
168
212
  const params = buildJobParams(options, developerId);
169
213
 
170
214
  if (options.check) {
171
- params.check = true;
172
- const auth = await getRemoteDevAuth();
173
- if (!auth) throw new Error(REMOTE_NOT_CONFIGURED_MSG);
174
- const { jobId } = await hostOpsApi.preflightHostOps(
175
- auth.serverUrl,
176
- auth.clientCertPem,
177
- { type: 'install-dev-platform', params },
178
- auth.serverCaPem || undefined
179
- );
180
- const job = await waitForHostOpsJob(auth, jobId, options);
181
- if (options.json) {
182
- logger.log(JSON.stringify(job, null, 2));
183
- } else if (Array.isArray(job.outcomes)) {
184
- job.outcomes.forEach((row) => {
185
- logger.log(` ${row.linuxUser || developerId}: ${row.overall || row.status}${row.detail ? ` — ${row.detail}` : ''}`);
186
- });
187
- }
188
- return job;
215
+ return handlePlatformInstallCheck(developerId, params, options);
189
216
  }
190
217
 
191
218
  if (!options.force && !options.yes) {
192
- const auth = await getRemoteDevAuth();
193
- if (!auth) throw new Error(REMOTE_NOT_CONFIGURED_MSG);
194
- const { jobId } = await hostOpsApi.preflightHostOps(
195
- auth.serverUrl,
196
- auth.clientCertPem,
197
- { type: 'install-dev-platform', params: { ...params, developerId } },
198
- auth.serverCaPem || undefined
199
- );
200
- const preflight = await waitForHostOpsJob(auth, jobId, { ...options, json: false });
201
- if (platformAlreadyInstalled(preflight.outcomes)) {
202
- const ok = await promptYesNo(
203
- `Platform already installed for dev${String(developerId).padStart(2, '0')}. Re-install?`
204
- );
205
- if (!ok) {
206
- logger.log(chalk.gray('Cancelled.'));
207
- return preflight;
208
- }
209
- await runHostOpsJob('reinstall-dev-platform', params, options);
210
- return;
219
+ const cancelled = await confirmPlatformReinstall(developerId, params, options);
220
+ if (cancelled) {
221
+ return cancelled;
211
222
  }
212
223
  }
213
224
 
@@ -230,7 +241,9 @@ async function handleRemoveDevUser(developerId, options) {
230
241
 
231
242
  module.exports = {
232
243
  buildJobParams,
244
+ buildHostOpsWaitOpts,
233
245
  waitForHostOpsJob,
246
+ runHostOpsJob,
234
247
  handlePlatformInstallCli,
235
248
  handlePlatformUpdate,
236
249
  handlePlatformInstall,
@@ -33,7 +33,7 @@ const {
33
33
  isLinuxCaSudoRequiredError
34
34
  } = require('../utils/dev-ca-install');
35
35
  const { runOptionalHostsSetup } = require('../utils/dev-hosts-helper');
36
- const { mergeDevSshConfigAfterInit } = require('../utils/dev-init-ssh-merge');
36
+ const { mergeDevSshConfigAfterInit, logDevSshConnectHint } = require('../utils/dev-init-ssh-merge');
37
37
  const { resolveInitOptions } = require('../utils/dev-init-resolve');
38
38
  const { displayDevConfig } = require('./dev-show-display');
39
39
  const {
@@ -426,6 +426,7 @@ async function runCertificateRefresh(auth) {
426
426
  warn: (msg) => logger.log(chalk.yellow(` ⚠ ${msg}`))
427
427
  });
428
428
  logger.log(formatSuccessLine('Certificate refreshed and config updated from server.\n'));
429
+ logDevSshConnectHint(await mergeDevSshConfigAfterInit(auth.serverUrl, devId));
429
430
  }
430
431
 
431
432
  /**
@@ -481,6 +482,7 @@ async function runDevRefresh(options = {}) {
481
482
  return;
482
483
  }
483
484
  await fetchAndMergeRemoteSettings(auth, clientCertPem, clientKeyPem, devId);
485
+ logDevSshConnectHint(await mergeDevSshConfigAfterInit(auth.serverUrl, devId));
484
486
  }
485
487
 
486
488
  module.exports = { runDevInit, runDevRefresh };
@@ -0,0 +1,284 @@
1
+ /**
2
+ * Enterprise Knowledge CLI commands (456.16).
3
+ *
4
+ * @fileoverview enterprise-knowledge generate-manifest
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const {
12
+ existsSync,
13
+ readFileSync,
14
+ mkdirSync,
15
+ writeFileSync
16
+ } = require('../internal/fs-real-sync');
17
+ const path = require('path');
18
+ const chalk = require('chalk');
19
+ const logger = require('../utils/logger');
20
+ const { resolveControllerUrl } = require('../utils/controller-url');
21
+ const { resolveDataplaneAndAuth } = require('./upload');
22
+ const { postGenerateManifest } = require('../api/enterprise-knowledge.api');
23
+ const { getEnterpriseKnowledgePath } = require('../utils/enterprise-knowledge-paths');
24
+ const { resolveAppWorkspace } = require('../utils/app-path-resolve');
25
+ const {
26
+ formatBlockingError,
27
+ formatSuccessLine,
28
+ formatWarningLine,
29
+ infoLine,
30
+ headerKeyValue
31
+ } = require('../utils/cli-layout-chalk');
32
+ const { formatApiError } = require('../utils/api-error-handler');
33
+
34
+ const DOMAIN_PATTERN = /^[a-z][a-z0-9-]*$/;
35
+ const GENERATED_DIR = 'generated-service-contracts';
36
+ const DEFAULT_PREVIEW_FILE = 'generate-manifest-preview.json';
37
+
38
+ const ENTERPRISE_KNOWLEDGE_HELP_AFTER = `
39
+
40
+ Examples:
41
+ $ aifabrix enterprise-knowledge generate-manifest --domain sales
42
+ $ aifabrix enterprise-knowledge generate-manifest --domain sales --source-system hubspot-e2e
43
+ $ aifabrix enterprise-knowledge generate-manifest --domain sales --output ./preview.json
44
+
45
+ Per-command help: aifabrix enterprise-knowledge <command> --help
46
+ `;
47
+
48
+ const GENERATE_MANIFEST_HELP_AFTER = `
49
+
50
+ Examples:
51
+ $ aifabrix enterprise-knowledge generate-manifest --domain sales
52
+ $ aifabrix enterprise-knowledge generate-manifest --domain sales --owner-system-key ek-sales
53
+ $ aifabrix enterprise-knowledge generate-manifest --domain sales --source-system vendor-crm --json
54
+
55
+ Preview only — review output before upload (candidate) and deploy.
56
+
57
+ `;
58
+
59
+ /**
60
+ * @param {string} raw
61
+ * @returns {string}
62
+ */
63
+ function requireDomain(raw) {
64
+ const domain = String(raw || '').trim().toLowerCase();
65
+ if (!domain) {
66
+ throw new Error('--domain is required.');
67
+ }
68
+ if (!DOMAIN_PATTERN.test(domain)) {
69
+ throw new Error(
70
+ 'domain must start with a lowercase letter and contain only lowercase letters, numbers, and hyphens.'
71
+ );
72
+ }
73
+ return domain;
74
+ }
75
+
76
+ /**
77
+ * @param {string} domain
78
+ * @param {string|undefined|null} raw
79
+ * @returns {string}
80
+ */
81
+ function resolveOwnerSystemKey(domain, raw) {
82
+ const key = String(raw || '').trim() || `ek-${domain}`;
83
+ if (!/^[a-z0-9-_]+$/.test(key)) {
84
+ throw new Error('owner-system-key must contain only lowercase letters, numbers, hyphens, and underscores.');
85
+ }
86
+ return key;
87
+ }
88
+
89
+ /**
90
+ * @param {string} ownerSystemKey
91
+ * @returns {Object[]}
92
+ */
93
+ function loadAnchorSubscriptions(ownerSystemKey) {
94
+ try {
95
+ const { appPath } = resolveAppWorkspace(ownerSystemKey, {
96
+ workspace: 'enterprise-knowledge'
97
+ });
98
+ const systemFile = path.join(appPath, `${ownerSystemKey}-system.json`);
99
+ if (!existsSync(systemFile)) {
100
+ return [];
101
+ }
102
+ const raw = JSON.parse(readFileSync(systemFile, 'utf8'));
103
+ return Array.isArray(raw.subscriptions) ? raw.subscriptions : [];
104
+ } catch {
105
+ return [];
106
+ }
107
+ }
108
+
109
+ /**
110
+ * @param {Object} options
111
+ * @param {string} domain
112
+ * @param {string} ownerSystemKey
113
+ * @returns {import('../api/types/enterprise-knowledge.types').GenerateManifestRequest}
114
+ */
115
+ function buildGenerateManifestRequest(options, domain, ownerSystemKey) {
116
+ if (options.file) {
117
+ const filePath = path.resolve(String(options.file));
118
+ if (!existsSync(filePath)) {
119
+ throw new Error(`File not found: ${filePath}`);
120
+ }
121
+ const parsed = JSON.parse(readFileSync(filePath, 'utf8'));
122
+ if (!parsed || typeof parsed !== 'object') {
123
+ throw new Error('Request file must be a JSON object.');
124
+ }
125
+ return {
126
+ domain: requireDomain(parsed.domain || domain),
127
+ ownerSystemKey: resolveOwnerSystemKey(domain, parsed.ownerSystemKey || ownerSystemKey),
128
+ displayName: parsed.displayName,
129
+ description: parsed.description,
130
+ subscriptions: Array.isArray(parsed.subscriptions) ? parsed.subscriptions : [],
131
+ sourceSystemKeys: Array.isArray(parsed.sourceSystemKeys) ? parsed.sourceSystemKeys : [],
132
+ version: parsed.version
133
+ };
134
+ }
135
+
136
+ const sourceKeys = [];
137
+ if (Array.isArray(options.sourceSystem)) {
138
+ sourceKeys.push(...options.sourceSystem.map((k) => String(k).trim()).filter(Boolean));
139
+ } else if (typeof options.sourceSystem === 'string' && options.sourceSystem.trim()) {
140
+ sourceKeys.push(options.sourceSystem.trim());
141
+ }
142
+
143
+ const subscriptions = loadAnchorSubscriptions(ownerSystemKey);
144
+ const title = domain.replace(/-/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase());
145
+
146
+ return {
147
+ domain,
148
+ ownerSystemKey,
149
+ displayName: options.displayName || `Enterprise Knowledge — ${title}`,
150
+ description:
151
+ options.description ||
152
+ `Domain enterprise-knowledge preview for ${domain}. Human approval required before upload.`,
153
+ subscriptions,
154
+ sourceSystemKeys: sourceKeys,
155
+ version: options.version || '1.0.0'
156
+ };
157
+ }
158
+
159
+ /**
160
+ * @param {string} ownerSystemKey
161
+ * @param {string|undefined|null} outputOption
162
+ * @returns {string}
163
+ */
164
+ function resolveOutputPath(ownerSystemKey, outputOption) {
165
+ if (outputOption) {
166
+ return path.resolve(String(outputOption));
167
+ }
168
+ const anchorDir = getEnterpriseKnowledgePath(ownerSystemKey);
169
+ return path.join(anchorDir, GENERATED_DIR, DEFAULT_PREVIEW_FILE);
170
+ }
171
+
172
+ /**
173
+ * @param {import('../api/types/enterprise-knowledge.types').GenerateManifestResponse} preview
174
+ * @returns {void}
175
+ */
176
+ function logPreviewSummary(preview) {
177
+ headerKeyValue('Enterprise Knowledge manifest preview', preview.ownerSystemKey);
178
+ infoLine('Status', preview.previewOnly ? 'preview only (not published)' : 'unexpected');
179
+ infoLine('Version', preview.version || '1.0.0');
180
+ infoLine('Generated datasources', String((preview.externalDataSources || []).length));
181
+ const compilerCount = (preview.compilerFindings || []).length;
182
+ const trustCount = (preview.trustFindings || []).length;
183
+ if (compilerCount > 0) {
184
+ formatWarningLine(`${compilerCount} compiler finding(s) require review`);
185
+ }
186
+ if (trustCount > 0) {
187
+ formatWarningLine(`${trustCount} trust finding(s) require review`);
188
+ }
189
+ if (preview.message) {
190
+ logger.log(chalk.gray(preview.message));
191
+ }
192
+ }
193
+
194
+ /**
195
+ * @param {Object} options
196
+ * @returns {Promise<void>}
197
+ */
198
+ async function runGenerateManifestCommand(options) {
199
+ const domain = requireDomain(options.domain);
200
+ const ownerSystemKey = resolveOwnerSystemKey(domain, options.ownerSystemKey);
201
+ const body = buildGenerateManifestRequest(options, domain, ownerSystemKey);
202
+
203
+ const { dataplaneUrl, authConfig } = await resolveDataplaneAndAuth(ownerSystemKey, {
204
+ silent: true
205
+ });
206
+ const controllerUrl = await resolveControllerUrl();
207
+
208
+ let preview;
209
+ try {
210
+ preview = await postGenerateManifest(dataplaneUrl, authConfig, body, { controllerUrl });
211
+ } catch (error) {
212
+ throw new Error(formatApiError(error, dataplaneUrl));
213
+ }
214
+
215
+ if (options.json) {
216
+ logger.log(JSON.stringify(preview, null, 2));
217
+ return;
218
+ }
219
+
220
+ const outputPath = resolveOutputPath(ownerSystemKey, options.output);
221
+ mkdirSync(path.dirname(outputPath), { recursive: true });
222
+ writeFileSync(outputPath, `${JSON.stringify(preview, null, 2)}\n`, 'utf8');
223
+
224
+ logPreviewSummary(preview);
225
+ formatSuccessLine(`Preview written to ${outputPath}`);
226
+ logger.log(chalk.gray('Review and edit before upload (candidate) and deploy.'));
227
+ }
228
+
229
+ /**
230
+ * @param {import('commander').Command} ek
231
+ * @returns {void}
232
+ */
233
+ function setupGenerateManifestCommand(ek) {
234
+ ek.command('generate-manifest')
235
+ .description('Preview full Enterprise Knowledge manifest from published Connected Systems')
236
+ .addHelpText('after', GENERATE_MANIFEST_HELP_AFTER)
237
+ .requiredOption('--domain <domain>', 'Business domain slug (e.g. sales)')
238
+ .option('--owner-system-key <key>', 'Enterprise Knowledge anchor key (default ek-<domain>)')
239
+ .option('--source-system <key>', 'Published Connected System key (repeatable)', collectValues, [])
240
+ .option('--display-name <name>', 'Enterprise Knowledge display name override')
241
+ .option('--description <text>', 'Enterprise Knowledge description override')
242
+ .option('--version <semver>', 'Manifest version label', '1.0.0')
243
+ .option('--file <path>', 'Full request JSON (overrides built-in body)')
244
+ .option('--output <path>', 'Write preview JSON to this path')
245
+ .option('--json', 'Print preview JSON to stdout instead of writing a file')
246
+ .action(async(options) => {
247
+ try {
248
+ await runGenerateManifestCommand(options);
249
+ } catch (error) {
250
+ formatBlockingError(error.message || String(error));
251
+ process.exit(1);
252
+ }
253
+ });
254
+ }
255
+
256
+ /**
257
+ * @param {string} value
258
+ * @param {string[]} previous
259
+ * @returns {string[]}
260
+ */
261
+ function collectValues(value, previous) {
262
+ return previous.concat([value]);
263
+ }
264
+
265
+ /**
266
+ * @param {import('commander').Command} program
267
+ * @returns {void}
268
+ */
269
+ function setupEnterpriseKnowledgeCommands(program) {
270
+ const ek = program
271
+ .command('enterprise-knowledge')
272
+ .description('Enterprise Knowledge authoring helpers')
273
+ .addHelpText('after', ENTERPRISE_KNOWLEDGE_HELP_AFTER);
274
+ setupGenerateManifestCommand(ek);
275
+ }
276
+
277
+ module.exports = {
278
+ setupEnterpriseKnowledgeCommands,
279
+ runGenerateManifestCommand,
280
+ buildGenerateManifestRequest,
281
+ resolveOutputPath,
282
+ requireDomain,
283
+ resolveOwnerSystemKey
284
+ };