@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
@@ -13,7 +13,11 @@ const fs = require('../internal/fs-real-sync');
13
13
  const yaml = require('js-yaml');
14
14
  const { resolveExternalSystemPath } = require('../utils/app-path-resolve');
15
15
  const { loadRoleAssistantSettingsSchema } = require('../utils/schema-loader');
16
- const { SYSTEM_KIND_DIGITAL_WORKER } = require('../utils/role-assistant-paths');
16
+ const {
17
+ SYSTEM_KIND_DIGITAL_WORKER,
18
+ WORKSPACE_ROLE_ASSISTANT,
19
+ bareRoleKey
20
+ } = require('../utils/role-assistant-paths');
17
21
 
18
22
  function getRoleAssistantYamlPath(systemKey, options = {}) {
19
23
  const appPath = resolveExternalSystemPath(systemKey, options.pathOptions || {});
@@ -115,6 +119,48 @@ function resolveRoleAssistantSettingsVersion(settings) {
115
119
  return value.trim();
116
120
  }
117
121
 
122
+ function defaultRoleAssistantSettings(systemKey) {
123
+ return {
124
+ apiVersion: 'aifabrix.ai/v1',
125
+ version: '1.0.0',
126
+ kind: 'RoleAssistantSettings',
127
+ roleKey: bareRoleKey(systemKey)
128
+ };
129
+ }
130
+
131
+ function mergeRoleAssistantSettings(existing, systemKey) {
132
+ const next = existing && typeof existing === 'object' ? { ...existing } : {};
133
+ const defaults = defaultRoleAssistantSettings(systemKey);
134
+ return {
135
+ ...defaults,
136
+ ...next,
137
+ apiVersion: defaults.apiVersion,
138
+ kind: defaults.kind,
139
+ roleKey: defaults.roleKey
140
+ };
141
+ }
142
+
143
+ function writeOrMergeRoleAssistantSettings(systemKey, options = {}) {
144
+ const filePath = getRoleAssistantYamlPath(systemKey, {
145
+ ...options,
146
+ pathOptions: {
147
+ ...(options.pathOptions || {}),
148
+ workspace: WORKSPACE_ROLE_ASSISTANT
149
+ }
150
+ });
151
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
152
+ let payload = defaultRoleAssistantSettings(systemKey);
153
+ if (!options.force && fs.existsSync(filePath)) {
154
+ try {
155
+ payload = mergeRoleAssistantSettings(parseRoleAssistantYaml(filePath), systemKey);
156
+ } catch {
157
+ payload = defaultRoleAssistantSettings(systemKey);
158
+ }
159
+ }
160
+ fs.writeFileSync(filePath, yaml.dump(payload, { lineWidth: -1 }), 'utf8');
161
+ return filePath;
162
+ }
163
+
118
164
  module.exports = {
119
165
  SYSTEM_KIND_DIGITAL_WORKER,
120
166
  getRoleAssistantYamlPath,
@@ -122,5 +168,6 @@ module.exports = {
122
168
  readRoleAssistantSettings,
123
169
  resolveRoleAssistantEnvironmentSettings,
124
170
  resolveDocumentStorageKeyFromRoleAssistantSettings,
125
- resolveRoleAssistantSettingsVersion
171
+ resolveRoleAssistantSettingsVersion,
172
+ writeOrMergeRoleAssistantSettings
126
173
  };
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Shared assertion row helpers (pass/fail/warn/notes/skip).
3
+ * @fileoverview Kind flags for Role Assistant test result rows
4
+ */
5
+
6
+ 'use strict';
7
+
8
+ function skipRow(id, message) {
9
+ return { id, passed: true, skip: true, kind: 'skip', message };
10
+ }
11
+
12
+ function notesRow(id, message) {
13
+ return { id, passed: true, notes: true, kind: 'notes', message };
14
+ }
15
+
16
+ function withKind(row) {
17
+ if (!row || row.kind) {
18
+ return row;
19
+ }
20
+ if (row.notes === true) {
21
+ return { ...row, kind: 'notes' };
22
+ }
23
+ if (row.skip === true) {
24
+ return { ...row, kind: 'skip' };
25
+ }
26
+ if (row.warn === true) {
27
+ return { ...row, kind: 'warn' };
28
+ }
29
+ return { ...row, kind: row.passed ? 'pass' : 'fail' };
30
+ }
31
+
32
+ module.exports = {
33
+ skipRow,
34
+ notesRow,
35
+ withKind
36
+ };
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Bind a Work Hub execution to the Role Assistant named on copy.
3
+ *
4
+ * @fileoverview Fail closed on mismatch; trust the CLI role when identity is absent
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const {
10
+ bareRoleKey,
11
+ roleAssistantSystemKey
12
+ } = require('../utils/role-assistant-paths');
13
+
14
+ const PLACEHOLDER = new Set(['', 'unknown', 'none', 'null']);
15
+
16
+ function throwCopyStatus(message, status) {
17
+ const err = new Error(message);
18
+ err.status = status;
19
+ throw err;
20
+ }
21
+
22
+ function usableIdentity(value) {
23
+ const token = String(value || '').trim();
24
+ if (!token || PLACEHOLDER.has(token.toLowerCase())) {
25
+ return '';
26
+ }
27
+ return token;
28
+ }
29
+
30
+ function pushIdentity(acc, value) {
31
+ const token = usableIdentity(value);
32
+ if (token) {
33
+ acc.push(token);
34
+ }
35
+ }
36
+
37
+ function boundIdentityTokens(status, result) {
38
+ const acc = [];
39
+ const task = result && result.task && typeof result.task === 'object' ? result.task : {};
40
+ pushIdentity(acc, status && status.assistantKey);
41
+ pushIdentity(acc, status && status.digitalWorkerKey);
42
+ pushIdentity(acc, result && result.assistantKey);
43
+ pushIdentity(acc, result && result.digitalWorkerKey);
44
+ pushIdentity(acc, task.assistantKey);
45
+ pushIdentity(acc, task.digitalWorkerKey);
46
+ pushIdentity(acc, task.activeBusinessRoleRef);
47
+ pushIdentity(acc, task.roleKey);
48
+ return [...new Set(acc)];
49
+ }
50
+
51
+ function identityMatchesSystem(token, systemKey) {
52
+ const expectedSystem = roleAssistantSystemKey(systemKey);
53
+ const expectedBare = bareRoleKey(systemKey).toLowerCase();
54
+ const lower = token.toLowerCase();
55
+ if (lower === expectedSystem.toLowerCase()) {
56
+ return true;
57
+ }
58
+ return bareRoleKey(token).toLowerCase() === expectedBare;
59
+ }
60
+
61
+ function assertCopyBoundToSystem(systemKey, status, result) {
62
+ const tokens = boundIdentityTokens(status, result);
63
+ if (tokens.length === 0) {
64
+ return { bound: false };
65
+ }
66
+ const mismatch = tokens.find((token) => !identityMatchesSystem(token, systemKey));
67
+ if (mismatch) {
68
+ throwCopyStatus('Execution belongs to a different Role Assistant', 409);
69
+ }
70
+ return { bound: true };
71
+ }
72
+
73
+ module.exports = {
74
+ throwCopyStatus,
75
+ boundIdentityTokens,
76
+ assertCopyBoundToSystem
77
+ };
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Derive copy input.message and expected.* from Work Hub reference payloads.
3
+ *
4
+ * @fileoverview No facts dump; do not invent a start message
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const { collectObservedCapabilities } = require('./test-cases');
10
+ const { throwCopyStatus } = require('./test-case-copy-bind');
11
+
12
+ const PLACEHOLDER = new Set(['', 'unknown', 'none', 'null']);
13
+ const STATUS_LIFECYCLE = {
14
+ completed: 'completed',
15
+ stopped: 'failed'
16
+ };
17
+ const OBJECTIVE_KEYS = new Set([
18
+ 'objective',
19
+ 'goal',
20
+ 'planObjective',
21
+ 'objectiveSummary',
22
+ 'acceptedObjective'
23
+ ]);
24
+
25
+ function usableText(value) {
26
+ const text = String(value || '').trim();
27
+ if (!text || PLACEHOLDER.has(text.toLowerCase())) {
28
+ return '';
29
+ }
30
+ return text;
31
+ }
32
+
33
+ function collectObjectiveStrings(value, acc, depth) {
34
+ if (depth > 8 || !value) {
35
+ return;
36
+ }
37
+ if (Array.isArray(value)) {
38
+ value.forEach((item) => collectObjectiveStrings(item, acc, depth + 1));
39
+ return;
40
+ }
41
+ if (typeof value !== 'object') {
42
+ return;
43
+ }
44
+ for (const [key, child] of Object.entries(value)) {
45
+ if (OBJECTIVE_KEYS.has(key) && typeof child === 'string') {
46
+ const text = usableText(child);
47
+ if (text) {
48
+ acc.push(text);
49
+ }
50
+ } else if (child && typeof child === 'object') {
51
+ collectObjectiveStrings(child, acc, depth + 1);
52
+ }
53
+ }
54
+ }
55
+
56
+ function startMessageFromWorkReference(result) {
57
+ const goal = usableText(result && result.task && result.task.acceptedIntent && result.task.acceptedIntent.goal);
58
+ if (goal) {
59
+ return goal;
60
+ }
61
+ const found = [];
62
+ collectObjectiveStrings(result, found, 0);
63
+ if (found[0]) {
64
+ return found[0];
65
+ }
66
+ throwCopyStatus('Execution has no reconstructable start message', 422);
67
+ }
68
+
69
+ function lifecycleStateFromStatus(status) {
70
+ const token = String((status && status.status) || '').trim();
71
+ if (token === 'waiting') {
72
+ const wait = status.wait && typeof status.wait === 'object' ? status.wait : {};
73
+ if (String(wait.answerType || wait.waitReason || '') === 'approval') {
74
+ return 'approval-required';
75
+ }
76
+ return 'question';
77
+ }
78
+ return STATUS_LIFECYCLE[token] || null;
79
+ }
80
+
81
+ function resultProjectionExists(result) {
82
+ return Boolean(result && typeof result === 'object' && (result.completion || result.sourceCompleteness));
83
+ }
84
+
85
+ function ranCapabilityKeys(result) {
86
+ if (!result || typeof result !== 'object') {
87
+ return [];
88
+ }
89
+ const fromSteps = [];
90
+ const seen = new Set();
91
+ const steps = Array.isArray(result.steps) ? result.steps : [];
92
+ for (const step of steps) {
93
+ const block = step && step.capabilityExecution && typeof step.capabilityExecution === 'object'
94
+ ? step.capabilityExecution
95
+ : {};
96
+ const key = String(block.capabilityKey || '').trim();
97
+ if (key && !seen.has(key)) {
98
+ seen.add(key);
99
+ fromSteps.push(key);
100
+ }
101
+ }
102
+ if (fromSteps.length > 0) {
103
+ return fromSteps;
104
+ }
105
+ return collectObservedCapabilities({ steps: result.steps, workResult: result });
106
+ }
107
+
108
+ function buildCopyExpected(status, result) {
109
+ const expected = {};
110
+ const lifecycle = lifecycleStateFromStatus(status);
111
+ if (lifecycle) {
112
+ expected.lifecycleState = lifecycle;
113
+ }
114
+ if (resultProjectionExists(result)) {
115
+ expected.honesty = { requireWorkResult: true };
116
+ }
117
+ const required = ranCapabilityKeys(result);
118
+ if (required.length > 0) {
119
+ expected.capabilities = { required };
120
+ }
121
+ return expected;
122
+ }
123
+
124
+ module.exports = {
125
+ startMessageFromWorkReference,
126
+ buildCopyExpected
127
+ };
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Build a Role Assistant test case from Work Hub status and result.
3
+ *
4
+ * @fileoverview CLI materializes 187 YAML; dataplane is the PE reference only
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const {
10
+ getWorkExecutionStatus,
11
+ getWorkExecutionResult
12
+ } = require('../api/work.api');
13
+ const { throwCopyStatus, assertCopyBoundToSystem } = require('./test-case-copy-bind');
14
+ const { mapCopyInteractions } = require('./test-case-copy-interactions');
15
+ const {
16
+ startMessageFromWorkReference,
17
+ buildCopyExpected
18
+ } = require('./test-case-copy-expected');
19
+
20
+ function remapCopyReferenceError(error) {
21
+ const status = Number(error && error.status) || 0;
22
+ if (status === 404) {
23
+ throwCopyStatus('Execution was not found', 404);
24
+ }
25
+ if (status === 403) {
26
+ throwCopyStatus('Permission denied', 403);
27
+ }
28
+ throw error;
29
+ }
30
+
31
+ async function readWorkStatus(dataplaneUrl, authConfig, processExecutionId) {
32
+ try {
33
+ return await getWorkExecutionStatus(dataplaneUrl, authConfig, processExecutionId);
34
+ } catch (error) {
35
+ remapCopyReferenceError(error);
36
+ }
37
+ return null;
38
+ }
39
+
40
+ async function readWorkResult(dataplaneUrl, authConfig, processExecutionId) {
41
+ try {
42
+ return await getWorkExecutionResult(dataplaneUrl, authConfig, processExecutionId, {
43
+ requestedDepth: 'business',
44
+ format: 'json'
45
+ });
46
+ } catch (error) {
47
+ if (Number(error && error.status) === 404) {
48
+ return null;
49
+ }
50
+ remapCopyReferenceError(error);
51
+ }
52
+ return null;
53
+ }
54
+
55
+ async function fetchWorkCopyReference(dataplaneUrl, authConfig, processExecutionId) {
56
+ const status = await readWorkStatus(dataplaneUrl, authConfig, processExecutionId);
57
+ const result = await readWorkResult(dataplaneUrl, authConfig, processExecutionId);
58
+ return { status, result };
59
+ }
60
+
61
+ function omitEmptyList(doc, key, rows) {
62
+ if (Array.isArray(rows) && rows.length > 0) {
63
+ doc[key] = rows;
64
+ }
65
+ }
66
+
67
+ function buildCopyCaseFromWorkReference(args) {
68
+ const { systemKey, caseId, processExecutionId, status, result } = args;
69
+ const bind = assertCopyBoundToSystem(systemKey, status, result);
70
+ const message = startMessageFromWorkReference(result);
71
+ const mapped = mapCopyInteractions(result);
72
+ const warnings = [...mapped.warnings];
73
+ if (!bind.bound) {
74
+ warnings.push('Role Assistant identity was not on the execution reference');
75
+ }
76
+ const caseDoc = {
77
+ caseId,
78
+ input: { executionPath: 'workHub', message },
79
+ expected: buildCopyExpected(status, result),
80
+ metadata: { sourceProcessExecutionId: processExecutionId }
81
+ };
82
+ omitEmptyList(caseDoc, 'answers', mapped.answers);
83
+ omitEmptyList(caseDoc, 'approvals', mapped.approvals);
84
+ return { case: caseDoc, warnings };
85
+ }
86
+
87
+ module.exports = {
88
+ fetchWorkCopyReference,
89
+ buildCopyCaseFromWorkReference
90
+ };
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Map work.result interactions onto 187 answers and approvals.
3
+ *
4
+ * @fileoverview Completed waits only; pending waits are omitted
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const { throwCopyStatus } = require('./test-case-copy-bind');
10
+
11
+ const ANSWERED = new Set(['answered', 'approved']);
12
+
13
+ function asObject(value) {
14
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
15
+ return {};
16
+ }
17
+ return value;
18
+ }
19
+
20
+ function interactionValue(row) {
21
+ const response = asObject(row.response);
22
+ if (Object.prototype.hasOwnProperty.call(response, 'decision') && response.decision !== null
23
+ && response.decision !== undefined) {
24
+ return response.decision;
25
+ }
26
+ if (Object.prototype.hasOwnProperty.call(response, 'data')) {
27
+ return response.data;
28
+ }
29
+ return null;
30
+ }
31
+
32
+ function mapAnsweredInteraction(row, answers, approvals, warnings) {
33
+ const questionKey = String(row.questionKey || '').trim();
34
+ if (!questionKey) {
35
+ warnings.push('Skipped a completed interaction without a questionKey');
36
+ return;
37
+ }
38
+ const entry = { when: { questionKey }, value: interactionValue(row) };
39
+ if (String(row.interactionKind || '') === 'approval') {
40
+ approvals.push(entry);
41
+ return;
42
+ }
43
+ answers.push(entry);
44
+ }
45
+
46
+ function mapCopyInteractions(result) {
47
+ const rows = Array.isArray(result && result.interactions) ? result.interactions : [];
48
+ const answers = [];
49
+ const approvals = [];
50
+ const warnings = [];
51
+ let answeredCount = 0;
52
+ for (const row of rows) {
53
+ if (!row || typeof row !== 'object' || !ANSWERED.has(String(row.status || ''))) {
54
+ continue;
55
+ }
56
+ answeredCount += 1;
57
+ mapAnsweredInteraction(row, answers, approvals, warnings);
58
+ }
59
+ if (answeredCount > 0 && answers.length === 0 && approvals.length === 0) {
60
+ throwCopyStatus('Completed interactions could not be bound to questionKey', 422);
61
+ }
62
+ return { answers, approvals, warnings };
63
+ }
64
+
65
+ module.exports = {
66
+ mapCopyInteractions
67
+ };
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Persist a copied Role Assistant test case as local YAML.
3
+ *
4
+ * @fileoverview UUID checks and AJV-gated write of a copied case document
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const path = require('path');
10
+ const yaml = require('js-yaml');
11
+ const fs = require('../internal/fs-real-sync');
12
+ const { YAML_SPEC_KEYS } = require('./test-pack-map');
13
+ const { assertTestCaseDocument } = require('./test-case-validate');
14
+
15
+ const PE_UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
16
+ const WORK_HUB_REF_MSG =
17
+ '--reference must be a Work Hub execution id (the same id printed after a run)';
18
+
19
+ function normalizeProcessExecutionId(value) {
20
+ return String(value || '')
21
+ .trim()
22
+ .replace(/^\{|\}$/g, '');
23
+ }
24
+
25
+ function defaultCaseIdFromReference(reference) {
26
+ const hex = normalizeProcessExecutionId(reference).replace(/-/g, '').toLowerCase();
27
+ return `copy-${hex.slice(0, 8)}`;
28
+ }
29
+
30
+ function assertProcessExecutionId(value) {
31
+ const id = normalizeProcessExecutionId(value);
32
+ if (!PE_UUID_RE.test(id)) {
33
+ throw new Error(WORK_HUB_REF_MSG);
34
+ }
35
+ return id.toLowerCase();
36
+ }
37
+
38
+ function assertFolderToken(value, label) {
39
+ const token = String(value || '').trim();
40
+ if (!token || token.includes('..') || /[/\\]/.test(token)) {
41
+ throw new Error(`${label} must be a folder name (for example 001)`);
42
+ }
43
+ return token;
44
+ }
45
+
46
+ function copyTargetPath(testsDir, suiteId, caseId) {
47
+ return path.join(testsDir, suiteId, `${caseId}.yaml`);
48
+ }
49
+
50
+ function extractCopyCase(payload) {
51
+ if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {
52
+ return null;
53
+ }
54
+ if (payload.case && typeof payload.case === 'object' && !Array.isArray(payload.case)) {
55
+ return payload.case;
56
+ }
57
+ if (typeof payload.caseId === 'string' || payload.input) {
58
+ return payload;
59
+ }
60
+ return null;
61
+ }
62
+
63
+ function withCopyProvenance(doc, processExecutionId) {
64
+ return {
65
+ ...doc,
66
+ metadata: {
67
+ ...(doc.metadata && typeof doc.metadata === 'object' ? doc.metadata : {}),
68
+ sourceProcessExecutionId: processExecutionId
69
+ }
70
+ };
71
+ }
72
+
73
+ function pickYamlSpec(doc) {
74
+ const out = {};
75
+ for (const key of YAML_SPEC_KEYS) {
76
+ if (doc[key] !== undefined) {
77
+ out[key] = doc[key];
78
+ }
79
+ }
80
+ return out;
81
+ }
82
+
83
+ function prepareCopyDocument(payload, caseId, processExecutionId) {
84
+ const raw = extractCopyCase(payload);
85
+ if (!raw) {
86
+ throw new Error('Copy did not return a test case');
87
+ }
88
+ const doc = withCopyProvenance({ ...raw, caseId }, processExecutionId);
89
+ assertTestCaseDocument(doc, `${caseId}.yaml`);
90
+ return pickYamlSpec(doc);
91
+ }
92
+
93
+ function yamlFromValidatedCase(doc) {
94
+ return yaml.dump(doc, { lineWidth: 120, noRefs: true, sortKeys: false });
95
+ }
96
+
97
+ function assertCopyTargetWritable(targetPath, force) {
98
+ if (fs.existsSync(targetPath) && force !== true) {
99
+ throw new Error('Test case already exists. Pass --force to overwrite.');
100
+ }
101
+ }
102
+
103
+ function persistCopyCaseYaml(targetPath, yamlText) {
104
+ fs.mkdirSync(path.dirname(targetPath), { recursive: true });
105
+ fs.writeFileSync(targetPath, yamlText, 'utf8');
106
+ }
107
+
108
+ module.exports = {
109
+ WORK_HUB_REF_MSG,
110
+ defaultCaseIdFromReference,
111
+ assertProcessExecutionId,
112
+ assertFolderToken,
113
+ copyTargetPath,
114
+ extractCopyCase,
115
+ prepareCopyDocument,
116
+ yamlFromValidatedCase,
117
+ assertCopyTargetWritable,
118
+ persistCopyCaseYaml
119
+ };