@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
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Platform RBAC preset for orchestration facade external systems (plan 154.7).
2
+ * Platform RBAC preset for orchestration facade external systems.
3
3
  *
4
4
  * @fileoverview Replace per-system admin/reader with dataplane platform roles
5
5
  * @author AI Fabrix Team
@@ -13,29 +13,40 @@ const fs = require('fs');
13
13
  const { loadConfigFile, writeConfigFile } = require('../utils/config-format');
14
14
  const { backupIntegrationFile } = require('../utils/integration-file-backup');
15
15
  const { CAPABILITIES } = require('../programmatic/capability-registry');
16
- const { listPlatformRoles, PLATFORM_ROLE_VALUES } = require('../programmatic/platform-rbac-catalog');
16
+ const {
17
+ listPlatformRoles,
18
+ PLATFORM_ROLE_VALUES,
19
+ ROLE_OBSERVER,
20
+ ROLE_EXTERNAL_SYSTEM_DISCOVERER,
21
+ ROLE_DEVELOPER,
22
+ ROLE_DEPLOYMENT_ADMIN,
23
+ ROLE_PLATFORM_ADMIN,
24
+ ROLE_SECURITY_ADMIN,
25
+ ROLE_COMPLIANCE_ADMIN,
26
+ ROLE_AI_TRUST_OPERATOR
27
+ } = require('../programmatic/platform-rbac-catalog');
17
28
 
18
29
  const READ_ROLES = Object.freeze([
19
- 'aifabrix-observer',
20
- 'aifabrix-external-system-discoverer',
21
- 'aifabrix-developer',
22
- 'aifabrix-deployment-admin',
23
- 'aifabrix-platform-admin'
30
+ ROLE_OBSERVER,
31
+ ROLE_EXTERNAL_SYSTEM_DISCOVERER,
32
+ ROLE_DEVELOPER,
33
+ ROLE_DEPLOYMENT_ADMIN,
34
+ ROLE_PLATFORM_ADMIN
24
35
  ]);
25
36
 
26
37
  const WRITE_ROLES = Object.freeze([
27
- 'aifabrix-developer',
28
- 'aifabrix-deployment-admin',
29
- 'aifabrix-platform-admin'
38
+ ROLE_DEVELOPER,
39
+ ROLE_DEPLOYMENT_ADMIN,
40
+ ROLE_PLATFORM_ADMIN
30
41
  ]);
31
42
 
32
- const APPLY_ROLES = Object.freeze(['aifabrix-deployment-admin', 'aifabrix-platform-admin']);
43
+ const APPLY_ROLES = Object.freeze([ROLE_DEPLOYMENT_ADMIN, ROLE_PLATFORM_ADMIN]);
33
44
 
34
45
  const CERTIFY_ROLES = Object.freeze([
35
- 'aifabrix-security-admin',
36
- 'aifabrix-compliance-admin',
37
- 'aifabrix-ai-trust-operator',
38
- 'aifabrix-platform-admin'
46
+ ROLE_SECURITY_ADMIN,
47
+ ROLE_COMPLIANCE_ADMIN,
48
+ ROLE_AI_TRUST_OPERATOR,
49
+ ROLE_PLATFORM_ADMIN
39
50
  ]);
40
51
 
41
52
  /** @type {ReadonlyMap<string, string>} */
@@ -11,6 +11,10 @@
11
11
  const fs = require('fs');
12
12
  const path = require('path');
13
13
  const { loadConfigFile } = require('../utils/config-format');
14
+ const {
15
+ pickCatalogAdminRoleValue,
16
+ pickCatalogReaderRoleValue
17
+ } = require('./repair-rbac-catalog-defaults');
14
18
 
15
19
  const READ_ONLY_HTTP_METHODS = new Set(['GET', 'HEAD']);
16
20
 
@@ -19,23 +23,6 @@ function roleValues(rbac) {
19
23
  return roles.map((r) => r?.value).filter((v) => typeof v === 'string' && v.trim());
20
24
  }
21
25
 
