@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
@@ -12,6 +12,7 @@ const fs = require('../internal/fs-real-sync');
12
12
  const path = require('path');
13
13
  const { ensureIntegrationDirectory } = require('./workspace-context');
14
14
  const { resolveChannelRuntimeValues } = require('../channels/channel-runtime-resolver');
15
+ const { vendorFacingUrlsFromCtx } = require('../channels/vendor-dataplane-url');
15
16
  const { generateChannelArtifact } = require('../channels/channel-artifact-generator');
16
17
  const { loadChannelPackageContext } = require('../channels/channel-discovery');
17
18
  const {
@@ -20,6 +21,10 @@ const {
20
21
  mergeChannelBranding
21
22
  } = require('../channels/channel-branding');
22
23
  const { isChannelTargetKey } = require('../channels/channel-targets');
24
+ const {
25
+ httpError,
26
+ readChannelInstallSessionForDefinition
27
+ } = require('./channel-install-session');
23
28
 
24
29
  /**
25
30
  * @param {import('./workspace-context').WorkspaceContext} ctx
@@ -43,6 +48,16 @@ function requireChannelTarget(systemKey) {
43
48
  return systemKey;
44
49
  }
45
50
 
51
+ /**
52
+ * Catalog packaging key: instance paths (name slug) still read dist/channels/<catalog>/.
53
+ * @param {import('./workspace-context').WorkspaceContext} ctx
54
+ * @returns {string}
55
+ */
56
+ function packagingChannelTarget(ctx) {
57
+ const { resolveInstallDefinitionKey } = require('./channel-install-help-resolve');
58
+ return requireChannelTarget(resolveInstallDefinitionKey(ctx));
59
+ }
60
+
46
61
  /**
47
62
  * @param {import('./workspace-context').WorkspaceContext} ctx
48
63
  * @returns {{ type: string, token: string }}
@@ -82,8 +97,13 @@ function generatePackageArtifact(ctx, body, channelTarget, branding, dataplaneUr
82
97
  branding.displayName || body.name || packageContext.displayName || channelTarget;
83
98
  const description =
84
99
  branding.description || body.description || packageContext.description || '';
100
+ const vendor = vendorFacingUrlsFromCtx({
101
+ ...ctx,
102
+ dataplaneUrl
103
+ });
85
104
  const runtimeValues = resolveChannelRuntimeValues({
86
- dataplaneBaseUrl: dataplaneUrl,
105
+ dataplaneBaseUrl: vendor.dataplaneBaseUrl,
106
+ controllerUrl: vendor.controllerUrl,
87
107
  channelTarget,
88
108
  appName,
89
109
  baseName: body.baseName || appName,
@@ -91,6 +111,7 @@ function generatePackageArtifact(ctx, body, channelTarget, branding, dataplaneUr
91
111
  appDescription: description,
92
112
  layerBToolNames: packageContext.governedToolNames || [],
93
113
  packageContext,
114
+ oauthPluginVaultReferenceId: body.oauthPluginVaultReferenceId,
94
115
  iconColorPath: branding.iconColorPath,
95
116
  iconOutlinePath: branding.iconOutlinePath
96
117
  });
@@ -108,7 +129,7 @@ function generatePackageArtifact(ctx, body, channelTarget, branding, dataplaneUr
108
129
  * @returns {Promise<Object>}
109
130
  */
110
131
  async function buildChannelPackage(ctx, body = {}) {
111
- const channelTarget = requireChannelTarget(ctx.systemKey);
132
+ const channelTarget = packagingChannelTarget(ctx);
112
133
  ensureIntegrationDirectory(ctx);
113
134
  const dir = workspaceSystemDir(ctx);
114
135
  const branding = mergeChannelBranding(readChannelBranding(dir), body.branding || {});
@@ -151,7 +172,7 @@ async function buildChannelPackage(ctx, body = {}) {
151
172
  * @returns {Object}
152
173
  */
153
174
  function getChannelPackageSummary(ctx) {
154
- const channelTarget = requireChannelTarget(ctx.systemKey);
175
+ const channelTarget = packagingChannelTarget(ctx);
155
176
  const projectRoot = ctx.getUserRoot();
156
177
  const summaryPath = path.join(
157
178
  projectRoot,
@@ -161,7 +182,7 @@ function getChannelPackageSummary(ctx) {
161
182
  `channel-${channelTarget}.json`
162
183
  );
163
184
  if (!fs.existsSync(summaryPath)) {
164
- throw new Error(`Channel package summary not found: ${summaryPath}`);
185
+ throw httpError(`Channel package summary not found: ${summaryPath}`, 404);
165
186
  }
166
187
  const summary = JSON.parse(fs.readFileSync(summaryPath, 'utf8'));
167
188
  return {
@@ -177,8 +198,8 @@ function getChannelPackageSummary(ctx) {
177
198
  * @param {import('./workspace-context').WorkspaceContext} ctx
178
199
  * @returns {{ fileName: string, contentType: string, byteLength: number, zipBase64: string }}
179
200
  */
180
- function getChannelPackageZip(ctx) {
181
- const channelTarget = requireChannelTarget(ctx.systemKey);
201
+ function readChannelPackageZip(ctx) {
202
+ const channelTarget = packagingChannelTarget(ctx);
182
203
  const summary = getChannelPackageSummary(ctx).summary;
183
204
  const zipPath =
184
205
  typeof summary?.links?.zip === 'string' && summary.links.zip
@@ -192,7 +213,7 @@ function getChannelPackageZip(ctx) {
192
213
  `appPackage.${summary.environment || 'dev'}.zip`
193
214
  );
194
215
  if (!fs.existsSync(zipPath)) {
195
- throw new Error(`Channel package ZIP not found: ${zipPath}`);
216
+ throw httpError(`Channel package ZIP not found: ${zipPath}`, 404);
196
217
  }
197
218
  const buffer = fs.readFileSync(zipPath);
198
219
  return {
@@ -203,6 +224,65 @@ function getChannelPackageZip(ctx) {
203
224
  };
204
225
  }
205
226
 
227
+ /**
228
+ * @param {Object|null} session
229
+ * @returns {Object}
230
+ */
231
+ function packageBodyFromSession(session) {
232
+ if (!session || typeof session !== 'object') {
233
+ return {};
234
+ }
235
+ return {
236
+ name: session.displayName || session.name,
237
+ oauthPluginVaultReferenceId: session.oauthPluginVaultReferenceId
238
+ };
239
+ }
240
+
241
+ /**
242
+ * Portal ZIP GET must not 500 with CLI `--oauth-plugin-vault-reference-id` text.
243
+ * @param {unknown} err
244
+ * @returns {unknown}
245
+ */
246
+ function mapCopilotPackageHttpError(err) {
247
+ if (err && err.statusCode) {
248
+ return err;
249
+ }
250
+ const msg = String((err && err.message) || '');
251
+ if (/oauth-plugin-vault-reference-id|OAuthPluginVault/i.test(msg)) {
252
+ return httpError(
253
+ 'Copilot app package is not ready until Teams Entra SSO registration is stored on this install.',
254
+ 409
255
+ );
256
+ }
257
+ return err;
258
+ }
259
+
260
+ /**
261
+ * Rebuild the Copilot ZIP when the workspace lost dist/ after an image recreate.
262
+ * @param {import('./workspace-context').WorkspaceContext} ctx
263
+ * @returns {Promise<{ fileName: string, contentType: string, byteLength: number, zipBase64: string }>}
264
+ */
265
+ async function getChannelPackageZip(ctx) {
266
+ let summaryMissing = false;
267
+ try {
268
+ getChannelPackageSummary(ctx);
269
+ } catch (err) {
270
+ if (!err || err.statusCode !== 404) {
271
+ throw mapCopilotPackageHttpError(err);
272
+ }
273
+ summaryMissing = true;
274
+ }
275
+ if (summaryMissing) {
276
+ try {
277
+ const session = readChannelInstallSessionForDefinition(ctx, packagingChannelTarget(ctx));
278
+ await buildChannelPackage(ctx, packageBodyFromSession(session));
279
+ } catch (err) {
280
+ throw mapCopilotPackageHttpError(err);
281
+ }
282
+ }
283
+ return readChannelPackageZip(ctx);
284
+ }
285
+
206
286
  /**
207
287
  * @param {import('./workspace-context').WorkspaceContext} ctx
208
288
  * @param {Object} body
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Programmatic download wrapper — CLI download parity for builder-api.
3
+ *
4
+ * @fileoverview runDownload for POST /systems/:systemKey/download
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const { downloadExternalSystem } = require('../external-system/download');
12
+ const { runWithWorkspaceContext } = require('./workspace-context');
13
+ const { mergeProgrammaticOptions } = require('./command-options');
14
+ const { touchWorkspaceMeta } = require('./workspace-meta');
15
+
16
+ /**
17
+ * @param {import('./workspace-context').WorkspaceContext} ctx
18
+ * @param {Object} [options]
19
+ * @param {boolean} [options.force]
20
+ * @param {boolean} [options.dryRun]
21
+ * @param {string} [options.format]
22
+ * @returns {Promise<Object>}
23
+ */
24
+ async function runDownload(ctx, options = {}) {
25
+ const merged = mergeProgrammaticOptions(ctx, options);
26
+ return runWithWorkspaceContext(ctx, async() => {
27
+ await downloadExternalSystem(ctx.systemKey, merged);
28
+ if (!options.dryRun) {
29
+ touchWorkspaceMeta(ctx, { lastOperation: 'download' });
30
+ }
31
+ return {
32
+ downloaded: options.dryRun !== true,
33
+ dryRun: options.dryRun === true,
34
+ systemKey: ctx.systemKey
35
+ };
36
+ });
37
+ }
38
+
39
+ module.exports = {
40
+ runDownload
41
+ };
@@ -51,6 +51,7 @@ function resolveWorkspaceRoot(segment) {
51
51
  * @param {string} [params.environment]
52
52
  * @param {string} [params.controllerUrl]
53
53
  * @param {string} [params.dataplaneUrl]
54
+ * @param {string} [params.publicOrigin]
54
55
  * @returns {WorkspaceContext}
55
56
  */
56
57
  function createWorkspaceContext(params) {
@@ -88,6 +89,7 @@ function createWorkspaceContext(params) {
88
89
  process.env.CONTROLLER_URL ||
89
90
  '',
90
91
  dataplaneUrl: params.dataplaneUrl || process.env.DATAPLANE_URL || '',
92
+ publicOrigin: typeof params.publicOrigin === 'string' ? params.publicOrigin.trim() : '',
91
93
  bearerToken,
92
94
  getUserRoot: () => userRoot,
93
95
  getIntegrationRoot: () => integrationRoot,
@@ -67,7 +67,9 @@ async function resolveCliProtectionDataplaneContext(options) {
67
67
  throw new Error('Authentication required. Run "aifabrix login" and try again.');
68
68
  }
69
69
 
70
- const dataplaneUrl = await resolveDataplaneUrl(controllerUrl, environment, authConfig);
70
+ const dataplaneUrl = await resolveDataplaneUrl(controllerUrl, environment, authConfig, {
71
+ silent: options.json === true || options.silent === true
72
+ });
71
73
  return { environment, controllerUrl, dataplaneUrl, authConfig };
72
74
  }
73
75
 
@@ -18,7 +18,7 @@ const {
18
18
  formatProgress,
19
19
  formatNextActions
20
20
  } = require('../utils/cli-test-layout-chalk');
21
- const { reportTaskRows } = require('./report-exit');
21
+ const { reportTaskRows, isProtectionProblemResponse } = require('./report-exit');
22
22
  const { describeProtectionRoot } = require('./paths');
23
23
  const {
24
24
  appendTaskRows,
@@ -46,7 +46,8 @@ function formatProtectionValidateTTY(report, opts = {}) {
46
46
  const meta = report?.metadata || {};
47
47
  appendProtectionReportHeader(lines, meta);
48
48
  const summary = report?.summary || {};
49
- const failCount = Number(summary.fail || 0);
49
+ const problem = isProtectionProblemResponse(report);
50
+ const failCount = problem ? Math.max(1, Number(summary.fail || 0)) : Number(summary.fail || 0);
50
51
  const warnCount = Number(summary.warn || 0);
51
52
  const aggregate = failCount > 0 ? 'fail' : warnCount > 0 ? 'warn' : 'ok';
52
53
  const glyph = aggregate === 'fail' ? '✖' : aggregate === 'warn' ? '⚠' : '✔';
@@ -23,6 +23,51 @@ function reportTaskRows(report) {
23
23
  return [];
24
24
  }
25
25
 
26
+ /**
27
+ * True when the payload is an RFC 7807 / API-client error, not a validate report.
28
+ * @param {*} report
29
+ * @returns {boolean}
30
+ */
31
+ function isProtectionProblemResponse(report) {
32
+ if (!report || typeof report !== 'object') {
33
+ return false;
34
+ }
35
+ if (report.success === false) {
36
+ return true;
37
+ }
38
+ const status = Number(report.statusCode || report.status);
39
+ if (Number.isFinite(status) && status >= 400) {
40
+ return true;
41
+ }
42
+ const type = typeof report.type === 'string' ? report.type : '';
43
+ return type.includes('/Errors/') || type.includes('application/problem');
44
+ }
45
+
46
+ /**
47
+ * @param {*} uploaded
48
+ * @returns {string}
49
+ */
50
+ function protectionUploadFailureMessage(uploaded) {
51
+ if (!uploaded || typeof uploaded !== 'object') {
52
+ return 'Protection upload returned empty response';
53
+ }
54
+ return (
55
+ uploaded.formattedError ||
56
+ uploaded.error ||
57
+ uploaded.detail ||
58
+ `Protection upload failed (HTTP ${uploaded.statusCode || uploaded.status || 0})`
59
+ );
60
+ }
61
+
62
+ /**
63
+ * @param {*} uploaded
64
+ */
65
+ function assertProtectionUploadSucceeded(uploaded) {
66
+ if (!uploaded || typeof uploaded !== 'object' || isProtectionProblemResponse(uploaded)) {
67
+ throw new Error(protectionUploadFailureMessage(uploaded));
68
+ }
69
+ }
70
+
26
71
  /**
27
72
  * @param {Object} report
28
73
  * @param {Object} [opts]
@@ -33,6 +78,9 @@ function exitCodeFromProtectionReport(report, opts = {}) {
33
78
  if (!report || typeof report !== 'object') {
34
79
  return 3;
35
80
  }
81
+ if (isProtectionProblemResponse(report)) {
82
+ return 1;
83
+ }
36
84
  const summary = report.summary || {};
37
85
  const failCount = Number(summary.fail || 0);
38
86
  const warnCount = Number(summary.warn || 0);
@@ -58,5 +106,7 @@ function exitCodeFromProtectionReport(report, opts = {}) {
58
106
 
59
107
  module.exports = {
60
108
  reportTaskRows,
109
+ isProtectionProblemResponse,
110
+ assertProtectionUploadSucceeded,
61
111
  exitCodeFromProtectionReport
62
112
  };
@@ -18,6 +18,7 @@ const {
18
18
  deleteProtection,
19
19
  findProtectionKeyByDatasource
20
20
  } = require('../api/protection.api');
21
+ const { assertProtectionUploadSucceeded } = require('./report-exit');
21
22
  const { preflightDatasourceReady } = require('./preflight-datasource-ready');
22
23
  const { runProtectionUploadDataSync } = require('./run-commands-upload-sync');
23
24
  const {
@@ -63,6 +64,7 @@ async function runProtectionUpload(datasourceKey, manifest, opts, logger) {
63
64
 
64
65
  logger.log(formatProgress('Uploading protection manifest...'));
65
66
  const uploaded = await uploadProtection(ctx.dataplaneUrl, ctx.authConfig, manifest);
67
+ assertProtectionUploadSucceeded(uploaded);
66
68
  logger.log(
67
69
  formatSuccessLine(
68
70
  `Protection for '${datasourceKey}' uploaded (deploymentId ${uploaded?.deploymentId || '—'}, revision ${uploaded?.revision ?? '—'})`
@@ -22,6 +22,7 @@ const {
22
22
  } = require('../api/evidence.api');
23
23
  const { resolveExternalSystemPath } = require('../utils/app-path-resolve');
24
24
  const { SYSTEM_KIND_DIGITAL_WORKER } = require('./settings');
25
+ const { formatEvidenceValidationIssues } = require('./evidence-validation-issues');
25
26
 
26
27
  const EVIDENCE_DIR_NAME = 'evidence';
27
28
  const EVIDENCE_EXPORT_FILE = 'evidence.json';
@@ -288,8 +289,9 @@ function isActivatedEvidenceRow(row) {
288
289
  async function runEvidenceLifecycleForRef(dataplaneUrl, authConfig, evidenceRef) {
289
290
  const validation = await validateEvidenceCandidate(dataplaneUrl, authConfig, evidenceRef);
290
291
  if (validationFailed(validation)) {
291
- const issues = Array.isArray(validation?.issues) ? validation.issues.length : 0;
292
- throw new Error(`Validation failed for evidence ${evidenceRef} (${issues} issue${issues === 1 ? '' : 's'}).`);
292
+ throw new Error(
293
+ `Validation failed for evidence ${evidenceRef} (${formatEvidenceValidationIssues(validation?.issues)}).`
294
+ );
293
295
  }
294
296
  if (String(validation?.status || '').trim().toLowerCase() !== VALIDATION_PASSED) {
295
297
  throw new Error(`Validation status for evidence ${evidenceRef} is "${validation?.status || 'unknown'}".`);
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Format Evidence validate issues[] for CLI errors.
3
+ */
4
+
5
+ 'use strict';
6
+
7
+ function formatOneEvidenceIssue(issue) {
8
+ if (issue === undefined || issue === null) {
9
+ return '';
10
+ }
11
+ if (typeof issue !== 'object') {
12
+ return String(issue);
13
+ }
14
+ const bits = [];
15
+ if (issue.field) {
16
+ bits.push(String(issue.field));
17
+ }
18
+ if (issue.code) {
19
+ bits.push(String(issue.code));
20
+ }
21
+ if (issue.message) {
22
+ bits.push(String(issue.message));
23
+ }
24
+ if (bits.length > 0) {
25
+ return bits.join(' — ');
26
+ }
27
+ try {
28
+ return JSON.stringify(issue);
29
+ } catch {
30
+ return String(issue);
31
+ }
32
+ }
33
+
34
+ /**
35
+ * @param {unknown} issues
36
+ * @returns {string}
37
+ */
38
+ function formatEvidenceValidationIssues(issues) {
39
+ if (!Array.isArray(issues) || issues.length === 0) {
40
+ return '0 issues';
41
+ }
42
+ const parts = issues.map(formatOneEvidenceIssue).filter(Boolean);
43
+ const noun = issues.length === 1 ? 'issue' : 'issues';
44
+ const detail = parts.length > 0 ? `: ${parts.join('; ')}` : '';
45
+ return `${issues.length} ${noun}${detail}`;
46
+ }
47
+
48
+ module.exports = {
49
+ formatOneEvidenceIssue,
50
+ formatEvidenceValidationIssues
51
+ };
@@ -19,6 +19,7 @@ const {
19
19
  updateAssistantSettings
20
20
  } = require('../api/assistants.api');
21
21
  const { resolveExternalSystemPath } = require('../utils/app-path-resolve');
22
+ const { bareRoleKey } = require('../utils/role-assistant-paths');
22
23
  const {
23
24
  SYSTEM_KIND_DIGITAL_WORKER,
24
25
  getRoleAssistantYamlPath,
@@ -75,7 +76,11 @@ async function resolveDocumentStorageKeyFromDataplane(dataplaneUrl, authConfig,
75
76
  return null;
76
77
  }
77
78
  try {
78
- const response = await getAssistantDetails(dataplaneUrl, systemKey, authConfig);
79
+ const response = await getAssistantDetails(
80
+ dataplaneUrl,
81
+ systemKey,
82
+ authConfig
83
+ );
79
84
  return extractDocumentStorageKeyFromAssistantDetails(response);
80
85
  } catch (_error) {
81
86
  return null;
@@ -141,16 +146,17 @@ async function applyAssistantSettingsPush(dataplaneUrl, systemKey, authConfig, s
141
146
  const { documentStorageKey, debugBody, patchBody } = settingsPush;
142
147
  const hasDocumentStorageKey = documentStorageKey !== '';
143
148
  const hasDebugSettings = Object.keys(debugBody).length > 0;
149
+ const assistantKey = String(systemKey || '').trim();
144
150
  let response = await updateAssistantSettings(
145
151
  dataplaneUrl,
146
- systemKey,
152
+ assistantKey,
147
153
  authConfig,
148
154
  patchBody
149
155
  );
150
156
  if (response && response.success === false && hasDocumentStorageKey && hasDebugSettings) {
151
157
  response = await updateAssistantSettings(
152
158
  dataplaneUrl,
153
- systemKey,
159
+ assistantKey,
154
160
  authConfig,
155
161
  debugBody
156
162
  );
@@ -352,7 +358,7 @@ function writeRoleAssistantSettingsFile(systemKey, docStorageKey, environment =
352
358
  apiVersion: 'aifabrix.ai/v1',
353
359
  version: '1.0.0',
354
360
  kind: 'RoleAssistantSettings',
355
- roleKey: systemKey,
361
+ roleKey: bareRoleKey(systemKey),
356
362
  [envKey]: {
357
363
  knowledge: docStorageKey ? { documentStorageKey: docStorageKey } : {}
358
364
  }
@@ -0,0 +1,175 @@
1
+ /**
2
+ * Role Assistant package folder validation (settings, tests, evidence, knowledge).
3
+ * @fileoverview Walk ra-* governed files. Ignore leftover Connected System artifacts.
4
+ */
5
+
6
+ 'use strict';
7
+
8
+ const path = require('path');
9
+ const fs = require('../internal/fs-real-sync');
10
+ const { validateExternalFile, parseJsonFileContent } = require('../validation/validate-external-file');
11
+ const { listTestCaseFiles } = require('./test-cases');
12
+ const { validateTestCaseFile } = require('./test-case-validate');
13
+
14
+ const SETTINGS_TYPE = 'role-assistant-settings';
15
+ const EMPTY_TESTS_SKIP = 'tests/: skipped (no test cases)';
16
+
17
+ function fileRow(filePath, type, result) {
18
+ return {
19
+ file: path.basename(filePath),
20
+ type,
21
+ valid: result.valid,
22
+ path: filePath,
23
+ errors: result.errors || [],
24
+ warnings: result.warnings || []
25
+ };
26
+ }
27
+
28
+ function listFilesByExt(dirPath, ext, acc) {
29
+ if (!fs.existsSync(dirPath)) {
30
+ return acc;
31
+ }
32
+ for (const name of fs.readdirSync(dirPath)) {
33
+ if (String(name).startsWith('.')) {
34
+ continue;
35
+ }
36
+ const full = path.join(dirPath, name);
37
+ const st = fs.statSync(full);
38
+ if (st.isDirectory()) {
39
+ listFilesByExt(full, ext, acc);
40
+ } else if (String(name).toLowerCase().endsWith(ext)) {
41
+ acc.push(full);
42
+ }
43
+ }
44
+ return acc;
45
+ }
46
+
47
+ function evidenceRows(parsed) {
48
+ if (Array.isArray(parsed)) {
49
+ return parsed;
50
+ }
51
+ if (parsed && typeof parsed === 'object') {
52
+ return [parsed];
53
+ }
54
+ return null;
55
+ }
56
+
57
+ function validateEvidenceJsonFile(filePath) {
58
+ const parseResult = parseJsonFileContent(filePath);
59
+ if (parseResult.error) {
60
+ return { ...parseResult.error, file: filePath, type: 'evidence' };
61
+ }
62
+ const rows = evidenceRows(parseResult.parsed);
63
+ const errors = [];
64
+ if (!rows) {
65
+ errors.push(`${filePath}: Evidence JSON must be an object or array of objects`);
66
+ } else {
67
+ rows.forEach((row, index) => {
68
+ const key = row && typeof row === 'object' && !Array.isArray(row) ? String(row.key || '').trim() : '';
69
+ if (!key) {
70
+ errors.push(`${filePath}: item ${index} is missing key`);
71
+ }
72
+ });
73
+ }
74
+ return { valid: errors.length === 0, errors, warnings: [], file: filePath, type: 'evidence' };
75
+ }
76
+
77
+ function validateKnowledgeMarkdown(filePath) {
78
+ const text = fs.readFileSync(filePath, 'utf8');
79
+ if (!String(text).trim()) {
80
+ return {
81
+ valid: false,
82
+ errors: [`${filePath}: knowledge markdown must not be empty`],
83
+ warnings: [],
84
+ file: filePath,
85
+ type: 'knowledge'
86
+ };
87
+ }
88
+ return { valid: true, errors: [], warnings: [], file: filePath, type: 'knowledge' };
89
+ }
90
+
91
+ async function validateSettingsFile(appPath) {
92
+ const yamlPath = path.join(appPath, 'role-assistant.yaml');
93
+ try {
94
+ const result = await validateExternalFile(yamlPath, SETTINGS_TYPE);
95
+ return fileRow(yamlPath, SETTINGS_TYPE, result);
96
+ } catch (error) {
97
+ return fileRow(yamlPath, SETTINGS_TYPE, {
98
+ valid: false,
99
+ errors: [error.message],
100
+ warnings: []
101
+ });
102
+ }
103
+ }
104
+
105
+ function collectDuplicateCaseIdErrors(caseFiles) {
106
+ const seen = new Map();
107
+ const errors = [];
108
+ for (const row of caseFiles) {
109
+ const parseResult = parseJsonFileContent(row.path);
110
+ const caseId = parseResult.parsed && String(parseResult.parsed.caseId || '').trim();
111
+ if (!caseId) {
112
+ continue;
113
+ }
114
+ if (seen.has(caseId)) {
115
+ errors.push(`${row.path}: duplicate caseId "${caseId}" (also ${seen.get(caseId)})`);
116
+ } else {
117
+ seen.set(caseId, row.path);
118
+ }
119
+ }
120
+ return errors;
121
+ }
122
+
123
+ function validateTestFiles(appPath) {
124
+ const testsDir = path.join(appPath, 'tests');
125
+ const yamlFiles = listTestCaseFiles(testsDir);
126
+ if (yamlFiles.length === 0) {
127
+ return { files: [], errors: [], warnings: [EMPTY_TESTS_SKIP] };
128
+ }
129
+ const files = yamlFiles.map((filePath) => fileRow(filePath, 'role-assistant-test-case', validateTestCaseFile(filePath)));
130
+ const errors = files.flatMap((row) => row.errors);
131
+ errors.push(...collectDuplicateCaseIdErrors(files));
132
+ return { files, errors, warnings: [] };
133
+ }
134
+
135
+ function validateEvidenceFiles(appPath) {
136
+ const jsonFiles = listFilesByExt(path.join(appPath, 'evidence'), '.json', []);
137
+ const files = jsonFiles.map((filePath) => fileRow(filePath, 'evidence', validateEvidenceJsonFile(filePath)));
138
+ return { files, errors: files.flatMap((row) => row.errors), warnings: [] };
139
+ }
140
+
141
+ function validateKnowledgeFiles(appPath) {
142
+ const mdFiles = listFilesByExt(path.join(appPath, 'knowledge'), '.md', []).filter((filePath) => {
143
+ return path.dirname(filePath) === path.join(appPath, 'knowledge');
144
+ });
145
+ const files = mdFiles.map((filePath) => fileRow(filePath, 'knowledge', validateKnowledgeMarkdown(filePath)));
146
+ return { files, errors: files.flatMap((row) => row.errors), warnings: [] };
147
+ }
148
+
149
+ async function validateRoleAssistantPackage(appPath) {
150
+ const settings = await validateSettingsFile(appPath);
151
+ const tests = validateTestFiles(appPath);
152
+ const evidence = validateEvidenceFiles(appPath);
153
+ const knowledge = validateKnowledgeFiles(appPath);
154
+ const files = [settings, ...tests.files, ...evidence.files, ...knowledge.files];
155
+ const errors = [
156
+ ...settings.errors,
157
+ ...tests.errors,
158
+ ...evidence.errors,
159
+ ...knowledge.errors
160
+ ];
161
+ const warnings = [...settings.warnings, ...tests.warnings, ...evidence.warnings, ...knowledge.warnings];
162
+ return {
163
+ valid: errors.length === 0,
164
+ errors,
165
+ warnings,
166
+ files
167
+ };
168
+ }
169
+
170
+ module.exports = {
171
+ EMPTY_TESTS_SKIP,
172
+ validateRoleAssistantPackage,
173
+ validateEvidenceJsonFile,
174
+ validateKnowledgeMarkdown
175
+ };