@aifabrix/builder 2.53.0 → 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 +119 -16
  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,55 @@
1
+ /**
2
+ * Microsoft channel provisioning adapter (auth-config + Agent 365 checkpoint).
3
+ *
4
+ * @fileoverview Single entry for Copilot Entra SSO capture and Teams Bot errors
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const { captureCopilotAuthConfigId } = require('./auth-config');
10
+ const {
11
+ startPortalMicrosoftLogin,
12
+ isLoopbackAuthorizeUrl,
13
+ peekPortalMicrosoftLogin,
14
+ awaitPortalMicrosoftLogin
15
+ } = require('./login-portal');
16
+ const { readProvisioningState, isReusableAuthConfig } = require('./persist');
17
+ const { wrongTenantError, wrapToolkitError, wrapTeamsCliError } = require('./errors');
18
+ const {
19
+ evaluateAgent365Checkpoint,
20
+ agent365AppliesToDeclarativeAgents,
21
+ registerExternalMcpServer
22
+ } = require('./a365');
23
+ const { extractTenantId, assertExpectedTenant } = require('./auth');
24
+ const { provisionTeamsBot, TEAMS_CLI_MISSING_REMAINING } = require('./teams-bot-provision');
25
+ const { buildAppCreateArgs } = require('./teams-bot-args');
26
+ const { isReusableTeamsBot, readTeamsBotState } = require('./teams-bot-persist');
27
+ const {
28
+ loadTeamsBotControllerContext,
29
+ extractAzureFromEnvironment
30
+ } = require('./teams-bot-controller');
31
+
32
+ module.exports = {
33
+ captureCopilotAuthConfigId,
34
+ startPortalMicrosoftLogin,
35
+ isLoopbackAuthorizeUrl,
36
+ peekPortalMicrosoftLogin,
37
+ awaitPortalMicrosoftLogin,
38
+ readProvisioningState,
39
+ isReusableAuthConfig,
40
+ extractTenantId,
41
+ assertExpectedTenant,
42
+ wrongTenantError,
43
+ wrapToolkitError,
44
+ wrapTeamsCliError,
45
+ evaluateAgent365Checkpoint,
46
+ agent365AppliesToDeclarativeAgents,
47
+ registerExternalMcpServer,
48
+ provisionTeamsBot,
49
+ buildAppCreateArgs,
50
+ isReusableTeamsBot,
51
+ readTeamsBotState,
52
+ TEAMS_CLI_MISSING_REMAINING,
53
+ loadTeamsBotControllerContext,
54
+ extractAzureFromEnvironment
55
+ };
@@ -0,0 +1,158 @@
1
+ /**
2
+ * Install Microsoft 365 Agents Toolkit CLI when `atk` / `teamsapp` is missing.
3
+ *
4
+ * @fileoverview Documented npm package only; skipped under Jest unless deps allow it
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const os = require('os');
10
+ const path = require('path');
11
+ const { promisify } = require('util');
12
+ const execFileDefault = promisify(require('child_process').execFile);
13
+ const { ATK_BINARIES, ATK_NPM_PACKAGE } = require('./constants');
14
+
15
+ /**
16
+ * @param {Object} [env]
17
+ * @returns {string}
18
+ */
19
+ function atkWritableHome(env = process.env) {
20
+ const home = typeof env.HOME === 'string' && env.HOME.trim() && env.HOME.trim() !== '/'
21
+ ? env.HOME.trim()
22
+ : os.tmpdir();
23
+ return home;
24
+ }
25
+
26
+ /**
27
+ * @param {Object} [env]
28
+ * @returns {string}
29
+ */
30
+ function atkInstallPrefix(env = process.env) {
31
+ return path.join(atkWritableHome(env), '.local');
32
+ }
33
+
34
+ /**
35
+ * npm must not use HOME=/ (container appuser) — that writes /.npm and EACCES.
36
+ * @param {Object} [env]
37
+ * @returns {Object}
38
+ */
39
+ function atkInstallEnv(env = process.env) {
40
+ const home = atkWritableHome(env);
41
+ const cache = path.join(home, '.npm');
42
+ const prefixBin = path.join(atkInstallPrefix(env), 'bin');
43
+ const pathValue = typeof env.PATH === 'string' ? env.PATH : '';
44
+ return {
45
+ ...env,
46
+ HOME: home,
47
+ NPM_CONFIG_CACHE: cache,
48
+ npm_config_cache: cache,
49
+ npm_config_update_notifier: 'false',
50
+ PATH: pathValue.includes(prefixBin) ? pathValue : `${prefixBin}${path.delimiter}${pathValue}`
51
+ };
52
+ }
53
+
54
+ /**
55
+ * @param {string} prefix
56
+ * @returns {string[]}
57
+ */
58
+ function atkInstallCandidates(prefix) {
59
+ return ATK_BINARIES.map((name) => path.join(prefix, 'bin', name));
60
+ }
61
+
62
+ /**
63
+ * @param {Object|null} resultOrError
64
+ * @returns {string}
65
+ */
66
+ function execText(resultOrError) {
67
+ const stdout = resultOrError && resultOrError.stdout ? String(resultOrError.stdout) : '';
68
+ const stderr = resultOrError && resultOrError.stderr ? String(resultOrError.stderr) : '';
69
+ return `${stdout}\n${stderr}`;
70
+ }
71
+
72
+ /**
73
+ * atk --version can print a version then exit 1 (HOME=/ mkdir /.fx).
74
+ * @param {string} text
75
+ * @returns {boolean}
76
+ */
77
+ function looksLikeAtkVersion(text) {
78
+ return /\d+\.\d+/.test(String(text || ''));
79
+ }
80
+
81
+ /**
82
+ * @param {Function} execFileImpl
83
+ * @param {string} bin
84
+ * @param {Object} [env]
85
+ * @returns {Promise<boolean>}
86
+ */
87
+ async function binaryResponds(execFileImpl, bin, env) {
88
+ const opts = { timeout: 20000, env: atkInstallEnv(env) };
89
+ try {
90
+ const result = await execFileImpl(bin, ['--version'], opts);
91
+ return looksLikeAtkVersion(execText(result));
92
+ } catch (error) {
93
+ return looksLikeAtkVersion(execText(error));
94
+ }
95
+ }
96
+
97
+ /**
98
+ * @param {Object} [deps]
99
+ * @returns {Promise<string|null>}
100
+ */
101
+ async function findAtkBinary(deps = {}) {
102
+ const execFileImpl = deps.execFile || execFileDefault;
103
+ const prefix = atkInstallPrefix(deps.env || process.env);
104
+ const bins = [...ATK_BINARIES, ...atkInstallCandidates(prefix)];
105
+ for (const bin of bins) {
106
+ if (await binaryResponds(execFileImpl, bin, deps.env || process.env)) {
107
+ return bin;
108
+ }
109
+ }
110
+ return null;
111
+ }
112
+
113
+ /**
114
+ * @param {Object} [deps]
115
+ * @returns {Promise<void>}
116
+ */
117
+ async function installAtkCli(deps = {}) {
118
+ if (typeof deps.installAtkImpl === 'function') {
119
+ await deps.installAtkImpl();
120
+ return;
121
+ }
122
+ const execFileImpl = deps.execFile || execFileDefault;
123
+ const prefix = atkInstallPrefix(deps.env || process.env);
124
+ await execFileImpl(
125
+ 'npm',
126
+ ['install', '-g', ATK_NPM_PACKAGE, '--prefix', prefix],
127
+ { timeout: 180000, env: atkInstallEnv(deps.env || process.env) }
128
+ );
129
+ }
130
+
131
+ /**
132
+ * @param {Object} [deps]
133
+ * @returns {Promise<string|null>}
134
+ */
135
+ async function findOrInstallAtkBinary(deps = {}) {
136
+ const existing = await findAtkBinary(deps);
137
+ if (existing) {
138
+ return existing;
139
+ }
140
+ if (deps.skipInstall === true) {
141
+ return null;
142
+ }
143
+ try {
144
+ await installAtkCli(deps);
145
+ } catch {
146
+ return null;
147
+ }
148
+ return findAtkBinary(deps);
149
+ }
150
+
151
+ module.exports = {
152
+ atkWritableHome,
153
+ atkInstallPrefix,
154
+ atkInstallEnv,
155
+ findAtkBinary,
156
+ installAtkCli,
157
+ findOrInstallAtkBinary
158
+ };
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Install Teams Developer CLI when `teams` is missing.
3
+ *
4
+ * @fileoverview Documented npm package only; skipped under Jest unless deps allow it
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const path = require('path');
10
+ const { promisify } = require('util');
11
+ const execFileDefault = promisify(require('child_process').execFile);
12
+ const { TEAMS_BINARIES, TEAMS_CLI_PACKAGE } = require('./constants');
13
+ const { atkInstallPrefix, atkInstallEnv } = require('./install-atk');
14
+
15
+ /**
16
+ * @param {Object|null} resultOrError
17
+ * @returns {string}
18
+ */
19
+ function execText(resultOrError) {
20
+ const stdout = resultOrError && resultOrError.stdout ? String(resultOrError.stdout) : '';
21
+ const stderr = resultOrError && resultOrError.stderr ? String(resultOrError.stderr) : '';
22
+ return `${stdout}\n${stderr}`;
23
+ }
24
+
25
+ /**
26
+ * @param {string} text
27
+ * @returns {boolean}
28
+ */
29
+ function looksLikeTeamsVersion(text) {
30
+ return /\d+\.\d+/.test(String(text || ''));
31
+ }
32
+
33
+ /**
34
+ * @param {Function} execFileImpl
35
+ * @param {string} bin
36
+ * @param {Object} [env]
37
+ * @returns {Promise<boolean>}
38
+ */
39
+ async function binaryResponds(execFileImpl, bin, env) {
40
+ const opts = { timeout: 20000, env: atkInstallEnv(env) };
41
+ try {
42
+ const result = await execFileImpl(bin, ['--version'], opts);
43
+ return looksLikeTeamsVersion(execText(result));
44
+ } catch (error) {
45
+ return looksLikeTeamsVersion(execText(error));
46
+ }
47
+ }
48
+
49
+ /**
50
+ * @param {string} prefix
51
+ * @returns {string[]}
52
+ */
53
+ function teamsInstallCandidates(prefix) {
54
+ return TEAMS_BINARIES.map((name) => path.join(prefix, 'bin', name));
55
+ }
56
+
57
+ /**
58
+ * @param {Object} [deps]
59
+ * @returns {Promise<string|null>}
60
+ */
61
+ async function findTeamsBinary(deps = {}) {
62
+ const execFileImpl = deps.execFile || execFileDefault;
63
+ const prefix = atkInstallPrefix(deps.env || process.env);
64
+ const bins = [...TEAMS_BINARIES, ...teamsInstallCandidates(prefix)];
65
+ for (const bin of bins) {
66
+ if (await binaryResponds(execFileImpl, bin, deps.env || process.env)) {
67
+ return bin;
68
+ }
69
+ }
70
+ return null;
71
+ }
72
+
73
+ /**
74
+ * @param {Object} [deps]
75
+ * @returns {Promise<void>}
76
+ */
77
+ async function installTeamsCli(deps = {}) {
78
+ if (typeof deps.installTeamsImpl === 'function') {
79
+ await deps.installTeamsImpl();
80
+ return;
81
+ }
82
+ const execFileImpl = deps.execFile || execFileDefault;
83
+ const prefix = atkInstallPrefix(deps.env || process.env);
84
+ await execFileImpl(
85
+ 'npm',
86
+ ['install', '-g', TEAMS_CLI_PACKAGE, '--prefix', prefix],
87
+ { timeout: 180000, env: atkInstallEnv(deps.env || process.env) }
88
+ );
89
+ }
90
+
91
+ /**
92
+ * @param {Object} [deps]
93
+ * @returns {Promise<string|null>}
94
+ */
95
+ async function findOrInstallTeamsBinary(deps = {}) {
96
+ const existing = await findTeamsBinary(deps);
97
+ if (existing) {
98
+ return existing;
99
+ }
100
+ if (deps.skipInstall === true) {
101
+ return null;
102
+ }
103
+ try {
104
+ await installTeamsCli(deps);
105
+ } catch {
106
+ return null;
107
+ }
108
+ return findTeamsBinary(deps);
109
+ }
110
+
111
+ module.exports = {
112
+ findTeamsBinary,
113
+ installTeamsCli,
114
+ findOrInstallTeamsBinary
115
+ };
@@ -0,0 +1,236 @@
1
+ /**
2
+ * Portal M365 device-code login via MSAL bundled with Agents Toolkit.
3
+ *
4
+ * @fileoverview Writes Toolkit ~/.fx account cache; never uses localhost redirect
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const path = require('path');
10
+ const { createRequire } = require('module');
11
+ const fs = require('../../internal/fs-real-sync');
12
+ const {
13
+ ATK_M365_CLIENT_ID,
14
+ ATK_APP_STUDIO_SCOPE,
15
+ ATK_DEVICE_LOGIN_URL,
16
+ ATK_ACCOUNT_NAME
17
+ } = require('./constants');
18
+ const { microsoftProvisioningError } = require('./errors');
19
+ const { atkInstallEnv, atkWritableHome } = require('./install-atk');
20
+
21
+ const localRequire = createRequire(__filename);
22
+
23
+ /**
24
+ * @param {string|null} atkBin
25
+ * @returns {string[]}
26
+ */
27
+ function msalCandidatePaths(atkBin) {
28
+ if (!atkBin) {
29
+ return [];
30
+ }
31
+ const prefix = path.resolve(path.dirname(atkBin), '..');
32
+ const pkg = '@microsoft/m365agentstoolkit-cli/node_modules/@azure/msal-node';
33
+ return [
34
+ path.join(prefix, 'lib/node_modules', pkg),
35
+ path.join(prefix, 'lib/node_modules/@azure/msal-node')
36
+ ];
37
+ }
38
+
39
+ /**
40
+ * @param {string|null} atkBin
41
+ * @param {Object} [deps]
42
+ * @returns {Object|null}
43
+ */
44
+ function loadMsalNode(atkBin, deps = {}) {
45
+ if (typeof deps.loadMsalNode === 'function') {
46
+ return deps.loadMsalNode(atkBin);
47
+ }
48
+ for (const candidate of msalCandidatePaths(atkBin)) {
49
+ try {
50
+ return localRequire(candidate);
51
+ } catch {
52
+ // next candidate
53
+ }
54
+ }
55
+ return null;
56
+ }
57
+
58
+ /**
59
+ * @param {string} home
60
+ * @returns {string}
61
+ */
62
+ function accountDir(home) {
63
+ return path.join(home, '.fx', 'account');
64
+ }
65
+
66
+ /**
67
+ * @param {string} home
68
+ * @returns {{ beforeCacheAccess: Function, afterCacheAccess: Function }}
69
+ */
70
+ function createFxCachePlugin(home) {
71
+ const filePath = path.join(accountDir(home), `token.cache.${ATK_ACCOUNT_NAME}.json`);
72
+ return {
73
+ async beforeCacheAccess(cacheContext) {
74
+ if (!fs.existsSync(filePath)) {
75
+ return;
76
+ }
77
+ const text = fs.readFileSync(filePath, 'utf8');
78
+ if (text) {
79
+ cacheContext.tokenCache.deserialize(text);
80
+ }
81
+ },
82
+ async afterCacheAccess(cacheContext) {
83
+ if (!cacheContext.cacheHasChanged) {
84
+ return;
85
+ }
86
+ fs.mkdirSync(accountDir(home), { recursive: true });
87
+ fs.writeFileSync(filePath, cacheContext.tokenCache.serialize());
88
+ }
89
+ };
90
+ }
91
+
92
+ /**
93
+ * @param {string} home
94
+ * @param {Object|null} result
95
+ * @returns {void}
96
+ */
97
+ function writeAccountSidecars(home, result) {
98
+ const account = result && result.account;
99
+ if (!account) {
100
+ return;
101
+ }
102
+ const dir = accountDir(home);
103
+ fs.mkdirSync(dir, { recursive: true });
104
+ if (account.homeAccountId) {
105
+ fs.writeFileSync(path.join(dir, `homeId.cache.${ATK_ACCOUNT_NAME}`), account.homeAccountId);
106
+ }
107
+ if (account.tenantId) {
108
+ fs.writeFileSync(path.join(dir, `tenantId.cache.${ATK_ACCOUNT_NAME}`), account.tenantId);
109
+ }
110
+ }
111
+
112
+ /**
113
+ * @param {string|null} tenantId
114
+ * @returns {string}
115
+ */
116
+ function authorityForTenant(tenantId) {
117
+ if (tenantId) {
118
+ return `https://login.microsoftonline.com/${tenantId}`;
119
+ }
120
+ return 'https://login.microsoftonline.com/organizations';
121
+ }
122
+
123
+ /**
124
+ * @param {Object} info
125
+ * @returns {{ loginUrl: string, userCode: string|null }}
126
+ */
127
+ function deviceInfoToLogin(info) {
128
+ const loginUrl =
129
+ typeof info.verificationUri === 'string' && info.verificationUri.trim()
130
+ ? info.verificationUri.trim()
131
+ : ATK_DEVICE_LOGIN_URL;
132
+ const userCode = typeof info.userCode === 'string' ? info.userCode.trim() : null;
133
+ return { loginUrl, userCode };
134
+ }
135
+
136
+ /**
137
+ * @param {Object} msal
138
+ * @param {string} home
139
+ * @param {string|null} tenantId
140
+ * @returns {Object}
141
+ */
142
+ function createPublicClient(msal, home, tenantId) {
143
+ return new msal.PublicClientApplication({
144
+ auth: {
145
+ clientId: ATK_M365_CLIENT_ID,
146
+ authority: authorityForTenant(tenantId)
147
+ },
148
+ cache: { cachePlugin: createFxCachePlugin(home) }
149
+ });
150
+ }
151
+
152
+ /**
153
+ * @param {Promise<{ loginUrl: string, userCode: string|null }>} ready
154
+ * @returns {Promise<{ loginUrl: string, userCode: string|null }|null>}
155
+ */
156
+ function waitForDeviceInfo(ready) {
157
+ return new Promise((resolve) => {
158
+ const timer = setTimeout(() => resolve(null), 20000);
159
+ ready
160
+ .then((parsed) => {
161
+ clearTimeout(timer);
162
+ resolve(parsed);
163
+ })
164
+ .catch(() => {
165
+ clearTimeout(timer);
166
+ resolve(null);
167
+ });
168
+ });
169
+ }
170
+
171
+ /**
172
+ * Start device-code login and return the browser URL as soon as MSAL prints it.
173
+ * @param {Object} params
174
+ * @param {string} key
175
+ * @param {Map} inflight
176
+ * @returns {Promise<{ waiting: boolean, loginUrl?: string, userCode?: string|null }>}
177
+ */
178
+ function deviceCodeStartError(message) {
179
+ const error = microsoftProvisioningError(message, 'TOOLKIT');
180
+ error.statusCode = 409;
181
+ return error;
182
+ }
183
+
184
+ async function startMsalDeviceCode(params, key, inflight) {
185
+ const deps = params.deps || {};
186
+ const msal = loadMsalNode(params.atkBinary || null, deps);
187
+ if (!msal || typeof msal.PublicClientApplication !== 'function') {
188
+ throw deviceCodeStartError(
189
+ 'Microsoft sign-in could not start (Agents Toolkit MSAL is not available).'
190
+ );
191
+ }
192
+ const home = atkWritableHome(atkInstallEnv(deps.env || process.env));
193
+ const pca = createPublicClient(msal, home, params.expectedTenantId || null);
194
+ let resolveReady;
195
+ const ready = new Promise((resolve) => {
196
+ resolveReady = resolve;
197
+ });
198
+ const request = {
199
+ scopes: [ATK_APP_STUDIO_SCOPE, 'openid', 'profile', 'offline_access'],
200
+ cancel: false,
201
+ deviceCodeCallback: (info) => resolveReady(deviceInfoToLogin(info))
202
+ };
203
+ const tokenPromise = pca.acquireTokenByDeviceCode(request).then((result) => {
204
+ writeAccountSidecars(home, result);
205
+ const job = inflight.get(key);
206
+ if (job) {
207
+ job.authenticated = true;
208
+ }
209
+ return result;
210
+ });
211
+ tokenPromise.catch(() => undefined);
212
+ const parsed = await waitForDeviceInfo(ready);
213
+ if (!parsed) {
214
+ request.cancel = true;
215
+ throw deviceCodeStartError(
216
+ 'Microsoft sign-in timed out before a device code was issued. Use Get a new code.'
217
+ );
218
+ }
219
+ if (key) {
220
+ inflight.set(key, {
221
+ request,
222
+ tokenPromise,
223
+ cli: 'atk',
224
+ loginUrl: parsed.loginUrl,
225
+ userCode: parsed.userCode
226
+ });
227
+ }
228
+ return { waiting: true, loginUrl: parsed.loginUrl, userCode: parsed.userCode };
229
+ }
230
+
231
+ module.exports = {
232
+ loadMsalNode,
233
+ startMsalDeviceCode,
234
+ writeAccountSidecars,
235
+ createFxCachePlugin
236
+ };
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Portal Microsoft login URL parsing. Device-code only — never loopback authorize.
3
+ *
4
+ * @fileoverview Remote browsers cannot complete MSAL localhost redirects
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const { ATK_DEVICE_LOGIN_URL } = require('./constants');
10
+
11
+ const DEVICE_LOGIN_RE =
12
+ /https:\/\/(?:www\.)?(?:microsoft\.com\/devicelogin|aka\.ms\/devicelogin)/i;
13
+ const DEVICEAUTH_RE =
14
+ /https:\/\/login\.microsoftonline\.com\/[^\s"'<>]*oauth2\/(?:v2\.0\/)?deviceauth/i;
15
+ const USER_CODE_RE = /enter the code\s+([A-Z0-9-]+)/i;
16
+ const LOOPBACK_HOST = /(?:localhost|127\.0\.0\.1)/i;
17
+
18
+ /**
19
+ * @param {string} url
20
+ * @returns {boolean}
21
+ */
22
+ function isLoopbackAuthorizeUrl(url) {
23
+ const text = String(url || '');
24
+ if (!/login\.microsoftonline\.com/i.test(text)) {
25
+ return false;
26
+ }
27
+ if (!/oauth2\/v2\.0\/authorize/i.test(text)) {
28
+ return false;
29
+ }
30
+ return /redirect_uri=/i.test(text) && LOOPBACK_HOST.test(text);
31
+ }
32
+
33
+ /**
34
+ * @param {string} url
35
+ * @returns {boolean}
36
+ */
37
+ function isDeviceLoginUrl(url) {
38
+ const text = String(url || '');
39
+ return DEVICE_LOGIN_RE.test(text) || DEVICEAUTH_RE.test(text);
40
+ }
41
+
42
+ /**
43
+ * Portal-safe Microsoft login URL (device-code hosts only).
44
+ * @param {string} url
45
+ * @returns {boolean}
46
+ */
47
+ function isMicrosoftLoginUrl(url) {
48
+ return isDeviceLoginUrl(url) && !isLoopbackAuthorizeUrl(url);
49
+ }
50
+
51
+ /**
52
+ * @param {string} text
53
+ * @returns {{ loginUrl: string|null, userCode: string|null }}
54
+ */
55
+ function parseMicrosoftLoginOutput(text) {
56
+ const blob = String(text || '');
57
+ const urls = blob.match(/https:\/\/[^\s"'<>]+/gi) || [];
58
+ const loginUrl = urls.find((item) => isMicrosoftLoginUrl(item)) || null;
59
+ const labelled = blob.match(USER_CODE_RE);
60
+ return {
61
+ loginUrl: loginUrl || (labelled ? ATK_DEVICE_LOGIN_URL : null),
62
+ userCode: labelled ? labelled[1] : null
63
+ };
64
+ }
65
+
66
+ module.exports = {
67
+ isLoopbackAuthorizeUrl,
68
+ isDeviceLoginUrl,
69
+ isMicrosoftLoginUrl,
70
+ parseMicrosoftLoginOutput
71
+ };