@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
@@ -37,6 +37,16 @@ function resolveInputMessage(testCase) {
37
37
  return '';
38
38
  }
39
39
 
40
+ function applyObjectiveField(payload, message) {
41
+ if (message) {
42
+ payload.objective = message;
43
+ return;
44
+ }
45
+ if (typeof payload.content === 'string' && payload.content.trim()) {
46
+ payload.objective = payload.content.trim();
47
+ }
48
+ }
49
+
40
50
  function applyStartPayloadOptionalFields(payload, input) {
41
51
  const mappedFields = [
42
52
  ['activationId', 'activationId'],
@@ -58,34 +68,77 @@ function buildStartPayloadSourceMetadata(roleKey, testCase, input) {
58
68
  };
59
69
  }
60
70
 
61
- function buildStartIntentPayload(roleKey, testCase) {
62
- const input = resolveInputObject(testCase);
63
- const message = resolveInputMessage(testCase);
64
- const hasContent = typeof input.content !== 'undefined';
71
+ function resolveCaseMetadata(testCase) {
72
+ if (testCase && typeof testCase.metadata === 'object' && testCase.metadata) {
73
+ return testCase.metadata;
74
+ }
75
+ return {};
76
+ }
77
+
78
+ function resolveLearningLevel(metadata) {
79
+ if (typeof metadata.learningLevel === 'string' && metadata.learningLevel.trim()) {
80
+ return metadata.learningLevel.trim();
81
+ }
82
+ return null;
83
+ }
84
+
85
+ function assertHasStartContent(testCase, hasContent, message) {
65
86
  if (!hasContent && !message) {
66
87
  throw new Error(
67
88
  `Role assistant test case "${testCase.caseId}" is missing input.message or input.content for runtime execution.`
68
89
  );
69
90
  }
70
- const payload = {
91
+ }
92
+
93
+ function resolveComVocabulary(input) {
94
+ if (Array.isArray(input.comVocabulary) && input.comVocabulary.length > 0) {
95
+ return input.comVocabulary.map((row) => String(row));
96
+ }
97
+ return ['objective', 'entity', 'action'];
98
+ }
99
+
100
+ function buildStartIntentBasePayload(roleKey, testCase, input, message, hasContent) {
101
+ return {
71
102
  submissionId: String(input.submissionId || buildRuntimeId(`ra-${roleKey}`)),
72
103
  content: hasContent ? input.content : message,
73
104
  comModelRef: String(input.comModelRef || 'aifabrix.com/intent/default'),
74
105
  comModelVersion: String(input.comModelVersion || '1.0'),
75
- comVocabulary:
76
- Array.isArray(input.comVocabulary) && input.comVocabulary.length > 0
77
- ? input.comVocabulary.map((row) => String(row))
78
- : ['objective', 'entity', 'action'],
106
+ comVocabulary: resolveComVocabulary(input),
79
107
  sourceType: String(input.sourceType || 'api'),
80
108
  sourceLanguage: String(input.sourceLanguage || 'en'),
81
109
  responseLanguage: String(input.responseLanguage || input.sourceLanguage || 'en'),
82
110
  sourceMetadata: buildStartPayloadSourceMetadata(roleKey, testCase, input)
83
111
  };
84
- applyStartPayloadOptionalFields(payload, input);
112
+ }
113
+
114
+ function applyLearningLevel(payload, learningLevel) {
115
+ if (learningLevel === null) {
116
+ return;
117
+ }
118
+ payload.learningLevel = learningLevel;
119
+ payload.sourceMetadata = {
120
+ ...(payload.sourceMetadata || {}),
121
+ learningLevel
122
+ };
123
+ }
124
+
125
+ function applyStartAttachments(payload, testCase) {
85
126
  const attachments = buildStartAttachments(testCase);
86
127
  if (attachments && attachments.length > 0) {
87
128
  payload.attachments = attachments;
88
129
  }
130
+ }
131
+
132
+ function buildStartIntentPayload(roleKey, testCase) {
133
+ const input = resolveInputObject(testCase);
134
+ const message = resolveInputMessage(testCase);
135
+ const hasContent = typeof input.content !== 'undefined';
136
+ assertHasStartContent(testCase, hasContent, message);
137
+ const payload = buildStartIntentBasePayload(roleKey, testCase, input, message, hasContent);
138
+ applyObjectiveField(payload, message);
139
+ applyStartPayloadOptionalFields(payload, input);
140
+ applyLearningLevel(payload, resolveLearningLevel(resolveCaseMetadata(testCase)));
141
+ applyStartAttachments(payload, testCase);
89
142
  return payload;
90
143
  }
91
144
 
@@ -11,6 +11,7 @@ const {
11
11
  resolveSuiteRunId,
12
12
  loadCaseBidDocument
13
13
  } = require('./test-runner-bid-document');
14
+ const { pickHumanRespondBody } = require('./test-runner-respond-body');
14
15
 
15
16
  function resolveWorkHubAnswerValue(answer) {
16
17
  if (answer === null || answer === undefined) {
@@ -31,24 +32,41 @@ function resolveWorkHubAnswerValue(answer) {
31
32
  return undefined;
32
33
  }
33
34
 
35
+ function asPlainObject(value) {
36
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
37
+ return {};
38
+ }
39
+ return value;
40
+ }
41
+
42
+ function firstNormalizedKey(candidates) {
43
+ for (const part of candidates) {
44
+ const text = String(part || '').trim().toLowerCase();
45
+ if (text) {
46
+ return text;
47
+ }
48
+ }
49
+ return '';
50
+ }
51
+
52
+ function waitQuestionKey(wait) {
53
+ const row = asPlainObject(wait);
54
+ const objectRef = asPlainObject(row.objectRef);
55
+ return firstNormalizedKey([row.questionKey, row.requestKey, objectRef.capabilityKey]);
56
+ }
57
+
58
+ function answerWhenKey(entry) {
59
+ const when = asPlainObject(asPlainObject(entry).when);
60
+ return firstNormalizedKey([when.questionKey, when.requestKey, when.key]);
61
+ }
62
+
34
63
  function pickAnswerForWait(answers, wait) {
35
- const questionKey = String(wait.questionKey || wait.requestKey || '').trim().toLowerCase();
64
+ const questionKey = waitQuestionKey(wait);
36
65
  if (!questionKey) {
37
66
  return null;
38
67
  }
39
- for (const entry of answers) {
40
- if (!entry || typeof entry !== 'object') {
41
- continue;
42
- }
43
- const when = entry.when && typeof entry.when === 'object' ? entry.when : {};
44
- const matchKey = String(when.questionKey || when.requestKey || when.key || '')
45
- .trim()
46
- .toLowerCase();
47
- if (matchKey && matchKey === questionKey) {
48
- return entry;
49
- }
50
- }
51
- return null;
68
+ const list = Array.isArray(answers) ? answers : [];
69
+ return list.find((entry) => answerWhenKey(entry) === questionKey) || null;
52
70
  }
53
71
 
54
72
  function parseFieldsFromPrompt(prompt) {
@@ -423,14 +441,25 @@ function buildRespondPayload(peId, wait, testCase, statusRow, interactions, obje
423
441
  };
424
442
  if (answerType === 'approval') {
425
443
  payload.approvalDecision = 'approved';
426
- return payload;
444
+ return pickHumanRespondBody(payload);
427
445
  }
428
446
  const value = resolveRespondValue(testCase, wait, statusRow, objective);
429
447
  if (value === undefined) {
430
448
  return null;
431
449
  }
450
+ const choiceIds = Array.isArray(wait.allowedChoiceIds) ? wait.allowedChoiceIds : [];
451
+ const isChoice =
452
+ String(wait.interactionKind || '').toLowerCase() === 'choice' || choiceIds.length > 0;
453
+ if (isChoice) {
454
+ const selected = typeof value === 'string' ? value.trim() : '';
455
+ if (!selected) {
456
+ return null;
457
+ }
458
+ payload.selectedOptionId = selected;
459
+ return pickHumanRespondBody(payload);
460
+ }
432
461
  payload.value = value;
433
- return payload;
462
+ return pickHumanRespondBody(payload);
434
463
  }
435
464
 
436
465
  module.exports = {
@@ -34,9 +34,45 @@ function resolveObjective(testCase) {
34
34
  return '';
35
35
  }
36
36
 
37
- function wantsWorkHubPath(testCase) {
37
+ function firstNonEmptyString(values) {
38
+ for (const value of values) {
39
+ if (typeof value === 'string' && value.trim()) {
40
+ return value.trim();
41
+ }
42
+ }
43
+ return '';
44
+ }
45
+
46
+ function searchPathToken(testCase) {
38
47
  const input = resolveInput(testCase);
39
- const pathToken = String(input.executionPath || input.mode || '').trim().toLowerCase();
48
+ return firstNonEmptyString([
49
+ input.executionPath,
50
+ input.execution_path,
51
+ testCase && testCase.executionPath,
52
+ input.mode
53
+ ]).toLowerCase();
54
+ }
55
+
56
+ function wantsSearchPath(testCase) {
57
+ const pathToken = searchPathToken(testCase);
58
+ return (
59
+ pathToken === 'search' ||
60
+ pathToken === 'work.search' ||
61
+ pathToken === 'skills' ||
62
+ pathToken === 'work.skills'
63
+ );
64
+ }
65
+
66
+ function wantsSkillsOnlyPath(testCase) {
67
+ const pathToken = searchPathToken(testCase);
68
+ return pathToken === 'skills' || pathToken === 'work.skills';
69
+ }
70
+
71
+ function wantsWorkHubPath(testCase) {
72
+ if (wantsSearchPath(testCase)) {
73
+ return false;
74
+ }
75
+ const pathToken = searchPathToken(testCase);
40
76
  if (pathToken === 'workhub' || pathToken === 'work-hub' || pathToken === 'plan') {
41
77
  return true;
42
78
  }
@@ -91,6 +127,8 @@ module.exports = {
91
127
  delayMs,
92
128
  resolveInput,
93
129
  resolveObjective,
130
+ wantsSearchPath,
131
+ wantsSkillsOnlyPath,
94
132
  wantsWorkHubPath,
95
133
  unwrapId,
96
134
  extractPeFromTask,
@@ -1,14 +1,20 @@
1
1
  /**
2
2
  * Soft Work Hub outcomes for insufficient-info / clarify-first Intent.
3
- * Soft cases may stop before accept when Intent is not Act-ready — that is a
4
- * governed fail-closed outcome, not a harness failure.
3
+ * Soft cases may stop before accept when Intent is not Act-ready or cannot be
4
+ * classified (unavailable without a next question) — that is a governed
5
+ * fail-closed outcome, not a harness failure.
5
6
  */
6
7
 
7
8
  'use strict';
8
9
 
9
10
  function isIntentNotActReadyError(error) {
10
11
  const msg = String((error && error.message) || error || '');
11
- return /not Act-ready|intentNotActReady/i.test(msg);
12
+ const type = String((error && (error.errorType || error.type)) || '');
13
+ return (
14
+ /not Act-ready|intentNotActReady/i.test(msg) ||
15
+ /Intent is not available|runtimeIntentUnavailable/i.test(msg) ||
16
+ /runtimeIntentUnavailable/i.test(type)
17
+ );
12
18
  }
13
19
 
14
20
  function attachPlanIdToError(error, planId) {
@@ -14,8 +14,7 @@ const {
14
14
  approveWorkTask,
15
15
  getWorkExecutionStatus,
16
16
  respondWorkExecution,
17
- continueWorkExecution,
18
- getWorkExecutionResult
17
+ continueWorkExecution
19
18
  } = require('../api/work.api');
20
19
  const {
21
20
  synthesizeWaitAnswer,
@@ -302,21 +301,36 @@ function assertTerminalWorkHubTask(last, taskId, timeoutMs, options = {}) {
302
301
  throw new Error(`Work Hub task ${taskId} produced no status rows.`);
303
302
  }
304
303
  const finalStatusToken = String(last?.status || last?.taskStatus || '').trim().toLowerCase();
305
- if (!TERMINAL_TASK.has(finalStatusToken)) {
306
- if (options.soft === true) {
307
- return last;
308
- }
309
- throw new Error(
310
- `Work Hub task ${taskId} did not reach a terminal status within ${timeoutMs}ms (last=${finalStatusToken || 'unknown'}).`
311
- );
304
+ if (!TERMINAL_TASK.has(finalStatusToken) && options.recordTimeout === true) {
305
+ last = {
306
+ ...last,
307
+ pollTimedOut: true,
308
+ lastStatus: finalStatusToken || 'unknown',
309
+ pollTimeoutMs: timeoutMs
310
+ };
312
311
  }
313
312
  return last;
314
313
  }
315
314
 
315
+ function shouldStopPendingApprovalPoll(status, ctx) {
316
+ if (status !== 'pendingapproval' && status !== 'pending_approval') {
317
+ return false;
318
+ }
319
+ return ctx.approveStopped === true && (Number(ctx.pendingApprovalStreak) || 0) >= 3;
320
+ }
321
+
322
+ function applyWorkHubPollStatus(ctx, last, status) {
323
+ ctx.status = status;
324
+ ctx.taskRow = last;
325
+ ctx.pendingApprovalStreak =
326
+ status === 'pendingapproval' || status === 'pending_approval'
327
+ ? (Number(ctx.pendingApprovalStreak) || 0) + 1
328
+ : 0;
329
+ }
330
+
316
331
  async function pollWorkHubTask(dataplaneUrl, authConfig, taskId, testCase, options) {
317
332
  const timeoutMs = Number(options.pollTimeoutMs) || 180000;
318
333
  const intervalMs = Number(options.pollIntervalMs) || 3000;
319
- const soft = testCase?.expected?.soft === true;
320
334
  const started = Date.now();
321
335
  let last = null;
322
336
  const timeline = [];
@@ -324,6 +338,7 @@ async function pollWorkHubTask(dataplaneUrl, authConfig, taskId, testCase, optio
324
338
  status: '',
325
339
  approveAttempts: 0,
326
340
  approveStopped: false,
341
+ pendingApprovalStreak: 0,
327
342
  interactions: [],
328
343
  taskRow: null
329
344
  };
@@ -335,30 +350,25 @@ async function pollWorkHubTask(dataplaneUrl, authConfig, taskId, testCase, optio
335
350
  if (TERMINAL_TASK.has(status)) {
336
351
  break;
337
352
  }
338
- ctx.status = status;
339
- ctx.taskRow = last;
353
+ applyWorkHubPollStatus(ctx, last, status);
340
354
  await maybeApproveTask(dataplaneUrl, authConfig, taskId, ctx);
341
355
  await maybeRespondWaiting(dataplaneUrl, authConfig, last, testCase, ctx.interactions);
356
+ if (shouldStopPendingApprovalPoll(status, ctx)) {
357
+ break;
358
+ }
342
359
  await delayMs(intervalMs);
343
360
  }
344
361
 
345
362
  return {
346
- finalTask: assertTerminalWorkHubTask(last, taskId, timeoutMs, { soft }),
363
+ finalTask: assertTerminalWorkHubTask(last, taskId, timeoutMs, { recordTimeout: true }),
347
364
  timeline,
348
365
  interactions: ctx.interactions
349
366
  };
350
367
  }
351
368
 
352
- async function fetchBusinessResult(dataplaneUrl, authConfig, processExecutionId) {
353
- try {
354
- const workResult = await getWorkExecutionResult(dataplaneUrl, authConfig, processExecutionId, {
355
- requestedDepth: 'business',
356
- format: 'json'
357
- });
358
- return { workResult, workResultError: null };
359
- } catch (error) {
360
- return { workResult: null, workResultError: error.message || String(error) };
361
- }
369
+ async function fetchBusinessResult(dataplaneUrl, authConfig, processExecutionId, options = {}) {
370
+ const { fetchWorkHubResult } = require('./test-runner-debug');
371
+ return fetchWorkHubResult(dataplaneUrl, authConfig, processExecutionId, options);
362
372
  }
363
373
 
364
374
  function buildWorkHubLifecycleResult(roleKey, testCase, started, pollState, peBundle) {
@@ -388,6 +398,38 @@ function buildWorkHubLifecycleResult(roleKey, testCase, started, pollState, peBu
388
398
  };
389
399
  }
390
400
 
401
+ async function finishWorkHubAfterPoll(args) {
402
+ const {
403
+ roleKey,
404
+ testCase,
405
+ started,
406
+ pollState,
407
+ dataplaneUrl,
408
+ authConfig,
409
+ options
410
+ } = args;
411
+ const processExecutionId = extractPeFromTask(pollState.finalTask);
412
+ if (!processExecutionId) {
413
+ throw new Error(`Work Hub task ${started.taskId} finished without processExecutionId.`);
414
+ }
415
+ const { persistRoleAssistantDebugLog } = require('./test-runner-debug');
416
+ const peBundle = {
417
+ processExecutionId,
418
+ ...(await fetchBusinessResult(dataplaneUrl, authConfig, processExecutionId, options))
419
+ };
420
+ await persistRoleAssistantDebugLog(
421
+ roleKey,
422
+ {
423
+ processExecutionId,
424
+ requestedDepth: options && options.debug === true ? 'technical' : 'business',
425
+ workResult: peBundle.workResult,
426
+ workResultError: peBundle.workResultError
427
+ },
428
+ options
429
+ );
430
+ return buildWorkHubLifecycleResult(roleKey, testCase, started, pollState, peBundle);
431
+ }
432
+
391
433
  async function runWorkHubCaseLifecycle(roleKey, testCase, runtimeContext, options = {}) {
392
434
  const { startWorkHubOrSoftClarify } = require('./test-runner-workhub-soft');
393
435
  const dataplaneUrl = runtimeContext?.dataplaneUrl;
@@ -422,15 +464,15 @@ async function runWorkHubCaseLifecycle(roleKey, testCase, runtimeContext, option
422
464
  testCase,
423
465
  options
424
466
  );
425
- const processExecutionId = extractPeFromTask(pollState.finalTask);
426
- if (!processExecutionId) {
427
- throw new Error(`Work Hub task ${started.taskId} finished without processExecutionId.`);
428
- }
429
- const peBundle = {
430
- processExecutionId,
431
- ...(await fetchBusinessResult(dataplaneUrl, authConfig, processExecutionId))
432
- };
433
- return buildWorkHubLifecycleResult(roleKey, testCase, started, pollState, peBundle);
467
+ return finishWorkHubAfterPoll({
468
+ roleKey,
469
+ testCase,
470
+ started,
471
+ pollState,
472
+ dataplaneUrl,
473
+ authConfig,
474
+ options
475
+ });
434
476
  }
435
477
 
436
478
  module.exports = {
@@ -18,11 +18,13 @@ const {
18
18
  getWorkExecutionResult
19
19
  } = require('../api/work.api');
20
20
  const { wantsWorkHubPath, runWorkHubCaseLifecycle } = require('./test-runner-workhub');
21
+ const { wantsSearchPath, runSearchCaseLifecycle } = require('./test-runner-search');
21
22
  const {
22
23
  buildStartIntentPayload,
23
24
  resolveInputObject,
24
25
  resolveInputMessage
25
26
  } = require('./test-runner-start-payload');
27
+ const { pickHumanRespondBody } = require('./test-runner-respond-body');
26
28
  const TERMINAL_STATUSES = new Set(['completed', 'stopped']);
27
29
  const WAITING_STATUS = 'waiting';
28
30
 
@@ -58,6 +60,9 @@ function applyOptionalStringField(payload, value, key) {
58
60
  }
59
61
 
60
62
  function isExecutableRoleAssistantCase(testCase) {
63
+ if (wantsSearchPath(testCase)) {
64
+ return true;
65
+ }
61
66
  const input = resolveInputObject(testCase);
62
67
  if (typeof input.content !== 'undefined') {
63
68
  return true;
@@ -70,6 +75,7 @@ function isExecutableRoleAssistantCase(testCase) {
70
75
 
71
76
  function extractProcessExecutionId(startResponse) {
72
77
  const candidates = [
78
+ startResponse?.work?.processExecutionId,
73
79
  startResponse?.intent?.processExecutionId,
74
80
  startResponse?.processExecutionId,
75
81
  startResponse?.status?.processExecutionId
@@ -107,6 +113,8 @@ function collectWaitMatchTokens(wait) {
107
113
  add(wait.objectRef.name);
108
114
  add(wait.objectRef.type);
109
115
  add(wait.objectRef.id);
116
+ add(wait.objectRef.capabilityKey);
117
+ add(wait.objectRef.resourceType);
110
118
  }
111
119
  if (wait.safeProjection && typeof wait.safeProjection === 'object') {
112
120
  add(wait.safeProjection.capabilityKey);
@@ -193,22 +201,40 @@ function applyWaitVersioningFields(payload, wait) {
193
201
  applyOptionalStringField(payload, wait.requestFingerprint, 'requestFingerprint');
194
202
  }
195
203
 
204
+ function waitIsChoice(wait) {
205
+ const ids = wait && Array.isArray(wait.allowedChoiceIds) ? wait.allowedChoiceIds : [];
206
+ return String((wait && wait.interactionKind) || '').toLowerCase() === 'choice' || ids.length > 0;
207
+ }
208
+
209
+ function choiceIdFromAnswer(answerEntry, respond) {
210
+ if (typeof respond.selectedOptionId === 'string' && respond.selectedOptionId.trim()) {
211
+ return respond.selectedOptionId.trim();
212
+ }
213
+ if (typeof answerEntry?.value === 'string' && answerEntry.value.trim()) {
214
+ return answerEntry.value.trim();
215
+ }
216
+ return '';
217
+ }
218
+
196
219
  function buildAskRespondPayload(answerEntry, wait) {
197
220
  const respond = answerEntry && typeof answerEntry.respond === 'object' && answerEntry.respond
198
221
  ? answerEntry.respond
199
222
  : {};
200
223
  const payload = {
201
224
  respondIdempotencyKey: buildRuntimeId('ra-answer'),
202
- answerType: 'ask',
203
- value: resolveAskRespondValue(respond)
225
+ answerType: 'ask'
204
226
  };
205
- applyOptionalStringField(payload, respond.selectedOptionId, 'selectedOptionId');
206
- applyOptionalStringField(payload, respond.evidenceRef, 'evidenceRef');
227
+ if (waitIsChoice(wait)) {
228
+ applyOptionalStringField(payload, choiceIdFromAnswer(answerEntry, respond), 'selectedOptionId');
229
+ } else {
230
+ payload.value = resolveAskRespondValue(Object.keys(respond).length ? respond : answerEntry);
231
+ applyOptionalStringField(payload, respond.evidenceRef, 'evidenceRef');
232
+ }
207
233
  if (respond.declined === true) {
208
234
  payload.declined = true;
209
235
  }
210
236
  applyWaitVersioningFields(payload, wait);
211
- return payload;
237
+ return pickHumanRespondBody(payload);
212
238
  }
213
239
 
214
240
  function buildApprovalRespondPayload(approvalEntry, wait) {
@@ -224,7 +250,7 @@ function buildApprovalRespondPayload(approvalEntry, wait) {
224
250
  approvalDecision: decision
225
251
  };
226
252
  applyWaitVersioningFields(payload, wait);
227
- return payload;
253
+ return pickHumanRespondBody(payload);
228
254
  }
229
255
 
230
256
  function buildStatusSnapshot(statusRow) {
@@ -243,7 +269,8 @@ function buildRunnerOptions(options = {}) {
243
269
  return {
244
270
  maxStatusPolls: Number.isFinite(maxStatusPolls) && maxStatusPolls > 0 ? maxStatusPolls : 20,
245
271
  statusPollIntervalMs:
246
- Number.isFinite(statusPollIntervalMs) && statusPollIntervalMs >= 0 ? statusPollIntervalMs : 750
272
+ Number.isFinite(statusPollIntervalMs) && statusPollIntervalMs >= 0 ? statusPollIntervalMs : 750,
273
+ debug: options.debug === true
247
274
  };
248
275
  }
249
276
 
@@ -266,6 +293,18 @@ function finalizeWaitingAdvanceStatus(respondResult, continueResult) {
266
293
  : afterRespondStatus;
267
294
  }
268
295
 
296
+ async function continueAfterRespond(dataplaneUrl, authConfig, processExecutionId) {
297
+ try {
298
+ return await continueWorkExecution(dataplaneUrl, authConfig, processExecutionId, {});
299
+ } catch (error) {
300
+ const text = String(error && error.message ? error.message : error);
301
+ if (/already terminal/i.test(text)) {
302
+ return getWorkExecutionStatus(dataplaneUrl, authConfig, processExecutionId);
303
+ }
304
+ throw error;
305
+ }
306
+ }
307
+
269
308
  async function advanceApprovalWaitingExecution(context, approvals, wait) {
270
309
  const { dataplaneUrl, authConfig, processExecutionId, usedApprovalIndexes } = context;
271
310
  const match = findMatchingEntry(approvals, usedApprovalIndexes, wait);
@@ -275,7 +314,7 @@ async function advanceApprovalWaitingExecution(context, approvals, wait) {
275
314
  usedApprovalIndexes.add(match.index);
276
315
  const payload = buildApprovalRespondPayload(match.entry, wait);
277
316
  const respondResult = await respondWorkExecution(dataplaneUrl, authConfig, processExecutionId, payload);
278
- const continueResult = await continueWorkExecution(dataplaneUrl, authConfig, processExecutionId, {});
317
+ const continueResult = await continueAfterRespond(dataplaneUrl, authConfig, processExecutionId);
279
318
  return {
280
319
  status: finalizeWaitingAdvanceStatus(respondResult, continueResult),
281
320
  matched: true,
@@ -293,7 +332,7 @@ async function advanceAskWaitingExecution(context, answers, wait) {
293
332
  usedAnswerIndexes.add(match.index);
294
333
  const payload = buildAskRespondPayload(match.entry, wait);
295
334
  const respondResult = await respondWorkExecution(dataplaneUrl, authConfig, processExecutionId, payload);
296
- const continueResult = await continueWorkExecution(dataplaneUrl, authConfig, processExecutionId, {});
335
+ const continueResult = await continueAfterRespond(dataplaneUrl, authConfig, processExecutionId);
297
336
  return {
298
337
  status: finalizeWaitingAdvanceStatus(respondResult, continueResult),
299
338
  matched: true,
@@ -340,7 +379,11 @@ async function pollCaseExecutionStatus(dataplaneUrl, authConfig, processExecutio
340
379
  type: advanced.interactionType,
341
380
  waitReason: wait.waitReason || wait.answerType || wait.interactionKind || null,
342
381
  matched: advanced.matched === true,
343
- questionKey: wait.questionKey || wait.requestKey || null
382
+ questionKey:
383
+ wait.questionKey ||
384
+ wait.requestKey ||
385
+ (wait.objectRef && wait.objectRef.capabilityKey) ||
386
+ null
344
387
  });
345
388
  if (!advanced.matched || !advanced.status) {
346
389
  break;
@@ -370,6 +413,9 @@ async function runRoleAssistantCaseLifecycle(roleKey, testCase, runtimeContext,
370
413
  throw new Error('Role assistant case runtime requires dataplane auth context.');
371
414
  }
372
415
  const runnerOptions = buildRunnerOptions(options);
416
+ if (wantsSearchPath(testCase)) {
417
+ return runSearchCaseLifecycle(roleKey, testCase, runtimeContext, runnerOptions);
418
+ }
373
419
  if (wantsWorkHubPath(testCase)) {
374
420
  return runWorkHubCaseLifecycle(roleKey, testCase, runtimeContext, runnerOptions);
375
421
  }
@@ -418,11 +464,19 @@ function mergeCaseExecutionIntoLifecycleResult(lifecycleResult, executionResult)
418
464
  task: executionResult?.workResult?.task || null,
419
465
  steps: Array.isArray(executionResult?.workResult?.steps) ? executionResult.workResult.steps : [],
420
466
  workTimeline: executionResult?.timeline || [],
421
- workInteractions: executionResult?.interactions || []
467
+ workInteractions: executionResult?.interactions || [],
468
+ search: executionResult?.search || null,
469
+ skills: executionResult?.skills || null,
470
+ roleRef: executionResult?.roleRef || null
422
471
  };
423
472
  }
424
473
 
425
474
  function lifecycleVerdictFromCaseExecution(executionResult, fallbackVerdict) {
475
+ if (executionResult?.kind === 'search' || executionResult?.kind === 'skills') {
476
+ return Number.isFinite(Number(executionResult.search?.status || executionResult.skills?.status))
477
+ ? VERDICT.VERIFIED
478
+ : VERDICT.FAILED;
479
+ }
426
480
  const statusToken = normalizeToken(executionResult?.finalStatus?.status);
427
481
  if (statusToken === 'completed') {
428
482
  return VERDICT.VERIFIED;
@@ -436,6 +490,7 @@ function lifecycleVerdictFromCaseExecution(executionResult, fallbackVerdict) {
436
490
  module.exports = {
437
491
  isExecutableRoleAssistantCase,
438
492
  buildStartIntentPayload,
493
+ buildRunnerOptions,
439
494
  runRoleAssistantCaseLifecycle,
440
495
  mergeCaseExecutionIntoLifecycleResult,
441
496
  lifecycleVerdictFromCaseExecution