@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
@@ -26,7 +26,7 @@ function extractTenantIdFromIssuer(issuer) {
26
26
  return null;
27
27
  }
28
28
  const match = issuer.match(
29
- /login\.microsoftonline\.com\/([0-9a-fA-F-]{36})(?:\/|$)/i
29
+ /login\.microsoft(?:online)?\.com\/([0-9a-fA-F-]{36})(?:\/|$)/i
30
30
  );
31
31
  return match ? match[1] : null;
32
32
  }
@@ -136,8 +136,37 @@ function trimNonEmptyString(value) {
136
136
  }
137
137
 
138
138
  /**
139
- * Teams Entra SSO Application ID URI: api://auth-{authConfigId}/{clientId}.
140
- * Only when oauthPluginVaultReferenceId is a GUID (Teams auth-config id).
139
+ * Teams Entra SSO auth-config id from vault reference_id.
140
+ * Accepts a bare GUID or opaque base64 `tenantId##authConfigId` (Developer Portal).
141
+ * @param {string|null|undefined} referenceId
142
+ * @returns {string|null}
143
+ */
144
+ function parseOauthPluginVaultAuthConfigId(referenceId) {
145
+ const raw = trimNonEmptyString(referenceId);
146
+ if (!raw) {
147
+ return null;
148
+ }
149
+ if (TEAMS_AUTH_CONFIG_GUID.test(raw)) {
150
+ return raw;
151
+ }
152
+ try {
153
+ const decoded = Buffer.from(raw, 'base64').toString('utf8');
154
+ const parts = decoded.split('##');
155
+ if (
156
+ parts.length === 2 &&
157
+ TEAMS_AUTH_CONFIG_GUID.test(parts[0]) &&
158
+ TEAMS_AUTH_CONFIG_GUID.test(parts[1])
159
+ ) {
160
+ return parts[1];
161
+ }
162
+ } catch {
163
+ return null;
164
+ }
165
+ return null;
166
+ }
167
+
168
+ /**
169
+ * Teams Application ID URI: api://auth-{authConfigId}/{clientId}.
141
170
  * @param {string|null} authConfigId
142
171
  * @param {string|null} clientId
143
172
  * @returns {string|null}
@@ -151,6 +180,24 @@ function buildTeamsWebApplicationInfoResource(authConfigId, clientId) {
151
180
  return `api://auth-${configId}/${appId}`;
152
181
  }
153
182
 
183
+ /**
184
+ * Prefer Trust Application ID URI (audience), else api://{clientId}.
185
+ * @param {string|null} clientId
186
+ * @param {string|null|undefined} audience
187
+ * @returns {string|null}
188
+ */
189
+ function buildApplicationIdUriResource(clientId, audience) {
190
+ const appId = trimNonEmptyString(clientId);
191
+ const aud = trimNonEmptyString(audience).replace(/\/$/, '');
192
+ if (aud.startsWith('api://')) {
193
+ return aud.endsWith('/invoke') ? aud.slice(0, -'/invoke'.length) : aud;
194
+ }
195
+ if (appId) {
196
+ return `api://${appId}`;
197
+ }
198
+ return null;
199
+ }
200
+
154
201
  /**
155
202
  * @param {Object} resolved
156
203
  * @returns {string|null}
@@ -163,30 +210,69 @@ function resolveWebApplicationClientId(resolved) {
163
210
  );
164
211
  }
165
212
 
213
+ /**
214
+ * @param {Object} resolved
215
+ * @param {Object} params
216
+ * @returns {string}
217
+ */
218
+ function resolveWebApplicationAudience(resolved, params) {
219
+ return (
220
+ trimNonEmptyString(params.entraProvider && params.entraProvider.audience) ||
221
+ trimNonEmptyString(resolved.discoveryAuthentication && resolved.discoveryAuthentication.audience)
222
+ );
223
+ }
224
+
225
+ /**
226
+ * @param {Object} sources
227
+ * @returns {{ id: string|null, resource: string|null }}
228
+ */
229
+ function pickWebApplicationInfo(sources) {
230
+ const {
231
+ explicitId,
232
+ explicitResource,
233
+ priorId,
234
+ priorResource,
235
+ clientId,
236
+ fromApp,
237
+ fromTeamsAuthConfig
238
+ } = sources;
239
+ const derivedId = fromApp || fromTeamsAuthConfig ? clientId : null;
240
+ return {
241
+ id: explicitId || derivedId || priorId || null,
242
+ resource: explicitResource || fromApp || priorResource || fromTeamsAuthConfig || null
243
+ };
244
+ }
245
+
166
246
  /**
167
247
  * Preserve / derive Teams webApplicationInfo for Entra SSO packages.
168
- * Prefer explicit params, then prior package values, then GUID auth-config + SSO client id.
169
- * Do not invent resource URIs from opaque (non-GUID) vault references.
248
+ * Prefer explicit → Trust audience / api://{clientId} (matches Azure identifierUris)
249
+ * → prior package → Teams api://auth-{configId}/{clientId} only as last resort.
170
250
  * @param {Object} resolved
171
251
  * @param {Object} params
172
252
  * @returns {void}
173
253
  */
