@aifabrix/builder 2.53.1 → 2.54.1

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 (321) hide show
  1. package/bin/aifabrix.js +2 -2
  2. package/lib/api/assistants.api.js +8 -5
  3. package/lib/api/channel-identity.api.js +41 -0
  4. package/lib/api/evidence-authoring.api.js +5 -1
  5. package/lib/api/evidence.api.js +2 -0
  6. package/lib/api/types/evidence.types.js +2 -0
  7. package/lib/api/work-search.api.js +136 -0
  8. package/lib/channels/add-channel.js +163 -126
  9. package/lib/channels/approval-guides/chatgpt.js +14 -18
  10. package/lib/channels/approval-guides/claude.js +29 -0
  11. package/lib/channels/approval-guides/index.js +88 -22
  12. package/lib/channels/approval-guides/mcp-client.js +27 -0
  13. package/lib/channels/approval-guides/microsoft-copilot.js +52 -3
  14. package/lib/channels/approval-guides/slack.js +10 -10
  15. package/lib/channels/approval-guides/teams-bot.js +8 -12
  16. package/lib/channels/channel-add-continuations.js +91 -0
  17. package/lib/channels/channel-add-ensure.js +124 -27
  18. package/lib/channels/channel-add-existing.js +160 -28
  19. package/lib/channels/channel-add-failure.js +60 -0
  20. package/lib/channels/channel-add-remaining.js +486 -0
  21. package/lib/channels/channel-add-tty.js +190 -0
  22. package/lib/channels/channel-add-wizard-config.js +138 -0
  23. package/lib/channels/channel-add-wizard.js +250 -0
  24. package/lib/channels/channel-artifact-generator.js +27 -13
  25. package/lib/channels/channel-cardinality.js +83 -0
  26. package/lib/channels/channel-catalog-icon.js +45 -0
  27. package/lib/channels/channel-cli-instructions.js +75 -0
  28. package/lib/channels/channel-configuration-map.js +213 -0
  29. package/lib/channels/channel-credential.js +11 -14
  30. package/lib/channels/channel-definition-project.js +101 -0
  31. package/lib/channels/channel-definition-registry.js +154 -0
  32. package/lib/channels/channel-description.js +59 -2
  33. package/lib/channels/channel-discovery.js +16 -2
  34. package/lib/channels/channel-external-system.js +86 -9
  35. package/lib/channels/channel-install-envelope-actions.js +88 -0
  36. package/lib/channels/channel-install-envelope-microsoft.js +155 -0
  37. package/lib/channels/channel-install-envelope.js +356 -0
  38. package/lib/channels/channel-install-help-md.js +172 -0
  39. package/lib/channels/channel-install-http-payload.js +62 -0
  40. package/lib/channels/channel-install-inventory.js +115 -0
  41. package/lib/channels/channel-install-profiles.js +90 -0
  42. package/lib/channels/channel-instance-collision.js +118 -0
  43. package/lib/channels/channel-instance-key.js +100 -0
  44. package/lib/channels/channel-instance-materialize.js +240 -0
  45. package/lib/channels/channel-integration-generator.js +16 -9
  46. package/lib/channels/channel-integration-template.js +101 -22
  47. package/lib/channels/channel-inventory-fetch.js +79 -0
  48. package/lib/channels/channel-oauth-preflight.js +104 -0
  49. package/lib/channels/channel-package-version.js +76 -0
  50. package/lib/channels/channel-predefined-client.js +154 -0
  51. package/lib/channels/channel-probe.js +7 -2
  52. package/lib/channels/channel-runtime-resolver.js +180 -72
  53. package/lib/channels/channel-status-display.js +86 -16
  54. package/lib/channels/channel-targets.js +106 -92
  55. package/lib/channels/chatgpt-callback.js +318 -0
  56. package/lib/channels/chatgpt-channel-add.js +229 -0
  57. package/lib/channels/chatgpt-preflight.js +396 -0
  58. package/lib/channels/chatgpt-runtime-contract.js +17 -0
  59. package/lib/channels/chatgpt-setup-values.js +124 -0
  60. package/lib/channels/claude-callback.js +67 -0
  61. package/lib/channels/claude-channel-add.js +254 -0
  62. package/lib/channels/claude-runtime-contract.js +40 -0
  63. package/lib/channels/claude-runtime.js +58 -0
  64. package/lib/channels/claude-setup-values.js +89 -0
  65. package/lib/channels/mcp-client/config-merge.js +148 -0
  66. package/lib/channels/mcp-client/ensure-client.js +231 -0
  67. package/lib/channels/mcp-client/paths.js +53 -0
  68. package/lib/channels/mcp-client/profiles.js +122 -0
  69. package/lib/channels/mcp-client/redirect-uris.js +99 -0
  70. package/lib/channels/mcp-client/runtime.js +59 -0
  71. package/lib/channels/mcp-client-channel-add.js +186 -0
  72. package/lib/channels/microsoft-copilot-channel-add.js +117 -7
  73. package/lib/channels/microsoft-copilot-entra-identifier-uris.js +187 -0
  74. package/lib/channels/microsoft-copilot-entra-sso-form.js +106 -18
  75. package/lib/channels/microsoft-copilot-entra-sso.js +31 -2
  76. package/lib/channels/microsoft-copilot-package-prior.js +107 -0
  77. package/lib/channels/microsoft-copilot-package.js +29 -28
  78. package/lib/channels/microsoft-provisioning/a365.js +80 -0
  79. package/lib/channels/microsoft-provisioning/auth-config.js +240 -0
  80. package/lib/channels/microsoft-provisioning/auth.js +179 -0
  81. package/lib/channels/microsoft-provisioning/cli.js +71 -0
  82. package/lib/channels/microsoft-provisioning/constants.js +75 -0
  83. package/lib/channels/microsoft-provisioning/errors.js +117 -0
  84. package/lib/channels/microsoft-provisioning/index.js +55 -0
  85. package/lib/channels/microsoft-provisioning/install-atk.js +158 -0
  86. package/lib/channels/microsoft-provisioning/install-teams.js +115 -0
  87. package/lib/channels/microsoft-provisioning/login-portal-device.js +236 -0
  88. package/lib/channels/microsoft-provisioning/login-portal-parse.js +71 -0
  89. package/lib/channels/microsoft-provisioning/login-portal-teams.js +193 -0
  90. package/lib/channels/microsoft-provisioning/login-portal.js +230 -0
  91. package/lib/channels/microsoft-provisioning/persist.js +110 -0
  92. package/lib/channels/microsoft-provisioning/teams-bot-args.js +119 -0
  93. package/lib/channels/microsoft-provisioning/teams-bot-controller.js +123 -0
  94. package/lib/channels/microsoft-provisioning/teams-bot-parse.js +134 -0
  95. package/lib/channels/microsoft-provisioning/teams-bot-persist.js +113 -0
  96. package/lib/channels/microsoft-provisioning/teams-bot-provision.js +234 -0
  97. package/lib/channels/microsoft-provisioning/teams-bot-secrets.js +45 -0
  98. package/lib/channels/microsoft-provisioning/teams-cli.js +82 -0
  99. package/lib/channels/runtime-tool-catalog.js +5 -2
  100. package/lib/channels/slack-channel-add-portal.js +130 -0
  101. package/lib/channels/slack-channel-add-tty-auth.js +95 -0
  102. package/lib/channels/slack-channel-add.js +258 -0
  103. package/lib/channels/slack-provisioning/apps.js +181 -0
  104. package/lib/channels/slack-provisioning/auth-store.js +110 -0
  105. package/lib/channels/slack-provisioning/auth-ticket.js +185 -0
  106. package/lib/channels/slack-provisioning/auth.js +115 -0
  107. package/lib/channels/slack-provisioning/callbacks.js +41 -0
  108. package/lib/channels/slack-provisioning/cli.js +226 -0
  109. package/lib/channels/slack-provisioning/constants.js +37 -0
  110. package/lib/channels/slack-provisioning/credentials.js +169 -0
  111. package/lib/channels/slack-provisioning/curl-shim.js +132 -0
  112. package/lib/channels/slack-provisioning/developer-install.js +118 -0
  113. package/lib/channels/slack-provisioning/env-file.js +120 -0
  114. package/lib/channels/slack-provisioning/errors.js +47 -0
  115. package/lib/channels/slack-provisioning/go-ca-bundle.js +137 -0
  116. package/lib/channels/slack-provisioning/index.js +250 -0
  117. package/lib/channels/slack-provisioning/install-cli.js +323 -0
  118. package/lib/channels/slack-provisioning/manifest.js +89 -0
  119. package/lib/channels/slack-provisioning/oauth-lock.js +33 -0
  120. package/lib/channels/slack-provisioning/offer-cli.js +113 -0
  121. package/lib/channels/slack-provisioning/onboard-members.js +122 -0
  122. package/lib/channels/slack-provisioning/onboard.js +89 -0
  123. package/lib/channels/slack-provisioning/persist.js +95 -0
  124. package/lib/channels/slack-provisioning/remaining-urls.js +158 -0
  125. package/lib/channels/slack-provisioning/with-curl-on-path.js +48 -0
  126. package/lib/channels/teams-bot-channel-add.js +94 -0
  127. package/lib/channels/vendor-dataplane-url.js +249 -0
  128. package/lib/cli/setup-certification.help.js +2 -0
  129. package/lib/cli/setup-external-system-help.js +2 -0
  130. package/lib/cli/setup-external-system.js +1 -1
  131. package/lib/commands/channel-add-help.js +366 -0
  132. package/lib/commands/channel-add-setup.js +162 -80
  133. package/lib/commands/channel-configure.js +118 -0
  134. package/lib/commands/channel.js +10 -1
  135. package/lib/commands/governance-upload-external.js +6 -3
  136. package/lib/commands/lifecycle-command-action.js +2 -5
  137. package/lib/commands/lifecycle-external.js +93 -21
  138. package/lib/commands/repair-datasource-test-payload.js +4 -2
  139. package/lib/commands/repair-datasource-webhooks-sync-bridge.js +23 -2
  140. package/lib/commands/repair-datasource.js +3 -0
  141. package/lib/commands/repair-external-run.js +59 -25
  142. package/lib/commands/repair-openapi-rest-runtime.js +127 -0
  143. package/lib/commands/repair-orchestration-tag-merge.js +339 -0
  144. package/lib/commands/repair-rbac-catalog-defaults.js +96 -0
  145. package/lib/commands/repair-rbac-platform-preset.js +26 -15
  146. package/lib/commands/repair-rbac-reader-roles.js +8 -21
  147. package/lib/commands/repair-rbac.js +10 -34
  148. package/lib/commands/repair-system-permissions.js +24 -22
  149. package/lib/commands/role-assistant-test-output.js +14 -0
  150. package/lib/commands/role-assistant.js +59 -21
  151. package/lib/commands/test-e2e-external.js +148 -21
  152. package/lib/commands/upload-credential-push-log.js +2 -1
  153. package/lib/commands/upload-publish-context.js +1 -1
  154. package/lib/commands/upload-role-assistant-shell.js +124 -0
  155. package/lib/commands/upload-sidecar-followups.js +6 -3
  156. package/lib/commands/upload.js +18 -3
  157. package/lib/core/secrets-docker-env.js +4 -1
  158. package/lib/core/secrets-env-content.js +17 -3
  159. package/lib/datasource/capability/capability-manifest.js +0 -3
  160. package/lib/datasource/capability/copy-test-payload.js +3 -0
  161. package/lib/external-system/deploy-helpers.js +26 -1
  162. package/lib/external-system/deploy.js +10 -6
  163. package/lib/external-system/download-helpers.js +29 -2
  164. package/lib/external-system/download-role-assistant.js +83 -4
  165. package/lib/external-system/download.js +40 -30
  166. package/lib/external-system/sync-deploy-manifest.js +3 -2
  167. package/lib/external-system/upload-identity.js +42 -0
  168. package/lib/generator/index.js +19 -15
  169. package/lib/generator/split.js +13 -2
  170. package/lib/lifecycle/role-assistant-governance.js +146 -0
  171. package/lib/lifecycle/scenario-upload.js +181 -30
  172. package/lib/programmatic/builder-api-cors.js +143 -0
  173. package/lib/programmatic/builder-api-request.js +6 -0
  174. package/lib/programmatic/builder-api-route-dispatch.js +56 -42
  175. package/lib/programmatic/builder-api-server.js +8 -1
  176. package/lib/programmatic/capability-registry.js +54 -0
  177. package/lib/programmatic/channel-install-help-resolve.js +359 -0
  178. package/lib/programmatic/channel-install-session.js +218 -0
  179. package/lib/programmatic/help-content/channel-onboarding.md +2 -0
  180. package/lib/programmatic/help-content/cip-overview.md +3 -1
  181. package/lib/programmatic/http-raw-response.js +62 -0
  182. package/lib/programmatic/openapi-channel-install-bindings.js +179 -0
  183. package/lib/programmatic/openapi-channel-install-schemas.js +286 -0
  184. package/lib/programmatic/openapi-component-schemas.js +18 -1
  185. package/lib/programmatic/openapi-description-enricher.js +3 -1
  186. package/lib/programmatic/openapi-descriptions.js +74 -3
  187. package/lib/programmatic/openapi-envelope-examples.js +117 -0
  188. package/lib/programmatic/openapi-operation-bindings.js +4 -1
  189. package/lib/programmatic/openapi-schema-descriptions-channel.js +316 -0
  190. package/lib/programmatic/openapi-spec.js +12 -8
  191. package/lib/programmatic/platform-rbac-catalog.js +36 -18
  192. package/lib/programmatic/route-handler-map.js +51 -1
  193. package/lib/programmatic/route-handlers-context.js +2 -1
  194. package/lib/programmatic/run-auth-permissions.js +54 -0
  195. package/lib/programmatic/run-channel-catalog.js +196 -0
  196. package/lib/programmatic/run-channel-install-artifacts.js +137 -0
  197. package/lib/programmatic/run-channel-install-copilot.js +353 -0
  198. package/lib/programmatic/run-channel-install-options.js +232 -0
  199. package/lib/programmatic/run-channel-install-teams-bot.js +204 -0
  200. package/lib/programmatic/run-channel-install.js +346 -0
  201. package/lib/programmatic/run-channel-package.js +87 -7
  202. package/lib/programmatic/workspace-context.js +2 -0
  203. package/lib/role-assistant/evidence-sync.js +4 -2
  204. package/lib/role-assistant/evidence-validation-issues.js +51 -0
  205. package/lib/role-assistant/knowledge-sync.js +10 -4
  206. package/lib/role-assistant/settings.js +49 -2
  207. package/lib/role-assistant/test-cases-evaluate.js +30 -2
  208. package/lib/role-assistant/test-cases-evidence.js +175 -0
  209. package/lib/role-assistant/test-cases-search.js +229 -0
  210. package/lib/role-assistant/test-cases.js +37 -4
  211. package/lib/role-assistant/test-runner-search.js +149 -0
  212. package/lib/role-assistant/test-runner-workhub-helpers.js +40 -2
  213. package/lib/role-assistant/test-runner-workhub-soft.js +9 -3
  214. package/lib/role-assistant/test-runner-workhub.js +29 -11
  215. package/lib/role-assistant/test-runner.js +16 -1
  216. package/lib/schema/external-datasource.schema.json +112 -18
  217. package/lib/schema/external-system.schema.json +159 -2
  218. package/lib/schema/mcp-client-profile.schema.json +103 -0
  219. package/lib/utils/app-path-resolve.js +4 -0
  220. package/lib/utils/authentication-env-template.js +44 -6
  221. package/lib/utils/credential-secrets-env.js +6 -1
  222. package/lib/utils/env-copy.js +19 -7
  223. package/lib/utils/external-env-template.js +20 -2
  224. package/lib/utils/paths.js +18 -1
  225. package/lib/utils/platform-shell-package.js +69 -0
  226. package/lib/utils/port-resolver.js +50 -1
  227. package/lib/utils/rewrite-name-flag.js +20 -0
  228. package/lib/utils/role-assistant-paths.js +13 -10
  229. package/lib/utils/schema-resolver.js +11 -1
  230. package/lib/utils/secrets-helpers.js +12 -21
  231. package/lib/utils/token-manager.js +10 -5
  232. package/lib/validation/validate.js +40 -0
  233. package/package.json +1 -1
  234. package/templates/README.md +1 -1
  235. package/templates/applications/builder-api/Dockerfile +1 -1
  236. package/templates/applications/builder-api/env.template +7 -0
  237. package/templates/applications/dataplane/application.yaml +6 -5
  238. package/templates/applications/dataplane/env.template +2 -2
  239. package/templates/applications/dataplane/rbac.yaml +7 -2
  240. package/templates/applications/keycloak/Dockerfile +30 -4
  241. package/templates/applications/keycloak/application.yaml +2 -2
  242. package/templates/applications/keycloak/cimd-lenient-parse/AbstractClientIdMetadataDocumentExecutor.java +896 -0
  243. package/templates/applications/keycloak/cimd-lenient-parse/SOURCE.md +19 -0
  244. package/templates/applications/keycloak/env.template +3 -0
  245. package/templates/applications/miso-controller/application.yaml +1 -2
  246. package/templates/applications/miso-controller/env.template +2 -0
  247. package/templates/channels/README.md +5 -5
  248. package/templates/channels/chatgpt/TROUBLESHOOTING.md +51 -0
  249. package/templates/channels/chatgpt/channel.json +59 -0
  250. package/templates/channels/chatgpt/icon.svg +1 -0
  251. package/templates/channels/chatgpt/install.template.md.hbs +20 -95
  252. package/templates/channels/chatgpt/integration/README.md +1 -1
  253. package/templates/channels/chatgpt/integration/application.json +2 -2
  254. package/templates/channels/chatgpt/integration/chatgpt-system.json +49 -4
  255. package/templates/channels/chatgpt/integration/env.template +2 -4
  256. package/templates/channels/chatgpt/integration/rbac.json +13 -0
  257. package/templates/channels/claude/TROUBLESHOOTING.md +41 -0
  258. package/templates/channels/claude/channel.json +59 -0
  259. package/templates/channels/claude/icon.svg +1 -0
  260. package/templates/channels/claude/install.template.md.hbs +21 -0
  261. package/templates/channels/claude/integration/README.md +14 -0
  262. package/templates/channels/claude/integration/application.json +15 -0
  263. package/templates/channels/claude/integration/claude-system.json +59 -0
  264. package/templates/channels/claude/integration/env.template +2 -0
  265. package/templates/channels/claude/integration/rbac.json +13 -0
  266. package/templates/channels/claude/manifest.template.json.hbs +40 -0
  267. package/templates/channels/mcp-client/channel.json +72 -0
  268. package/templates/channels/mcp-client/icon.svg +1 -0
  269. package/templates/channels/mcp-client/install.template.md.hbs +24 -0
  270. package/templates/channels/mcp-client/integration/README.md +13 -0
  271. package/templates/channels/mcp-client/integration/application.json +15 -0
  272. package/templates/channels/mcp-client/integration/env.template +2 -0
  273. package/templates/channels/mcp-client/integration/mcp-client-system.json +72 -0
  274. package/templates/channels/mcp-client/integration/rbac.json +13 -0
  275. package/templates/channels/mcp-client/manifest.template.json.hbs +41 -0
  276. package/templates/channels/mcp-client/profiles/cursor.json +26 -0
  277. package/templates/channels/mcp-client/profiles/github-copilot.json +29 -0
  278. package/templates/channels/mcp-client/profiles/vscode.json +29 -0
  279. package/templates/channels/microsoft-copilot/channel.json +73 -0
  280. package/templates/channels/microsoft-copilot/declarative-agent.template.json.hbs +8 -4
  281. package/templates/channels/microsoft-copilot/entra-sso-registration.template.md.hbs +65 -5
  282. package/templates/channels/microsoft-copilot/icon.svg +1 -0
  283. package/templates/channels/microsoft-copilot/install.template.md.hbs +9 -9
  284. package/templates/channels/microsoft-copilot/integration/README.md +1 -1
  285. package/templates/channels/microsoft-copilot/integration/application.json +2 -2
  286. package/templates/channels/microsoft-copilot/integration/env.template +3 -6
  287. package/templates/channels/microsoft-copilot/integration/microsoft-copilot-system.json +63 -4
  288. package/templates/channels/microsoft-copilot/integration/rbac.json +13 -0
  289. package/templates/channels/microsoft-copilot/oauth-plugin-vault-required.template.md.hbs +5 -5
  290. package/templates/channels/slack/channel.json +223 -0
  291. package/templates/channels/slack/icon.svg +1 -0
  292. package/templates/channels/slack/install.template.md.hbs +36 -28
  293. package/templates/channels/slack/integration/README.md +245 -22
  294. package/templates/channels/slack/integration/application.json +44 -7
  295. package/templates/channels/slack/integration/env.template +15 -6
  296. package/templates/channels/slack/integration/openapi/openapi.json +126 -0
  297. package/templates/channels/slack/integration/rbac.json +84 -0
  298. package/templates/channels/slack/integration/slack-datasource-commands.json +154 -0
  299. package/templates/channels/slack/integration/slack-datasource-conversations.json +28 -3
  300. package/templates/channels/slack/integration/slack-datasource-events.json +154 -0
  301. package/templates/channels/slack/integration/slack-datasource-interactive.json +154 -0
  302. package/templates/channels/slack/integration/slack-datasource-messages.json +40 -2
  303. package/templates/channels/slack/integration/slack-system.json +155 -77
  304. package/templates/channels/slack/manifest.template.json.hbs +5 -2
  305. package/templates/channels/teams-bot/channel.json +161 -0
  306. package/templates/channels/teams-bot/icon.svg +1 -0
  307. package/templates/channels/teams-bot/install.template.md.hbs +12 -13
  308. package/templates/channels/teams-bot/integration/README.md +5 -4
  309. package/templates/channels/teams-bot/integration/application.json +6 -4
  310. package/templates/channels/teams-bot/integration/env.template +5 -4
  311. package/templates/channels/teams-bot/integration/openapi/openapi.json +68 -0
  312. package/templates/channels/teams-bot/integration/rbac.json +21 -0
  313. package/templates/channels/teams-bot/integration/teams-bot-datasource-activities.json +154 -0
  314. package/templates/channels/teams-bot/integration/teams-bot-system.json +128 -23
  315. package/templates/channels/web-embed/channel.json +60 -0
  316. package/templates/channels/web-embed/install.template.md.hbs +1 -1
  317. package/templates/channels/web-embed/integration/README.md +2 -2
  318. package/templates/channels/web-embed/integration/application.json +2 -2
  319. package/templates/channels/web-embed/integration/env.template +1 -1
  320. package/templates/channels/web-embed/integration/rbac.json +13 -0
  321. package/templates/channels/web-embed/integration/web-embed-system.json +50 -4
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Write Slack provisioned secrets into integration .env (plain KV_* values).
3
+ *
4
+ * @fileoverview .env is the local SSOT; dataplane push reads these keys
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const fs = require('fs');
10
+ const path = require('path');
11
+ const { getIntegrationPath } = require('../../utils/paths');
12
+ const {
13
+ systemKeyToKvPrefix,
14
+ securityKeyToVar
15
+ } = require('../../utils/credential-secrets-env-kv');
16
+
17
+ /**
18
+ * @param {unknown} value
19
+ * @returns {string}
20
+ */
21
+ function trimmed(value) {
22
+ return typeof value === 'string' && value.trim() ? value.trim() : '';
23
+ }
24
+
25
+ /**
26
+ * kv://slack/signingSecret → KV_SLACK_SIGNINGSECRET
27
+ * @param {string} kvPath
28
+ * @returns {string}
29
+ */
30
+ function kvPathToEnvVar(kvPath) {
31
+ const pathKey = String(kvPath || '').replace(/^kv:\/\//, '');
32
+ const slash = pathKey.indexOf('/');
33
+ if (slash <= 0) {
34
+ return '';
35
+ }
36
+ const systemKey = pathKey.slice(0, slash);
37
+ const securityKey = pathKey.slice(slash + 1);
38
+ if (!systemKey || !securityKey) {
39
+ return '';
40
+ }
41
+ return `KV_${systemKeyToKvPrefix(systemKey)}_${securityKeyToVar(securityKey)}`;
42
+ }
43
+
44
+ /**
45
+ * @param {Array<{ key: string, value: string }>} items
46
+ * @returns {Object.<string, string>}
47
+ */
48
+ function slackEnvMapFromItems(items) {
49
+ const map = {};
50
+ for (const item of items || []) {
51
+ const envKey = kvPathToEnvVar(item && item.key);
52
+ if (envKey && trimmed(item.value)) {
53
+ map[envKey] = String(item.value).trim();
54
+ }
55
+ }
56
+ return map;
57
+ }
58
+
59
+ /**
60
+ * Catalog HMAC uses kv://slack/…; instance packages still use those KV_SLACK_* names.
61
+ * @param {Object} [ctx]
62
+ * @param {Object} [deps]
63
+ * @returns {string[]}
64
+ */
65
+ function resolveSlackEnvPaths(ctx, deps = {}) {
66
+ const root = trimmed(deps.projectRoot);
67
+ const instanceKey = trimmed(deps.instanceSystemKey || (ctx && ctx.instanceSystemKey));
68
+ const folders = ['slack'];
69
+ if (instanceKey && instanceKey !== 'slack') {
70
+ folders.push(instanceKey);
71
+ }
72
+ return folders.map((folder) => (
73
+ root
74
+ ? path.join(path.resolve(root), 'integration', folder, '.env')
75
+ : path.join(getIntegrationPath(folder), '.env')
76
+ ));
77
+ }
78
+
79
+ /**
80
+ * @param {string} envPath
81
+ * @param {Object.<string, string>} envMap
82
+ * @returns {void}
83
+ */
84
+ function mergeSlackEnvFile(envPath, envMap) {
85
+ const { mergeEnvMapIntoContent } = require('../../core/secrets-env-content');
86
+ fs.mkdirSync(path.dirname(envPath), { recursive: true });
87
+ const existing = fs.existsSync(envPath) ? fs.readFileSync(envPath, 'utf8') : '';
88
+ const merged = mergeEnvMapIntoContent(existing, envMap);
89
+ const withNl = merged.endsWith('\n') ? merged : `${merged}\n`;
90
+ fs.writeFileSync(envPath, withNl, 'utf8');
91
+ }
92
+
93
+ /**
94
+ * @param {Object} [ctx]
95
+ * @param {Array<{ key: string, value: string }>} items
96
+ * @param {Object} [deps]
97
+ * @returns {string[]}
98
+ */
99
+ function writeSlackSecretsEnvFiles(ctx, items, deps = {}) {
100
+ const envMap = slackEnvMapFromItems(items);
101
+ if (Object.keys(envMap).length === 0) {
102
+ return [];
103
+ }
104
+ if (typeof deps.writeSlackEnvFiles === 'function') {
105
+ return deps.writeSlackEnvFiles(envMap) || [];
106
+ }
107
+ const written = [];
108
+ for (const envPath of resolveSlackEnvPaths(ctx, deps)) {
109
+ mergeSlackEnvFile(envPath, envMap);
110
+ written.push(envPath);
111
+ }
112
+ return written;
113
+ }
114
+
115
+ module.exports = {
116
+ kvPathToEnvVar,
117
+ slackEnvMapFromItems,
118
+ resolveSlackEnvPaths,
119
+ writeSlackSecretsEnvFiles
120
+ };
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Normalize Slack provisioning failures without leaking tokens.
3
+ *
4
+ * @fileoverview User-facing Slack adapter errors
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ /**
10
+ * @param {string} message
11
+ * @param {string} [code]
12
+ * @returns {Error}
13
+ */
14
+ function slackProvisioningError(message, code) {
15
+ const error = new Error(message);
16
+ error.code = code || 'SLACK_PROVISIONING';
17
+ return error;
18
+ }
19
+
20
+ /**
21
+ * @param {string} text
22
+ * @returns {string}
23
+ */
24
+ function redactSlackSecrets(text) {
25
+ return String(text)
26
+ .replace(/xox[baprs]-[A-Za-z0-9-]+/g, '[redacted]')
27
+ .replace(/signing[_-]?secret["']?\s*[:=]\s*["']?[^"'\s]+/gi, 'signing_secret=[redacted]');
28
+ }
29
+
30
+ /**
31
+ * @param {unknown} error
32
+ * @returns {Error}
33
+ */
34
+ function wrapSlackCliError(error) {
35
+ const raw = error && error.message ? String(error.message) : String(error);
36
+ const compact = redactSlackSecrets(raw.replace(/\s+/g, ' ').trim()).slice(0, 400);
37
+ return slackProvisioningError(
38
+ `Slack CLI could not complete app provisioning. ${compact}`,
39
+ 'SLACK_CLI'
40
+ );
41
+ }
42
+
43
+ module.exports = {
44
+ slackProvisioningError,
45
+ redactSlackSecrets,
46
+ wrapSlackCliError
47
+ };
@@ -0,0 +1,137 @@
1
+ /**
2
+ * Trust store for the Go Slack CLI (SSL_CERT_FILE is the whole bundle).
3
+ *
4
+ * @fileoverview Do not set SSL_CERT_FILE to NODE_EXTRA_CA_CERTS alone
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const fs = require('fs');
10
+ const path = require('path');
11
+ const tls = require('tls');
12
+
13
+ const SYSTEM_CA_CANDIDATES = [
14
+ '/etc/ssl/certs/ca-certificates.crt',
15
+ '/etc/pki/tls/certs/ca-bundle.crt',
16
+ '/etc/ssl/cert.pem'
17
+ ];
18
+
19
+ /**
20
+ * @param {string[]} filePaths
21
+ * @returns {string}
22
+ */
23
+ function firstExistingFile(filePaths) {
24
+ return filePaths.find((filePath) => filePath && fs.existsSync(filePath)) || '';
25
+ }
26
+
27
+ /**
28
+ * @returns {string}
29
+ */
30
+ function systemCaBundlePath() {
31
+ return firstExistingFile(SYSTEM_CA_CANDIDATES);
32
+ }
33
+
34
+ /**
35
+ * @param {NodeJS.ProcessEnv} env
36
+ * @returns {string}
37
+ */
38
+ function extraCaPath(env) {
39
+ const fromNode = typeof env.NODE_EXTRA_CA_CERTS === 'string' ? env.NODE_EXTRA_CA_CERTS.trim() : '';
40
+ if (fromNode && fs.existsSync(fromNode)) {
41
+ return fromNode;
42
+ }
43
+ return '';
44
+ }
45
+
46
+ /**
47
+ * @returns {string}
48
+ */
49
+ function nodeRootCaPem() {
50
+ const certs = tls.rootCertificates;
51
+ if (!Array.isArray(certs) || certs.length === 0) {
52
+ return '';
53
+ }
54
+ return `${certs.join('\n')}\n`;
55
+ }
56
+
57
+ /**
58
+ * @param {string} filePath
59
+ * @returns {string}
60
+ */
61
+ function readPem(filePath) {
62
+ if (!filePath) {
63
+ return '';
64
+ }
65
+ try {
66
+ return fs.readFileSync(filePath, 'utf8').trim();
67
+ } catch {
68
+ return '';
69
+ }
70
+ }
71
+
72
+ /**
73
+ * @param {string[]} parts
74
+ * @returns {string}
75
+ */
76
+ function joinPemParts(parts) {
77
+ const body = parts
78
+ .map((part) => String(part || '').trim())
79
+ .filter(Boolean)
80
+ .join('\n');
81
+ return body ? `${body}\n` : '';
82
+ }
83
+
84
+ /**
85
+ * @param {string} destDir
86
+ * @param {string} pem
87
+ * @returns {string}
88
+ */
89
+ function writeBundle(destDir, pem) {
90
+ fs.mkdirSync(destDir, { recursive: true });
91
+ const dest = path.join(destDir, 'ca-bundle.pem');
92
+ if (readPem(dest) === pem.trim()) {
93
+ return dest;
94
+ }
95
+ fs.writeFileSync(dest, pem, { mode: 0o600 });
96
+ return dest;
97
+ }
98
+
99
+ /**
100
+ * @param {string} extra
101
+ * @param {string} systemPath
102
+ * @param {string} [nodePem]
103
+ * @returns {string}
104
+ */
105
+ function resolveTrustPem(extra, systemPath, nodePem) {
106
+ const rootsPem = readPem(systemPath) || nodePem || nodeRootCaPem();
107
+ const extraPem = extra && extra !== systemPath ? readPem(extra) : '';
108
+ return joinPemParts([rootsPem, extraPem]);
109
+ }
110
+
111
+ /**
112
+ * @param {NodeJS.ProcessEnv} env
113
+ * @param {string} slackHome
114
+ * @param {Object} [deps]
115
+ * @returns {NodeJS.ProcessEnv}
116
+ */
117
+ function withGoTrustedCa(env, slackHome, deps = {}) {
118
+ if (env.SSL_CERT_FILE || env.SSL_CERT_DIR) {
119
+ return env;
120
+ }
121
+ const extra = deps.extraCaPath !== undefined ? deps.extraCaPath : extraCaPath(env);
122
+ const systemPath = deps.systemCaPath !== undefined ? deps.systemCaPath : systemCaBundlePath();
123
+ if (systemPath && !extra) {
124
+ return { ...env, SSL_CERT_FILE: systemPath };
125
+ }
126
+ const pem = resolveTrustPem(extra, systemPath, deps.nodeRootPem);
127
+ if (!pem) {
128
+ return extra ? { ...env, SSL_CERT_FILE: extra } : env;
129
+ }
130
+ const bundlePath = writeBundle(path.join(slackHome, '.ssl'), pem);
131
+ return { ...env, SSL_CERT_FILE: bundlePath };
132
+ }
133
+
134
+ module.exports = {
135
+ withGoTrustedCa,
136
+ systemCaBundlePath
137
+ };
@@ -0,0 +1,250 @@
1
+ /**
2
+ * Slack channel provisioning adapter (CLI + Manifest API).
3
+ *
4
+ * @fileoverview Create/reuse Slack app from generated manifest; store secrets via dataplane
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const { assertSlackCallbackUrls } = require('./callbacks');
10
+ const { parseGeneratedManifest, assertLocalManifest } = require('./manifest');
11
+ const {
12
+ validateManifestRemote,
13
+ createManifestApp,
14
+ updateManifestApp,
15
+ installManifestApp,
16
+ exportManifestApp,
17
+ exportManifestLookup,
18
+ resolveSlackClientId
19
+ } = require('./apps');
20
+ const { preserveSlackOAuthLocks } = require('./oauth-lock');
21
+ const {
22
+ pickSlackSecrets,
23
+ storeSlackChannelSecrets,
24
+ localSlackSigningPresent
25
+ } = require('./credentials');
26
+ const {
27
+ readProvisioningState,
28
+ writeProvisioningState,
29
+ hasProvenAppIdentity
30
+ } = require('./persist');
31
+ const { listSlackAuths, pickSlackWorkspace, workspaceFromSessionToken } = require('./auth');
32
+ const { slackProvisioningError } = require('./errors');
33
+ const { pickSlackClientId, slackConsentRemaining, slackConsentUrls } = require('./remaining-urls');
34
+ const { botScopesFromManifest } = require('./developer-install');
35
+
36
+ /**
37
+ * @param {Object} params
38
+ * @returns {Object}
39
+ */
40
+ function loadProvenState(params) {
41
+ const state = readProvisioningState(params.projectRoot);
42
+ if (state && !hasProvenAppIdentity(state)) {
43
+ throw slackProvisioningError(
44
+ 'Slack provisioning state exists but app id is missing. Fix or delete dist/channels/slack/provisioning-state.json.',
45
+ 'UNPROVEN_IDENTITY'
46
+ );
47
+ }
48
+ return state;
49
+ }
50
+
51
+ /**
52
+ * @param {Object} params
53
+ * @param {Object} [deps]
54
+ * @returns {Promise<void>}
55
+ */
56
+ async function resolveWorkspace(params, deps) {
57
+ const fromToken = await workspaceFromSessionToken(deps);
58
+ const auths = fromToken ? [fromToken] : await listSlackAuths(deps);
59
+ const workspace = pickSlackWorkspace(auths, params.expectedTeamId);
60
+ if (!workspace) {
61
+ throw slackProvisioningError(
62
+ 'No Slack workspace is signed in.',
63
+ 'UNPROVEN_IDENTITY'
64
+ );
65
+ }
66
+ return workspace;
67
+ }
68
+
69
+ /**
70
+ * @param {Object} params
71
+ * @param {Object} payload
72
+ * @returns {void}
73
+ */
74
+ function persistIds(params, payload) {
75
+ writeProvisioningState(params.projectRoot, {
76
+ environment: params.environment,
77
+ appId: payload.appId,
78
+ clientId: payload.clientId || null,
79
+ teamId: payload.teamId || null,
80
+ botId: payload.botId || null,
81
+ secretsStored: payload.secretsStored === true
82
+ });
83
+ }
84
+
85
+ /**
86
+ * @param {Object} params
87
+ * @param {Object} captured
88
+ * @param {Object} [deps]
89
+ * @returns {Promise<{ connected: boolean, remaining: string[], appId: string }>}
90
+ */
91
+ async function storeAndFinish(params, captured, deps) {
92
+ const secrets = pickSlackSecrets(captured);
93
+ const stored = await storeSlackChannelSecrets(params.ctx, secrets, {
94
+ ...deps,
95
+ projectRoot: params.projectRoot,
96
+ instanceSystemKey: params.ctx && params.ctx.instanceSystemKey
97
+ });
98
+ const signingReady = stored.storedSigningSecret || params.priorSecretsStored === true;
99
+ const botReady = stored.storedBotToken || params.priorSecretsStored === true;
100
+ const secretsStored = signingReady && botReady;
101
+ let clientId = pickSlackClientId(captured);
102
+ if (!clientId && !secretsStored) {
103
+ clientId = await resolveSlackClientId(captured, deps);
104
+ }
105
+ persistIds(params, {
106
+ appId: captured.appId,
107
+ clientId,
108
+ teamId: captured.teamId || params.workspaceTeamId,
109
+ botId: captured.botId,
110
+ secretsStored
111
+ });
112
+ const urls = slackConsentUrls({
113
+ ...captured,
114
+ clientId,
115
+ teamId: captured.teamId || params.workspaceTeamId
116
+ });
117
+ return {
118
+ connected: secretsStored,
119
+ remaining: slackConsentRemaining(
120
+ secretsStored ? { storedSigningSecret: true } : stored
121
+ ),
122
+ appId: captured.appId,
123
+ signingSecretFallback: stored.storedSigningSecret !== true,
124
+ storedSigningSecret: stored.storedSigningSecret === true,
125
+ storedBotToken: stored.storedBotToken === true,
126
+ ...urls
127
+ };
128
+ }
129
+
130
+ /**
131
+ * Install deps: HTTP developerInstall always; native CLI `app install` only when not quiet.
132
+ * @param {Object} params
133
+ * @param {Object} manifest
134
+ * @param {Object} [deps]
135
+ * @returns {Object}
136
+ */
137
+ function slackInstallDeps(params, manifest, deps) {
138
+ return {
139
+ ...deps,
140
+ quiet: params && params.quiet === true,
141
+ botScopes: botScopesFromManifest(manifest)
142
+ };
143
+ }
144
+
145
+ /**
146
+ * Capture bot token from Slack. Portal skips native CLI hang (CIP 120s).
147
+ * @param {string} appId
148
+ * @param {Object} [deps]
149
+ * @returns {Promise<Object>}
150
+ */
151
+ async function maybeInstallSlackApp(appId, deps) {
152
+ try {
153
+ return (await installManifestApp(appId, deps)) || {};
154
+ } catch {
155
+ return {};
156
+ }
157
+ }
158
+
159
+ /**
160
+ * @param {Object} params
161
+ * @param {Object} manifest
162
+ * @param {Object} [deps]
163
+ * @returns {Promise<Object>}
164
+ */
165
+ async function createNewSlackApp(params, manifest, deps) {
166
+ await validateManifestRemote(manifest, deps);
167
+ const created = await createManifestApp(manifest, deps);
168
+ persistIds(params, {
169
+ appId: created.app_id,
170
+ clientId: pickSlackClientId(created),
171
+ teamId: params.workspaceTeamId,
172
+ secretsStored: false
173
+ });
174
+ const installed = await maybeInstallSlackApp(
175
+ created.app_id,
176
+ slackInstallDeps(params, manifest, deps)
177
+ );
178
+ return storeAndFinish(params, {
179
+ appId: created.app_id,
180
+ clientId: pickSlackClientId(created),
181
+ teamId: installed.teamId || params.workspaceTeamId,
182
+ botId: installed.botId,
183
+ credentials: created.credentials,
184
+ oauth_authorize_url: created.oauth_authorize_url,
185
+ botToken: installed.botToken
186
+ }, deps);
187
+ }
188
+
189
+ /**
190
+ * @param {Object} params
191
+ * @param {Object} manifest
192
+ * @param {Object} state
193
+ * @param {Object} [deps]
194
+ * @returns {Promise<Object>}
195
+ */
196
+ async function reuseSlackApp(params, manifest, state, deps, remote) {
197
+ const exported = remote === undefined ? await exportManifestApp(state.appId, deps) : remote;
198
+ const merged = preserveSlackOAuthLocks(manifest, exported);
199
+ await validateManifestRemote(merged, { ...deps, appId: state.appId });
200
+ await updateManifestApp(state.appId, merged, deps);
201
+ const installed = await maybeInstallSlackApp(
202
+ state.appId,
203
+ slackInstallDeps(params, manifest, deps)
204
+ );
205
+ return storeAndFinish(
206
+ { ...params, priorSecretsStored: state.secretsStored === true },
207
+ {
208
+ appId: state.appId,
209
+ clientId: state.clientId,
210
+ teamId: installed.teamId || state.teamId || params.workspaceTeamId,
211
+ botId: installed.botId || state.botId,
212
+ botToken: installed.botToken
213
+ },
214
+ deps
215
+ );
216
+ }
217
+
218
+ /**
219
+ * @param {Object} params
220
+ * @param {Object} [deps]
221
+ * @returns {Promise<{ connected: boolean, remaining: string[], appId?: string }>}
222
+ */
223
+ async function provisionSlackChannel(params, deps = {}) {
224
+ assertSlackCallbackUrls(params.runtimeValues);
225
+ const manifest = parseGeneratedManifest(params.artifact && params.artifact.content);
226
+ assertLocalManifest(manifest);
227
+ const workspace = await resolveWorkspace(params, deps);
228
+ const workspaceTeamId = workspace.team_id || workspace.teamId;
229
+ const apiDeps = {
230
+ ...deps,
231
+ teamId: workspaceTeamId
232
+ };
233
+ const state = loadProvenState(params);
234
+ const withTeam = { ...params, workspaceTeamId };
235
+ const reuseKnownApp =
236
+ hasProvenAppIdentity(state) && (await localSlackSigningPresent(apiDeps));
237
+ if (reuseKnownApp) {
238
+ const lookup = await exportManifestLookup(state.appId, apiDeps);
239
+ if (!lookup.missing) {
240
+ return reuseSlackApp(withTeam, manifest, state, apiDeps, lookup.manifest);
241
+ }
242
+ }
243
+ return createNewSlackApp(withTeam, manifest, apiDeps);
244
+ }
245
+
246
+ module.exports = {
247
+ provisionSlackChannel,
248
+ loadProvenState,
249
+ persistIds
250
+ };