@aifabrix/builder 2.53.1 → 2.55.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 (470) hide show
  1. package/README.md +8 -0
  2. package/bin/aifabrix.js +2 -2
  3. package/lib/agent-kit/apply-ops.js +82 -0
  4. package/lib/agent-kit/checksums.js +28 -0
  5. package/lib/agent-kit/classify.js +113 -0
  6. package/lib/agent-kit/claude-shim.js +61 -0
  7. package/lib/agent-kit/constants.js +55 -0
  8. package/lib/agent-kit/file-list.js +103 -0
  9. package/lib/agent-kit/host-approve.js +130 -0
  10. package/lib/agent-kit/hosting/github.js +63 -0
  11. package/lib/agent-kit/hosts.js +71 -0
  12. package/lib/agent-kit/init.js +319 -0
  13. package/lib/agent-kit/kit-root.js +17 -0
  14. package/lib/agent-kit/managed-section.js +79 -0
  15. package/lib/agent-kit/package-load.js +45 -0
  16. package/lib/agent-kit/plan-ops.js +69 -0
  17. package/lib/agent-kit/remote-prompts.js +239 -0
  18. package/lib/agent-kit/render-host-markdown.js +40 -0
  19. package/lib/agent-kit/repo-guard.js +47 -0
  20. package/lib/agent-kit/report.js +107 -0
  21. package/lib/agent-kit/run.js +82 -0
  22. package/lib/agent-kit/scm/git.js +122 -0
  23. package/lib/agent-kit/state-file.js +83 -0
  24. package/lib/agent-kit/status.js +50 -0
  25. package/lib/agent-kit/v1-detect.js +81 -0
  26. package/lib/agent-kit/validate-kit.js +87 -0
  27. package/lib/agent-kit/workspace-name.js +40 -0
  28. package/lib/agent-kit/workspace-skeleton.js +103 -0
  29. package/lib/api/assistants.api.js +8 -5
  30. package/lib/api/channel-identity.api.js +41 -0
  31. package/lib/api/evidence-authoring.api.js +5 -1
  32. package/lib/api/evidence.api.js +2 -0
  33. package/lib/api/role-assistant-test-pack.api.js +86 -0
  34. package/lib/api/types/evidence.types.js +2 -0
  35. package/lib/api/work-search.api.js +163 -0
  36. package/lib/api/work.api.js +19 -12
  37. package/lib/app/list-external-systems.js +2 -1
  38. package/lib/app/show-display.js +33 -6
  39. package/lib/app/show.js +25 -2
  40. package/lib/channels/add-channel.js +164 -126
  41. package/lib/channels/approval-guides/chatgpt.js +14 -18
  42. package/lib/channels/approval-guides/claude.js +29 -0
  43. package/lib/channels/approval-guides/index.js +88 -22
  44. package/lib/channels/approval-guides/mcp-client.js +27 -0
  45. package/lib/channels/approval-guides/microsoft-copilot.js +52 -3
  46. package/lib/channels/approval-guides/slack.js +10 -10
  47. package/lib/channels/approval-guides/teams-bot.js +8 -12
  48. package/lib/channels/channel-add-continuations.js +91 -0
  49. package/lib/channels/channel-add-ensure.js +124 -27
  50. package/lib/channels/channel-add-existing.js +160 -28
  51. package/lib/channels/channel-add-failure.js +61 -0
  52. package/lib/channels/channel-add-remaining.js +492 -0
  53. package/lib/channels/channel-add-tty.js +190 -0
  54. package/lib/channels/channel-add-wizard-config.js +138 -0
  55. package/lib/channels/channel-add-wizard.js +250 -0
  56. package/lib/channels/channel-artifact-generator.js +27 -13
  57. package/lib/channels/channel-cardinality.js +83 -0
  58. package/lib/channels/channel-catalog-icon.js +45 -0
  59. package/lib/channels/channel-cli-instructions.js +75 -0
  60. package/lib/channels/channel-configuration-map.js +213 -0
  61. package/lib/channels/channel-credential.js +11 -14
  62. package/lib/channels/channel-definition-project.js +101 -0
  63. package/lib/channels/channel-definition-registry.js +154 -0
  64. package/lib/channels/channel-definition-status.js +115 -0
  65. package/lib/channels/channel-description.js +60 -2
  66. package/lib/channels/channel-discovery.js +16 -2
  67. package/lib/channels/channel-external-system.js +86 -9
  68. package/lib/channels/channel-install-envelope-actions.js +88 -0
  69. package/lib/channels/channel-install-envelope-microsoft.js +155 -0
  70. package/lib/channels/channel-install-envelope.js +358 -0
  71. package/lib/channels/channel-install-help-md.js +172 -0
  72. package/lib/channels/channel-install-http-payload.js +62 -0
  73. package/lib/channels/channel-install-inventory.js +115 -0
  74. package/lib/channels/channel-install-profiles.js +90 -0
  75. package/lib/channels/channel-instance-collision.js +118 -0
  76. package/lib/channels/channel-instance-key.js +100 -0
  77. package/lib/channels/channel-instance-materialize.js +240 -0
  78. package/lib/channels/channel-integration-generator.js +18 -9
  79. package/lib/channels/channel-integration-template.js +101 -22
  80. package/lib/channels/channel-inventory-fetch.js +79 -0
  81. package/lib/channels/channel-oauth-preflight.js +104 -0
  82. package/lib/channels/channel-package-version.js +76 -0
  83. package/lib/channels/channel-predefined-client.js +154 -0
  84. package/lib/channels/channel-probe.js +7 -2
  85. package/lib/channels/channel-runtime-resolver.js +194 -72
  86. package/lib/channels/channel-status-display.js +86 -16
  87. package/lib/channels/channel-targets.js +132 -92
  88. package/lib/channels/chatgpt-callback.js +318 -0
  89. package/lib/channels/chatgpt-channel-add.js +229 -0
  90. package/lib/channels/chatgpt-preflight.js +396 -0
  91. package/lib/channels/chatgpt-runtime-contract.js +17 -0
  92. package/lib/channels/chatgpt-setup-values.js +124 -0
  93. package/lib/channels/claude-callback.js +67 -0
  94. package/lib/channels/claude-channel-add.js +254 -0
  95. package/lib/channels/claude-runtime-contract.js +40 -0
  96. package/lib/channels/claude-runtime.js +58 -0
  97. package/lib/channels/claude-setup-values.js +92 -0
  98. package/lib/channels/mcp-client/config-merge.js +148 -0
  99. package/lib/channels/mcp-client/ensure-client.js +231 -0
  100. package/lib/channels/mcp-client/paths.js +53 -0
  101. package/lib/channels/mcp-client/profiles.js +122 -0
  102. package/lib/channels/mcp-client/redirect-uris.js +99 -0
  103. package/lib/channels/mcp-client/runtime.js +59 -0
  104. package/lib/channels/mcp-client-channel-add.js +186 -0
  105. package/lib/channels/microsoft-copilot-channel-add.js +117 -7
  106. package/lib/channels/microsoft-copilot-entra-identifier-uris.js +187 -0
  107. package/lib/channels/microsoft-copilot-entra-sso-form.js +106 -18
  108. package/lib/channels/microsoft-copilot-entra-sso.js +31 -2
  109. package/lib/channels/microsoft-copilot-package-prior.js +107 -0
  110. package/lib/channels/microsoft-copilot-package.js +29 -28
  111. package/lib/channels/microsoft-provisioning/a365.js +80 -0
  112. package/lib/channels/microsoft-provisioning/auth-config.js +240 -0
  113. package/lib/channels/microsoft-provisioning/auth.js +179 -0
  114. package/lib/channels/microsoft-provisioning/cli.js +71 -0
  115. package/lib/channels/microsoft-provisioning/constants.js +75 -0
  116. package/lib/channels/microsoft-provisioning/errors.js +117 -0
  117. package/lib/channels/microsoft-provisioning/index.js +55 -0
  118. package/lib/channels/microsoft-provisioning/install-atk.js +158 -0
  119. package/lib/channels/microsoft-provisioning/install-teams.js +115 -0
  120. package/lib/channels/microsoft-provisioning/login-portal-device.js +236 -0
  121. package/lib/channels/microsoft-provisioning/login-portal-parse.js +71 -0
  122. package/lib/channels/microsoft-provisioning/login-portal-teams.js +193 -0
  123. package/lib/channels/microsoft-provisioning/login-portal.js +230 -0
  124. package/lib/channels/microsoft-provisioning/persist.js +110 -0
  125. package/lib/channels/microsoft-provisioning/teams-bot-args.js +119 -0
  126. package/lib/channels/microsoft-provisioning/teams-bot-controller.js +123 -0
  127. package/lib/channels/microsoft-provisioning/teams-bot-parse.js +134 -0
  128. package/lib/channels/microsoft-provisioning/teams-bot-persist.js +113 -0
  129. package/lib/channels/microsoft-provisioning/teams-bot-provision.js +234 -0
  130. package/lib/channels/microsoft-provisioning/teams-bot-secrets.js +45 -0
  131. package/lib/channels/microsoft-provisioning/teams-cli.js +82 -0
  132. package/lib/channels/runtime-tool-catalog.js +5 -2
  133. package/lib/channels/slack-channel-add-portal.js +130 -0
  134. package/lib/channels/slack-channel-add-tty-auth.js +95 -0
  135. package/lib/channels/slack-channel-add.js +311 -0
  136. package/lib/channels/slack-mcp-callback.js +51 -0
  137. package/lib/channels/slack-mcp-runtime.js +156 -0
  138. package/lib/channels/slack-provisioning/apps.js +181 -0
  139. package/lib/channels/slack-provisioning/auth-store.js +110 -0
  140. package/lib/channels/slack-provisioning/auth-ticket.js +185 -0
  141. package/lib/channels/slack-provisioning/auth.js +115 -0
  142. package/lib/channels/slack-provisioning/callbacks.js +41 -0
  143. package/lib/channels/slack-provisioning/cli.js +226 -0
  144. package/lib/channels/slack-provisioning/constants.js +37 -0
  145. package/lib/channels/slack-provisioning/credentials.js +169 -0
  146. package/lib/channels/slack-provisioning/curl-shim.js +132 -0
  147. package/lib/channels/slack-provisioning/developer-install.js +118 -0
  148. package/lib/channels/slack-provisioning/env-file.js +120 -0
  149. package/lib/channels/slack-provisioning/errors.js +47 -0
  150. package/lib/channels/slack-provisioning/go-ca-bundle.js +137 -0
  151. package/lib/channels/slack-provisioning/index.js +250 -0
  152. package/lib/channels/slack-provisioning/install-cli.js +335 -0
  153. package/lib/channels/slack-provisioning/manifest.js +89 -0
  154. package/lib/channels/slack-provisioning/oauth-lock.js +33 -0
  155. package/lib/channels/slack-provisioning/offer-cli.js +113 -0
  156. package/lib/channels/slack-provisioning/onboard-members.js +122 -0
  157. package/lib/channels/slack-provisioning/onboard.js +89 -0
  158. package/lib/channels/slack-provisioning/persist.js +95 -0
  159. package/lib/channels/slack-provisioning/remaining-urls.js +158 -0
  160. package/lib/channels/slack-provisioning/with-curl-on-path.js +53 -0
  161. package/lib/channels/teams-bot-channel-add.js +94 -0
  162. package/lib/channels/vendor-dataplane-url.js +249 -0
  163. package/lib/cli/index.js +4 -0
  164. package/lib/cli/setup-certification-commands.js +2 -2
  165. package/lib/cli/setup-certification.help.js +5 -1
  166. package/lib/cli/setup-external-system-help.js +2 -0
  167. package/lib/cli/setup-external-system.js +1 -1
  168. package/lib/commands/agent-kit-help.js +79 -0
  169. package/lib/commands/agent-kit.js +346 -0
  170. package/lib/commands/channel-add-help.js +366 -0
  171. package/lib/commands/channel-add-setup.js +162 -80
  172. package/lib/commands/channel-configure.js +118 -0
  173. package/lib/commands/channel.js +10 -1
  174. package/lib/commands/datasource-capability-relate-cli.js +5 -4
  175. package/lib/commands/governance-upload-external.js +6 -3
  176. package/lib/commands/lifecycle-command-action.js +2 -5
  177. package/lib/commands/lifecycle-external.js +93 -21
  178. package/lib/commands/repair-auth-apply.js +1 -1
  179. package/lib/commands/repair-datasource-key-skip.js +39 -0
  180. package/lib/commands/repair-datasource-keys.js +24 -12
  181. package/lib/commands/repair-datasource-test-payload.js +4 -2
  182. package/lib/commands/repair-datasource-webhooks-sync-bridge.js +23 -2
  183. package/lib/commands/repair-datasource.js +3 -0
  184. package/lib/commands/repair-external-run.js +59 -25
  185. package/lib/commands/repair-openapi-rest-runtime.js +127 -0
  186. package/lib/commands/repair-orchestration-tag-merge.js +339 -0
  187. package/lib/commands/repair-rbac-catalog-defaults.js +96 -0
  188. package/lib/commands/repair-rbac-platform-preset.js +26 -15
  189. package/lib/commands/repair-rbac-reader-roles.js +8 -21
  190. package/lib/commands/repair-rbac.js +26 -44
  191. package/lib/commands/repair-system-permissions.js +24 -22
  192. package/lib/commands/role-assistant-copy-output.js +61 -0
  193. package/lib/commands/role-assistant-copy.js +155 -0
  194. package/lib/commands/role-assistant-test-output.js +22 -9
  195. package/lib/commands/role-assistant-test-result-rows.js +42 -0
  196. package/lib/commands/role-assistant.js +150 -43
  197. package/lib/commands/search.js +143 -0
  198. package/lib/commands/test-e2e-external.js +148 -21
  199. package/lib/commands/test-trust-external.js +7 -5
  200. package/lib/commands/upload-credential-push-log.js +2 -1
  201. package/lib/commands/upload-publish-context.js +1 -1
  202. package/lib/commands/upload-role-assistant-shell.js +124 -0
  203. package/lib/commands/upload-sidecar-followups.js +10 -4
  204. package/lib/commands/upload.js +18 -3
  205. package/lib/commands/verify-operations-skip-e2e.js +131 -0
  206. package/lib/commands/verify-operations-step-plan.js +6 -33
  207. package/lib/commands/verify-operations-steps.js +3 -1
  208. package/lib/core/secrets-docker-env.js +4 -1
  209. package/lib/core/secrets-env-content.js +17 -3
  210. package/lib/datasource/capability/capability-manifest.js +0 -3
  211. package/lib/datasource/capability/copy-test-payload.js +3 -0
  212. package/lib/datasource/capability/relate-operations.js +28 -10
  213. package/lib/datasource/capability/run-capability-relate.js +48 -25
  214. package/lib/datasource/datasource-identifier.js +13 -5
  215. package/lib/deployment/deployer-poll-run.js +117 -35
  216. package/lib/external-system/deploy-dataplane-published.js +70 -0
  217. package/lib/external-system/deploy-helpers.js +26 -1
  218. package/lib/external-system/deploy.js +22 -8
  219. package/lib/external-system/download-helpers.js +29 -2
  220. package/lib/external-system/download-role-assistant.js +109 -4
  221. package/lib/external-system/download.js +46 -30
  222. package/lib/external-system/sync-deploy-manifest.js +3 -2
  223. package/lib/external-system/upload-identity.js +42 -0
  224. package/lib/generator/index.js +19 -15
  225. package/lib/generator/split.js +13 -2
  226. package/lib/generator/wizard-datasource-key.js +54 -0
  227. package/lib/generator/wizard.js +55 -54
  228. package/lib/integration-definition/apply-datasource-keys.js +75 -0
  229. package/lib/integration-definition/apply-relationships.js +195 -0
  230. package/lib/integration-definition/apply-static-enterprise.js +229 -0
  231. package/lib/integration-definition/apply-system-file.js +71 -0
  232. package/lib/integration-definition/apply-test-endpoint.js +89 -0
  233. package/lib/integration-definition/apply-viewpoint-defaults.js +157 -0
  234. package/lib/integration-definition/apply.js +78 -59
  235. package/lib/integration-definition/enrich-openapi-operations.js +36 -10
  236. package/lib/integration-definition/enrich-openapi-pick.js +87 -0
  237. package/lib/lifecycle/role-assistant-governance.js +181 -0
  238. package/lib/lifecycle/scenario-upload.js +181 -30
  239. package/lib/programmatic/builder-api-cors.js +143 -0
  240. package/lib/programmatic/builder-api-request.js +6 -0
  241. package/lib/programmatic/builder-api-route-dispatch.js +56 -42
  242. package/lib/programmatic/builder-api-server.js +8 -1
  243. package/lib/programmatic/capability-registry.js +55 -0
  244. package/lib/programmatic/channel-install-help-resolve.js +359 -0
  245. package/lib/programmatic/channel-install-session.js +218 -0
  246. package/lib/programmatic/help-content/channel-onboarding.md +2 -0
  247. package/lib/programmatic/help-content/cip-overview.md +3 -1
  248. package/lib/programmatic/http-raw-response.js +62 -0
  249. package/lib/programmatic/index.js +2 -0
  250. package/lib/programmatic/openapi-apply-result-schemas.js +8 -0
  251. package/lib/programmatic/openapi-channel-install-bindings.js +179 -0
  252. package/lib/programmatic/openapi-channel-install-schemas.js +289 -0
  253. package/lib/programmatic/openapi-component-schemas.js +19 -1
  254. package/lib/programmatic/openapi-description-enricher.js +3 -1
  255. package/lib/programmatic/openapi-descriptions.js +80 -3
  256. package/lib/programmatic/openapi-envelope-examples.js +124 -0
  257. package/lib/programmatic/openapi-operation-bindings.js +9 -1
  258. package/lib/programmatic/openapi-request-schemas.js +5 -0
  259. package/lib/programmatic/openapi-schema-descriptions-channel.js +319 -0
  260. package/lib/programmatic/openapi-schema-descriptions-operations.js +19 -0
  261. package/lib/programmatic/openapi-spec.js +13 -8
  262. package/lib/programmatic/platform-rbac-catalog.js +36 -18
  263. package/lib/programmatic/request-timeout.js +3 -0
  264. package/lib/programmatic/route-handler-map.js +58 -1
  265. package/lib/programmatic/route-handlers-context.js +2 -1
  266. package/lib/programmatic/run-auth-permissions.js +54 -0
  267. package/lib/programmatic/run-channel-catalog.js +238 -0
  268. package/lib/programmatic/run-channel-install-artifacts.js +137 -0
  269. package/lib/programmatic/run-channel-install-copilot.js +353 -0
  270. package/lib/programmatic/run-channel-install-options.js +236 -0
  271. package/lib/programmatic/run-channel-install-teams-bot.js +204 -0
  272. package/lib/programmatic/run-channel-install.js +346 -0
  273. package/lib/programmatic/run-channel-package.js +87 -7
  274. package/lib/programmatic/run-download.js +41 -0
  275. package/lib/programmatic/workspace-context.js +2 -0
  276. package/lib/protection/auth-context.js +3 -1
  277. package/lib/protection/protection-display.js +3 -2
  278. package/lib/protection/report-exit.js +50 -0
  279. package/lib/protection/run-commands.js +2 -0
  280. package/lib/role-assistant/evidence-sync.js +4 -2
  281. package/lib/role-assistant/evidence-validation-issues.js +51 -0
  282. package/lib/role-assistant/knowledge-sync.js +10 -4
  283. package/lib/role-assistant/package-validate.js +175 -0
  284. package/lib/role-assistant/settings.js +49 -2
  285. package/lib/role-assistant/test-case-assertion-row.js +36 -0
  286. package/lib/role-assistant/test-case-copy-bind.js +77 -0
  287. package/lib/role-assistant/test-case-copy-expected.js +127 -0
  288. package/lib/role-assistant/test-case-copy-from-work.js +90 -0
  289. package/lib/role-assistant/test-case-copy-interactions.js +67 -0
  290. package/lib/role-assistant/test-case-copy.js +119 -0
  291. package/lib/role-assistant/test-case-expected-catalog.js +135 -0
  292. package/lib/role-assistant/test-case-validate.js +88 -0
  293. package/lib/role-assistant/test-cases-bid.js +117 -4
  294. package/lib/role-assistant/test-cases-evaluate.js +159 -24
  295. package/lib/role-assistant/test-cases-evidence.js +175 -0
  296. package/lib/role-assistant/test-cases-honesty.js +155 -6
  297. package/lib/role-assistant/test-cases-lifecycle.js +291 -0
  298. package/lib/role-assistant/test-cases-search-graph.js +122 -0
  299. package/lib/role-assistant/test-cases-search.js +247 -0
  300. package/lib/role-assistant/test-cases.js +71 -172
  301. package/lib/role-assistant/test-pack-map.js +180 -0
  302. package/lib/role-assistant/test-pack-sync.js +187 -0
  303. package/lib/role-assistant/test-runner-debug.js +54 -0
  304. package/lib/role-assistant/test-runner-respond-body.js +36 -0
  305. package/lib/role-assistant/test-runner-search.js +164 -0
  306. package/lib/role-assistant/test-runner-start-payload.js +63 -10
  307. package/lib/role-assistant/test-runner-workhub-answers.js +45 -16
  308. package/lib/role-assistant/test-runner-workhub-helpers.js +40 -2
  309. package/lib/role-assistant/test-runner-workhub-soft.js +9 -3
  310. package/lib/role-assistant/test-runner-workhub.js +74 -32
  311. package/lib/role-assistant/test-runner.js +66 -11
  312. package/lib/schema/external-datasource.schema.json +146 -21
  313. package/lib/schema/external-system.schema.json +177 -2
  314. package/lib/schema/mcp-client-profile.schema.json +103 -0
  315. package/lib/schema/role-assistant-test-case.schema.json +408 -0
  316. package/lib/search/dataplane-context.js +23 -0
  317. package/lib/search/search-args.js +211 -0
  318. package/lib/search/search-display.js +238 -0
  319. package/lib/search/search-errors.js +50 -0
  320. package/lib/search/search-prompts.js +119 -0
  321. package/lib/search/search-roles.js +85 -0
  322. package/lib/search/search-run.js +241 -0
  323. package/lib/search/search-skills.js +198 -0
  324. package/lib/utils/app-path-resolve.js +4 -0
  325. package/lib/utils/authentication-env-template.js +44 -6
  326. package/lib/utils/authentication-slot-show.js +153 -0
  327. package/lib/utils/credential-display.js +43 -1
  328. package/lib/utils/credential-secrets-env.js +6 -1
  329. package/lib/utils/env-copy.js +19 -7
  330. package/lib/utils/external-env-template.js +20 -2
  331. package/lib/utils/external-system-readiness-compact-blocks.js +5 -1
  332. package/lib/utils/external-system-readiness-compact-display.js +30 -1
  333. package/lib/utils/external-system-validators.js +2 -1
  334. package/lib/utils/help-builder.js +3 -1
  335. package/lib/utils/paths.js +18 -1
  336. package/lib/utils/platform-shell-package.js +69 -0
  337. package/lib/utils/port-resolver.js +50 -1
  338. package/lib/utils/rewrite-name-flag.js +20 -0
  339. package/lib/utils/role-assistant-paths.js +13 -10
  340. package/lib/utils/schema-loader.js +37 -0
  341. package/lib/utils/schema-resolver.js +11 -1
  342. package/lib/utils/secrets-helpers.js +12 -21
  343. package/lib/utils/token-manager.js +10 -5
  344. package/lib/validation/validate-external-file.js +5 -1
  345. package/lib/validation/validate.js +41 -0
  346. package/package.json +1 -1
  347. package/templates/README.md +1 -1
  348. package/templates/agent-kit/adapters/claude/nested.CLAUDE.md +1 -0
  349. package/templates/agent-kit/adapters/claude/root.CLAUDE.md +5 -0
  350. package/templates/agent-kit/adapters/cursor/commands/cust-0-plan.md +5 -0
  351. package/templates/agent-kit/adapters/cursor/commands/cust-1-validate.md +5 -0
  352. package/templates/agent-kit/adapters/cursor/commands/cust-2-build.md +5 -0
  353. package/templates/agent-kit/adapters/cursor/commands/cust-3-push.md +5 -0
  354. package/templates/agent-kit/adapters/cursor/commands/cust-biz-1-validate.md +5 -0
  355. package/templates/agent-kit/adapters/cursor/commands/cust-biz-2-build.md +5 -0
  356. package/templates/agent-kit/adapters/cursor/commands/cust-biz-3-prove.md +5 -0
  357. package/templates/agent-kit/agent-kit.yaml +45 -0
  358. package/templates/agent-kit/instructions/AGENTKIT.md +83 -0
  359. package/templates/agent-kit/instructions/integration.AGENTS.md +25 -0
  360. package/templates/agent-kit/instructions/role-assistant.AGENTS.md +22 -0
  361. package/templates/agent-kit/instructions/root.AGENTS.md +37 -0
  362. package/templates/agent-kit/parity-inventory.yaml +188 -0
  363. package/templates/agent-kit/skills/aifabrix-connected-system/SKILL.md +58 -0
  364. package/templates/agent-kit/skills/aifabrix-connected-system/references/contract-checklist.md +40 -0
  365. package/templates/agent-kit/skills/aifabrix-connected-system/references/delivery-gates.md +54 -0
  366. package/templates/agent-kit/skills/aifabrix-connected-system/references/production-safety.md +35 -0
  367. package/templates/agent-kit/skills/aifabrix-connected-system/scripts/reserved-system-key.js +19 -0
  368. package/templates/agent-kit/skills/aifabrix-plan/SKILL.md +51 -0
  369. package/templates/agent-kit/skills/aifabrix-plan/references/challenge-checklist.md +108 -0
  370. package/templates/agent-kit/skills/aifabrix-plan/references/interaction.md +34 -0
  371. package/templates/agent-kit/skills/aifabrix-plan/references/plan-template.md +182 -0
  372. package/templates/agent-kit/skills/aifabrix-prove/SKILL.md +50 -0
  373. package/templates/agent-kit/skills/aifabrix-prove/references/demo-template.md +65 -0
  374. package/templates/agent-kit/skills/aifabrix-prove/references/evidence-lifecycle.md +68 -0
  375. package/templates/agent-kit/skills/aifabrix-prove/references/learning-template.md +66 -0
  376. package/templates/agent-kit/skills/aifabrix-role-assistant/SKILL.md +42 -0
  377. package/templates/agent-kit/skills/aifabrix-role-assistant/references/package-boundary.md +21 -0
  378. package/templates/agent-kit/skills/shared/hosts.md +78 -0
  379. package/templates/agent-kit/workspace/.cursor/plans/README.md +22 -0
  380. package/templates/agent-kit/workspace/LICENSE.mit +21 -0
  381. package/templates/agent-kit/workspace/README.md +89 -0
  382. package/templates/applications/builder-api/Dockerfile +3 -1
  383. package/templates/applications/builder-api/env.template +7 -0
  384. package/templates/applications/dataplane/application.yaml +6 -5
  385. package/templates/applications/dataplane/env.template +2 -2
  386. package/templates/applications/dataplane/rbac.yaml +35 -2
  387. package/templates/applications/keycloak/Dockerfile +30 -4
  388. package/templates/applications/keycloak/application.yaml +2 -2
  389. package/templates/applications/keycloak/cimd-lenient-parse/AbstractClientIdMetadataDocumentExecutor.java +896 -0
  390. package/templates/applications/keycloak/cimd-lenient-parse/SOURCE.md +19 -0
  391. package/templates/applications/keycloak/env.template +3 -0
  392. package/templates/applications/miso-controller/application.yaml +1 -2
  393. package/templates/applications/miso-controller/env.template +10 -9
  394. package/templates/channels/README.md +5 -5
  395. package/templates/channels/chatgpt/TROUBLESHOOTING.md +51 -0
  396. package/templates/channels/chatgpt/channel.json +59 -0
  397. package/templates/channels/chatgpt/icon.svg +1 -0
  398. package/templates/channels/chatgpt/install.template.md.hbs +20 -95
  399. package/templates/channels/chatgpt/integration/README.md +1 -1
  400. package/templates/channels/chatgpt/integration/application.json +2 -2
  401. package/templates/channels/chatgpt/integration/chatgpt-system.json +49 -4
  402. package/templates/channels/chatgpt/integration/env.template +2 -4
  403. package/templates/channels/chatgpt/integration/rbac.json +13 -0
  404. package/templates/channels/claude/TROUBLESHOOTING.md +44 -0
  405. package/templates/channels/claude/channel.json +59 -0
  406. package/templates/channels/claude/icon.svg +1 -0
  407. package/templates/channels/claude/install.template.md.hbs +22 -0
  408. package/templates/channels/claude/integration/README.md +14 -0
  409. package/templates/channels/claude/integration/application.json +15 -0
  410. package/templates/channels/claude/integration/claude-system.json +59 -0
  411. package/templates/channels/claude/integration/env.template +2 -0
  412. package/templates/channels/claude/integration/rbac.json +13 -0
  413. package/templates/channels/claude/manifest.template.json.hbs +40 -0
  414. package/templates/channels/mcp-client/channel.json +72 -0
  415. package/templates/channels/mcp-client/icon.svg +1 -0
  416. package/templates/channels/mcp-client/install.template.md.hbs +24 -0
  417. package/templates/channels/mcp-client/integration/README.md +13 -0
  418. package/templates/channels/mcp-client/integration/application.json +15 -0
  419. package/templates/channels/mcp-client/integration/env.template +2 -0
  420. package/templates/channels/mcp-client/integration/mcp-client-system.json +72 -0
  421. package/templates/channels/mcp-client/integration/rbac.json +13 -0
  422. package/templates/channels/mcp-client/manifest.template.json.hbs +41 -0
  423. package/templates/channels/mcp-client/profiles/cursor.json +26 -0
  424. package/templates/channels/mcp-client/profiles/github-copilot.json +29 -0
  425. package/templates/channels/mcp-client/profiles/vscode.json +29 -0
  426. package/templates/channels/microsoft-copilot/channel.json +73 -0
  427. package/templates/channels/microsoft-copilot/declarative-agent.template.json.hbs +8 -4
  428. package/templates/channels/microsoft-copilot/entra-sso-registration.template.md.hbs +65 -5
  429. package/templates/channels/microsoft-copilot/icon.svg +1 -0
  430. package/templates/channels/microsoft-copilot/install.template.md.hbs +9 -9
  431. package/templates/channels/microsoft-copilot/integration/README.md +1 -1
  432. package/templates/channels/microsoft-copilot/integration/application.json +2 -2
  433. package/templates/channels/microsoft-copilot/integration/env.template +3 -6
  434. package/templates/channels/microsoft-copilot/integration/microsoft-copilot-system.json +63 -4
  435. package/templates/channels/microsoft-copilot/integration/rbac.json +13 -0
  436. package/templates/channels/microsoft-copilot/oauth-plugin-vault-required.template.md.hbs +5 -5
  437. package/templates/channels/slack/channel.json +234 -0
  438. package/templates/channels/slack/icon.svg +1 -0
  439. package/templates/channels/slack/install.template.md.hbs +45 -28
  440. package/templates/channels/slack/integration/README.md +245 -22
  441. package/templates/channels/slack/integration/application.json +44 -7
  442. package/templates/channels/slack/integration/env.template +15 -6
  443. package/templates/channels/slack/integration/openapi/openapi.json +126 -0
  444. package/templates/channels/slack/integration/rbac.json +84 -0
  445. package/templates/channels/slack/integration/slack-datasource-commands.json +154 -0
  446. package/templates/channels/slack/integration/slack-datasource-conversations.json +28 -3
  447. package/templates/channels/slack/integration/slack-datasource-events.json +154 -0
  448. package/templates/channels/slack/integration/slack-datasource-interactive.json +154 -0
  449. package/templates/channels/slack/integration/slack-datasource-messages.json +40 -2
  450. package/templates/channels/slack/integration/slack-system.json +161 -72
  451. package/templates/channels/slack/manifest.template.json.hbs +10 -4
  452. package/templates/channels/teams-bot/channel.json +162 -0
  453. package/templates/channels/teams-bot/icon.svg +1 -0
  454. package/templates/channels/teams-bot/install.template.md.hbs +12 -13
  455. package/templates/channels/teams-bot/integration/README.md +5 -4
  456. package/templates/channels/teams-bot/integration/application.json +6 -4
  457. package/templates/channels/teams-bot/integration/env.template +5 -4
  458. package/templates/channels/teams-bot/integration/openapi/openapi.json +68 -0
  459. package/templates/channels/teams-bot/integration/rbac.json +21 -0
  460. package/templates/channels/teams-bot/integration/teams-bot-datasource-activities.json +154 -0
  461. package/templates/channels/teams-bot/integration/teams-bot-system.json +128 -23
  462. package/templates/channels/web-embed/channel.json +60 -0
  463. package/templates/channels/web-embed/install.template.md.hbs +1 -1
  464. package/templates/channels/web-embed/integration/README.md +2 -2
  465. package/templates/channels/web-embed/integration/application.json +2 -2
  466. package/templates/channels/web-embed/integration/env.template +1 -1
  467. package/templates/channels/web-embed/integration/rbac.json +13 -0
  468. package/templates/channels/web-embed/integration/web-embed-system.json +50 -4
  469. package/templates/python/docker-compose.hbs +14 -0
  470. package/templates/typescript/docker-compose.hbs +14 -0