22
- function pickAdminRoleValue(roleValuesList, systemKey) {
23
- return (
24
- roleValuesList.find((v) => v === `${systemKey}-admin`) ||
25
- roleValuesList.find((v) => /-admin$/.test(v)) ||
26
- roleValuesList[0] ||
27
- null
28
- );
29
- }
30
-
31
- function pickReaderRoleValue(roleValuesList, systemKey) {
32
- return (
33
- roleValuesList.find((v) => v === `${systemKey}-reader`) ||
34
- roleValuesList.find((v) => /-reader$/.test(v)) ||
35
- null
36
- );
37
- }
38
-
39
26
  function capabilityFromPermissionName(name) {
40
27
  if (typeof name !== 'string' || !name.includes(':')) return null;
41
28
  return name.split(':')[1] || null;
@@ -71,8 +58,8 @@ function ensureNonEmptyPermissionRoles(rbac, systemKey, changes) {
71
58
  const values = roleValues(rbac);
72
59
  if (!Array.isArray(rbac.permissions) || values.length === 0) return false;
73
60
 
74
- const adminValue = pickAdminRoleValue(values, systemKey);
75
- const readerValue = pickReaderRoleValue(values, systemKey);
61
+ const adminValue = pickCatalogAdminRoleValue(values, systemKey);
62
+ const readerValue = pickCatalogReaderRoleValue(values, systemKey);
76
63
  let updated = false;
77
64
 
78
65
  for (const perm of rbac.permissions) {
@@ -103,8 +90,8 @@ function ensureNonEmptyPermissionRoles(rbac, systemKey, changes) {
103
90
  */
104
91
  function ensureReaderRoleOnReadPermissions(rbac, appPath, datasourceFiles, systemKey, changes) {
105
92
  const values = roleValues(rbac);
106
- const readerValue = pickReaderRoleValue(values, systemKey);
107
- const adminValue = pickAdminRoleValue(values, systemKey);
93
+ const readerValue = pickCatalogReaderRoleValue(values, systemKey);
94
+ const adminValue = pickCatalogAdminRoleValue(values, systemKey);
108
95
  if (!readerValue || !adminValue) return false;
109
96
  if (!Array.isArray(rbac.permissions) || rbac.permissions.length === 0) return false;
110
97
 
@@ -29,6 +29,8 @@ const {
29
29
  ensureOrchestrationResourceType
30
30
  } = require('./repair-rbac-platform-preset');
31
31
  const { trackRepairWrite } = require('./repair-changed-files');
32
+ const { listCapabilityKeys } = require('../datasource/capability/capability-manifest');
33
+ const { ensureDefaultRoles } = require('./repair-rbac-catalog-defaults');
32
34
 
33
35
  const DEFAULT_CAPABILITIES = ['list', 'get', 'create', 'update', 'delete'];
34
36
 
@@ -46,24 +48,29 @@ function _normalizeOperationKey(opKey) {
46
48
  return cleaned.replace(/-+/g, '-').replace(/^-+|-+$/g, '');
47
49
  }
48
50
 
51
+ function defaultCapabilitiesForDatasource(parsed) {
52
+ if (String(parsed?.storageType || '') === 'view') {
53
+ return ['list', 'get'];
54
+ }
55
+ return [...DEFAULT_CAPABILITIES];
56
+ }
57
+
49
58
  /**
50
- * Resolves capabilities from datasource (array or legacy object).
59
+ * Resolves capabilities from datasource (array, COM objects, or legacy map).
51
60
  * @param {Object} parsed - Parsed datasource
52
61
  * @returns {string[]}
53
62
  */
54
63
  function getCapabilitiesFromDatasource(parsed) {
55
- const cap = parsed?.capabilities;
56
- if (Array.isArray(cap)) {
57
- const arr = cap.filter(c => typeof c === 'string');
58
- if (arr.length > 0) return arr;
59
- return [...DEFAULT_CAPABILITIES];
64
+ const fromList = listCapabilityKeys(parsed?.capabilities);
65
+ if (fromList.length > 0) {
66
+ return fromList;
60
67
  }
61
- if (cap && typeof cap === 'object') {
62
- const keys = Object.keys(cap).filter(k => cap[k] === true);
68
+ const cap = parsed?.capabilities;
69
+ if (cap && typeof cap === 'object' && !Array.isArray(cap)) {
70
+ const keys = Object.keys(cap).filter((k) => cap[k] === true);
63
71
  if (keys.length > 0) return keys;
64
- return [...DEFAULT_CAPABILITIES];
65
72
  }
66
- return [...DEFAULT_CAPABILITIES];
73
+ return defaultCapabilitiesForDatasource(parsed);
67
74
  }
68
75
 
69
76
  /**
@@ -269,48 +276,23 @@ function addMissingPermissions(rbac, permissionNames, changes) {
269
276
  return updated;
270
277
  }
271
278
 
272
- /**
273
- * Ensures default Admin and Reader roles if rbac.roles is empty. Mutates rbac.
274
- * @param {Object} rbac - RBAC object (mutated)
275
- * @param {string} systemKey - System key
276
- * @param {string} displayName - Display name
277
- * @param {string[]} changes - Array to append to
278
- * @returns {boolean}
279
- */
280
- function ensureDefaultRoles(rbac, systemKey, displayName, changes) {
281
- const hasRoles = Array.isArray(rbac.roles) && rbac.roles.length > 0;
282
- if (hasRoles) return false;
283
- const adminValue = `${systemKey}-admin`;
284
- const readerValue = `${systemKey}-reader`;
285
- rbac.roles = [
286
- { name: `${displayName} Admin`, value: adminValue, description: `Full access to all ${displayName} operations`, groups: [] },
287
- { name: `${displayName} Reader`, value: readerValue, description: `Read-only access to all ${displayName} data`, groups: [] }
288
- ];
289
- const listGetPerms = (rbac.permissions || [])
290
- .filter(p => p?.name && (p.name.split(':')[1] === 'list' || p.name.split(':')[1] === 'get'))
291
- .map(p => p.name);
292
- for (const p of rbac.permissions || []) {
293
- if (!p.roles) p.roles = [];
294
- if (p.name && listGetPerms.includes(p.name) && !p.roles.includes(readerValue)) p.roles.push(readerValue);
295
- if (!p.roles.includes(adminValue)) p.roles.push(adminValue);
296
- }
297
- changes.push('Added default Admin and Reader roles to rbac file');
298
- return true;
299
- }
300
-
301
279
  /**
302
280
  * @param {Object} opts
303
281
  * @returns {boolean}
304
282
  */
305
283
  function applyRbacPresetRoles(opts) {
306
- const { rbac, rbacPreset, systemKey, displayName, appPath, datasourceFiles, changes } = opts;
284
+ const { rbac, rbacPreset, appPath, datasourceFiles, changes } = opts;
307
285
  if (rbacPreset === 'platform') {
308
- return (
309
- ensurePlatformRolesOnRbac(rbac, changes) ||
310
- applyPlatformRolesToPermissions(rbac, appPath, datasourceFiles, changes)
286
+ const rolesUpdated = ensurePlatformRolesOnRbac(rbac, changes);
287
+ const permsUpdated = applyPlatformRolesToPermissions(
288
+ rbac,
289
+ appPath,
290
+ datasourceFiles,
291
+ changes
311
292
  );
293
+ return rolesUpdated || permsUpdated;
312
294
  }
313
- return ensureDefaultRoles(rbac, systemKey, displayName, changes);
295
+ return ensureDefaultRoles(rbac, changes);
314
296
  }
315
297
 
316
298
  /**
@@ -9,6 +9,11 @@
9
9
  const path = require('path');
10
10
  const fs = require('fs');
11
11
  const { loadConfigFile } = require('../utils/config-format');
12
+ const {
13
+ catalogAdminReaderRoles,
14
+ pickCatalogAdminRoleValue,
15
+ pickCatalogReaderRoleValue
16
+ } = require('./repair-rbac-catalog-defaults');
12
17
 
13
18
  function _safeString(v) {
14
19
  return typeof v === 'string' && v.trim() ? v.trim() : '';
@@ -23,32 +28,29 @@ function _normalizeOperationKey(opKey) {
23
28
  return cleaned.replace(/-+/g, '-').replace(/^-+|-+$/g, '');
24
29
  }
25
30
 
26
- function _ensureDefaultRoles(systemParsed, systemKey) {
31
+ function _roleValuesFromSystem(systemParsed) {
32
+ const roles = Array.isArray(systemParsed.roles) ? systemParsed.roles : [];
33
+ return roles
34
+ .map((r) => (r && typeof r === 'object' ? _safeString(r.value) : ''))
35
+ .filter(Boolean);
36
+ }
37
+
38
+ function _ensureDefaultRoles(systemParsed) {
27
39
  if (Array.isArray(systemParsed.roles) && systemParsed.roles.length > 0) return false;
28
- const key = _safeString(systemKey) || _safeString(systemParsed?.key) || 'system';
29
- const display = _safeString(systemParsed?.displayName) || key;
30
- systemParsed.roles = [
31
- {
32
- name: `${display} Admin`,
33
- value: `${key}-admin`,
34
- description: `Full access to all ${display} operations`,
35
- groups: []
36
- },
37
- {
38
- name: `${display} Reader`,
39
- value: `${key}-reader`,
40
- description: `Read-only access to all ${display} data`,
41
- groups: []
42
- }
43
- ];
40
+ const seeded = catalogAdminReaderRoles();
41
+ if (seeded.length < 2) return false;
42
+ systemParsed.roles = seeded;
44
43
  return true;
45
44
  }
46
45
 
47
46
  function _pickRoleValue(systemParsed, suffix, fallback) {
48
- const roles = Array.isArray(systemParsed.roles) ? systemParsed.roles : [];
49
- const vals = roles
50
- .map((r) => r && typeof r === 'object' ? _safeString(r.value) : '')
51
- .filter(Boolean);
47
+ const vals = _roleValuesFromSystem(systemParsed);
48
+ if (suffix === '-admin') {
49
+ return pickCatalogAdminRoleValue(vals, undefined, fallback);
50
+ }
51
+ if (suffix === '-reader') {
52
+ return pickCatalogReaderRoleValue(vals, undefined, vals[0] || fallback);
53
+ }
52
54
  return vals.find((v) => v.endsWith(suffix)) || vals[0] || fallback;
53
55
  }
54
56
 
@@ -145,7 +147,7 @@ function ensureSystemPermissionsForAutoRbac(appPath, systemParsed, datasourceFil
145
147
  const desired = _collectAutoRbacOperationPermissions(appPath, datasourceFiles);
146
148
  if (desired.size === 0) return false;
147
149
 
148
- const rolesAdded = _ensureDefaultRoles(systemParsed, systemParsed?.key);
150
+ const rolesAdded = _ensureDefaultRoles(systemParsed);
149
151
  if (rolesAdded) {
150
152
  changes.push('Added default Admin/Reader roles (required for RBAC permissions)');
151
153
  }
@@ -0,0 +1,61 @@
1
+ /**
2
+ * TTY and --json output for role-assistant copy.
3
+ *
4
+ * @fileoverview Success and blocking copy envelopes
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const logger = require('../utils/logger');
10
+ const { formatSuccessLine, formatBlockingError } = require('../utils/cli-layout-chalk');
11
+
12
+ function copyWarnings(result) {
13
+ return Array.isArray(result.warnings) ? result.warnings : [];
14
+ }
15
+
16
+ function buildCopyEnvelope(result) {
17
+ const envelope = {
18
+ success: true,
19
+ path: result.path,
20
+ caseId: result.caseId,
21
+ suiteId: result.suiteId,
22
+ processExecutionId: result.processExecutionId
23
+ };
24
+ const warnings = copyWarnings(result);
25
+ if (warnings.length > 0) {
26
+ envelope.warnings = warnings;
27
+ }
28
+ if (result.dryRun === true) {
29
+ envelope.dryRun = true;
30
+ envelope.yaml = result.yaml;
31
+ }
32
+ return envelope;
33
+ }
34
+
35
+ function emitCopySuccess(options, result) {
36
+ if (options && options.json) {
37
+ logger.log(JSON.stringify(buildCopyEnvelope(result), null, 2));
38
+ return;
39
+ }
40
+ if (result.dryRun === true) {
41
+ logger.log(result.yaml);
42
+ logger.log(formatSuccessLine(`Would write ${result.path}`));
43
+ return;
44
+ }
45
+ logger.log(formatSuccessLine(`Wrote ${result.path}`));
46
+ }
47
+
48
+ function emitCopyFailure(options, error) {
49
+ const message = error && error.message ? error.message : String(error);
50
+ if (options && options.json) {
51
+ logger.log(JSON.stringify({ success: false, error: message }));
52
+ return;
53
+ }
54
+ logger.error(formatBlockingError(message));
55
+ }
56
+
57
+ module.exports = {
58
+ buildCopyEnvelope,
59
+ emitCopySuccess,
60
+ emitCopyFailure
61
+ };
@@ -0,0 +1,155 @@
1
+ /**
2
+ * aifabrix role-assistant copy — capture one Work Hub execution as YAML.
3
+ *
4
+ * @fileoverview Leaf command; Builder materializes the case from Work Hub reference
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const { resolveLifecycleAuth } = require('./lifecycle-external');
10
+ const { fetchWorkCopyReference, buildCopyCaseFromWorkReference } = require(
11
+ '../role-assistant/test-case-copy-from-work'
12
+ );
13
+ const { roleAssistantSystemKey } = require('../utils/role-assistant-paths');
14
+ const { roleAssistantTestsDir } = require('../role-assistant/test-cases');
15
+ const {
16
+ defaultCaseIdFromReference,
17
+ assertProcessExecutionId,
18
+ assertFolderToken,
19
+ copyTargetPath,
20
+ prepareCopyDocument,
21
+ yamlFromValidatedCase,
22
+ assertCopyTargetWritable,
23
+ persistCopyCaseYaml
24
+ } = require('../role-assistant/test-case-copy');
25
+ const { emitCopySuccess, emitCopyFailure } = require('./role-assistant-copy-output');
26
+
27
+ function copyHelpAfter() {
28
+ return `
29
+ Examples:
30
+ $ aifabrix role-assistant copy customer-support-bot --suite 001 --reference a9f09fb8-d9eb-477f-8bb4-59e670fc82a4
31
+ $ aifabrix role-assistant copy customer-support-bot --suite 001 --reference a9f09fb8-d9eb-477f-8bb4-59e670fc82a4 --case address-change
32
+ $ aifabrix role-assistant copy customer-support-bot --suite 001 --reference a9f09fb8-d9eb-477f-8bb4-59e670fc82a4 --dry-run
33
+ $ aifabrix role-assistant copy customer-support-bot --suite 001 --reference a9f09fb8-d9eb-477f-8bb4-59e670fc82a4 --json
34
+
35
+ Notes:
36
+ - <roleKey> is bare; package folder is role-assistant/ra-<roleKey>/.
37
+ - --reference is the Work Hub execution id (the same id printed after a run).
38
+ - Writes tests/<suite>/<caseId>.yaml. Default caseId is copy-<first 8 hex of the execution id>.
39
+ - Existing files are not overwritten unless --force is set.
40
+ - --dry-run prints YAML and does not write.
41
+ - Builds local YAML from Work Hub execution status and result. Does not publish; use upload / deploy.
42
+ `;
43
+ }
44
+
45
+ function normalizeCopyOptions(options) {
46
+ const opts = options && typeof options === 'object' ? options : {};
47
+ return {
48
+ env: opts.env || 'dev',
49
+ suite: opts.suite,
50
+ reference: opts.reference,
51
+ case: opts.case,
52
+ force: opts.force === true,
53
+ dryRun: opts.dryRun === true,
54
+ json: opts.json === true,
55
+ testsDir: opts.testsDir || null
56
+ };
57
+ }
58
+
59
+ function requireCopyFlags(opts) {
60
+ if (!opts.suite) {
61
+ throw new Error('--suite is required');
62
+ }
63
+ if (!opts.reference) {
64
+ throw new Error('--reference is required');
65
+ }
66
+ }
67
+
68
+ async function fetchCopyCase(systemKey, opts, peId, caseId) {
69
+ const auth = await resolveLifecycleAuth(systemKey, {
70
+ env: opts.env,
71
+ run: false,
72
+ noPublish: true
73
+ });
74
+ if (!auth || !auth.dataplaneUrl || !auth.authConfig) {
75
+ throw new Error('Not authenticated. Run aifabrix login, then retry.');
76
+ }
77
+ const reference = await fetchWorkCopyReference(
78
+ auth.dataplaneUrl,
79
+ auth.authConfig,
80
+ peId
81
+ );
82
+ return buildCopyCaseFromWorkReference({
83
+ systemKey,
84
+ caseId,
85
+ processExecutionId: peId,
86
+ status: reference.status,
87
+ result: reference.result
88
+ });
89
+ }
90
+
91
+ async function runRoleAssistantCopy(roleKey, options) {
92
+ const opts = normalizeCopyOptions(options);
93
+ requireCopyFlags(opts);
94
+ const peId = assertProcessExecutionId(opts.reference);
95
+ const suiteId = assertFolderToken(opts.suite, 'Suite id');
96
+ const caseId = assertFolderToken(
97
+ opts.case || defaultCaseIdFromReference(peId),
98
+ 'Case id'
99
+ );
100
+ const systemKey = roleAssistantSystemKey(roleKey);
101
+ const testsDir = roleAssistantTestsDir(systemKey, { testsDir: opts.testsDir });
102
+ const targetPath = copyTargetPath(testsDir, suiteId, caseId);
103
+ if (!opts.dryRun) {
104
+ assertCopyTargetWritable(targetPath, opts.force);
105
+ }
106
+ const payload = await fetchCopyCase(systemKey, opts, peId, caseId);
107
+ const caseDoc = prepareCopyDocument(payload, caseId, peId);
108
+ const yamlText = yamlFromValidatedCase(caseDoc);
109
+ if (!opts.dryRun) {
110
+ persistCopyCaseYaml(targetPath, yamlText);
111
+ }
112
+ return {
113
+ success: true,
114
+ path: targetPath,
115
+ caseId,
116
+ suiteId,
117
+ processExecutionId: peId,
118
+ warnings: payload && payload.warnings,
119
+ yaml: yamlText,
120
+ dryRun: opts.dryRun
121
+ };
122
+ }
123
+
124
+ async function roleAssistantCopyHandler(roleKey, options) {
125
+ try {
126
+ const result = await runRoleAssistantCopy(roleKey, options);
127
+ emitCopySuccess(options, result);
128
+ } catch (error) {
129
+ emitCopyFailure(options, error);
130
+ process.exit(error && error.exitCode ? error.exitCode : 1);
131
+ }
132
+ }
133
+
134
+ function registerRoleAssistantCopyCommand(roleAssistant) {
135
+ roleAssistant
136
+ .command('copy <roleKey>')
137
+ .description('Capture one Work Hub execution as a local YAML test case')
138
+ .requiredOption('--suite <suiteId>', 'Suite folder under tests/ (for example 001)')
139
+ .requiredOption('--reference <executionId>', 'Work Hub execution id')
140
+ .option('--case <caseId>', 'Case id (default: copy-<first 8 hex of the execution id>)')
141
+ .option('--force', 'Overwrite an existing YAML file')
142
+ .option('--dry-run', 'Print YAML and do not write')
143
+ .option('-e, --env <env>', 'Environment: dev, tst, or pro', 'dev')
144
+ .option('--json', 'Machine-readable output envelope')
145
+ .addHelpText('after', copyHelpAfter())
146
+ .action((roleKey, options) => roleAssistantCopyHandler(roleKey, options));
147
+ }
148
+
149
+ module.exports = {
150
+ copyHelpAfter,
151
+ normalizeCopyOptions,
152
+ runRoleAssistantCopy,
153
+ roleAssistantCopyHandler,
154
+ registerRoleAssistantCopyCommand
155
+ };
@@ -16,6 +16,7 @@ const {
16
16
  formatBlockingError,
17
17
  metadata
18
18
  } = require('../utils/cli-test-layout-chalk');
19
+ const { formatCaseResultRows } = require('./role-assistant-test-result-rows');
19
20
 
20
21
  /**
21
22
  * Bucket a lifecycle step status into ok | failed | skipped | other.
@@ -81,6 +82,19 @@ function mapCaseEnvelopeRow(row) {
81
82
  };
82
83
  }
83
84
 
85
+ function attachEnvelopeIsolation(envelope, opts) {
86
+ const emails = Array.isArray(opts.subjectEmail)
87
+ ? opts.subjectEmail.map((value) => String(value || '').trim()).filter(Boolean)
88
+ : [];
89
+ const userIds = Array.isArray(opts.subjectUserId)
90
+ ? opts.subjectUserId.map((value) => String(value || '').trim()).filter(Boolean)
91
+ : [];
92
+ if (emails.length === 0 && userIds.length === 0) {
93
+ return;
94
+ }
95
+ envelope.isolation = { subjectEmails: emails, subjectUserIds: userIds };
96
+ }
97
+
84
98
  function attachEnvelopeCases(envelope, caseResult) {
85
99
  if (Array.isArray(caseResult)) {
86
100
  envelope.cases = caseResult.map(mapCaseEnvelopeRow);
@@ -118,6 +132,7 @@ function buildRoleAssistantTestEnvelope(roleKey, verdict, portalUrl, result, opt
118
132
  summary: null
119
133
  };
120
134
  attachEnvelopeCases(envelope, caseResult);
135
+ attachEnvelopeIsolation(envelope, opts);
121
136
  if (opts.verbose || opts.debug) {
122
137
  envelope.report = report;
123
138
  }
@@ -143,15 +158,12 @@ function displayCaseResultSummary(caseResult) {
143
158
  }
144
159
  if (caseResult.passed) {
145
160
  logger.log(formatSuccessLine('Case assertions passed.'));
146
- const warnings = Array.isArray(caseResult.warnings) ? caseResult.warnings : [];
147
- for (const row of warnings) {
148
- logger.log(formatWarningLine(row.message || String(row)));
149
- }
150
- return;
161
+ } else {
162
+ logger.log(formatBlockingError('Case assertions failed.'));
151
163
  }
152
- logger.log(formatBlockingError('Case assertions failed.'));
153
- for (const row of caseResult.failedAssertions) {
154
- logger.log(formatWarningLine(row.message));
164
+ logger.log(metadata('Results:'));
165
+ for (const line of formatCaseResultRows(caseResult.assertions)) {
166
+ logger.log(line);
155
167
  }
156
168
  }
157
169
 
@@ -196,5 +208,6 @@ function displayRoleAssistantTestSummary(roleKey, verdict, portalUrl, result, ca
196
208
  module.exports = {
197
209
  formatStepsRunSummary,
198
210
  buildRoleAssistantTestEnvelope,
199
- displayRoleAssistantTestSummary
211
+ displayRoleAssistantTestSummary,
212
+ formatCaseResultRows
200
213
  };
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Human TTY lines for Role Assistant case assertion rows.
3
+ * @fileoverview Canonical glyphs for pass/fail/warn/notes/skip
4
+ */
5
+
6
+ 'use strict';
7
+
8
+ const {
9
+ formatSuccessLine,
10
+ formatWarningLine,
11
+ formatBlockingError,
12
+ infoLine,
13
+ metadata
14
+ } = require('../utils/cli-test-layout-chalk');
15
+ const { withKind } = require('../role-assistant/test-case-assertion-row');
16
+
17
+ function formatCaseResultLine(assertion) {
18
+ const row = withKind(assertion || {});
19
+ const text = `${row.id || 'assertion'} — ${row.message || ''}`.trim();
20
+ if (row.kind === 'fail') {
21
+ return ` ${formatBlockingError(text)}`;
22
+ }
23
+ if (row.kind === 'warn') {
24
+ return ` ${formatWarningLine(text)}`;
25
+ }
26
+ if (row.kind === 'notes') {
27
+ return ` ${infoLine(`ℹ ${text}`)}`;
28
+ }
29
+ if (row.kind === 'skip') {
30
+ return ` ${metadata(`⏭ ${text}`)}`;
31
+ }
32
+ return ` ${formatSuccessLine(text)}`;
33
+ }
34
+
35
+ function formatCaseResultRows(assertions) {
36
+ return (Array.isArray(assertions) ? assertions : []).map(formatCaseResultLine);
37
+ }
38
+
39
+ module.exports = {
40
+ formatCaseResultLine,
41
+ formatCaseResultRows
42
+ };