174
254
  function applyWebApplicationInfoFields(resolved, params = {}) {
175
255
  const prior = params.priorWebApplicationInfo || null;
176
- const explicitId = trimNonEmptyString(params.webApplicationInfoId);
177
- const explicitResource = trimNonEmptyString(params.webApplicationInfoResource);
178
- const priorId = trimNonEmptyString(prior && prior.id);
179
- const priorResource = trimNonEmptyString(prior && prior.resource);
180
256
  const clientId = resolveWebApplicationClientId(resolved);
181
- const derivedResource = buildTeamsWebApplicationInfoResource(
182
- resolved.oauthPluginVaultReferenceId,
183
- clientId
184
- );
185
- const id = explicitId || priorId || (derivedResource ? clientId : null);
186
- const resource = explicitResource || priorResource || derivedResource || null;
187
- if (id && resource) {
188
- resolved.webApplicationInfoId = id;
189
- resolved.webApplicationInfoResource = resource;
257
+ const audience = resolveWebApplicationAudience(resolved, params);
258
+ const authConfigId = parseOauthPluginVaultAuthConfigId(resolved.oauthPluginVaultReferenceId);
259
+ const fromTeamsAuthConfig = buildTeamsWebApplicationInfoResource(authConfigId, clientId);
260
+ const fromApp = buildApplicationIdUriResource(clientId, audience);
261
+ resolved.entraSsoAuthConfigId = authConfigId;
262
+ resolved.teamsApplicationIdUri = fromTeamsAuthConfig;
263
+ resolved.azureApplicationIdUri = fromApp || (clientId ? `api://${clientId}` : null);
264
+ const picked = pickWebApplicationInfo({
265
+ explicitId: trimNonEmptyString(params.webApplicationInfoId),
266
+ explicitResource: trimNonEmptyString(params.webApplicationInfoResource),
267
+ priorId: trimNonEmptyString(prior && prior.id),
268
+ priorResource: trimNonEmptyString(prior && prior.resource),
269
+ clientId,
270
+ fromApp,
271
+ fromTeamsAuthConfig
272
+ });
273
+ if (picked.id && picked.resource) {
274
+ resolved.webApplicationInfoId = picked.id;
275
+ resolved.webApplicationInfoResource = picked.resource;
190
276
  }
191
277
  }
192
278
 
@@ -245,7 +331,9 @@ module.exports = {
245
331
  resolveEntraTenantId,
246
332
  applyCopilotEntraSsoFormFields,
247
333
  applyWebApplicationInfoFields,
334
+ parseOauthPluginVaultAuthConfigId,
248
335
  buildTeamsWebApplicationInfoResource,
336
+ buildApplicationIdUriResource,
249
337
  renderCopilotChannelTemplate,
250
338
  formatOauthPluginVaultReferenceRequiredError
251
339
  };
@@ -25,7 +25,10 @@ function isPresent(value) {
25
25
  * @returns {boolean}
26
26
  */
27
27
  function skipsChannelOauthCredential(channelTarget) {
28
- return channelTarget === 'microsoft-copilot';
28
+ return channelTarget === 'microsoft-copilot'
29
+ || channelTarget === 'mcp-client'
30
+ || channelTarget === 'claude'
31
+ || channelTarget === 'chatgpt';
29
32
  }
30
33
 
31
34
  /**
@@ -109,6 +112,21 @@ function mapCopilotPackageAuthentication(auth) {
109
112
  * @param {Object|null} [params.entraProvider]
110
113
  * @returns {string[]}
111
114
  */
115
+ /**
116
+ * @param {string|null|undefined} audience
117
+ * @returns {string[]}
118
+ */
119
+ function scopesFromAudience(audience) {
120
+ const aud = typeof audience === 'string' ? audience.trim().replace(/\/$/, '') : '';
121
+ if (!aud.startsWith('api://')) {
122
+ return [];
123
+ }
124
+ if (aud.endsWith('/invoke')) {
125
+ return [aud];
126
+ }
127
+ return [`${aud}/invoke`];
128
+ }
129
+
112
130
  function resolveCopilotEntraScopes(params) {
113
131
  const explicit = normalizeScopeList(params.explicitScopes);
114
132
  if (explicit.length > 0 && !isOpenIdOnlyOrEmptyScopes(explicit)) {
@@ -118,6 +136,17 @@ function resolveCopilotEntraScopes(params) {
118
136
  if (fromProvider.length > 0 && !isOpenIdOnlyOrEmptyScopes(fromProvider)) {
119
137
  return fromProvider;
120
138
  }
139
+ const fromProviderAudience = scopesFromAudience(params.entraProvider?.audience);
140
+ if (fromProviderAudience.length > 0) {
141
+ return fromProviderAudience;
142
+ }
143
+ const enterpriseAppId =
144
+ typeof params.entraIdentityProvider?.enterpriseAppId === 'string'
145
+ ? params.entraIdentityProvider.enterpriseAppId.trim()
146
+ : '';
147
+ if (enterpriseAppId) {
148
+ return scopesFromAudience(`api://${enterpriseAppId}`);
149
+ }
121
150
  const auth = params.packageContext?.authentication || null;
122
151
  const fromAuth = normalizeScopeList(auth?.scopes || auth?.allowedScopes);
123
152
  if (fromAuth.length > 0 && !isOpenIdOnlyOrEmptyScopes(fromAuth)) {
@@ -125,7 +154,7 @@ function resolveCopilotEntraScopes(params) {
125
154
  }
126
155
  const resource = typeof auth?.resource === 'string' ? auth.resource.trim() : '';
127
156
  if (resource.startsWith('api://')) {
128
- return [resource];
157
+ return scopesFromAudience(resource);
129
158
  }
130
159
  return [];
131
160
  }
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Read prior Microsoft Copilot package identity from dist/source (regenerate).
3
+ *
4
+ * @fileoverview Preserve Entra webApplicationInfo / vault ref; bump Teams version
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const fs = require('../internal/fs-real-sync');
12
+ const path = require('path');
13
+ const {
14
+ parseSemverTriple,
15
+ bumpMinorPackageVersion,
16
+ resolvePackageVersionForWrite
17
+ } = require('./channel-package-version');
18
+
19
+ /**
20
+ * @param {string} sourceDir
21
+ * @returns {string|null}
22
+ */
23
+ function readPriorPackageVersion(sourceDir) {
24
+ const manifestPath = path.join(sourceDir, 'manifest.json');
25
+ if (!fs.existsSync(manifestPath)) {
26
+ return null;
27
+ }
28
+ try {
29
+ const parsed = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
30
+ const version = parsed && parsed.version;
31
+ return parseSemverTriple(version) ? String(version).trim() : null;
32
+ } catch {
33
+ return null;
34
+ }
35
+ }
36
+
37
+ /**
38
+ * Read prior webApplicationInfo from an existing source manifest (preserve on regenerate).
39
+ * @param {string} sourceDir
40
+ * @returns {{ id: string, resource: string }|null}
41
+ */
42
+ function readPriorWebApplicationInfo(sourceDir) {
43
+ const manifestPath = path.join(sourceDir, 'manifest.json');
44
+ if (!fs.existsSync(manifestPath)) {
45
+ return null;
46
+ }
47
+ try {
48
+ const parsed = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
49
+ const info = parsed && parsed.webApplicationInfo;
50
+ if (
51
+ info &&
52
+ typeof info.id === 'string' &&
53
+ info.id.trim() &&
54
+ typeof info.resource === 'string' &&
55
+ info.resource.trim()
56
+ ) {
57
+ return { id: info.id.trim(), resource: info.resource.trim() };
58
+ }
59
+ } catch {
60
+ return null;
61
+ }
62
+ return null;
63
+ }
64
+
65
+ /**
66
+ * Reuse Teams Entra SSO OAuthPluginVault reference_id from a prior ai-plugin.json.
67
+ * @param {string} sourceDir
68
+ * @returns {string|null}
69
+ */
70
+ function readPriorOauthPluginVaultReferenceId(sourceDir) {
71
+ const pluginPath = path.join(sourceDir, 'ai-plugin.json');
72
+ if (!fs.existsSync(pluginPath)) {
73
+ return null;
74
+ }
75
+ try {
76
+ const parsed = JSON.parse(fs.readFileSync(pluginPath, 'utf8'));
77
+ const runtimes = Array.isArray(parsed?.runtimes) ? parsed.runtimes : [];
78
+ for (const runtime of runtimes) {
79
+ const ref = runtime?.auth?.reference_id;
80
+ if (typeof ref === 'string' && ref.trim()) {
81
+ return ref.trim();
82
+ }
83
+ }
84
+ } catch {
85
+ return null;
86
+ }
87
+ return null;
88
+ }
89
+
90
+ /**
91
+ * @param {string} projectRoot
92
+ * @param {string} [channelTarget]
93
+ * @returns {string}
94
+ */
95
+ function getCopilotPackageSourceDir(projectRoot, channelTarget = 'microsoft-copilot') {
96
+ return path.join(projectRoot, 'dist', 'channels', channelTarget, 'source');
97
+ }
98
+
99
+ module.exports = {
100
+ parseSemverTriple,
101
+ bumpMinorPackageVersion,
102
+ readPriorPackageVersion,
103
+ resolvePackageVersionForWrite,
104
+ readPriorWebApplicationInfo,
105
+ readPriorOauthPluginVaultReferenceId,
106
+ getCopilotPackageSourceDir
107
+ };
@@ -22,6 +22,12 @@ const {
22
22
  renderCopilotChannelTemplate,
23
23
  applyWebApplicationInfoFields
24
24
  } = require('./microsoft-copilot-entra-sso-form');
25
+ const {
26
+ readPriorWebApplicationInfo,
27
+ readPriorPackageVersion,
28
+ readPriorOauthPluginVaultReferenceId,
29
+ resolvePackageVersionForWrite
30
+ } = require('./microsoft-copilot-package-prior');
25
31
 
26
32
  /**
27
33
  * @param {string} outputPath
@@ -330,43 +336,36 @@ function buildCopilotPackagePayload(params, runtimeValues, paths, icons) {
330
336
  }
331
337
 
332
338
  /**
333
- * Read prior webApplicationInfo from an existing source manifest (preserve on regenerate).
334
- * @param {string} sourceDir
335
- * @returns {{ id: string, resource: string }|null}
339
+ * Apply prior vault / Teams version / webApplicationInfo before render.
340
+ * @param {Object} runtimeValues
341
+ * @param {Object} paths
342
+ * @returns {void}
336
343
  */
337
- function readPriorWebApplicationInfo(sourceDir) {
338
- const manifestPath = path.join(sourceDir, 'manifest.json');
339
- if (!fs.existsSync(manifestPath)) {
340
- return null;
341
- }
342
- try {
343
- const parsed = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
344
- const info = parsed && parsed.webApplicationInfo;
345
- if (
346
- info &&
347
- typeof info.id === 'string' &&
348
- info.id.trim() &&
349
- typeof info.resource === 'string' &&
350
- info.resource.trim()
351
- ) {
352
- return { id: info.id.trim(), resource: info.resource.trim() };
344
+ function applyPriorPackageFields(runtimeValues, paths) {
345
+ if (!runtimeValues.oauthPluginVaultReferenceId) {
346
+ const priorVault = readPriorOauthPluginVaultReferenceId(paths.sourceDir);
347
+ if (priorVault) {
348
+ runtimeValues.oauthPluginVaultReferenceId = priorVault;
353
349
  }
354
- } catch {
355
- return null;
356
350
  }
357
- return null;
358
- }
359
-
360
- function generateMicrosoftCopilotPackage(params) {
361
- const runtimeValues = applyMicrosoftCopilotDisplayLimits({ ...(params.runtimeValues || {}) });
362
- assertCopilotPackageOauthPluginVaultReference(runtimeValues);
363
- const paths = buildCopilotOutputPaths(params.outputPath, runtimeValues);
351
+ const priorVersion = readPriorPackageVersion(paths.sourceDir);
352
+ const explicitVersion =
353
+ runtimeValues.packageVersionExplicit === true ? runtimeValues.packageVersion : null;
354
+ runtimeValues.packageVersion = resolvePackageVersionForWrite(explicitVersion, priorVersion);
355
+ runtimeValues.priorPackageVersion = priorVersion;
364
356
  const prior = readPriorWebApplicationInfo(paths.sourceDir);
365
357
  applyWebApplicationInfoFields(runtimeValues, {
366
358
  webApplicationInfoId: runtimeValues.webApplicationInfoId,
367
359
  webApplicationInfoResource: runtimeValues.webApplicationInfoResource,
368
360
  priorWebApplicationInfo: prior
369
361
  });
362
+ }
363
+
364
+ function generateMicrosoftCopilotPackage(params) {
365
+ const runtimeValues = applyMicrosoftCopilotDisplayLimits({ ...(params.runtimeValues || {}) });
366
+ const paths = buildCopilotOutputPaths(params.outputPath, runtimeValues);
367
+ applyPriorPackageFields(runtimeValues, paths);
368
+ assertCopilotPackageOauthPluginVaultReference(runtimeValues);
370
369
  const icons = resolvePackageIcons(runtimeValues);
371
370
  const payload = buildCopilotPackagePayload(params, runtimeValues, paths, icons);
372
371
  if (!params.dryRun) {
@@ -387,6 +386,8 @@ function generateMicrosoftCopilotPackage(params) {
387
386
  installPath: paths.installPath,
388
387
  zipPath: paths.zipPath,
389
388
  links: payload.summary.links,
389
+ packageVersion: runtimeValues.packageVersion,
390
+ priorPackageVersion: runtimeValues.priorPackageVersion || null,
390
391
  installReady: payload.summary.installReady === true,
391
392
  blocker: payload.summary.blocker || null,
392
393
  packageReady: payload.summary.packageReady === true,
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Agent 365 BYO MCP register wrap (preview). Not used by microsoft-copilot DA packaging.
3
+ *
4
+ * @fileoverview Checkpoint + optional a365 CLI; remaining admin/UI stays honest
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const { AGENT365_CHECKPOINT } = require('./constants');
10
+ const {
11
+ microsoftProvisioningError,
12
+ wrongEnvironmentRegistrationError
13
+ } = require('./errors');
14
+
15
+ /**
16
+ * @returns {{ preview: boolean, declarativeAgentsSupported: boolean, republishSupported: boolean, copilotStudioApiAttach: boolean, adminApprovalRequired: boolean, byoMcpRegisterCli: boolean, reason: string }}
17
+ */
18
+ function evaluateAgent365Checkpoint() {
19
+ return { ...AGENT365_CHECKPOINT };
20
+ }
21
+
22
+ /**
23
+ * Declarative Agent packaging must not consume Agent 365 BYO registrations.
24
+ * @returns {boolean}
25
+ */
26
+ function agent365AppliesToDeclarativeAgents() {
27
+ return evaluateAgent365Checkpoint().declarativeAgentsSupported === true;
28
+ }
29
+
30
+ /**
31
+ * @param {Object} existing
32
+ * @param {Object} requested
33
+ * @returns {void}
34
+ */
35
+ function assertMatchingRegistration(existing, requested) {
36
+ if (!existing || !existing.registrationId) {
37
+ return;
38
+ }
39
+ if (existing.environment && existing.environment !== requested.environment) {
40
+ throw wrongEnvironmentRegistrationError(requested.environment, existing.environment);
41
+ }
42
+ if (existing.mcpServerUrl && existing.mcpServerUrl !== requested.mcpServerUrl) {
43
+ throw microsoftProvisioningError(
44
+ 'Existing Agent 365 registration points at a different MCP URL. Republish is not supported.',
45
+ 'REPUBLISH_UNSUPPORTED'
46
+ );
47
+ }
48
+ }
49
+
50
+ /**
51
+ * @param {Object} params
52
+ * @param {Object} [deps]
53
+ * @returns {Promise<{ skipped: boolean, reason?: string, registrationId?: string }>}
54
+ */
55
+ async function registerExternalMcpServer(params, deps = {}) {
56
+ const checkpoint = evaluateAgent365Checkpoint();
57
+ if (params && params.forDeclarativeAgent === true && !checkpoint.declarativeAgentsSupported) {
58
+ return { skipped: true, reason: checkpoint.reason };
59
+ }
60
+ const existing = params && params.existingRegistration;
61
+ if (existing && existing.registrationId) {
62
+ assertMatchingRegistration(existing, params);
63
+ return { skipped: false, registrationId: existing.registrationId, reused: true };
64
+ }
65
+ if (typeof deps.runA365 !== 'function') {
66
+ return { skipped: true, reason: checkpoint.reason };
67
+ }
68
+ const registrationId = await deps.runA365(params);
69
+ if (!registrationId) {
70
+ throw microsoftProvisioningError('Agent 365 register did not return a registration id.', 'A365');
71
+ }
72
+ return { skipped: false, registrationId, reused: false };
73
+ }
74
+
75
+ module.exports = {
76
+ evaluateAgent365Checkpoint,
77
+ agent365AppliesToDeclarativeAgents,
78
+ assertMatchingRegistration,
79
+ registerExternalMcpServer
80
+ };