@@ -36,7 +36,30 @@ const {
36
36
  const path = require('path');
37
37
 
38
38
  /** Runtime/API fields that must not appear on external-system manifests. */
39
- const NON_MANIFEST_SYSTEM_KEYS = ['showOpenApiDocs'];
39
+ const NON_MANIFEST_SYSTEM_KEYS = ['showOpenApiDocs', 'rbac'];
40
+
41
+ /**
42
+ * Coerce system dataSources to unique string keys (dataplane may return objects).
43
+ * @param {*} dataSources
44
+ * @returns {string[]}
45
+ */
46
+ function normalizeManifestDataSourceKeys(dataSources) {
47
+ if (!Array.isArray(dataSources)) {
48
+ return [];
49
+ }
50
+ const keys = [];
51
+ const seen = new Set();
52
+ for (const item of dataSources) {
53
+ const raw = typeof item === 'string' ? item : item && item.key;
54
+ const key = typeof raw === 'string' ? raw.trim() : '';
55
+ if (!key || seen.has(key)) {
56
+ continue;
57
+ }
58
+ seen.add(key);
59
+ keys.push(key);
60
+ }
61
+ return keys;
62
+ }
40
63
 
41
64
  /**
42
65
  * True when cwd looks like a product/workspace repo (integration, builder, or EK tree).
@@ -114,6 +137,9 @@ function sanitizeDownloadedApplication(application) {
114
137
  for (const key of NON_MANIFEST_SYSTEM_KEYS) {
115
138
  delete cleaned[key];
116
139
  }
140
+ if (Array.isArray(cleaned.dataSources)) {
141
+ cleaned.dataSources = normalizeManifestDataSourceKeys(cleaned.dataSources);
142
+ }
117
143
  return cleaned;
118
144
  }
119
145
 
@@ -296,6 +322,7 @@ module.exports = {
296
322
  runConvertToJsonIfRequested,
297
323
  generateVariablesYaml,
298
324
  generateReadme,
299
- NON_MANIFEST_SYSTEM_KEYS
325
+ NON_MANIFEST_SYSTEM_KEYS,
326
+ normalizeManifestDataSourceKeys
300
327
  };
301
328
 
@@ -1,17 +1,46 @@
1
1
  /**
2
2
  * Role Assistant sidecar handling during external-system download.
3
3
  *
4
- * @fileoverview Post-download evidence/knowledge/workflow actions for digitalWorker systems
4
+ * @fileoverview Platform-shell download (digitalWorker / enterpriseKnowledge) plus RA sidecars
5
5
  * @author AI Fabrix Team
6
- * @version 1.0.0
6
+ * @version 1.1.0
7
7
  */
8
8
 
9
9
  'use strict';
10
10
 
11
+ const path = require('path');
11
12
  const logger = require('../utils/logger');
12
- const { formatWarningLine } = require('../utils/cli-test-layout-chalk');
13
+ const {
14
+ formatWarningLine,
15
+ formatSuccessLine,
16
+ metadata
17
+ } = require('../utils/cli-test-layout-chalk');
13
18
  const { exportRoleAssistantKnowledge, logKnowledgeExportSummary } = require('../role-assistant/knowledge-sync');
14
19
  const { exportRoleAssistantEvidence, logRoleAssistantEvidenceExportSummary } = require('../role-assistant/evidence-sync');
20
+ const { writeOrMergeRoleAssistantSettings } = require('../role-assistant/settings');
21
+ const {
22
+ isDigitalWorkerKind,
23
+ isEnterpriseKnowledgeKind,
24
+ isPlatformShellKind
25
+ } = require('../utils/platform-shell-package');
26
+
27
+ function connectedSystemDryRunFileNames(systemKey, dataSources, format) {
28
+ const { getExternalDatasourceFileName } = require('../generator/split-variables');
29
+ const ext = format === 'json' ? 'json' : 'yaml';
30
+ const names = [
31
+ `${systemKey}-deploy.json`,
32
+ `application.${ext}`,
33
+ `${systemKey}-system.${ext}`,
34
+ 'env.template',
35
+ 'README.md'
36
+ ];
37
+ const list = Array.isArray(dataSources) ? dataSources : [];
38
+ for (let i = 0; i < list.length; i += 1) {
39
+ const yamlName = getExternalDatasourceFileName(systemKey, list[i], i);
40
+ names.push(ext === 'json' ? yamlName.replace(/\.yaml$/i, '.json') : yamlName);
41
+ }
42
+ return names;
43
+ }
15
44
 
16
45
  async function maybeExportRoleAssistantEvidenceArtifacts(systemKey, manifest, dataplaneUrl, authConfig, options) {
17
46
  try {
@@ -28,6 +57,23 @@ async function maybeExportRoleAssistantEvidenceArtifacts(systemKey, manifest, da
28
57
  }
29
58
  }
30
59
 
60
+ async function maybeExportRoleAssistantTestsArtifacts(systemKey, dataplaneUrl, authConfig, options) {
61
+ try {
62
+ const { exportRoleAssistantTests } = require('../role-assistant/test-pack-sync');
63
+ const testsResult = await exportRoleAssistantTests({
64
+ systemKey,
65
+ dataplaneUrl,
66
+ authConfig,
67
+ options
68
+ });
69
+ if (testsResult && testsResult.skipped) {
70
+ logger.log(formatWarningLine(`Role assistant tests export skipped: ${testsResult.reason}`));
71
+ }
72
+ } catch (testsErr) {
73
+ logger.log(formatWarningLine(`Role assistant tests export skipped: ${testsErr.message}`));
74
+ }
75
+ }
76
+
31
77
  async function maybeExportRoleAssistantKnowledgeArtifacts(systemKey, manifest, dataplaneUrl, authConfig, options) {
32
78
  try {
33
79
  const knowledgeResult = await exportRoleAssistantKnowledge({
@@ -48,8 +94,67 @@ async function runRoleAssistantDownloadSidecars(params) {
48
94
  const { systemKey, manifest, dataplaneUrl, authConfig, options = {} } = params;
49
95
  await maybeExportRoleAssistantEvidenceArtifacts(systemKey, manifest, dataplaneUrl, authConfig, options);
50
96
  await maybeExportRoleAssistantKnowledgeArtifacts(systemKey, manifest, dataplaneUrl, authConfig, options);
97
+ await maybeExportRoleAssistantTestsArtifacts(systemKey, dataplaneUrl, authConfig, options);
98
+ }
99
+
100
+ function logConnectedSystemDryRunFiles(systemKey, dataSources, format) {
101
+ logger.log(metadata('Would create:'));
102
+ connectedSystemDryRunFileNames(systemKey, dataSources, format).forEach((fileName) => {
103
+ logger.log(metadata(` - integration/${systemKey}/${fileName}`));
104
+ });
105
+ }
106
+
107
+ function handleDownloadDryRun(systemKey, dataplaneUrl, application, dataSources, format) {
108
+ logger.log(formatWarningLine('Dry run mode: no files written.'));
109
+ logger.log(metadata(`Would fetch: ${dataplaneUrl}/api/v1/external/systems/${systemKey}/config`));
110
+ if (isEnterpriseKnowledgeKind(application)) {
111
+ logger.log(metadata('Would not write local package files.'));
112
+ return;
113
+ }
114
+ if (isDigitalWorkerKind(application)) {
115
+ logger.log(metadata('Would create:'));
116
+ logger.log(metadata(` - role-assistant/${systemKey}/role-assistant.yaml`));
117
+ return;
118
+ }
119
+ logConnectedSystemDryRunFiles(systemKey, dataSources, format);
120
+ }
121
+
122
+ async function downloadDigitalWorkerPackage(params) {
123
+ const { systemKey, manifest, dataplaneUrl, authConfig, options = {} } = params;
124
+ const yamlPath = writeOrMergeRoleAssistantSettings(systemKey, {
125
+ force: options.force === true,
126
+ pathOptions: options.pathOptions || {}
127
+ });
128
+ logger.log(formatSuccessLine(`Wrote ${path.relative(process.cwd(), yamlPath)}`));
129
+ await runRoleAssistantDownloadSidecars({
130
+ systemKey,
131
+ manifest,
132
+ dataplaneUrl,
133
+ authConfig,
134
+ options
135
+ });
136
+ return true;
137
+ }
138
+
139
+ async function downloadPlatformShellIfNeeded(params) {
140
+ const application = params.manifest && params.manifest.application;
141
+ if (!isPlatformShellKind(application)) {
142
+ return false;
143
+ }
144
+ if (isEnterpriseKnowledgeKind(application)) {
145
+ logger.log(
146
+ formatSuccessLine(
147
+ `Enterprise Knowledge '${params.systemKey}' stays on the platform; no local package files written.`
148
+ )
149
+ );
150
+ return true;
151
+ }
152
+ return downloadDigitalWorkerPackage(params);
51
153
  }
52
154
 
53
155
  module.exports = {
54
- runRoleAssistantDownloadSidecars
156
+ runRoleAssistantDownloadSidecars,
157
+ downloadPlatformShellIfNeeded,
158
+ handleDownloadDryRun,
159
+ connectedSystemDryRunFileNames
55
160
  };
@@ -31,7 +31,7 @@ const readline = require('readline');
31
31
  const yaml = require('js-yaml');
32
32
  const { getExternalSystemConfig } = require('../api/external-systems.api');
33
33
  const { getDeploymentAuth, requireBearerForDataplanePipeline } = require('../utils/token-manager');
34
- const { getConfig } = require('../core/config');
34
+ const { getConfig, getFormat } = require('../core/config');
35
35
  const { retemplateConfigurationForDownload, retemplateAllVariableDefinitions } = require('../utils/configuration-env-resolver');
36
36
  const { syncRuntimeConfigurationFromDataplane } = require('../utils/runtime-configuration-download');
37
37
  const logger = require('../utils/logger');
@@ -41,12 +41,17 @@ const {
41
41
  validateSystemType,
42
42
  validateDownloadedData,
43
43
  sanitizeDownloadedApplication,
44
+ normalizeManifestDataSourceKeys,
44
45
  resolveDownloadDestinationPath,
45
46
  logDownloadCommandHeader,
46
47
  displayDownloadSuccess,
47
48
  runConvertToJsonIfRequested
48
49
  } = require('./download-helpers');
49
- const { runRoleAssistantDownloadSidecars } = require('./download-role-assistant');
50
+ const {
51
+ runRoleAssistantDownloadSidecars,
52
+ downloadPlatformShellIfNeeded,
53
+ handleDownloadDryRun
54
+ } = require('./download-role-assistant');
50
55
 
51
56
  /**
52
57
  * Setup authentication and get dataplane URL
@@ -187,10 +192,14 @@ function augmentConfigurationWithAuthSecrets(system) {
187
192
  * @returns {Object} Deploy JSON object for splitDeployJson
188
193
  */
189
194
  function buildDeployJsonFromManifest(application, dataSources, version) {
190
- const dataSourcesKeys = Array.isArray(dataSources)
191
- ? dataSources.map(ds => (ds && ds.key) ? ds.key : ds)
192
- : [];
193
- const system = { ...application, dataSources: application.dataSources || dataSourcesKeys };
195
+ const fromApp = normalizeManifestDataSourceKeys(application.dataSources);
196
+ const fromInline = normalizeManifestDataSourceKeys(
197
+ Array.isArray(dataSources) ? dataSources.map(ds => (ds && ds.key) ? ds.key : ds) : []
198
+ );
199
+ const system = {
200
+ ...application,
201
+ dataSources: fromApp.length ? fromApp : fromInline
202
+ };
194
203
  augmentConfigurationWithAuthSecrets(system);
195
204
  const deploy = { system, dataSources };
196
205
  if (version) deploy.version = version;
@@ -211,26 +220,6 @@ function validateSystemKeyFormat(systemKey) {
211
220
  }
212
221
  }
213
222
 
214
- /**
215
- * Handle dry run mode
216
- * @param {string} systemKey - System key
217
- * @param {string} dataplaneUrl - Dataplane URL
218
- */
219
- function handleDryRun(systemKey, dataplaneUrl) {
220
- logger.log(formatWarningLine('Dry run mode: no files written.'));
221
- logger.log(metadata(`Would fetch: ${dataplaneUrl}/api/v1/external/systems/${systemKey}/config`));
222
- logger.log(metadata('Would create:'));
223
- [
224
- `integration/${systemKey}/${systemKey}-deploy.json`,
225
- `integration/${systemKey}/application.yaml`,
226
- `integration/${systemKey}/${systemKey}-system.yaml`,
227
- `integration/${systemKey}/env.template`,
228
- `integration/${systemKey}/README.md`
229
- ].forEach(rel => {
230
- logger.log(metadata(` - ${rel}`));
231
- });
232
- }
233
-
234
223
  /**
235
224
  * Validate and log downloaded data
236
225
  * @param {Object} application - Application configuration
@@ -406,9 +395,21 @@ async function finalizeDownloadArtifacts({
406
395
  * @param {Object} [options]
407
396
  * @returns {Promise<void>}
408
397
  */
398
+ async function resolveDownloadFormat(requested) {
399
+ const raw = typeof requested === 'string' ? requested.trim().toLowerCase() : '';
400
+ if (raw === 'json' || raw === 'yaml') {
401
+ return raw;
402
+ }
403
+ const fromConfig = await getFormat();
404
+ if (fromConfig === 'json' || fromConfig === 'yaml') {
405
+ return fromConfig;
406
+ }
407
+ return 'yaml';
408
+ }
409
+
409
410
  async function downloadExternalSystem(systemKey, options = {}) {
410
411
  validateSystemKeyFormat(systemKey);
411
- const format = (options.format || 'yaml').toLowerCase();
412
+ const format = await resolveDownloadFormat(options.format);
412
413
 
413
414
  try {
414
415
  logDownloadCommandHeader(systemKey);
@@ -418,12 +419,27 @@ async function downloadExternalSystem(systemKey, options = {}) {
418
419
  options,
419
420
  config
420
421
  );
422
+ const manifest = await downloadFullManifest(dataplaneUrl, systemKey, authConfig, options);
421
423
  if (options.dryRun) {
422
- handleDryRun(systemKey, dataplaneUrl);
424
+ handleDownloadDryRun(
425
+ systemKey,
426
+ dataplaneUrl,
427
+ manifest.application,
428
+ manifest.dataSources,
429
+ format
430
+ );
431
+ return;
432
+ }
433
+ const platformHandled = await downloadPlatformShellIfNeeded({
434
+ systemKey,
435
+ manifest,
436
+ dataplaneUrl,
437
+ authConfig,
438
+ options
439
+ });
440
+ if (platformHandled) {
423
441
  return;
424
442
  }
425
-
426
- const manifest = await downloadFullManifest(dataplaneUrl, systemKey, authConfig, options);
427
443
  validateAndLogDownloadedData(manifest.application, manifest.dataSources);
428
444
  const finalPath = resolveDownloadDestinationPath(systemKey, manifest.application);
429
445
  await processDownloadedSystem(
@@ -21,8 +21,9 @@ const logger = require('../utils/logger');
21
21
  * @returns {Promise<string>} Absolute path to the written deploy JSON file
22
22
  */
23
23
  async function syncDeployJsonFromSources(systemKey, opts = {}) {
24
- const deployPath = await generator.generateDeployJson(systemKey, {});
25
- if (!opts.quiet) {
24
+ const { quiet, ...generateOpts } = opts;
25
+ const deployPath = await generator.generateDeployJson(systemKey, generateOpts);
26
+ if (!quiet) {
26
27
  logger.log(formatSuccessLine(`Updated deployment manifest: ${deployPath}`));
27
28
  }
28
29
  return deployPath;
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Fail closed when an upload payload's keys do not match the target system.
3
+ *
4
+ * @fileoverview Same contract as dataplane system_key_mismatch
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ /**
12
+ * @param {Object} payload
13
+ * @param {string} systemKey
14
+ * @returns {void}
15
+ */
16
+ function assertUploadPackageIdentity(payload, systemKey) {
17
+ if (!payload || typeof payload !== 'object') {
18
+ throw new Error('Upload payload is required.');
19
+ }
20
+ const applicationKey =
21
+ payload.application && typeof payload.application.key === 'string'
22
+ ? payload.application.key
23
+ : '';
24
+ if (applicationKey !== systemKey) {
25
+ throw new Error(
26
+ `systemKey '${applicationKey}' does not match expected system key '${systemKey}'`
27
+ );
28
+ }
29
+ const dataSources = Array.isArray(payload.dataSources) ? payload.dataSources : [];
30
+ for (const ds of dataSources) {
31
+ if (!ds || ds.systemKey === systemKey) {
32
+ continue;
33
+ }
34
+ throw new Error(
35
+ `systemKey '${ds.systemKey}' does not match expected system key '${systemKey}'`
36
+ );
37
+ }
38
+ }
39
+
40
+ module.exports = {
41
+ assertUploadPackageIdentity
42
+ };
@@ -298,26 +298,30 @@ async function writeRegularDeployJson(appName, appPath, appType) {
298
298
  return jsonPath;
299
299
  }
300
300
 
301
- async function generateDeployJson(appName, options = {}) {
302
- if (!appName || typeof appName !== 'string') {
303
- throw new Error('App name is required and must be a string');
304
- }
305
- let appPath;
306
- let isExternal;
307
- let appType;
301
+ async function resolveDeployJsonAppContext(appName, options) {
308
302
  if (options.appPath) {
309
- appPath = path.resolve(options.appPath);
303
+ const appPath = path.resolve(options.appPath);
310
304
  const configPath = resolveApplicationConfigPath(appPath);
311
305
  const { loadConfigFile } = require('../utils/config-format');
312
306
  const variables = loadConfigFile(configPath);
313
- appType = variables?.app?.type || 'external';
314
- isExternal = appType === 'external';
315
- } else {
316
- const detected = await detectAppType(appName, options);
317
- appPath = detected.appPath;
318
- isExternal = detected.isExternal;
319
- appType = detected.appType;
307
+ const appType = variables?.app?.type || 'external';
308
+ return { appPath, appType, isExternal: appType === 'external' };
309
+ }
310
+ const detected = await detectAppType(appName, options);
311
+ const { throwIfPlatformShellHasNoDeployJson } = require('../utils/platform-shell-package');
312
+ throwIfPlatformShellHasNoDeployJson(appName, detected.baseDir);
313
+ return {
314
+ appPath: detected.appPath,
315
+ isExternal: detected.isExternal,
316
+ appType: detected.appType
317
+ };
318
+ }
319
+
320
+ async function generateDeployJson(appName, options = {}) {
321
+ if (!appName || typeof appName !== 'string') {
322
+ throw new Error('App name is required and must be a string');
320
323
  }
324
+ const { appPath, isExternal, appType } = await resolveDeployJsonAppContext(appName, options);
321
325
  logOfflinePathWhenType(appPath);
322
326
  if (isExternal) {
323
327
  return writeExternalDeployJson(appName, appPath, options);
@@ -15,6 +15,18 @@ const { parseImageReference } = require('./parse-image');
15
15
  const { generateReadmeFromDeployJson } = require('./split-readme');
16
16
  const { extractVariablesYaml, getExternalDatasourceFileName } = require('./split-variables');
17
17
  const { generateExternalEnvTemplateContent } = require('../utils/external-env-template');
18
+ const { normalizeManifestDataSourceKeys } = require('../external-system/download-helpers');
19
+
20
+ /**
21
+ * System YAML payload: omit runtime RBAC fields and coerce dataSources to keys.
22
+ * @param {Object} system
23
+ * @returns {Object}
24
+ */
25
+ function systemYamlPayload(system) {
26
+ const { roles: _roles, permissions: _permissions, rbac: _rbac, ...rest } = system;
27
+ rest.dataSources = normalizeManifestDataSourceKeys(rest.dataSources);
28
+ return rest;
29
+ }
18
30
 
19
31
  /**
20
32
  * Converts configuration array back to env.template format
@@ -339,9 +351,8 @@ async function writeExternalSystemAndDatasourceFiles(outputDir, deployment) {
339
351
  const system = deployment.system;
340
352
  const systemKey = system.key || 'external-system';
341
353
  const dataSourcesList = deployment.dataSources || deployment.datasources || [];
342
- const { roles: _roles, permissions: _permissions, ...systemWithoutRbac } = system;
343
354
  const systemPath = path.join(outputDir, `${systemKey}-system.yaml`);
344
- await writeComponentFile(systemPath, yaml.dump(systemWithoutRbac, { indent: 2, lineWidth: -1 }));
355
+ await writeComponentFile(systemPath, yaml.dump(systemYamlPayload(system), { indent: 2, lineWidth: -1 }));
345
356
  const datasourcePaths = await writeDatasourceFiles(outputDir, systemKey, dataSourcesList);
346
357
  return { systemFile: systemPath, datasourceFiles: datasourcePaths };
347
358
  }
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Canonical kebab datasource keys for wizard generate-config.
3
+ *
4
+ * @fileoverview Wizard datasource key segments
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ /**
10
+ * @param {string} str
11
+ * @returns {string}
12
+ */
13
+ function toKeySegment(str) {
14
+ if (!str || typeof str !== 'string') {
15
+ return 'default';
16
+ }
17
+ const withHyphens = str.replace(/([A-Z])/g, '-$1').toLowerCase();
18
+ const sanitized = withHyphens.replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');
19
+ return sanitized || 'default';
20
+ }
21
+
22
+ /**
23
+ * @param {string} finalSystemKey
24
+ * @param {{ key?: string, entityName?: string, entityType?: string, entityKey?: string }} ds
25
+ * @param {string} originalPrefix
26
+ * @param {Set<string>} [usedKeys]
27
+ * @returns {string}
28
+ */
29
+ function wizardCanonicalDatasourceKey(finalSystemKey, ds, originalPrefix, usedKeys) {
30
+ const dsKey = String(ds.key || '').trim();
31
+ let segment;
32
+ if (dsKey && originalPrefix && dsKey.startsWith(originalPrefix)) {
33
+ segment = toKeySegment(dsKey.substring(originalPrefix.length));
34
+ } else {
35
+ const raw = ds.entityName || dsKey || ds.entityType || ds.entityKey || 'default';
36
+ segment = toKeySegment(raw);
37
+ }
38
+ let candidate = segment.includes('-') && !segment.startsWith(`${finalSystemKey}-`)
39
+ ? segment
40
+ : `${finalSystemKey}-${segment}`;
41
+ if (usedKeys && usedKeys.has(candidate)) {
42
+ let suffix = 2;
43
+ while (usedKeys.has(`${candidate}-${suffix}`)) {
44
+ suffix += 1;
45
+ }
46
+ candidate = `${candidate}-${suffix}`;
47
+ }
48
+ return candidate;
49
+ }
50
+
51
+ module.exports = {
52
+ toKeySegment,
53
+ wizardCanonicalDatasourceKey
54
+ };
@@ -17,19 +17,7 @@ const { loadConfigFile, writeConfigFile } = require('../utils/config-format');
17
17
  const { systemKeyToKvPrefix, securityKeyToVar, isValidKvPath } = require('../utils/credential-secrets-env');
18
18
  const { generateExternalEnvTemplateContent } = require('../utils/external-env-template');
19
19
  const { generateReadme } = require('./wizard-readme');
20
-
21
- /**
22
- * Converts a string to a schema-valid key segment (lowercase letters, numbers, hyphens only).
23
- * e.g. "recordStorage" -> "record-storage", "documentStorage" -> "document-storage"
24
- * @param {string} str - Raw entity type or key segment (may be camelCase)
25
- * @returns {string} Segment matching ^[a-z0-9-]+$
26
- */
27
- function toKeySegment(str) {
28
- if (!str || typeof str !== 'string') return 'default';
29
- const withHyphens = str.replace(/([A-Z])/g, '-$1').toLowerCase();
30
- const sanitized = withHyphens.replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');
31
- return sanitized || 'default';
32
- }
20
+ const { toKeySegment, wizardCanonicalDatasourceKey } = require('./wizard-datasource-key');
33
21
 
34
22
  const { normalizeAuthenticationToSystemKey } = require('../utils/authentication-shape');
35
23
 
@@ -118,10 +106,46 @@ async function writeDatasourceYamlFiles(appPath, finalSystemKey, datasourceConfi
118
106
  * @param {string} [params.aiGeneratedReadme] - Optional AI-generated README content
119
107
  * @returns {Promise<Object>} Object with file paths
120
108
  */
121
- async function generateConfigFilesForWizard(params) {
122
- const { appPath, appName, finalSystemKey, systemFileName, datasourceFileNames, systemConfig, datasourceConfigs, aiGeneratedReadme, format } = params;
109
+ async function writeWizardEnvTemplate(appPath, systemConfig) {
110
+ const envTemplatePath = path.join(appPath, 'env.template');
111
+ const envTemplateContent = generateExternalEnvTemplateContent(systemConfig);
112
+ await fs.writeFile(envTemplatePath, envTemplateContent, 'utf8');
113
+ logger.log(formatSuccessLine('Generated env.template'));
114
+ try {
115
+ const secretsEnsure = require('../core/secrets-ensure');
116
+ await secretsEnsure.ensureSecretsFromEnvTemplate(envTemplatePath, {
117
+ emptyValuesForCredentials: true
118
+ });
119
+ } catch (err) {
120
+ if (err.code !== 'ENOENT') {
121
+ logger.warn(`Could not ensure integration placeholder secrets: ${err.message}`);
122
+ }
123
+ }
124
+ return envTemplatePath;
125
+ }
123
126
 
124
- // Generate or update application config with externalIntegration block
127
+ async function writeWizardDeployManifest(appPath, appName, finalSystemKey) {
128
+ const { generateControllerManifest, toDeployJsonShape } = require('./external-controller-manifest');
129
+ const manifest = await generateControllerManifest(appName, { appPath });
130
+ const deployJson = toDeployJsonShape(manifest);
131
+ const deployManifestPath = path.join(appPath, `${finalSystemKey}-deploy.json`);
132
+ await fs.writeFile(deployManifestPath, JSON.stringify(deployJson, null, 2), 'utf8');
133
+ logger.log(formatSuccessLine(`Generated deployment manifest: ${finalSystemKey}-deploy.json`));
134
+ return deployManifestPath;
135
+ }
136
+
137
+ async function generateConfigFilesForWizard(params) {
138
+ const {
139
+ appPath,
140
+ appName,
141
+ finalSystemKey,
142
+ systemFileName,
143
+ datasourceFileNames,
144
+ systemConfig,
145
+ datasourceConfigs,
146
+ aiGeneratedReadme,
147
+ format
148
+ } = params;
125
149
  const configPath = await generateOrUpdateVariablesYaml({
126
150
  appPath,
127
151
  appName,
@@ -131,21 +155,7 @@ async function generateConfigFilesForWizard(params) {
131
155
  systemConfig,
132
156
  format: format || 'yaml'
133
157
  });
134
-
135
- // Generate env.template with Authentication and Configuration sections (Handlebars)
136
- const envTemplatePath = path.join(appPath, 'env.template');
137
- const envTemplateContent = generateExternalEnvTemplateContent(systemConfig);
138
- await fs.writeFile(envTemplatePath, envTemplateContent, 'utf8');
139
- logger.log(formatSuccessLine('Generated env.template'));
140
-
141
- try {
142
- const secretsEnsure = require('../core/secrets-ensure');
143
- await secretsEnsure.ensureSecretsFromEnvTemplate(envTemplatePath, { emptyValuesForCredentials: true });
144
- } catch (err) {
145
- if (err.code !== 'ENOENT') logger.warn(`Could not ensure integration placeholder secrets: ${err.message}`);
146
- }
147
-
148
- // Generate README.md (use AI-generated content if available)
158
+ const envTemplatePath = await writeWizardEnvTemplate(appPath, systemConfig);
149
159
  await generateReadme({
150
160
  appPath,
151
161
  appName,
@@ -155,21 +165,16 @@ async function generateConfigFilesForWizard(params) {
155
165
  aiGeneratedContent: aiGeneratedReadme,
156
166
  format
157
167
  });
158
-
159
- // Generate deployment scripts
160
- const deployScripts = await generateDeployScripts(appPath, finalSystemKey, systemFileName, datasourceFileNames);
161
-
162
- // Generate deployment manifest (<systemKey>-deploy.json) using controller format
163
- const { generateControllerManifest, toDeployJsonShape } = require('./external-controller-manifest');
164
- const manifest = await generateControllerManifest(appName, { appPath });
165
- const deployJson = toDeployJsonShape(manifest);
166
- const deployManifestPath = path.join(appPath, `${finalSystemKey}-deploy.json`);
167
- await fs.writeFile(deployManifestPath, JSON.stringify(deployJson, null, 2), 'utf8');
168
- logger.log(formatSuccessLine(`Generated deployment manifest: ${finalSystemKey}-deploy.json`));
169
-
168
+ const deployScripts = await generateDeployScripts(
169
+ appPath,
170
+ finalSystemKey,
171
+ systemFileName,
172
+ datasourceFileNames
173
+ );
174
+ const deployManifestPath = await writeWizardDeployManifest(appPath, appName, finalSystemKey);
170
175
  return {
171
176
  variablesPath: configPath,
172
- envTemplatePath: path.join(appPath, 'env.template'),
177
+ envTemplatePath,
173
178
  readmePath: path.join(appPath, 'README.md'),
174
179
  applicationSchemaPath: deployManifestPath,
175
180
  ...deployScripts
@@ -190,16 +195,10 @@ async function prepareWizardContext(appName, systemConfig, datasourceConfigs) {
190
195
  appDisplayName
191
196
  );
192
197
  const originalPrefix = `${originalSystemKey}-`;
198
+ const usedKeys = new Set();
193
199
  const updatedDatasourceConfigs = datasourceConfigs.map(ds => {
194
- let newKey;
195
- const dsKey = ds.key || '';
196
- if (dsKey && dsKey.startsWith(originalPrefix)) {
197
- newKey = `${finalSystemKey}-${dsKey.substring(originalPrefix.length)}`;
198
- } else {
199
- const entityType = ds.entityType || ds.entityKey || dsKey.split('-').pop() || 'default';
200
- const keySegment = toKeySegment(entityType);
201
- newKey = `${finalSystemKey}-${keySegment}`;
202
- }
200
+ const newKey = wizardCanonicalDatasourceKey(finalSystemKey, ds, originalPrefix, usedKeys);
201
+ usedKeys.add(newKey);
203
202
  const entityType = ds.entityType || ds.entityKey || newKey.split('-').pop() || 'default';
204
203
  const entityDisplayName = String(entityType).charAt(0).toUpperCase() + String(entityType).slice(1).replace(/-/g, ' ');
205
204
  return { ...ds, key: newKey, systemKey: finalSystemKey, displayName: ds.displayName || `${appDisplayName} ${entityDisplayName}` };
@@ -481,6 +480,8 @@ const { generateDeployScripts } = require('./deploy-script');
481
480
 
482
481
  module.exports = {
483
482
  generateWizardFiles,
484
- generateDeployScripts
483
+ generateDeployScripts,
484
+ wizardCanonicalDatasourceKey,
485
+ toKeySegment
485
486
  };
486
487