@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
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Offer to install Slack CLI and sign in during channel add.
3
+ *
4
+ * @fileoverview Interactive TTY only — CI / JSON keep remaining steps
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const inquirer = require('inquirer');
10
+ const { isChannelAddInteractive } = require('../channel-add-wizard');
11
+ const { shouldSkipLiveSlackCli, resolveSlackBinary } = require('./cli');
12
+ const {
13
+ isSlackCliInstallerSupported,
14
+ installOfficialSlackCli,
15
+ runSlackLogin
16
+ } = require('./install-cli');
17
+ const { slackProvisioningError } = require('./errors');
18
+
19
+ /**
20
+ * @param {Object} [deps]
21
+ * @returns {boolean}
22
+ */
23
+ function shouldSkipCliOffer(deps = {}) {
24
+ if (typeof deps.confirm === 'function') {
25
+ return false;
26
+ }
27
+ if (typeof deps.slackApi === 'function') {
28
+ return true;
29
+ }
30
+ return shouldSkipLiveSlackCli(deps);
31
+ }
32
+
33
+ /**
34
+ * @param {Object} [options]
35
+ * @param {Object} [deps]
36
+ * @returns {boolean}
37
+ */
38
+ function canOfferSlackCliInstall(options = {}, deps = {}) {
39
+ if (typeof deps.confirm === 'function') {
40
+ return true;
41
+ }
42
+ if (!isSlackCliInstallerSupported()) {
43
+ return false;
44
+ }
45
+ return isChannelAddInteractive(options);
46
+ }
47
+
48
+ /**
49
+ * @param {string} message
50
+ * @param {Object} [deps]
51
+ * @returns {Promise<boolean>}
52
+ */
53
+ async function confirmYesNo(message, deps = {}) {
54
+ if (typeof deps.confirm === 'function') {
55
+ return deps.confirm(message);
56
+ }
57
+ const answers = await inquirer.prompt([
58
+ {
59
+ type: 'confirm',
60
+ name: 'ok',
61
+ message,
62
+ default: true
63
+ }
64
+ ]);
65
+ return answers.ok === true;
66
+ }
67
+
68
+ /**
69
+ * @param {Object} [deps]
70
+ * @returns {Promise<void>}
71
+ */
72
+ async function offerInstallAndLogin(deps = {}) {
73
+ const accepted = await confirmYesNo('Install Slack CLI now?', deps);
74
+ if (!accepted) {
75
+ throw slackProvisioningError('Slack CLI install declined.', 'SLACK_CLI_MISSING');
76
+ }
77
+ await installOfficialSlackCli(deps);
78
+ const signIn = await confirmYesNo('Sign in to Slack now?', deps);
79
+ if (signIn) {
80
+ await runSlackLogin(deps);
81
+ }
82
+ }
83
+
84
+ /**
85
+ * Prompt + install Slack CLI when missing, then continue channel add.
86
+ * @param {Object} [options]
87
+ * @param {Object} [deps]
88
+ * @returns {Promise<void>}
89
+ */
90
+ async function ensureSlackCliReady(options = {}, deps = {}) {
91
+ if (shouldSkipCliOffer(deps)) {
92
+ return;
93
+ }
94
+ const existing = await resolveSlackBinary(deps);
95
+ if (existing) {
96
+ return;
97
+ }
98
+ if (!canOfferSlackCliInstall(options, deps)) {
99
+ throw slackProvisioningError(
100
+ 'Slack CLI (`slack`) is not installed or not on PATH.',
101
+ 'SLACK_CLI_MISSING'
102
+ );
103
+ }
104
+ await offerInstallAndLogin(deps);
105
+ }
106
+
107
+ module.exports = {
108
+ shouldSkipCliOffer,
109
+ canOfferSlackCliInstall,
110
+ confirmYesNo,
111
+ offerInstallAndLogin,
112
+ ensureSlackCliReady
113
+ };
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Slack workspace member list + email-join helpers for channel onboard.
3
+ *
4
+ * @fileoverview Skip bots; never print emails or Slack user ids on TTY
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const { listUsers } = require('../../api/users.api');
10
+ const { extractUserListItems } = require('../../identity/resolve-user-id');
11
+ const { runSlackApi } = require('./cli');
12
+ const { slackProvisioningError } = require('./errors');
13
+
14
+ /**
15
+ * @param {Object} member
16
+ * @returns {'skip'|'unmatched'|'candidate'}
17
+ */
18
+ function classifySlackMember(member) {
19
+ if (!member || member.deleted === true) {
20
+ return 'skip';
21
+ }
22
+ if (member.is_bot === true || member.is_app_user === true || member.id === 'USLACKBOT') {
23
+ return 'skip';
24
+ }
25
+ if (typeof member.id !== 'string' || !member.id.trim()) {
26
+ return 'skip';
27
+ }
28
+ const email = member.profile && String(member.profile.email || '').trim();
29
+ if (!email || !email.includes('@')) {
30
+ return 'unmatched';
31
+ }
32
+ return 'candidate';
33
+ }
34
+
35
+ /**
36
+ * @param {Object} [deps]
37
+ * @returns {Promise<Object[]>}
38
+ */
39
+ async function listSlackWorkspaceMembers(deps = {}) {
40
+ const members = [];
41
+ let cursor = '';
42
+ for (let page = 0; page < 50; page += 1) {
43
+ const payload = { limit: 200 };
44
+ if (cursor) {
45
+ payload.cursor = cursor;
46
+ }
47
+ const body = await runSlackApi('users.list', payload, deps);
48
+ if (!body || body.ok !== true) {
49
+ throw slackProvisioningError('Slack users.list failed.', 'SLACK_API');
50
+ }
51
+ members.push(...(Array.isArray(body.members) ? body.members : []));
52
+ cursor = (body.response_metadata && body.response_metadata.next_cursor) || '';
53
+ if (!cursor) {
54
+ break;
55
+ }
56
+ }
57
+ return members;
58
+ }
59
+
60
+ /**
61
+ * @async
62
+ * @param {string} controllerUrl
63
+ * @param {Object} authConfig
64
+ * @param {string} email
65
+ * @returns {Promise<Object|null>}
66
+ */
67
+ async function lookupUniqueUserByEmail(controllerUrl, authConfig, email) {
68
+ const value = String(email || '').trim();
69
+ if (!value) {
70
+ return null;
71
+ }
72
+ const listed = await listUsers(controllerUrl, authConfig, {
73
+ filter: `email:eq:${value}`,
74
+ pageSize: 2,
75
+ page: 1
76
+ });
77
+ if (!listed || listed.success === false) {
78
+ return null;
79
+ }
80
+ const lower = value.toLowerCase();
81
+ const matches = extractUserListItems(listed).filter(
82
+ (user) => String(user.email || '').toLowerCase() === lower && user.id
83
+ );
84
+ return matches.length === 1 ? matches[0] : null;
85
+ }
86
+
87
+ /**
88
+ * @async
89
+ * @param {Object[]} members
90
+ * @param {{ controllerUrl: string, authConfig: Object }} ctx
91
+ * @param {Object} [deps]
92
+ * @returns {Promise<{ items: Object[], unmatched: number }>}
93
+ */
94
+ async function matchSlackMembersToUsers(members, ctx, deps = {}) {
95
+ const lookup = deps.lookupUniqueUserByEmail || lookupUniqueUserByEmail;
96
+ const items = [];
97
+ let unmatched = 0;
98
+ for (const member of members || []) {
99
+ const kind = classifySlackMember(member);
100
+ if (kind === 'skip') {
101
+ continue;
102
+ }
103
+ if (kind !== 'candidate') {
104
+ unmatched += 1;
105
+ continue;
106
+ }
107
+ const user = await lookup(ctx.controllerUrl, ctx.authConfig, member.profile.email.trim());
108
+ if (user && user.id) {
109
+ items.push({ externalUserId: member.id, platformUserId: user.id });
110
+ } else {
111
+ unmatched += 1;
112
+ }
113
+ }
114
+ return { items, unmatched };
115
+ }
116
+
117
+ module.exports = {
118
+ classifySlackMember,
119
+ listSlackWorkspaceMembers,
120
+ lookupUniqueUserByEmail,
121
+ matchSlackMembersToUsers
122
+ };
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Optional Slack user onboard after channel add (email join).
3
+ *
4
+ * @fileoverview One yes/no question; no member dump on default TTY
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const { isChannelAddInteractive } = require('../channel-add-wizard');
10
+ const { upsertChannelIdentityMappings } = require('../../api/channel-identity.api');
11
+ const { confirmYesNo } = require('./offer-cli');
12
+ const { listSlackWorkspaceMembers, matchSlackMembersToUsers } = require('./onboard-members');
13
+
14
+ /**
15
+ * @param {Object} [options]
16
+ * @returns {boolean}
17
+ */
18
+ function shouldSkipOnboard(options = {}) {
19
+ if (options.dryRun === true) {
20
+ return true;
21
+ }
22
+ if (options.onboardUsers === false) {
23
+ return true;
24
+ }
25
+ return false;
26
+ }
27
+
28
+ /**
29
+ * @param {Object} [options]
30
+ * @param {Object} [deps]
31
+ * @returns {Promise<boolean>}
32
+ */
33
+ async function shouldOnboardUsers(options = {}, deps = {}) {
34
+ if (shouldSkipOnboard(options)) {
35
+ return false;
36
+ }
37
+ if (options.onboardUsers === true) {
38
+ return true;
39
+ }
40
+ if (!isChannelAddInteractive(options)) {
41
+ return false;
42
+ }
43
+ return confirmYesNo('Onboard users?', deps);
44
+ }
45
+
46
+ /**
47
+ * @param {number} unmatched
48
+ * @returns {string|null}
49
+ */
50
+ function unmatchedRemainingStep(unmatched) {
51
+ const count = Number(unmatched) || 0;
52
+ if (count <= 0) {
53
+ return null;
54
+ }
55
+ return `${count} Slack users still use Link account (no email match)`;
56
+ }
57
+
58
+ /**
59
+ * @param {Object} params
60
+ * @param {Object} [deps]
61
+ * @returns {Promise<{ ran: boolean, linked: number, unmatched: number }>}
62
+ */
63
+ async function maybeOnboardSlackUsers(params = {}, deps = {}) {
64
+ const options = params.options || {};
65
+ const ctx = params.ctx || {};
66
+ if (ctx.slackConnected !== true && options.onboardUsers !== true) {
67
+ return { ran: false, linked: 0, unmatched: 0 };
68
+ }
69
+ if (!(await shouldOnboardUsers(options, deps))) {
70
+ return { ran: false, linked: 0, unmatched: 0 };
71
+ }
72
+ const members = await listSlackWorkspaceMembers(deps);
73
+ const matched = await matchSlackMembersToUsers(members, ctx, deps);
74
+ if (matched.items.length > 0) {
75
+ const upsert = deps.upsertChannelIdentityMappings || upsertChannelIdentityMappings;
76
+ await upsert(ctx.dataplaneUrl, ctx.authConfig, {
77
+ sourceChannel: 'slack',
78
+ items: matched.items
79
+ });
80
+ }
81
+ return { ran: true, linked: matched.items.length, unmatched: matched.unmatched };
82
+ }
83
+
84
+ module.exports = {
85
+ shouldSkipOnboard,
86
+ shouldOnboardUsers,
87
+ unmatchedRemainingStep,
88
+ maybeOnboardSlackUsers
89
+ };
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Persist non-secret Slack app / workspace IDs only.
3
+ *
4
+ * @fileoverview Never store bot tokens or signing secrets
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const path = require('path');
10
+ const fs = require('../../internal/fs-real-sync');
11
+ const { STATE_FILE, STATE_KIND, SECRET_KEY_RE } = require('./constants');
12
+ const { slackProvisioningError } = require('./errors');
13
+
14
+ /**
15
+ * @param {string} projectRoot
16
+ * @returns {string}
17
+ */
18
+ function provisioningStatePath(projectRoot) {
19
+ const root = projectRoot || process.cwd();
20
+ return path.join(root, 'dist', 'channels', 'slack', STATE_FILE);
21
+ }
22
+
23
+ /**
24
+ * @param {Object} record
25
+ * @returns {void}
26
+ */
27
+ function assertNoSecrets(record) {
28
+ const keys = record && typeof record === 'object' ? Object.keys(record) : [];
29
+ const hit = keys.find((key) => SECRET_KEY_RE.test(key));
30
+ if (hit) {
31
+ throw slackProvisioningError(`Refusing to persist Slack secret field "${hit}".`, 'SECRET');
32
+ }
33
+ const blob = JSON.stringify(record || {});
34
+ if (/xox[baprs]-/i.test(blob)) {
35
+ throw slackProvisioningError('Refusing to persist a Slack token value.', 'SECRET');
36
+ }
37
+ }
38
+
39
+ /**
40
+ * @param {string} projectRoot
41
+ * @returns {Object|null}
42
+ */
43
+ function readProvisioningState(projectRoot) {
44
+ const filePath = provisioningStatePath(projectRoot);
45
+ if (!fs.existsSync(filePath)) {
46
+ return null;
47
+ }
48
+ try {
49
+ const parsed = JSON.parse(fs.readFileSync(filePath, 'utf8'));
50
+ if (!parsed || parsed.kind !== STATE_KIND) {
51
+ return null;
52
+ }
53
+ assertNoSecrets(parsed);
54
+ return parsed;
55
+ } catch {
56
+ return null;
57
+ }
58
+ }
59
+
60
+ /**
61
+ * @param {Object|null} state
62
+ * @returns {boolean}
63
+ */
64
+ function hasProvenAppIdentity(state) {
65
+ return Boolean(state && typeof state.appId === 'string' && state.appId.trim());
66
+ }
67
+
68
+ /**
69
+ * @param {string} projectRoot
70
+ * @param {Object} state
71
+ * @returns {void}
72
+ */
73
+ function writeProvisioningState(projectRoot, state) {
74
+ const record = {
75
+ kind: STATE_KIND,
76
+ environment: state.environment,
77
+ appId: state.appId,
78
+ clientId: state.clientId || null,
79
+ teamId: state.teamId || null,
80
+ botId: state.botId || null,
81
+ secretsStored: state.secretsStored === true
82
+ };
83
+ assertNoSecrets(record);
84
+ const filePath = provisioningStatePath(projectRoot);
85
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
86
+ fs.writeFileSync(filePath, `${JSON.stringify(record, null, 2)}\n`, 'utf8');
87
+ }
88
+
89
+ module.exports = {
90
+ provisioningStatePath,
91
+ readProvisioningState,
92
+ writeProvisioningState,
93
+ hasProvenAppIdentity,
94
+ assertNoSecrets
95
+ };
@@ -0,0 +1,158 @@
1
+ /**
2
+ * Slack post-create consent URLs (app, Install App, workspace approve).
3
+ *
4
+ * @fileoverview App id and team id are public; never include client_secret
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ /**
10
+ * @param {string} [appId]
11
+ * @returns {string}
12
+ */
13
+ function slackAppRootUrl(appId) {
14
+ if (typeof appId !== 'string' || !appId.trim()) {
15
+ return '';
16
+ }
17
+ return `https://api.slack.com/apps/${encodeURIComponent(appId.trim())}`;
18
+ }
19
+
20
+ /**
21
+ * @param {string} [appId]
22
+ * @param {string} page
23
+ * @returns {string}
24
+ */
25
+ function slackAppPageUrl(appId, page) {
26
+ const root = slackAppRootUrl(appId);
27
+ if (!root || typeof page !== 'string' || !page.trim()) {
28
+ return root;
29
+ }
30
+ return `${root}/${page}`;
31
+ }
32
+
33
+ /**
34
+ * @param {string} [appId]
35
+ * @returns {string}
36
+ */
37
+ function slackAppGeneralUrl(appId) {
38
+ return slackAppPageUrl(appId, 'general');
39
+ }
40
+
41
+ /**
42
+ * Workspace install URL that actually adds the app (`/install-on-team`).
43
+ * @param {string} [appId]
44
+ * @returns {string}
45
+ */
46
+ function slackAppInstallOnTeamUrl(appId) {
47
+ return slackAppPageUrl(appId, 'install-on-team');
48
+ }
49
+
50
+ /**
51
+ * Slack workspace admin approval for this app.
52
+ * @param {string} [teamId]
53
+ * @param {string} [appId]
54
+ * @returns {string}
55
+ */
56
+ function buildSlackWorkspaceApproveUrl(teamId, appId) {
57
+ if (typeof teamId !== 'string' || !teamId.trim()) {
58
+ return '';
59
+ }
60
+ if (typeof appId !== 'string' || !appId.trim()) {
61
+ return '';
62
+ }
63
+ const team = encodeURIComponent(teamId.trim());
64
+ const app = encodeURIComponent(appId.trim());
65
+ return `https://app.slack.com/apps-manage/${team}/integrations/profile/${app}/permissions`;
66
+ }
67
+
68
+ /**
69
+ * @param {string} [url]
70
+ * @returns {string}
71
+ */
72
+ function clientIdFromAuthorizeUrl(url) {
73
+ if (typeof url !== 'string' || !url.includes('client_id=')) {
74
+ return '';
75
+ }
76
+ try {
77
+ return String(new URL(url).searchParams.get('client_id') || '').trim();
78
+ } catch {
79
+ return '';
80
+ }
81
+ }
82
+
83
+ /**
84
+ * @param {Object} [captured]
85
+ * @returns {string}
86
+ */
87
+ function pickSlackClientId(captured) {
88
+ const credentials = (captured && captured.credentials) || {};
89
+ const nested = captured && captured.data && typeof captured.data === 'object' ? captured.data : {};
90
+ const candidates = [
91
+ captured && captured.clientId,
92
+ captured && captured.client_id,
93
+ credentials.clientId,
94
+ credentials.client_id,
95
+ nested.clientId,
96
+ nested.client_id
97
+ ];
98
+ const direct = candidates.find((value) => typeof value === 'string' && value.trim());
99
+ if (direct) {
100
+ return String(direct).trim();
101
+ }
102
+ return clientIdFromAuthorizeUrl(
103
+ (captured && captured.oauth_authorize_url) || credentials.oauth_authorize_url
104
+ );
105
+ }
106
+
107
+ /**
108
+ * @param {Object} [captured]
109
+ * @returns {string}
110
+ */
111
+ function pickSlackTeamId(captured) {
112
+ const credentials = (captured && captured.credentials) || {};
113
+ const candidates = [
114
+ captured && captured.teamId,
115
+ captured && captured.team_id,
116
+ credentials.teamId,
117
+ credentials.team_id
118
+ ];
119
+ const hit = candidates.find((value) => typeof value === 'string' && value.trim());
120
+ return hit ? String(hit).trim() : '';
121
+ }
122
+
123
+ /**
124
+ * @param {Object} [captured]
125
+ * @returns {{ slackAppSettingsUrl: string, slackInstallAppUrl: string,
126
+ * slackWorkspaceApproveUrl: string }}
127
+ */
128
+ function slackConsentUrls(captured) {
129
+ const appId = captured && captured.appId;
130
+ return {
131
+ slackAppSettingsUrl: slackAppRootUrl(appId),
132
+ slackInstallAppUrl: slackAppInstallOnTeamUrl(appId),
133
+ slackWorkspaceApproveUrl: buildSlackWorkspaceApproveUrl(pickSlackTeamId(captured), appId)
134
+ };
135
+ }
136
+
137
+ /**
138
+ * @param {{ storedSigningSecret?: boolean }} [stored]
139
+ * @returns {string[]}
140
+ */
141
+ function slackConsentRemaining(stored) {
142
+ const steps = ['Upload your logo (Basic Information)', 'Activate the application'];
143
+ if (!stored || stored.storedSigningSecret !== true) {
144
+ steps.push('Store the signing secret in Authentication (Slack cannot re-read it after create)');
145
+ }
146
+ return steps;
147
+ }
148
+
149
+ module.exports = {
150
+ slackAppRootUrl,
151
+ slackAppGeneralUrl,
152
+ slackAppInstallOnTeamUrl,
153
+ buildSlackWorkspaceApproveUrl,
154
+ pickSlackClientId,
155
+ pickSlackTeamId,
156
+ slackConsentUrls,
157
+ slackConsentRemaining
158
+ };
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Ensure `curl` is on PATH for Slack CLI install.sh (Node shim when missing).
3
+ */
4
+
5
+ 'use strict';
6
+
7
+ const { execFile } = require('child_process');
8
+ const fs = require('fs');
9
+ const os = require('os');
10
+ const path = require('path');
11
+ const { promisify } = require('util');
12
+
13
+ const execFileAsync = promisify(execFile);
14
+
15
+ async function curlExists(env) {
16
+ try {
17
+ await execFileAsync('curl', ['--version'], { env, timeout: 5000 });
18
+ return true;
19
+ } catch {
20
+ return false;
21
+ }
22
+ }
23
+
24
+ function writeCurlShim(dir) {
25
+ const source = path.join(__dirname, 'curl-shim.js');
26
+ if (!fs.existsSync(source)) {
27
+ throw new Error(`Slack CLI curl shim missing: ${source}`);
28
+ }
29
+ const runtime = path.join(dir, 'curl-shim.js');
30
+ fs.copyFileSync(source, runtime);
31
+ const wrapper = `#!/bin/sh\nexec "${process.execPath}" "${runtime}" "$@"\n`;
32
+ fs.writeFileSync(path.join(dir, 'curl'), wrapper, { mode: 0o755 });
33
+ }
34
+
35
+ /**
36
+ * @param {NodeJS.ProcessEnv} [env]
37
+ * @param {{ curlExists?: Function }} [deps]
38
+ * @returns {Promise<NodeJS.ProcessEnv>}
39
+ */
40
+ async function withCurlOnPath(env = process.env, deps = {}) {
41
+ const exists = deps.curlExists || curlExists;
42
+ if (await exists(env)) {
43
+ return env;
44
+ }
45
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'aifabrix-curl-'));
46
+ writeCurlShim(dir);
47
+ return {
48
+ ...env,
49
+ PATH: `${dir}${path.delimiter}${env.PATH || ''}`
50
+ };
51
+ }
52
+
53
+ module.exports = { curlExists, withCurlOnPath };