From 0734b398ab7d255b4925a8a290a74628dc8b0811 Mon Sep 17 00:00:00 2001 From: Ning Tang Date: Wed, 18 Mar 2026 16:57:55 +0800 Subject: [PATCH 01/27] fix(vsc): skill path --- packages/vscode-extension/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vscode-extension/package.json b/packages/vscode-extension/package.json index fe0924fd1f7..dc2c95f7bc8 100644 --- a/packages/vscode-extension/package.json +++ b/packages/vscode-extension/package.json @@ -1920,7 +1920,7 @@ ], "chatSkills": [ { - "path": "skills/microsoft-365-agents-toolkit" + "path": "skills/microsoft-365-agents-toolkit/SKILL.md" } ] }, From 23f09f5825a9aa0314c250ea7a08e2d189c28a19 Mon Sep 17 00:00:00 2001 From: Zhiyu You Date: Thu, 19 Mar 2026 16:00:18 +0800 Subject: [PATCH 02/27] fix: compatible to the new API of MCP Gateway --- .../src/handlers/updateActionWithMCP.ts | 52 +++++++++----- .../vscode.proposed.mcpServerDefinitions.d.ts | 46 +++++++++--- .../test/handlers/updateActionWithMCP.test.ts | 71 +++++++++++++++++-- 3 files changed, 137 insertions(+), 32 deletions(-) diff --git a/packages/vscode-extension/src/handlers/updateActionWithMCP.ts b/packages/vscode-extension/src/handlers/updateActionWithMCP.ts index bd4b02ff9a1..792ad06a8e8 100644 --- a/packages/vscode-extension/src/handlers/updateActionWithMCP.ts +++ b/packages/vscode-extension/src/handlers/updateActionWithMCP.ts @@ -253,25 +253,41 @@ export async function updateActionWithMCP(args?: any[]): Promise(); - tools = result.tools.filter((tool) => { - const key = `${tool.name}\n${tool.description ?? ""}`; - if (selectedToolKeys.has(key) && !matched.has(key)) { - matched.add(key); - return true; - } - return false; - }); - } catch { - tools = selectedTools; - } finally { - await client.close(); + // New API: mcpGateway.servers (array of McpGatewayServer with label + address) + // Old API: mcpGateway.address (single Uri) + let gatewayAddress: string | undefined; + if ("servers" in mcpGateway && Array.isArray(mcpGateway.servers)) { + const matchingServer = (mcpGateway.servers as vscode.McpGatewayServer[]).find( + (s) => sanitizeMCPName(s.label) === mcpName + ); + gatewayAddress = matchingServer?.address?.toString(); + } else if ("address" in mcpGateway) { + gatewayAddress = (mcpGateway as any).address.toString(); + } + if (gatewayAddress) { + const transport = new StreamableHTTPClientTransport(new URL(gatewayAddress)); + const client = new Client({ name: "atk", version: "1.0.0" }); + try { + await client.connect(transport); + const result = await client.listTools(); + const matched = new Set(); + tools = result.tools.filter((tool) => { + const key = `${tool.name}\n${tool.description ?? ""}`; + if (selectedToolKeys.has(key) && !matched.has(key)) { + matched.add(key); + return true; + } + return false; + }); + } catch { + tools = selectedTools; + } finally { + await client.close(); + mcpGateway.dispose(); + } + } else { mcpGateway.dispose(); + tools = selectedTools; } } else { tools = selectedTools; diff --git a/packages/vscode-extension/src/vscode.proposed.mcpServerDefinitions.d.ts b/packages/vscode-extension/src/vscode.proposed.mcpServerDefinitions.d.ts index cd1df2c494c..3d72e313f45 100644 --- a/packages/vscode-extension/src/vscode.proposed.mcpServerDefinitions.d.ts +++ b/packages/vscode-extension/src/vscode.proposed.mcpServerDefinitions.d.ts @@ -2,23 +2,47 @@ // Licensed under the MIT license. +// version: 1 + declare module "vscode" { // https://github.com/microsoft/vscode/issues/288777 @DonJayamanne /** - * Represents an MCP gateway that exposes MCP servers via HTTP. - * The gateway provides an HTTP endpoint that external processes can connect - * to in order to interact with MCP servers known to the editor. + * Represents a single MCP server exposed by the gateway via its own HTTP endpoint. */ - export interface McpGateway extends Disposable { + export interface McpGatewayServer { + /** + * The human-readable label of the MCP server. + */ + readonly label: string; + /** * The address of the HTTP MCP server endpoint. - * External processes can connect to this URI to interact with MCP servers. + * External processes can connect to this URI to interact with this MCP server. */ readonly address: Uri; } + /** + * Represents an MCP gateway that exposes MCP servers via HTTP. + * Each known MCP server gets its own HTTP endpoint. The gateway + * dynamically tracks server additions and removals. + */ + export interface McpGateway extends Disposable { + /** + * The MCP servers currently exposed by the gateway. + * Each server has its own HTTP endpoint address. + */ + readonly servers: readonly McpGatewayServer[]; + + /** + * Event that fires when the set of gateway servers changes. + * This can be due to MCP servers being added, removed, or restarted. + */ + readonly onDidChangeServers: Event; + } + /** * Namespace for language model related functionality. */ @@ -41,14 +65,16 @@ declare module "vscode" { export const onDidChangeMcpServerDefinitions: Event; /** - * Starts an MCP gateway that exposes MCP servers via an HTTP endpoint. + * Starts an MCP gateway that exposes MCP servers via HTTP endpoints. * - * The gateway creates a localhost HTTP server that external processes (such as - * CLI-based agent loops) can connect to in order to interact with MCP servers - * that the editor knows about. + * The gateway creates a localhost HTTP server where each MCP server known + * to the editor gets its own endpoint. External processes (such as CLI-based + * agent loops) can connect to these endpoints to interact with individual + * MCP servers. * * The HTTP server is shared among all gateways and is automatically torn down - * when the last gateway is disposed. + * when the last gateway is disposed. The gateway dynamically tracks server + * additions and removals via {@link McpGateway.onDidChangeServers}. * * @returns A promise that resolves to an {@link McpGateway} if successful, * or `undefined` if no Node process is available (e.g., in serverless web environments). diff --git a/packages/vscode-extension/test/handlers/updateActionWithMCP.test.ts b/packages/vscode-extension/test/handlers/updateActionWithMCP.test.ts index 79e390101d9..be8e43f7e61 100644 --- a/packages/vscode-extension/test/handlers/updateActionWithMCP.test.ts +++ b/packages/vscode-extension/test/handlers/updateActionWithMCP.test.ts @@ -1148,7 +1148,7 @@ describe("updateActionWithMCP", () => { sandbox.stub(vscode.lm, "tools").value(mockTools); const mockGateway = { - address: { toString: () => "http://localhost:12345" }, + servers: [{ label: "testServer", address: { toString: () => "http://localhost:12345" } }], dispose: sandbox.stub(), }; Object.defineProperty(vscode.lm, "startMcpGateway", { @@ -1190,7 +1190,7 @@ describe("updateActionWithMCP", () => { sandbox.stub(vscode.lm, "tools").value(mockTools); const mockGateway = { - address: { toString: () => "http://localhost:12345" }, + servers: [{ label: "testServer", address: { toString: () => "http://localhost:12345" } }], dispose: sandbox.stub(), }; Object.defineProperty(vscode.lm, "startMcpGateway", { @@ -1222,7 +1222,7 @@ describe("updateActionWithMCP", () => { sandbox.stub(vscode.lm, "tools").value(mockTools); const mockGateway = { - address: { toString: () => "http://localhost:12345" }, + servers: [{ label: "testServer", address: { toString: () => "http://localhost:12345" } }], dispose: sandbox.stub(), }; Object.defineProperty(vscode.lm, "startMcpGateway", { @@ -1257,7 +1257,7 @@ describe("updateActionWithMCP", () => { sandbox.stub(vscode.lm, "tools").value(mockTools); const mockGateway = { - address: { toString: () => "http://localhost:12345" }, + servers: [{ label: "testServer", address: { toString: () => "http://localhost:12345" } }], dispose: sandbox.stub(), }; Object.defineProperty(vscode.lm, "startMcpGateway", { @@ -1282,6 +1282,69 @@ describe("updateActionWithMCP", () => { // No tools match, so should return error chai.assert.isTrue(result.isErr()); }); + + it("should fall back to old gateway address API when servers property is absent", async () => { + const args = [{ serverName: "testServer", serverConfig: { url: "http://test.com" } }]; + const mockTools = [ + { name: "mcp_testserver_tool1", description: "Test tool 1", inputSchema: {}, tags: [] }, + ]; + + sandbox.stub(vscode.lm, "tools").value(mockTools); + const mockGateway = { + address: { toString: () => "http://localhost:12345" }, + dispose: sandbox.stub(), + }; + Object.defineProperty(vscode.lm, "startMcpGateway", { + value: sandbox.stub().resolves(mockGateway), + configurable: true, + }); + sandbox.stub(Client.prototype, "connect").resolves(); + sandbox.stub(Client.prototype, "listTools").resolves({ + tools: [ + { name: "tool1", description: "Test tool 1", inputSchema: { type: "object" as const } }, + ], + }); + sandbox.stub(Client.prototype, "close").resolves(); + sandbox.stub(axios, "get").resolves({ status: 200 }); + const runCommandStub = sandbox.stub(sharedOpts, "runCommand").resolves(ok(undefined)); + + const result = await updateActionWithMCP(args); + + chai.assert.isTrue(result.isOk()); + sinon.assert.calledOnce(mockGateway.dispose as sinon.SinonStub); + const calledInputs = runCommandStub.getCall(0).args[1] as Inputs; + const tools = calledInputs[QuestionNames.MCPForDAAvailableTools]; + chai.assert.equal(tools.length, 1); + chai.assert.equal(tools[0].name, "tool1"); + }); + + it("should fall back to selectedTools when no matching server found in gateway", async () => { + const args = [{ serverName: "testServer", serverConfig: { url: "http://test.com" } }]; + const mockTools = [ + { name: "mcp_testserver_tool1", description: "Test tool", inputSchema: {}, tags: [] }, + ]; + + sandbox.stub(vscode.lm, "tools").value(mockTools); + const mockGateway = { + servers: [{ label: "otherServer", address: { toString: () => "http://localhost:12345" } }], + dispose: sandbox.stub(), + }; + Object.defineProperty(vscode.lm, "startMcpGateway", { + value: sandbox.stub().resolves(mockGateway), + configurable: true, + }); + sandbox.stub(axios, "get").resolves({ status: 200 }); + const runCommandStub = sandbox.stub(sharedOpts, "runCommand").resolves(ok(undefined)); + + const result = await updateActionWithMCP(args); + + chai.assert.isTrue(result.isOk()); + sinon.assert.calledOnce(mockGateway.dispose as sinon.SinonStub); + const calledInputs = runCommandStub.getCall(0).args[1] as Inputs; + const tools = calledInputs[QuestionNames.MCPForDAAvailableTools]; + chai.assert.equal(tools.length, 1); + chai.assert.equal(tools[0].name, "tool1"); + }); }); describe("extractLocalServerIdentifier edge cases", () => { From ff95d09ede5700a1e6ece6fc50fcb7fef2feb759 Mon Sep 17 00:00:00 2001 From: wh-alice Date: Wed, 8 Apr 2026 06:07:34 +0000 Subject: [PATCH 03/27] build(release): publish detail - @microsoft/eslint-plugin-teamsfx@0.0.11-rc.0 - templates@6.6.4-rc.0 --- packages/eslint-plugin-teamsfx/package.json | 2 +- packages/fx-core/src/common/templates-config.json | 4 ++-- templates/package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/eslint-plugin-teamsfx/package.json b/packages/eslint-plugin-teamsfx/package.json index f5f75543c7c..cc1ef85b4d2 100644 --- a/packages/eslint-plugin-teamsfx/package.json +++ b/packages/eslint-plugin-teamsfx/package.json @@ -1,6 +1,6 @@ { "name": "@microsoft/eslint-plugin-teamsfx", - "version": "0.0.10", + "version": "0.0.11-rc.0", "description": "eslint for teamsfx", "keywords": [ "eslint", diff --git a/packages/fx-core/src/common/templates-config.json b/packages/fx-core/src/common/templates-config.json index ba63657aa56..a76a5849e57 100644 --- a/packages/fx-core/src/common/templates-config.json +++ b/packages/fx-core/src/common/templates-config.json @@ -1,6 +1,6 @@ { - "version": "~6.6", - "localVersion": "6.6.3", + "version": "0.0.0-rc", + "localVersion": "6.6.4-rc.0", "tagPrefix": "templates@", "vstagPrefix": "templates-vs@", "vsversion": "18.6.0", diff --git a/templates/package.json b/templates/package.json index 1d66ecb9494..f81d025e765 100644 --- a/templates/package.json +++ b/templates/package.json @@ -1,6 +1,6 @@ { "name": "templates", - "version": "6.6.3", + "version": "6.6.4-rc.0", "private": "true", "license": "MIT", "vsversion": "18.6.0", From ca0d3f7a3661e5e6b75f8a7fcc96bcee4108729e Mon Sep 17 00:00:00 2001 From: Qinzhou Xu Date: Wed, 8 Apr 2026 15:22:49 +0800 Subject: [PATCH 04/27] fix: mac os playground can not be started --- templates/configs/playground/typescript/.vscode/tasks.json | 2 +- templates/vsc/ts/foundry-agent-to-m365/.vscode/tasks.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/configs/playground/typescript/.vscode/tasks.json b/templates/configs/playground/typescript/.vscode/tasks.json index 868b72c319c..3e32e40ae71 100644 --- a/templates/configs/playground/typescript/.vscode/tasks.json +++ b/templates/configs/playground/typescript/.vscode/tasks.json @@ -70,7 +70,7 @@ "isBackground": true, "options": { "env": { - "PATH": "${workspaceFolder}/devTools/playground/node_modules/.bin;${env:PATH}" + "PATH": "${workspaceFolder}/devTools/playground/node_modules/.bin:${env:PATH}" } }, "windows": { diff --git a/templates/vsc/ts/foundry-agent-to-m365/.vscode/tasks.json b/templates/vsc/ts/foundry-agent-to-m365/.vscode/tasks.json index 2fc7147172b..d3570e07485 100644 --- a/templates/vsc/ts/foundry-agent-to-m365/.vscode/tasks.json +++ b/templates/vsc/ts/foundry-agent-to-m365/.vscode/tasks.json @@ -70,7 +70,7 @@ "isBackground": true, "options": { "env": { - "PATH": "${workspaceFolder}/devTools/playground/node_modules/.bin;${env:PATH}" + "PATH": "${workspaceFolder}/devTools/playground/node_modules/.bin:${env:PATH}" } }, "windows": { From a177e5e4972fbdccb65b04d5fbb99bc629efe2fd Mon Sep 17 00:00:00 2001 From: Zhiyu You Date: Wed, 8 Apr 2026 15:54:12 +0800 Subject: [PATCH 05/27] fix: tab template for 2.0.7 SDK --- templates/vsc/ts/basic-tab/src/index.ts | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/templates/vsc/ts/basic-tab/src/index.ts b/templates/vsc/ts/basic-tab/src/index.ts index 0d431bd2c00..a028ed4daa6 100644 --- a/templates/vsc/ts/basic-tab/src/index.ts +++ b/templates/vsc/ts/basic-tab/src/index.ts @@ -2,7 +2,7 @@ import fs from "fs"; import https from "https"; import path from "path"; -import { App, HttpPlugin, IPlugin } from "@microsoft/teams.apps"; +import { App, ExpressAdapter, IPlugin } from "@microsoft/teams.apps"; import { ConsoleLogger } from "@microsoft/teams.common/logging"; import { DevtoolsPlugin } from "@microsoft/teams.dev"; @@ -10,17 +10,30 @@ const sslOptions = { key: process.env.SSL_KEY_FILE ? fs.readFileSync(process.env.SSL_KEY_FILE) : undefined, cert: process.env.SSL_CRT_FILE ? fs.readFileSync(process.env.SSL_CRT_FILE) : undefined, }; -const plugins: IPlugin[] = [new DevtoolsPlugin()]; + +// Workaround for SDK bug in v2.0.6+: ExpressAdapter uses `instanceof http.Server` +// which fails for https.Server (extends tls.Server, not http.Server). +// Fix: create the adapter, then replace its internal http.Server with our https.Server. +const adapter = new ExpressAdapter(); if (sslOptions.cert && sslOptions.key) { - plugins.push(new HttpPlugin(https.createServer(sslOptions))); + const httpsServer = https.createServer(sslOptions, (adapter as any).express); + (adapter as any).server = httpsServer; +} + +// Only use DevtoolsPlugin locally — it crashes on Azure App Service +// because it calls parseInt() on the named pipe PORT value. +const plugins: IPlugin[] = []; +if (process.env.SSL_KEY_FILE) { + plugins.push(new DevtoolsPlugin()); } const app = new App({ logger: new ConsoleLogger("tab", { level: "debug" }), plugins: plugins, + httpServerAdapter: adapter, }); app.tab("home", path.join(__dirname, "./client")); (async () => { - await app.start(+(process.env.PORT || 3978)); + await app.start(process.env.PORT || 3978); })(); From ff3fafe6861b96f298a74108751faedd3e75005f Mon Sep 17 00:00:00 2001 From: Qinzhou Xu Date: Thu, 9 Apr 2026 16:05:57 +0800 Subject: [PATCH 06/27] fix: python teams agent can not start --- templates/vsc/python/custom-copilot-basic/src/app.py.tpl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/templates/vsc/python/custom-copilot-basic/src/app.py.tpl b/templates/vsc/python/custom-copilot-basic/src/app.py.tpl index 4f3bca48693..c7f3f158d44 100644 --- a/templates/vsc/python/custom-copilot-basic/src/app.py.tpl +++ b/templates/vsc/python/custom-copilot-basic/src/app.py.tpl @@ -76,9 +76,10 @@ async def handle_stateful_conversation(model: AIModel, ctx: ActivityContext[Mess try: chat_result = await chat_prompt.send( - input=input, + input=ctx.activity.text, memory=memory, - instructions=f"{INSTRUCTIONS}\n\nAdditional Context:\n${data_context.output}" + instructions=INSTRUCTIONS, + on_chunk=lambda chunk: ctx.stream.emit(chunk) ) except Exception as e: print(f"Error sending chat prompt: {e}") From d58be13f31e65a9ed332e60168dae50e00a4c022 Mon Sep 17 00:00:00 2001 From: Zhiyu You Date: Thu, 9 Apr 2026 16:34:24 +0800 Subject: [PATCH 07/27] fix: message extension template for 2.0.7 SDK Conditionally include DevtoolsPlugin only for local development, matching the pattern used in teams-collaborator-agent template. DevtoolsPlugin crashes on Azure App Service because it calls parseInt() on the named pipe PORT value. --- templates/vsc/ts/message-extension-v2/src/index.ts.tpl | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/templates/vsc/ts/message-extension-v2/src/index.ts.tpl b/templates/vsc/ts/message-extension-v2/src/index.ts.tpl index 245f9b7e95a..c031c698687 100644 --- a/templates/vsc/ts/message-extension-v2/src/index.ts.tpl +++ b/templates/vsc/ts/message-extension-v2/src/index.ts.tpl @@ -33,13 +33,15 @@ const tokenCredentials: TokenCredentials = { token: createTokenFactory(), }; -const credentialOptions = - process.env.BOT_TYPE === "UserAssignedMsi" ? { ...tokenCredentials } : undefined; +// Use managed identity in cloud environment, otherwise use devtools plugin for local development +const options = + process.env.BOT_TYPE === "UserAssignedMsi" + ? { ...tokenCredentials } + : { plugins: [new DevtoolsPlugin()] }; const app = new App({ - ...credentialOptions, + ...options, logger: new ConsoleLogger("{{appName}}", { level: "debug" }), - plugins: [new DevtoolsPlugin()], }); app.on("install.add", async ({ send }) => { From 256567e69bad33ac015a5cfcf686b8653e98d198 Mon Sep 17 00:00:00 2001 From: wh-alice Date: Thu, 9 Apr 2026 10:17:40 +0000 Subject: [PATCH 08/27] build(release): publish detail - templates@6.6.4-rc.1 --- packages/fx-core/src/common/templates-config.json | 2 +- templates/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/fx-core/src/common/templates-config.json b/packages/fx-core/src/common/templates-config.json index a76a5849e57..50c5ef332af 100644 --- a/packages/fx-core/src/common/templates-config.json +++ b/packages/fx-core/src/common/templates-config.json @@ -1,6 +1,6 @@ { "version": "0.0.0-rc", - "localVersion": "6.6.4-rc.0", + "localVersion": "6.6.4-rc.1", "tagPrefix": "templates@", "vstagPrefix": "templates-vs@", "vsversion": "18.6.0", diff --git a/templates/package.json b/templates/package.json index f81d025e765..cfdf2b34be7 100644 --- a/templates/package.json +++ b/templates/package.json @@ -1,6 +1,6 @@ { "name": "templates", - "version": "6.6.4-rc.0", + "version": "6.6.4-rc.1", "private": "true", "license": "MIT", "vsversion": "18.6.0", From 6c0a59a84c666205df1a61e9fd6af1fc33807d6b Mon Sep 17 00:00:00 2001 From: Qinzhou Xu Date: Fri, 10 Apr 2026 15:09:30 +0800 Subject: [PATCH 09/27] build: modify code for generate release bits --- packages/vscode-extension/src/debug/common/localDebugSession.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/vscode-extension/src/debug/common/localDebugSession.ts b/packages/vscode-extension/src/debug/common/localDebugSession.ts index cc63c6f190d..2a7dab39ca9 100644 --- a/packages/vscode-extension/src/debug/common/localDebugSession.ts +++ b/packages/vscode-extension/src/debug/common/localDebugSession.ts @@ -11,6 +11,7 @@ export class LocalDebugSession { const session = new LocalDebugSession(uuid.v4()); return session; } + static createInvalidSession() { return new LocalDebugSession(); } From 9ad4d3101f94452c2261ea61919c9a67c38c8300 Mon Sep 17 00:00:00 2001 From: qfai Date: Mon, 13 Apr 2026 17:00:07 +0800 Subject: [PATCH 10/27] fix: replace missing core.* NLS keys with template.* equivalents 33 NLS keys referenced in fx-core source were missing from package.nls.json, causing blank/empty labels in VS Code QuickPick menus (notably the Add Action MCP option). These core.* keys were deleted during the JSON-driven wizard migration but the old TypeScript code paths still referenced them. Fixed by: - Replacing 29 core.* key references with their template.* equivalents - Adding 4 genuinely missing keys to fx-core package.nls.json Affected files: - constants.ts: MCP and RAG option labels - CapabilityOptions.ts: CEA, Teams agent, RAG source labels - teamsProjectTypeNode.ts: RAG label/placeholder - create.ts: RAG placeholder Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- packages/fx-core/resource/package.nls.json | 4 +++ packages/fx-core/src/question/constants.ts | 16 ++++----- packages/fx-core/src/question/create.ts | 2 +- .../scaffold/vsc/CapabilityOptions.ts | 36 +++++++++---------- .../scaffold/vsc/teamsProjectTypeNode.ts | 4 +-- 5 files changed, 33 insertions(+), 29 deletions(-) diff --git a/packages/fx-core/resource/package.nls.json b/packages/fx-core/resource/package.nls.json index 44b9d3db852..e82ac58c43e 100644 --- a/packages/fx-core/resource/package.nls.json +++ b/packages/fx-core/resource/package.nls.json @@ -247,6 +247,7 @@ "error.generator.FetchSampleInfoError": "Unable to fetch sample info", "error.generator.DownloadSampleApiLimitError": "Unable to download sample due to rate limitation. Try again in an hour after rate limit reset or you can manually clone the repo from %s.", "error.generator.DownloadSampleNetworkError": "Unable to download sample due to network error. Check your network connection and try again or you can manually clone the repo from %s", + "error.generator.UnknownPolicy": "Unknown auth policy: %s", "error.copilotPlugin.apiSpecNotUsedInPlugin": "\"%s\" is not used in the plugin.", "error.apime.noExtraAPICanBeAdded": "Unable to add API because only GET and POST methods are supported, with a maximum of 5 required parameters and no authentication. Also, methods defined in the manifest are not listed.", "error.copilot.noExtraAPICanBeAdded": "Unable to add API because no authentication is supported. Also, methods defined in the current OpenAPI description document are not listed.", @@ -320,6 +321,7 @@ "core.copilotPlugin.scaffold.summary.warning.generate.ac.failed": "Failed to create the adaptive card for API '%s': %s. Mitigation: Not required but you can manually add it to the adaptiveCards folder.", "core.createCapabilityQuestion.titleNew": "Capabilities", "core.createProjectQuestion.option.description.preview": "Preview", + "core.createProjectQuestion.option.description.previewOnWindow": "Preview on Windows", "core.createProjectQuestion.option.description.worksInOutlook": "Works in Teams and Outlook", "core.createProjectQuestion.option.description.worksInOutlookM365": "Works in Teams, Outlook, and the Microsoft 365 application", "core.createProjectQuestion.projectType.bot.detail": "Create instant, engaging chat experiences that automate tasks seamlessly", @@ -367,6 +369,7 @@ "core.createProjectQuestion.capability.knowledgeEmbeddedKnowledge.detail": "Embed files directly as grounding information.", "core.createProjectQuestion.oneDriveSharePointItem.title": "OneDrive or SharePoint Content", "core.createProjectQuestion.oneDriveSharePointItem.placeholder": "Enter a URL to OneDrive or SharePoint", + "core.createProjectQuestion.oneDriveSharePointItem.confirm": "Confirm your selection", "core.createProjectQuestion.log.fail.validateOneDriveSharePointItem": "Failed to validate OneDrive/SharePoint URL: %s", "core.createProjectQuestion.log.fail.invalidOneDriveSharePointURL": "The OneDrive/SharePoint URL is invalid.", "core.createProjectQuestion.llmService.title": "Service for Large Language Model (LLM)", @@ -1055,6 +1058,7 @@ "core.addKnowledgeQuestion.searchType.oneDriveSharepoint": "Search all content within your organization", "core.addKnowledgeQuestion.searchType.url": "Search by URL", "driver.typeSpec.compile.start": "Executing action %s", + "driver.typeSpec.compile.description": "Compile TypeSpec project", "driver.typespec.error.noSpecError": "No OpenApi spec found. Please make sure your TypeSpec files are valid and try again.", "driver.typespec.error.multipleActionError": "More than one action found in declarativeAgent.json. Please make sure your TypeSpec files are valid and try again.", "driver.typeSpec.progressBar": "Compiling and generating files...", diff --git a/packages/fx-core/src/question/constants.ts b/packages/fx-core/src/question/constants.ts index de2b94c42e6..63812b188d0 100644 --- a/packages/fx-core/src/question/constants.ts +++ b/packages/fx-core/src/question/constants.ts @@ -293,10 +293,10 @@ export class CustomCopilotRagOptions { return { id: "custom-copilot-rag-customize", label: getLocalizedString( - "core.createProjectQuestion.capability.customCopilotRagCustomizeOption.label" + "template.teams.rag.source.customize.label" ), detail: getLocalizedString( - "core.createProjectQuestion.capability.customCopilotRagCustomizeOption.detail" + "template.teams.rag.source.customize.detail" ), }; } @@ -305,10 +305,10 @@ export class CustomCopilotRagOptions { return { id: "custom-copilot-rag-azureAISearch", label: getLocalizedString( - "core.createProjectQuestion.capability.customCopilotRagAzureAISearchOption.label" + "template.teams.rag.source.azureAISearch.label" ), detail: getLocalizedString( - "core.createProjectQuestion.capability.customCopilotRagAzureAISearchOption.detail" + "template.teams.rag.source.azureAISearch.detail" ), }; } @@ -317,10 +317,10 @@ export class CustomCopilotRagOptions { return { id: "custom-copilot-rag-customApi", label: getLocalizedString( - "core.createProjectQuestion.capability.customCopilotRagCustomApiOption.label" + "template.teams.rag.source.customApi.label" ), detail: getLocalizedString( - "core.createProjectQuestion.capability.customCopilotRagCustomApiOption.detail" + "template.teams.rag.source.customApi.detail" ), description: getLocalizedString("core.createProjectQuestion.option.description.preview"), }; @@ -503,8 +503,8 @@ export class ActionStartOptions { static mcp(): OptionItem { return { id: "mcp", - label: getLocalizedString("core.createProjectQuestion.mcpForDa.label"), - detail: getLocalizedString("core.createProjectQuestion.mcpForDa.detail"), + label: getLocalizedString("template.createProjectQuestion.mcpForDa.label"), + detail: getLocalizedString("template.createProjectQuestion.mcpForDa.detail"), }; } diff --git a/packages/fx-core/src/question/create.ts b/packages/fx-core/src/question/create.ts index d4d6579f5a1..1c292ef2fc9 100644 --- a/packages/fx-core/src/question/create.ts +++ b/packages/fx-core/src/question/create.ts @@ -1016,7 +1016,7 @@ function customCopilotRagQuestion(): SingleSelectQuestion { name: QuestionNames.CustomCopilotRag, title: getLocalizedString("core.createProjectQuestion.capability.customCopilotRag.title"), placeholder: getLocalizedString( - "core.createProjectQuestion.capability.customCopilotRag.placeholder" + "template.teams.rag.source.placeholder" ), staticOptions: CustomCopilotRagOptions.all(), dynamicOptions: () => CustomCopilotRagOptions.all(), diff --git a/packages/fx-core/src/question/scaffold/vsc/CapabilityOptions.ts b/packages/fx-core/src/question/scaffold/vsc/CapabilityOptions.ts index 56e0c6de98d..4986cb03fd4 100644 --- a/packages/fx-core/src/question/scaffold/vsc/CapabilityOptions.ts +++ b/packages/fx-core/src/question/scaffold/vsc/CapabilityOptions.ts @@ -18,10 +18,10 @@ export class CustomEngineAgentOptions { return { id: "basic-custom-engine-agent", label: getLocalizedString( - "core.createProjectQuestion.capability.basicCustomEngineAgentOption.label" + "template.customEngineAgent.basic.label" ), detail: getLocalizedString( - "core.createProjectQuestion.capability.basicCustomEngineAgentOption.detail" + "template.customEngineAgent.basic.detail" ), data: TemplateNames.BasicCustomEngineAgent, }; @@ -30,8 +30,8 @@ export class CustomEngineAgentOptions { static weatherAgent(): OptionItem { return { id: "weather-agent", - label: getLocalizedString("core.createProjectQuestion.capability.weatherAgentOption.label"), - detail: getLocalizedString("core.createProjectQuestion.capability.weatherAgentOption.detail"), + label: getLocalizedString("template.customEngineAgent.weather.label"), + detail: getLocalizedString("template.customEngineAgent.weather.detail"), data: TemplateNames.WeatherAgent, }; } @@ -101,10 +101,10 @@ export class TeamsAgentCapabilityOptions { return { id: "custom-copilot-basic", label: getLocalizedString( - "core.createProjectQuestion.capability.customCopilotBasicOption.label" + "template.teams.general.label" ), detail: getLocalizedString( - "core.createProjectQuestion.capability.customCopilotBasicOption.detail" + "template.teams.general.detail" ), description: description, data: TemplateNames.CustomCopilotBasic, @@ -118,10 +118,10 @@ export class TeamsAgentCapabilityOptions { return { id: "custom-copilot-rag", label: getLocalizedString( - "core.createProjectQuestion.capability.customCopilotRagOption.label" + "template.teams.rag.label" ), detail: getLocalizedString( - "core.createProjectQuestion.capability.customCopilotRagOption.detail" + "template.teams.rag.detail" ), description: description, }; @@ -131,10 +131,10 @@ export class TeamsAgentCapabilityOptions { return { id: "teams-collaborator-agent", label: getLocalizedString( - "core.createProjectQuestion.capability.teamsAgent.collaborator.label" + "template.teams.collaboratorAgent.label" ), detail: getLocalizedString( - "core.createProjectQuestion.capability.teamsAgent.collaborator.detail" + "template.teams.collaboratorAgent.detail" ), data: TemplateNames.TeamsCollaboratorAgent, }; @@ -146,8 +146,8 @@ export class TeamsAgentCapabilityOptions { : undefined; return { id: "others", - label: getLocalizedString("core.createProjectQuestion.capability.teamsAgent.others.label"), - detail: getLocalizedString("core.createProjectQuestion.capability.teamsAgent.others.detail"), + label: getLocalizedString("template.teams.others.label"), + detail: getLocalizedString("template.teams.others.detail"), description: description, }; } @@ -174,10 +174,10 @@ export class CustomCopilotRagOptions { return { id: "custom-copilot-rag-customize", label: getLocalizedString( - "core.createProjectQuestion.capability.customCopilotRagCustomizeOption.label" + "template.teams.rag.source.customize.label" ), detail: getLocalizedString( - "core.createProjectQuestion.capability.customCopilotRagCustomizeOption.detail" + "template.teams.rag.source.customize.detail" ), data: TemplateNames.CustomCopilotRagCustomize, }; @@ -187,10 +187,10 @@ export class CustomCopilotRagOptions { return { id: "custom-copilot-rag-azureAISearch", label: getLocalizedString( - "core.createProjectQuestion.capability.customCopilotRagAzureAISearchOption.label" + "template.teams.rag.source.azureAISearch.label" ), detail: getLocalizedString( - "core.createProjectQuestion.capability.customCopilotRagAzureAISearchOption.detail" + "template.teams.rag.source.azureAISearch.detail" ), data: TemplateNames.CustomCopilotRagAzureAISearch, }; @@ -200,10 +200,10 @@ export class CustomCopilotRagOptions { return { id: "custom-copilot-rag-customApi", label: getLocalizedString( - "core.createProjectQuestion.capability.customCopilotRagCustomApiOption.label" + "template.teams.rag.source.customApi.label" ), detail: getLocalizedString( - "core.createProjectQuestion.capability.customCopilotRagCustomApiOption.detail" + "template.teams.rag.source.customApi.detail" ), description: getLocalizedString("core.createProjectQuestion.option.description.preview"), data: TemplateNames.CustomCopilotRagCustomApi, diff --git a/packages/fx-core/src/question/scaffold/vsc/teamsProjectTypeNode.ts b/packages/fx-core/src/question/scaffold/vsc/teamsProjectTypeNode.ts index 2d0a7ad4f28..ca97b5f2991 100644 --- a/packages/fx-core/src/question/scaffold/vsc/teamsProjectTypeNode.ts +++ b/packages/fx-core/src/question/scaffold/vsc/teamsProjectTypeNode.ts @@ -94,10 +94,10 @@ export function customCopilotRagNode(): IQTreeNode { type: "singleSelect", name: QuestionNames.CustomCopilotRag, title: getLocalizedString( - "core.createProjectQuestion.capability.customCopilotRagOption.label" + "template.teams.rag.label" ), placeholder: getLocalizedString( - "core.createProjectQuestion.capability.customCopilotRag.placeholder" + "template.teams.rag.source.placeholder" ), staticOptions: [ CustomCopilotRagOptions.customize(), From e601f21b7dd7cf058858cae3adfcae88e00dcfbe Mon Sep 17 00:00:00 2001 From: Zhiyu You Date: Mon, 13 Apr 2026 17:02:44 +0800 Subject: [PATCH 11/27] build: update vsc version to 6.8 --- packages/vscode-extension/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vscode-extension/package.json b/packages/vscode-extension/package.json index 6b7b7793410..3a0e74c7a36 100644 --- a/packages/vscode-extension/package.json +++ b/packages/vscode-extension/package.json @@ -2,7 +2,7 @@ "name": "ms-teams-vscode-extension", "displayName": "Microsoft 365 Agents Toolkit", "description": "Create, debug, and deploy agents with Microsoft 365 Agents Toolkit", - "version": "6.6.1", + "version": "6.8.0-rc", "publisher": "TeamsDevApp", "author": "Microsoft Corporation", "private": true, From 0bd51e17f98427e6a93bc9ff7aa6fe9a5ffcc866 Mon Sep 17 00:00:00 2001 From: Helly Zhang <49181894+hellyzh@users.noreply.github.com> Date: Mon, 13 Apr 2026 16:45:03 +0800 Subject: [PATCH 12/27] fix: replace variable accounName for cli login (#15694) --- packages/cli/src/commonlib/codeFlowLogin.ts | 6 +- .../unit/commonlib/codeFlowLogin.tests.ts | 81 +++++++++++++++++++ 2 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 packages/cli/tests/unit/commonlib/codeFlowLogin.tests.ts diff --git a/packages/cli/src/commonlib/codeFlowLogin.ts b/packages/cli/src/commonlib/codeFlowLogin.ts index 0a0339df659..e60bb8a77db 100644 --- a/packages/cli/src/commonlib/codeFlowLogin.ts +++ b/packages/cli/src/commonlib/codeFlowLogin.ts @@ -303,7 +303,11 @@ export class CodeFlowLogin { const loopbackTemplatePath = path.join(__dirname, "codeFlowResult", "index.html"); let loopbackTemplate = undefined; if (fs.pathExistsSync(loopbackTemplatePath)) { - loopbackTemplate = await fs.readFile(loopbackTemplatePath, "utf-8"); + const displayName = this.accountName == "azure" ? "Azure" : "M365"; + loopbackTemplate = (await fs.readFile(loopbackTemplatePath, "utf-8")).replace( + /\${accountName}/g, + displayName + ); } const interactiveRequest = { scopes: scopes, diff --git a/packages/cli/tests/unit/commonlib/codeFlowLogin.tests.ts b/packages/cli/tests/unit/commonlib/codeFlowLogin.tests.ts new file mode 100644 index 00000000000..ebbb535e87e --- /dev/null +++ b/packages/cli/tests/unit/commonlib/codeFlowLogin.tests.ts @@ -0,0 +1,81 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import "mocha"; +import sinon from "sinon"; +import { expect } from "../utils"; +import { CodeFlowLogin } from "../../../src/commonlib/codeFlowLogin"; +import CliTelemetry from "../../../src/telemetry/cliTelemetry"; + +describe("CodeFlowLogin.loginWithBroker", function () { + const sandbox = sinon.createSandbox(); + + // A minimal JWT-like token: header.payload.signature + // payload = base64({"oid":"fake-oid","upn":"test@test.com"}) + const fakeAccessToken = + "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9." + + Buffer.from(JSON.stringify({ oid: "fake-oid", upn: "test@test.com" })).toString("base64") + + ".fake-signature"; + + const fakeResponse = { + account: { + homeAccountId: "fake-id", + environment: "login.microsoftonline.com", + tenantId: "fake-tenant", + username: "test@test.com", + localAccountId: "fake-local-id", + }, + accessToken: fakeAccessToken, + }; + + const config = { + auth: { + clientId: "fake-client-id", + authority: "https://login.microsoftonline.com/common", + }, + }; + + afterEach(() => { + sandbox.restore(); + }); + + function setupLogin(accountName: string) { + sandbox.stub(CliTelemetry, "sendTelemetryEvent"); + + const codeFlowLogin = new CodeFlowLogin([], config, 0, accountName); + let capturedRequest: any; + sandbox.stub(codeFlowLogin.pca, "acquireTokenInteractive").callsFake(async (request: any) => { + capturedRequest = request; + return fakeResponse as any; + }); + sandbox.stub(codeFlowLogin as any, "mutex").value({ + runExclusive: async (fn: any) => fn(), + }); + + return { codeFlowLogin, getCapturedRequest: () => capturedRequest }; + } + + it("should replace accountName placeholder with M365 in loopback template for m365 account", async () => { + const { codeFlowLogin, getCapturedRequest } = setupLogin("appStudio"); + + await codeFlowLogin.loginWithBroker(["scope1"]); + const req = getCapturedRequest(); + + expect(req.successTemplate).to.include("M365 - Sign In"); + expect(req.successTemplate).to.not.include("$" + "{accountName}"); + expect(req.errorTemplate).to.include("M365 - Sign In"); + expect(req.errorTemplate).to.not.include("$" + "{accountName}"); + }); + + it("should replace accountName placeholder with Azure in loopback template for azure account", async () => { + const { codeFlowLogin, getCapturedRequest } = setupLogin("azure"); + + await codeFlowLogin.loginWithBroker(["scope1"]); + const req = getCapturedRequest(); + + expect(req.successTemplate).to.include("Azure - Sign In"); + expect(req.successTemplate).to.not.include("$" + "{accountName}"); + expect(req.errorTemplate).to.include("Azure - Sign In"); + expect(req.errorTemplate).to.not.include("$" + "{accountName}"); + }); +}); From 39ae81b294ef0b118ec56134f1ed309ab704de53 Mon Sep 17 00:00:00 2001 From: Zhiyu You Date: Mon, 13 Apr 2026 17:14:38 +0800 Subject: [PATCH 13/27] fix: add action ui on vsc --- packages/fx-core/src/question/constants.ts | 7 +- .../fx-core/tests/question/question.test.ts | 65 +++++++++++++++++++ 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/packages/fx-core/src/question/constants.ts b/packages/fx-core/src/question/constants.ts index de2b94c42e6..bdb26131814 100644 --- a/packages/fx-core/src/question/constants.ts +++ b/packages/fx-core/src/question/constants.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { Inputs, OptionItem } from "@microsoft/teamsfx-api"; +import { Inputs, OptionItem, Platform } from "@microsoft/teamsfx-api"; import { FeatureFlags, featureFlagManager } from "../common/featureFlags"; import { getLocalizedString } from "../common/localizeUtils"; export { QuestionNames } from "./questionNames"; @@ -517,7 +517,10 @@ export class ActionStartOptions { static all(inputs: Inputs, doesProjectExists?: boolean): OptionItem[] { if (doesProjectExists) { const options: OptionItem[] = [ActionStartOptions.apiSpec()]; - if (featureFlagManager.getBooleanValue(FeatureFlags.MCPForDA)) { + if ( + featureFlagManager.getBooleanValue(FeatureFlags.MCPForDA) && + inputs.platform !== Platform.VSCode + ) { options.push(ActionStartOptions.mcp()); } return options; diff --git a/packages/fx-core/tests/question/question.test.ts b/packages/fx-core/tests/question/question.test.ts index b23bb2f15fa..d99b94a07e5 100644 --- a/packages/fx-core/tests/question/question.test.ts +++ b/packages/fx-core/tests/question/question.test.ts @@ -1813,3 +1813,68 @@ describe("updateActionWithMCP", async () => { // function1 should not be included (wrong runtime type) }); }); + +describe("ActionStartOptions", () => { + const sandbox = sinon.createSandbox(); + afterEach(() => { + sandbox.restore(); + }); + + describe("all()", () => { + it("should not include MCP option on VSCode platform even when MCPForDA is enabled", () => { + sandbox.stub(featureFlagManager, "getBooleanValue").callsFake((flag) => { + if (flag === FeatureFlags.MCPForDA) return true; + return false; + }); + const inputs: Inputs = { platform: Platform.VSCode }; + const options = ActionStartOptions.all(inputs, true); + assert.isFalse(options.some((o) => o.id === ActionStartOptions.mcp().id)); + assert.isTrue(options.some((o) => o.id === ActionStartOptions.apiSpec().id)); + }); + + it("should include MCP option on CLI platform when MCPForDA is enabled", () => { + sandbox.stub(featureFlagManager, "getBooleanValue").callsFake((flag) => { + if (flag === FeatureFlags.MCPForDA) return true; + return false; + }); + const inputs: Inputs = { platform: Platform.CLI }; + const options = ActionStartOptions.all(inputs, true); + assert.isTrue(options.some((o) => o.id === ActionStartOptions.mcp().id)); + assert.isTrue(options.some((o) => o.id === ActionStartOptions.apiSpec().id)); + }); + + it("should not include MCP option on CLI platform when MCPForDA is disabled", () => { + sandbox.stub(featureFlagManager, "getBooleanValue").callsFake((flag) => { + if (flag === FeatureFlags.MCPForDA) return false; + return false; + }); + const inputs: Inputs = { platform: Platform.CLI }; + const options = ActionStartOptions.all(inputs, true); + assert.isFalse(options.some((o) => o.id === ActionStartOptions.mcp().id)); + }); + + it("should return newApi and apiSpec when doesProjectExists is false", () => { + const inputs: Inputs = { platform: Platform.VSCode }; + const options = ActionStartOptions.all(inputs, false); + assert.equal(options.length, 2); + assert.isTrue(options.some((o) => o.id === ActionStartOptions.newApi().id)); + assert.isTrue(options.some((o) => o.id === ActionStartOptions.apiSpec().id)); + }); + }); + + describe("staticAll()", () => { + it("should include apiSpec and mcp when doesProjectExists is true", () => { + const options = ActionStartOptions.staticAll(true); + assert.equal(options.length, 2); + assert.isTrue(options.some((o) => o.id === ActionStartOptions.apiSpec().id)); + assert.isTrue(options.some((o) => o.id === ActionStartOptions.mcp().id)); + }); + + it("should include newApi and apiSpec when doesProjectExists is false", () => { + const options = ActionStartOptions.staticAll(false); + assert.equal(options.length, 2); + assert.isTrue(options.some((o) => o.id === ActionStartOptions.newApi().id)); + assert.isTrue(options.some((o) => o.id === ActionStartOptions.apiSpec().id)); + }); + }); +}); From 63500ea47ba8d912a7d6d09fd4c4cf46802e279e Mon Sep 17 00:00:00 2001 From: qfai Date: Mon, 13 Apr 2026 17:33:24 +0800 Subject: [PATCH 14/27] style: format files with prettier Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- packages/fx-core/src/question/constants.ts | 24 ++------ packages/fx-core/src/question/create.ts | 4 +- .../scaffold/vsc/CapabilityOptions.ts | 56 +++++-------------- .../scaffold/vsc/teamsProjectTypeNode.ts | 8 +-- 4 files changed, 23 insertions(+), 69 deletions(-) diff --git a/packages/fx-core/src/question/constants.ts b/packages/fx-core/src/question/constants.ts index cff01b73226..a2a9f5cf08b 100644 --- a/packages/fx-core/src/question/constants.ts +++ b/packages/fx-core/src/question/constants.ts @@ -292,36 +292,24 @@ export class CustomCopilotRagOptions { static customize(): OptionItem { return { id: "custom-copilot-rag-customize", - label: getLocalizedString( - "template.teams.rag.source.customize.label" - ), - detail: getLocalizedString( - "template.teams.rag.source.customize.detail" - ), + label: getLocalizedString("template.teams.rag.source.customize.label"), + detail: getLocalizedString("template.teams.rag.source.customize.detail"), }; } static azureAISearch(): OptionItem { return { id: "custom-copilot-rag-azureAISearch", - label: getLocalizedString( - "template.teams.rag.source.azureAISearch.label" - ), - detail: getLocalizedString( - "template.teams.rag.source.azureAISearch.detail" - ), + label: getLocalizedString("template.teams.rag.source.azureAISearch.label"), + detail: getLocalizedString("template.teams.rag.source.azureAISearch.detail"), }; } static customApi(): OptionItem { return { id: "custom-copilot-rag-customApi", - label: getLocalizedString( - "template.teams.rag.source.customApi.label" - ), - detail: getLocalizedString( - "template.teams.rag.source.customApi.detail" - ), + label: getLocalizedString("template.teams.rag.source.customApi.label"), + detail: getLocalizedString("template.teams.rag.source.customApi.detail"), description: getLocalizedString("core.createProjectQuestion.option.description.preview"), }; } diff --git a/packages/fx-core/src/question/create.ts b/packages/fx-core/src/question/create.ts index 1c292ef2fc9..96498d5c648 100644 --- a/packages/fx-core/src/question/create.ts +++ b/packages/fx-core/src/question/create.ts @@ -1015,9 +1015,7 @@ function customCopilotRagQuestion(): SingleSelectQuestion { type: "singleSelect", name: QuestionNames.CustomCopilotRag, title: getLocalizedString("core.createProjectQuestion.capability.customCopilotRag.title"), - placeholder: getLocalizedString( - "template.teams.rag.source.placeholder" - ), + placeholder: getLocalizedString("template.teams.rag.source.placeholder"), staticOptions: CustomCopilotRagOptions.all(), dynamicOptions: () => CustomCopilotRagOptions.all(), default: CustomCopilotRagOptions.customize().id, diff --git a/packages/fx-core/src/question/scaffold/vsc/CapabilityOptions.ts b/packages/fx-core/src/question/scaffold/vsc/CapabilityOptions.ts index 4986cb03fd4..7fa610b09c4 100644 --- a/packages/fx-core/src/question/scaffold/vsc/CapabilityOptions.ts +++ b/packages/fx-core/src/question/scaffold/vsc/CapabilityOptions.ts @@ -17,12 +17,8 @@ export class CustomEngineAgentOptions { static basicCustomEngineAgent(): OptionItem { return { id: "basic-custom-engine-agent", - label: getLocalizedString( - "template.customEngineAgent.basic.label" - ), - detail: getLocalizedString( - "template.customEngineAgent.basic.detail" - ), + label: getLocalizedString("template.customEngineAgent.basic.label"), + detail: getLocalizedString("template.customEngineAgent.basic.detail"), data: TemplateNames.BasicCustomEngineAgent, }; } @@ -100,12 +96,8 @@ export class TeamsAgentCapabilityOptions { : undefined; return { id: "custom-copilot-basic", - label: getLocalizedString( - "template.teams.general.label" - ), - detail: getLocalizedString( - "template.teams.general.detail" - ), + label: getLocalizedString("template.teams.general.label"), + detail: getLocalizedString("template.teams.general.detail"), description: description, data: TemplateNames.CustomCopilotBasic, }; @@ -117,12 +109,8 @@ export class TeamsAgentCapabilityOptions { : undefined; return { id: "custom-copilot-rag", - label: getLocalizedString( - "template.teams.rag.label" - ), - detail: getLocalizedString( - "template.teams.rag.detail" - ), + label: getLocalizedString("template.teams.rag.label"), + detail: getLocalizedString("template.teams.rag.detail"), description: description, }; } @@ -130,12 +118,8 @@ export class TeamsAgentCapabilityOptions { static collaboratorAgent(): OptionItem { return { id: "teams-collaborator-agent", - label: getLocalizedString( - "template.teams.collaboratorAgent.label" - ), - detail: getLocalizedString( - "template.teams.collaboratorAgent.detail" - ), + label: getLocalizedString("template.teams.collaboratorAgent.label"), + detail: getLocalizedString("template.teams.collaboratorAgent.detail"), data: TemplateNames.TeamsCollaboratorAgent, }; } @@ -173,12 +157,8 @@ export class CustomCopilotRagOptions { static customize(): OptionItem { return { id: "custom-copilot-rag-customize", - label: getLocalizedString( - "template.teams.rag.source.customize.label" - ), - detail: getLocalizedString( - "template.teams.rag.source.customize.detail" - ), + label: getLocalizedString("template.teams.rag.source.customize.label"), + detail: getLocalizedString("template.teams.rag.source.customize.detail"), data: TemplateNames.CustomCopilotRagCustomize, }; } @@ -186,12 +166,8 @@ export class CustomCopilotRagOptions { static azureAISearch(): OptionItem { return { id: "custom-copilot-rag-azureAISearch", - label: getLocalizedString( - "template.teams.rag.source.azureAISearch.label" - ), - detail: getLocalizedString( - "template.teams.rag.source.azureAISearch.detail" - ), + label: getLocalizedString("template.teams.rag.source.azureAISearch.label"), + detail: getLocalizedString("template.teams.rag.source.azureAISearch.detail"), data: TemplateNames.CustomCopilotRagAzureAISearch, }; } @@ -199,12 +175,8 @@ export class CustomCopilotRagOptions { static customApi(): OptionItem { return { id: "custom-copilot-rag-customApi", - label: getLocalizedString( - "template.teams.rag.source.customApi.label" - ), - detail: getLocalizedString( - "template.teams.rag.source.customApi.detail" - ), + label: getLocalizedString("template.teams.rag.source.customApi.label"), + detail: getLocalizedString("template.teams.rag.source.customApi.detail"), description: getLocalizedString("core.createProjectQuestion.option.description.preview"), data: TemplateNames.CustomCopilotRagCustomApi, }; diff --git a/packages/fx-core/src/question/scaffold/vsc/teamsProjectTypeNode.ts b/packages/fx-core/src/question/scaffold/vsc/teamsProjectTypeNode.ts index ca97b5f2991..cb85899f714 100644 --- a/packages/fx-core/src/question/scaffold/vsc/teamsProjectTypeNode.ts +++ b/packages/fx-core/src/question/scaffold/vsc/teamsProjectTypeNode.ts @@ -93,12 +93,8 @@ export function customCopilotRagNode(): IQTreeNode { data: { type: "singleSelect", name: QuestionNames.CustomCopilotRag, - title: getLocalizedString( - "template.teams.rag.label" - ), - placeholder: getLocalizedString( - "template.teams.rag.source.placeholder" - ), + title: getLocalizedString("template.teams.rag.label"), + placeholder: getLocalizedString("template.teams.rag.source.placeholder"), staticOptions: [ CustomCopilotRagOptions.customize(), CustomCopilotRagOptions.azureAISearch(), From ae9d3762feba77b4e21e00c6971ece0400b8ad58 Mon Sep 17 00:00:00 2001 From: Zhiyu You Date: Tue, 14 Apr 2026 13:30:23 +0800 Subject: [PATCH 15/27] build: bump template version to 6.8 --- packages/fx-core/src/common/templates-config.json | 4 ++-- templates/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/fx-core/src/common/templates-config.json b/packages/fx-core/src/common/templates-config.json index 50c5ef332af..ff96ca18bb1 100644 --- a/packages/fx-core/src/common/templates-config.json +++ b/packages/fx-core/src/common/templates-config.json @@ -1,6 +1,6 @@ { - "version": "0.0.0-rc", - "localVersion": "6.6.4-rc.1", + "version": "~6.8", + "localVersion": "6.8.0", "tagPrefix": "templates@", "vstagPrefix": "templates-vs@", "vsversion": "18.6.0", diff --git a/templates/package.json b/templates/package.json index cfdf2b34be7..549c4ee3268 100644 --- a/templates/package.json +++ b/templates/package.json @@ -1,6 +1,6 @@ { "name": "templates", - "version": "6.6.4-rc.1", + "version": "6.8.0", "private": "true", "license": "MIT", "vsversion": "18.6.0", From ccf16faa10291456d4ac8594d904605fe5dc38e8 Mon Sep 17 00:00:00 2001 From: wh-alice Date: Tue, 14 Apr 2026 06:50:01 +0000 Subject: [PATCH 16/27] build(release): publish detail - @microsoft/m365agentstoolkit-cli@1.1.7-rc.0 - @microsoft/teamsfx-core@3.0.12-rc.0 - @microsoft/teamsfx-server@2.0.28-rc.0 - @microsoft/teamsfx-test@0.1.17-rc.0 - ms-teams-vscode-extension@6.8.0-rc.0 - templates@6.8.1-rc.0 --- packages/cli/package.json | 2 +- packages/fx-core/package.json | 4 ++-- packages/fx-core/src/common/templates-config.json | 4 ++-- packages/server/package.json | 2 +- packages/tests/package.json | 2 +- packages/vscode-extension/package.json | 2 +- templates/package.json | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/cli/package.json b/packages/cli/package.json index 920ad03e86c..a83165d4ef5 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@microsoft/m365agentstoolkit-cli", - "version": "1.1.6", + "version": "1.1.7-rc.0", "author": "Microsoft Corporation", "description": "Microsoft 365 Agents Toolkit CLI", "license": "MIT", diff --git a/packages/fx-core/package.json b/packages/fx-core/package.json index 950cae46b8a..67b5ba8839b 100644 --- a/packages/fx-core/package.json +++ b/packages/fx-core/package.json @@ -1,6 +1,6 @@ { "name": "@microsoft/teamsfx-core", - "version": "3.0.11", + "version": "3.0.12-rc.0", "main": "build/index.js", "types": "build/index.d.ts", "license": "MIT", @@ -108,10 +108,10 @@ "@feathersjs/hooks": "^0.6.5", "@microsoft/dev-tunnels-contracts": "1.1.9", "@microsoft/dev-tunnels-management": "1.1.9", - "@modelcontextprotocol/sdk": "^1.27.1", "@microsoft/kiota": "1.29.0", "@microsoft/m365-spec-parser": "workspace:^", "@microsoft/teamsfx-api": "workspace:*", + "@modelcontextprotocol/sdk": "^1.27.1", "adm-zip": "^0.5.10", "ajv": "^8.18.0", "axios": "^1.8.3", diff --git a/packages/fx-core/src/common/templates-config.json b/packages/fx-core/src/common/templates-config.json index ff96ca18bb1..1723b617fbf 100644 --- a/packages/fx-core/src/common/templates-config.json +++ b/packages/fx-core/src/common/templates-config.json @@ -1,6 +1,6 @@ { - "version": "~6.8", - "localVersion": "6.8.0", + "version": "0.0.0-rc", + "localVersion": "6.8.1-rc.0", "tagPrefix": "templates@", "vstagPrefix": "templates-vs@", "vsversion": "18.6.0", diff --git a/packages/server/package.json b/packages/server/package.json index f8045c01f87..a381025c896 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,6 +1,6 @@ { "name": "@microsoft/teamsfx-server", - "version": "2.0.27", + "version": "2.0.28-rc.0", "author": "Microsoft Corporation", "description": "", "license": "MIT", diff --git a/packages/tests/package.json b/packages/tests/package.json index 62481c41aff..d39ab67ae11 100644 --- a/packages/tests/package.json +++ b/packages/tests/package.json @@ -1,6 +1,6 @@ { "name": "@microsoft/teamsfx-test", - "version": "0.1.16", + "version": "0.1.17-rc.0", "description": "A UI Test Project of Teams Toolkit Extension", "private": true, "author": "Microsoft Corporation", diff --git a/packages/vscode-extension/package.json b/packages/vscode-extension/package.json index 3a0e74c7a36..66a7c084553 100644 --- a/packages/vscode-extension/package.json +++ b/packages/vscode-extension/package.json @@ -2,7 +2,7 @@ "name": "ms-teams-vscode-extension", "displayName": "Microsoft 365 Agents Toolkit", "description": "Create, debug, and deploy agents with Microsoft 365 Agents Toolkit", - "version": "6.8.0-rc", + "version": "6.8.0-rc.0", "publisher": "TeamsDevApp", "author": "Microsoft Corporation", "private": true, diff --git a/templates/package.json b/templates/package.json index 549c4ee3268..55d56e7a99b 100644 --- a/templates/package.json +++ b/templates/package.json @@ -1,6 +1,6 @@ { "name": "templates", - "version": "6.8.0", + "version": "6.8.1-rc.0", "private": "true", "license": "MIT", "vsversion": "18.6.0", From 17233d553da3ffaa2161e7c71dc890b026b5ddd7 Mon Sep 17 00:00:00 2001 From: qfai Date: Wed, 15 Apr 2026 15:38:57 +0800 Subject: [PATCH 17/27] feat: update App Manifest version to v1.26 in all templates and packages Cherry-pick from copilot/update-app-manifest-version-v1-26-another-one (34bca03c58) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../manifest/src/generated-types/index.ts | 9 +- .../teams/TeamsManifestV1D26.ts | 3376 ++++++++++++++++ .../teams/v1.26/MicrosoftTeams.schema.json | 3407 +++++++++++++++++ packages/mcp-server/src/fetcher.ts | 2 +- packages/mcp-server/tests/fetcher.test.ts | 2 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../sso-tab-ssr/appPackage/manifest.json.tpl | 4 +- .../workflow/appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../non-sso-tab/appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../sso-tab-naa/appPackage/manifest.json.tpl | 4 +- .../js/workflow/appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../non-sso-tab/appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../ts/spfx-tab/appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.local.json.tpl | 4 +- .../sso-tab-naa/appPackage/manifest.json.tpl | 4 +- .../ts/workflow/appPackage/manifest.json.tpl | 4 +- .../basic-tab/appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../default-bot/appPackage/manifest.json.tpl | 4 +- .../csharp/empty/appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../default-bot/appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../basic-tab/appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../default-bot/appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../ts/basic-tab/appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../default-bot/appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- .../appPackage/manifest.json.tpl | 4 +- 128 files changed, 7039 insertions(+), 249 deletions(-) create mode 100644 packages/manifest/src/generated-types/teams/TeamsManifestV1D26.ts create mode 100644 packages/manifest/src/json-schemas/teams/v1.26/MicrosoftTeams.schema.json diff --git a/packages/manifest/src/generated-types/index.ts b/packages/manifest/src/generated-types/index.ts index d44c35bb186..4e5483284a1 100644 --- a/packages/manifest/src/generated-types/index.ts +++ b/packages/manifest/src/generated-types/index.ts @@ -36,6 +36,7 @@ import * as TeamsManifestV1D22 from "./teams/TeamsManifestV1D22"; import * as TeamsManifestV1D23 from "./teams/TeamsManifestV1D23"; import * as TeamsManifestV1D24 from "./teams/TeamsManifestV1D24"; import * as TeamsManifestV1D25 from "./teams/TeamsManifestV1D25"; +import * as TeamsManifestV1D26 from "./teams/TeamsManifestV1D26"; import * as TeamsManifestV1D3 from "./teams/TeamsManifestV1D3"; import * as TeamsManifestV1D4 from "./teams/TeamsManifestV1D4"; import * as TeamsManifestV1D5 from "./teams/TeamsManifestV1D5"; @@ -73,6 +74,7 @@ export { TeamsManifestV1D23, TeamsManifestV1D24, TeamsManifestV1D25, + TeamsManifestV1D26, TeamsManifestV1D3, TeamsManifestV1D4, TeamsManifestV1D5, @@ -110,9 +112,10 @@ export type TeamsManifest = | TeamsManifestV1D23.TeamsManifestV1D23 | TeamsManifestV1D24.TeamsManifestV1D24 | TeamsManifestV1D25.TeamsManifestV1D25 + | TeamsManifestV1D26.TeamsManifestV1D26 | TeamsManifestVDevPreview.TeamsManifestVDevPreview; -export type TeamsManifestLatest = TeamsManifestV1D25.TeamsManifestV1D25; +export type TeamsManifestLatest = TeamsManifestV1D26.TeamsManifestV1D26; export { SensitivityLabel } from "./copilot/declarative-agent/DeclarativeAgentManifestV1D6"; @@ -236,6 +239,10 @@ const TeamsManifestConverterMap: Converters = { TeamsManifestV1D25.Convert.toTeamsManifestV1D25, TeamsManifestV1D25.Convert.teamsManifestV1D25ToJson, ], + "1.26": [ + TeamsManifestV1D26.Convert.toTeamsManifestV1D26, + TeamsManifestV1D26.Convert.teamsManifestV1D26ToJson, + ], devPreview: [ TeamsManifestVDevPreview.Convert.toTeamsManifestVDevPreview, TeamsManifestVDevPreview.Convert.teamsManifestVDevPreviewToJson, diff --git a/packages/manifest/src/generated-types/teams/TeamsManifestV1D26.ts b/packages/manifest/src/generated-types/teams/TeamsManifestV1D26.ts new file mode 100644 index 00000000000..4fd5f40b66f --- /dev/null +++ b/packages/manifest/src/generated-types/teams/TeamsManifestV1D26.ts @@ -0,0 +1,3376 @@ +// To parse this data: +// +// import { Convert, TeamsManifestV1D26 } from "./file"; +// +// const teamsManifestV1D26 = Convert.toTeamsManifestV1D26(json); +// +// These functions will throw an error if the JSON doesn't +// match the expected interface, even if the JSON is valid. + +export interface TeamsManifestV1D26 { + $schema?: string; + /** + * The version of the schema this manifest is using. This schema version supports extending + * Teams apps to other parts of the Microsoft 365 ecosystem. More info at + * https://aka.ms/extendteamsapps. + */ + manifestVersion: "1.26"; + /** + * The version of the app. Changes to your manifest should cause a version change. This + * version string must follow the semver standard (http://semver.org). + */ + version: string; + /** + * A unique identifier for this app. This id must be a GUID. + */ + id: string; + localizationInfo?: LocalizationInfo; + developer: Developer; + name: NameClass; + description: Description; + icons: Icons; + /** + * A color to use in conjunction with the icon. The value must be a valid HTML color code + * starting with '#', for example `#4464ee`. + */ + accentColor: string; + /** + * These are tabs users can optionally add to their channels and 1:1 or group chats and + * require extra configuration before they are added. Configurable tabs are not supported in + * the personal scope. Currently only one configurable tab per app is supported. + */ + configurableTabs?: ConfigurableTab[]; + /** + * A set of tabs that may be 'pinned' by default, without the user adding them manually. + * Static tabs declared in personal scope are always pinned to the app's personal + * experience. Static tabs do not currently support the 'teams' scope. + */ + staticTabs?: StaticTab[]; + /** + * The set of bots for this app. Currently only one bot per app is supported. + */ + bots?: Bot[]; + /** + * The set of Office365 connectors for this app. Currently only one connector per app is + * supported. + */ + connectors?: Connector[]; + /** + * Subscription offer associated with this app. + */ + subscriptionOffer?: SubscriptionOffer; + /** + * The set of compose extensions for this app. Currently only one compose extension per app + * is supported. + */ + composeExtensions?: ComposeExtension[]; + /** + * Specifies the permissions the app requests from users. + */ + permissions?: Permission[]; + /** + * Specify the native features on a user's device that your app may request access to. + */ + devicePermissions?: DevicePermission[]; + /** + * A list of valid domains from which the tabs expect to load any content. Domain listings + * can include wildcards, for example `*.example.com`. If your tab configuration or content + * UI needs to navigate to any other domain besides the one use for tab configuration, that + * domain must be specified here. + */ + validDomains?: string[]; + /** + * Specify your AAD App ID and Graph information to help users seamlessly sign into your AAD + * app. + */ + webApplicationInfo?: WebApplicationInfo; + /** + * Specify the app's Graph connector configuration. If this is present then + * webApplicationInfo.id must also be specified. + */ + graphConnector?: GraphConnector; + /** + * A value indicating whether or not show loading indicator when app/tab is loading + */ + showLoadingIndicator?: boolean; + /** + * A value indicating whether a personal app is rendered without a tab header-bar + */ + isFullScreen?: boolean; + activities?: Activities; + /** + * A property in the app manifest that declares support for all channel features, + * categorized by tiers. + */ + supportsChannelFeatures?: "tier1"; + /** + * List of 'non-standard' channel types that the app supports. Note: Channels of standard + * type are supported by default if the app supports team scope. + */ + supportedChannelTypes?: SupportedChannelType[]; + /** + * A list of tenant configured properties for an app + */ + configurableProperties?: ConfigurableProperty[]; + /** + * A value indicating whether an app is blocked by default until admin allows it + */ + defaultBlockUntilAdminAction?: boolean; + /** + * The url to the page that provides additional app information for the admins + */ + publisherDocsUrl?: string; + /** + * The install scope defined for this app by default. This will be the option displayed on + * the button when a user tries to add the app + */ + defaultInstallScope?: DefaultInstallScope; + /** + * When a group install scope is selected, this will define the default capability when the + * user installs the app + */ + defaultGroupCapability?: DefaultGroupCapability; + /** + * Specify meeting extension definition. + */ + meetingExtensionDefinition?: MeetingExtensionDefinition; + /** + * Specify and consolidates authorization related information for the App. + */ + authorization?: TeamsManifestV1D26Authorization; + extensions?: ElementExtension[]; + /** + * Defines the list of cards which could be pinned to dashboards that can provide summarized + * view of information relevant to user. + */ + dashboardCards?: DashboardCard[]; + /** + * The Intune-related properties for the app. + */ + intuneInfo?: IntuneInfo; + copilotAgents?: CopilotAgents; + /** + * An array of agentic user templates references. + */ + agenticUserTemplates?: AgenticUserTemplateRef[]; + elementRelationshipSet?: ElementRelationshipSet; + /** + * Optional property containing background loading configuration. By opting in to this + * performance enhancement, your app is eligible to be loaded in the background in any + * Microsoft 365 application host that supports this feature. + */ + backgroundLoadConfiguration?: BackgroundLoadConfiguration; +} + +export interface Activities { + /** + * Specify the types of activites that your app can post to a users activity feed + */ + activityTypes?: ActivityType[]; + /** + * Specify the customized icons that your app can post to a users activity feed + */ + activityIcons?: ActivityIcon[]; +} + +export interface ActivityIcon { + /** + * Represents the unique icon ID. + */ + id: string; + /** + * Represents the relative path to the icon image. Image should be size 32x32. + */ + iconFile: string; +} + +export interface ActivityType { + type: string; + description: string; + templateText: string; + /** + * An array containing valid icon IDs per activity type. + */ + allowedIconIds?: string[]; +} + +export interface AgenticUserTemplateRef { + /** + * Unique identifier for the agentic user template. Must contain only alphanumeric + * characters, dots, underscores, and hyphens. + */ + id: string; + /** + * Relative file path to this agentic user template element file in the application package. + */ + file: string; +} + +/** + * Specify and consolidates authorization related information for the App. + */ +export interface TeamsManifestV1D26Authorization { + /** + * List of permissions that the app needs to function. + */ + permissions?: Permissions; +} + +/** + * List of permissions that the app needs to function. + */ +export interface Permissions { + /** + * Permissions that must be granted on a per resource instance basis. + */ + resourceSpecific?: ResourceSpecific[]; +} + +export interface ResourceSpecific { + /** + * The name of the resource-specific permission. + */ + name: string; + /** + * The type of the resource-specific permission: delegated vs application. + */ + type: ResourceSpecificType; +} + +/** + * The type of the resource-specific permission: delegated vs application. + */ +export type ResourceSpecificType = "Application" | "Delegated"; + +/** + * Optional property containing background loading configuration. By opting in to this + * performance enhancement, your app is eligible to be loaded in the background in any + * Microsoft 365 application host that supports this feature. + */ +export interface BackgroundLoadConfiguration { + /** + * Optional property within backgroundLoadConfiguration containing tab settings for + * background loading. + */ + tabConfiguration?: TabConfiguration; +} + +/** + * Optional property within backgroundLoadConfiguration containing tab settings for + * background loading. + */ +export interface TabConfiguration { + /** + * Required URL for background loading. This can be the same contentUrl from the staticTabs + * section or an alternative endpoint used for background loading. + */ + contentUrl: string; +} + +export interface Bot { + /** + * The Microsoft App ID specified for the bot in the Bot Framework portal + * (https://dev.botframework.com/bots) + */ + botId: string; + configuration?: Configuration; + /** + * This value describes whether or not the bot utilizes a user hint to add the bot to a + * specific channel. + */ + needsChannelSelector?: boolean; + /** + * A value indicating whether or not the bot is a one-way notification only bot, as opposed + * to a conversational bot. + */ + isNotificationOnly?: boolean; + /** + * A value indicating whether the bot supports uploading/downloading of files. + */ + supportsFiles?: boolean; + /** + * A value indicating whether the bot supports audio calling. + */ + supportsCalling?: boolean; + /** + * A value indicating whether the bot supports video calling. + */ + supportsVideo?: boolean; + /** + * Specifies whether the bot offers an experience in the context of a channel in a team, in + * a group chat (groupChat), an experience scoped to an individual user alone (personal) OR + * within Copilot surfaces. These options are non-exclusive. + */ + scopes: CommandListScope[]; + /** + * The list of commands that the bot supplies, including their usage, description, and the + * scope for which the commands are valid. A separate command list should be used for each + * scope. + */ + commandLists?: CommandList[]; + requirementSet?: ElementRequirementSet; + /** + * System‑generated metadata. This information is maintained by Microsoft services and must + * not be modified manually. + */ + registrationInfo?: RegistrationInfo; +} + +export interface CommandList { + /** + * Specifies the scopes for which the command list is valid + */ + scopes: CommandListScope[]; + commands: CommandListCommand[]; +} + +export interface CommandListCommand { + /** + * The bot command name + */ + title: string; + /** + * A simple text description or an example of the command syntax and its arguments. + */ + description: string; +} + +export type CommandListScope = "team" | "personal" | "groupChat" | "copilot"; + +export interface Configuration { + team?: Team; + groupChat?: Team; +} + +export interface Team { + fetchTask?: boolean; + taskInfo?: TaskInfo; +} + +export interface TaskInfo { + /** + * Initial dialog title + */ + title?: string; + /** + * Dialog width - either a number in pixels or default layout such as 'large', 'medium', or + * 'small' + */ + width?: string; + /** + * Dialog height - either a number in pixels or default layout such as 'large', 'medium', or + * 'small' + */ + height?: string; + /** + * Initial webview URL + */ + url?: string; +} + +/** + * System‑generated metadata. This information is maintained by Microsoft services and must + * not be modified manually. + */ +export interface RegistrationInfo { + /** + * The partner source through which the bot is registered. System‑generated metadata. This + * information is maintained by Microsoft services and must not be modified manually. + */ + source: Source; + /** + * A Power Platform environment that serves as a container for building apps under a + * Microsoft 365 tenant and can only be accessed by users within that tenant. + * System‑generated metadata. This information is maintained by Microsoft services and must + * not be modified manually. + */ + environment?: string; + /** + * The Copilot Studio copilot schema name. System‑generated metadata. This information is + * maintained by Microsoft services and must not be modified manually. + */ + schemaName?: string; + /** + * The core services cluster category for Copilot Studio copilots. System‑generated + * metadata. This information is maintained by Microsoft services and must not be modified + * manually. + */ + clusterCategory?: string; +} + +/** + * The partner source through which the bot is registered. System‑generated metadata. This + * information is maintained by Microsoft services and must not be modified manually. + */ +export type Source = "standard" | "microsoftCopilotStudio" | "onedriveSharepoint"; + +/** + * An object representing a set of requirements that the host must support for the element. + */ +export interface ElementRequirementSet { + hostMustSupportFunctionalities: HostFunctionality[]; +} + +/** + * An object representing a specific functionality that a host must support. + */ +export interface HostFunctionality { + /** + * The name of the functionality. + */ + name: HostMustSupportFunctionalityName; +} + +/** + * The name of the functionality. + */ +export type HostMustSupportFunctionalityName = "dialogUrl" | "dialogUrlBot" | "dialogAdaptiveCard" | "dialogAdaptiveCardBot"; + +export interface ComposeExtension { + /** + * A unique identifier for the compose extension. + */ + id?: string; + /** + * The Microsoft App ID specified for the bot powering the compose extension in the Bot + * Framework portal (https://dev.botframework.com/bots) + */ + botId?: string; + /** + * Type of the compose extension. + */ + composeExtensionType?: ComposeExtensionType; + /** + * Object capturing authorization information. + */ + authorization?: ComposeExtensionAuthorization; + /** + * A relative file path to the api specification file in the manifest package. + */ + apiSpecificationFile?: string; + /** + * A value indicating whether the configuration of a compose extension can be updated by the + * user. + */ + canUpdateConfiguration?: boolean | null; + commands?: ComposeExtensionCommand[]; + /** + * A list of handlers that allow apps to be invoked when certain conditions are met + */ + messageHandlers?: MessageHandler[]; + requirementSet?: ElementRequirementSet; +} + +/** + * Object capturing authorization information. + */ +export interface ComposeExtensionAuthorization { + /** + * Enum of possible authentication types. + */ + authType?: AuthType; + /** + * Object capturing details needed to do single aad auth flow. It will be only present when + * auth type is entraId. + */ + microsoftEntraConfiguration?: MicrosoftEntraConfiguration; + /** + * Object capturing details needed to do service auth. It will be only present when auth + * type is apiSecretServiceAuth. + */ + apiSecretServiceAuthConfiguration?: APISecretServiceAuthConfiguration; + /** + * Object capturing details needed to match the application's OAuth configuration for the + * app. This should be and must be populated only when authType is set to oAuth2.0r + */ + oAuthConfiguration?: OAuthConfiguration; +} + +/** + * Object capturing details needed to do service auth. It will be only present when auth + * type is apiSecretServiceAuth. + */ +export interface APISecretServiceAuthConfiguration { + /** + * Registration id returned when developer submits the api key through Developer Portal. + */ + apiSecretRegistrationId?: string; +} + +/** + * Enum of possible authentication types. + */ +export type AuthType = "none" | "apiSecretServiceAuth" | "microsoftEntra" | "oAuth2.0"; + +/** + * Object capturing details needed to do single aad auth flow. It will be only present when + * auth type is entraId. + */ +export interface MicrosoftEntraConfiguration { + /** + * Boolean indicating whether single sign on is configured for the app. + */ + supportsSingleSignOn?: boolean; +} + +/** + * Object capturing details needed to match the application's OAuth configuration for the + * app. This should be and must be populated only when authType is set to oAuth2.0r + */ +export interface OAuthConfiguration { + /** + * The oAuth configuration id obtained by the Developer when registering their configuration + * in Developer Portal. + */ + oAuthConfigurationId?: string; +} + +export interface ComposeExtensionCommand { + /** + * Id of the command. + */ + id: string; + /** + * Type of the command + */ + type?: CommandType; + samplePrompts?: SamplePrompt[]; + /** + * A relative file path for api response rendering template file. + */ + apiResponseRenderingTemplateFile?: string; + /** + * Context where the command would apply + */ + context?: CommandContext[]; + /** + * Title of the command. + */ + title: string; + /** + * Description of the command. + */ + description?: string; + /** + * A boolean value that indicates if the command should be run once initially with no + * parameter. + */ + initialRun?: boolean; + /** + * A boolean value that indicates if it should fetch task module dynamically + */ + fetchTask?: boolean; + parameters?: Parameter[]; + taskInfo?: TaskInfo; + /** + * Semantic description for the command. + */ + semanticDescription?: string; +} + +export type CommandContext = "compose" | "commandBox" | "message"; + +export interface Parameter { + /** + * Name of the parameter. + */ + name: string; + /** + * Type of the parameter + */ + inputType?: InputType; + /** + * Title of the parameter. + */ + title: string; + /** + * Description of the parameter. + */ + description?: string; + /** + * The value indicates if this parameter is a required field. + */ + isRequired?: boolean; + /** + * Initial value for the parameter + */ + value?: string; + /** + * The choice options for the parameter + */ + choices?: Choice[]; + /** + * Semantic description for the parameter. + */ + semanticDescription?: string; +} + +export interface Choice { + /** + * Title of the choice + */ + title: string; + /** + * Value of the choice + */ + value: string; +} + +/** + * Type of the parameter + */ +export type InputType = "text" | "textarea" | "number" | "date" | "time" | "toggle" | "choiceset"; + +export interface SamplePrompt { + /** + * This string will hold the sample prompt + */ + text: string; +} + +/** + * Type of the command + */ +export type CommandType = "query" | "action"; + +/** + * Type of the compose extension. + */ +export type ComposeExtensionType = "botBased" | "apiBased"; + +export interface MessageHandler { + /** + * Type of the message handler + */ + type: "link"; + value: MessageHandlerValue; +} + +/** + * Type of the message handler + */ + +export interface MessageHandlerValue { + /** + * A list of domains that the link message handler can register for, and when they are + * matched the app will be invoked + */ + domains?: string[]; + /** + * A boolean that indicates whether the app's link message handler supports anonymous invoke + * flow. + */ + supportsAnonymizedPayloads?: boolean; +} + +export type ConfigurableProperty = "name" | "shortDescription" | "longDescription" | "smallImageUrl" | "largeImageUrl" | "accentColor" | "developerUrl" | "privacyUrl" | "termsOfUseUrl"; + +export interface ConfigurableTab { + /** + * A unique identifier for the tab. This id must be unique within the app manifest. + */ + id?: string; + /** + * The url to use when configuring the tab. + */ + configurationUrl: string; + /** + * A value indicating whether an instance of the tab's configuration can be updated by the + * user after creation. + */ + canUpdateConfiguration?: boolean; + /** + * Specifies whether the tab offers an experience in the context of a channel in a team, in + * a 1:1 or group chat, or in an experience scoped to an individual user alone. These + * options are non-exclusive. Currently, configurable tabs are only supported in the teams + * and groupchats scopes. + */ + scopes: ConfigurableTabScope[]; + /** + * The set of meetingSurfaceItem scopes that a tab belong to + */ + meetingSurfaces?: MeetingSurface[]; + /** + * The set of contextItem scopes that a tab belong to + */ + context?: ConfigurableTabContext[]; + /** + * A relative file path to a tab preview image for use in SharePoint. Size 1024x768. + */ + sharePointPreviewImage?: string; + /** + * Defines how your tab will be made available in SharePoint. + */ + supportedSharePointHosts?: SupportedSharePointHost[]; +} + +export type ConfigurableTabContext = "personalTab" | "channelTab" | "privateChatTab" | "meetingChatTab" | "meetingDetailsTab" | "meetingSidePanel" | "meetingStage"; + +export type MeetingSurface = "sidePanel" | "stage"; + +export type ConfigurableTabScope = "team" | "groupChat"; + +export type SupportedSharePointHost = "sharePointFullPage" | "sharePointWebPart"; + +export interface Connector { + /** + * A unique identifier for the connector which matches its ID in the Connectors Developer + * Portal. + */ + connectorId: string; + /** + * The url to use for configuring the connector using the inline configuration experience. + */ + configurationUrl?: string; + /** + * Specifies whether the connector offers an experience in the context of a channel in a + * team, or an experience scoped to an individual user alone. Currently, only the team scope + * is supported. + */ + scopes: "team"[]; +} + +export interface CopilotAgents { + /** + * An array of declarative agent elements references. Currently, only one declarative agent + * per application is supported. + */ + declarativeAgents?: DeclarativeAgentRef[]; + /** + * An array of Custom Engine Agents. Currently only one Custom Engine Agent per application + * is supported. Support is currently in public preview. + */ + customEngineAgents?: CustomEngineAgent[]; +} + +export interface CustomEngineAgent { + /** + * The id of the Custom Engine Agent. If it is of type bot, the id must match the id + * specified in a bot in the bots node and the referenced bot must have personal scope. The + * app short name and short description must also be defined. + */ + id: string; + /** + * The type of the Custom Engine Agent. Currently only type bot is supported. + */ + type: "bot"; + disclaimer?: Disclaimer; +} + +export interface Disclaimer { + /** + * The message shown to users before they interact with this application. + */ + text: string; + [property: string]: any; +} + +/** + * The type of the Custom Engine Agent. Currently only type bot is supported. + * + * The content of the dashboard card is sourced from a bot. + */ + +/** + * A reference to a declarative agent element. The element's definition is in a separate + * file. + */ +export interface DeclarativeAgentRef { + /** + * A unique identifier for this declarative agent element. + */ + id: string; + /** + * Relative file path to this declarative agent element file in the application package. + */ + file: string; +} + +/** + * Cards wich could be pinned to dashboard providing summarized view of information relevant + * to user. + */ +export interface DashboardCard { + /** + * Unique Id for the card. Must be unique inside the app. + */ + id: string; + /** + * Represents the name of the card. Maximum length is 255 characters. + */ + displayName: string; + /** + * Description of the card.Maximum length is 255 characters. + */ + description: string; + /** + * Id of the group in the card picker. This must be guid. + */ + pickerGroupId: string; + icon?: DashboardCardIcon; + contentSource: DashboardCardContentSource; + /** + * Rendering Size for dashboard card. + */ + defaultSize: DefaultSize; +} + +/** + * Represents a configuration for the source of the card’s content. + */ +export interface DashboardCardContentSource { + /** + * The content of the dashboard card is sourced from a bot. + */ + sourceType?: "bot"; + /** + * The configuration for the bot source. Required if sourceType is set to bot. + */ + botConfiguration?: BotConfiguration; +} + +/** + * The configuration for the bot source. Required if sourceType is set to bot. + */ +export interface BotConfiguration { + /** + * The unique Microsoft app ID for the bot as registered with the Bot Framework. + */ + botId?: string; +} + +/** + * Rendering Size for dashboard card. + */ +export type DefaultSize = "medium" | "large"; + +/** + * Represents a configuration for the source of the card’s content + */ +export interface DashboardCardIcon { + /** + * The icon for the card, to be displayed in the toolbox and card bar, represented as URL. + */ + iconUrl?: string; + /** + * Office UI Fabric/Fluent UI icon friendly name for the card. This value will be used if + * ‘iconUrl’ is not specified. + */ + officeUIFabricIconName?: string; +} + +/** + * When a group install scope is selected, this will define the default capability when the + * user installs the app + */ +export interface DefaultGroupCapability { + /** + * When the install scope selected is Team, this field specifies the default capability + * available + */ + team?: Groupchat; + /** + * When the install scope selected is GroupChat, this field specifies the default capability + * available + */ + groupchat?: Groupchat; + /** + * When the install scope selected is Meetings, this field specifies the default capability + * available + */ + meetings?: Groupchat; +} + +/** + * When the install scope selected is GroupChat, this field specifies the default capability + * available + * + * When the install scope selected is Meetings, this field specifies the default capability + * available + * + * When the install scope selected is Team, this field specifies the default capability + * available + */ +export type Groupchat = "tab" | "bot" | "connector"; + +/** + * The install scope defined for this app by default. This will be the option displayed on + * the button when a user tries to add the app + */ +export type DefaultInstallScope = "personal" | "team" | "groupChat" | "meetings" | "copilot"; + +export interface Description { + /** + * A short description of the app used when space is limited. Maximum length is 80 + * characters. + */ + short: string; + /** + * The full description of the app. Maximum length is 4000 characters. + */ + full: string; + /** + * Array of features sections describing what the app can do. + */ + features?: Feature[]; +} + +export interface Feature { + /** + * Title of the feature the app provides. + */ + title: string; + /** + * Detailed description of the specific feature. + */ + description: string; +} + +export interface Developer { + /** + * The display name for the developer. + */ + name: string; + /** + * The Microsoft Partner Network ID that identifies the partner organization building the + * app. This field is not required, and should only be used if you are already part of the + * Microsoft Partner Network. More info at https://aka.ms/partner + */ + mpnId?: string; + /** + * The url to the page that provides support information for the app. + */ + websiteUrl: string; + /** + * The url to the page that provides privacy information for the app. + */ + privacyUrl: string; + /** + * The url to the page that provides the terms of use for the app. + */ + termsOfUseUrl: string; +} + +export type DevicePermission = "geolocation" | "media" | "notifications" | "midi" | "openExternal"; + +export interface ElementRelationshipSet { + /** + * An array containing multiple instances of unidirectional dependency relationships (each + * represented by a oneWayDependency object). + */ + oneWayDependencies?: OneWayDependency[]; + /** + * An array containing multiple instances of mutual dependency relationships between + * elements (each represented by a mutualDependency object). + */ + mutualDependencies?: Array; +} + +/** + * A specific instance of mutual dependency between two or more elements, indicating that + * each element depends on the others in a bidirectional manner. + */ +export interface ElementReference { + name: MutualDependencyName; + id: string; + commandIds?: string[]; +} + +export type MutualDependencyName = "bots" | "staticTabs" | "composeExtensions" | "configurableTabs"; + +/** + * An object representing a unidirectional dependency relationship, where one specific + * element (referred to as the `element`) relies on an array of other elements (referred to + * as the `dependsOn`) in a single direction. + */ +export interface OneWayDependency { + element: ElementReference; + dependsOn: ElementReference[]; +} + +/** + * The set of extensions for this app. Currently only one extensions per app is supported. + */ +export interface ElementExtension { + requirements?: RequirementsExtensionElement; + runtimes?: ExtensionRuntimesArray[]; + ribbons?: ExtensionRibbonsArray[]; + autoRunEvents?: ExtensionAutoRunEventsArray[]; + alternates?: ExtensionAlternateVersionsArray[]; + contentRuntimes?: ExtensionContentRuntimeArray[]; + getStartedMessages?: ExtensionGetStartedMessageArray[]; + contextMenus?: ExtensionContextMenuArray[]; + /** + * Keyboard shortcuts, also known as key combinations, enable your add-in's users to work + * more efficiently. Keyboard shortcuts also improve the add-in's accessibility for users + * with disabilities by providing an alternative to the mouse. + */ + keyboardShortcuts?: ExtensionKeyboardShortcut[]; + /** + * The url for your extension, used to validate Exchange user identity tokens. + */ + audienceClaimUrl?: string; +} + +export interface ExtensionAlternateVersionsArray { + requirements?: RequirementsExtensionElement; + prefer?: Prefer; + hide?: Hide; + alternateIcons?: AlternateIcons; +} + +export interface AlternateIcons { + icon: ExtensionCommonIcon; + highResolutionIcon: ExtensionCommonIcon; +} + +export interface ExtensionCommonIcon { + /** + * Size in pixels of the icon. Three image sizes are required (16, 32, and 80 pixels) + */ + size: number; + /** + * Absolute Url to the icon. + */ + url: string; +} + +export interface Hide { + storeOfficeAddin?: StoreOfficeAddin; + customOfficeAddin?: CustomOfficeAddin; + /** + * Configures how to hide windows native extensions + */ + windowsExtensions?: WindowsExtensions; + [property: string]: any; +} + +export interface CustomOfficeAddin { + /** + * Solution ID of the in-market add-in to hide. Maximum length is 64 characters. + */ + officeAddinId: string; +} + +export interface StoreOfficeAddin { + /** + * Solution ID of an in-market add-in to hide. Maximum length is 64 characters. + */ + officeAddinId: string; + /** + * Asset ID of the in-market add-in to hide. Maximum length is 64 characters. + */ + assetId: string; +} + +/** + * Configures how to hide windows native extensions + */ +export interface WindowsExtensions { + /** + * Specifies the effect to take while installing the web add-in if the equivalent add-in is + * installed. + */ + effect: Effect; + /** + * Specifies the equivalent COM add-ins + */ + comAddin?: WindowsExtensionsCOMAddin; + /** + * Specifies the equivalent automation add-ins + */ + automationAddin?: AutomationAddin; + /** + * Specifies the XLL-based add-ins custom function + */ + xllCustomFunctions?: XllCustomFunctions; +} + +/** + * Specifies the equivalent automation add-ins + */ +export interface AutomationAddin { + /** + * Specifies the program Ids of the equivalent automation add-ins + */ + progIds: string[]; +} + +/** + * Specifies the equivalent COM add-ins + */ +export interface WindowsExtensionsCOMAddin { + /** + * Specifies the program Ids of the equivalent COM add-ins + */ + progIds: string[]; +} + +/** + * Specifies the effect to take while installing the web add-in if the equivalent add-in is + * installed. + */ +export type Effect = "userOptionToDisable" | "disableWithNotification"; + +/** + * Specifies the XLL-based add-ins custom function + */ +export interface XllCustomFunctions { + /** + * Specifies the file names of the XLL-based add-ins custom function + */ + fileNames: string[]; +} + +export interface Prefer { + comAddin?: PreferCOMAddin; + xllCustomFunctions?: ExtensionXllCustomFunctions; + [property: string]: any; +} + +export interface PreferCOMAddin { + /** + * Program ID of the alternate com extension. Maximum length is 64 characters. + */ + progId: string; +} + +export interface ExtensionXllCustomFunctions { + /** + * File name for the XLL extension. Maximum length is 254 characters. + */ + fileName?: string; + [property: string]: any; +} + +/** + * Specifies limitations on which clients the add-in can be installed on, including + * limitations on the Office host application, the form factors, and the requirement sets + * that the client must support. + * + * Specifies the Office requirement sets. + */ +export interface RequirementsExtensionElement { + capabilities?: Capability[]; + /** + * Identifies the scopes in which the add-in can run. Supported values: 'mail', 'workbook', + * 'document', 'presentation'. + */ + scopes?: RequirementsScope[]; + /** + * Identifies the form factors that support the add-in. Supported values: mobile, desktop. + */ + formFactors?: FormFactor[]; +} + +export interface Capability { + /** + * Identifies the name of the requirement sets that the add-in needs to run. + */ + name: string; + /** + * Identifies the minimum version for the requirement sets that the add-in needs to run. + */ + minVersion?: string; + /** + * Identifies the maximum version for the requirement sets that the add-in needs to run. + */ + maxVersion?: string; +} + +export type FormFactor = "desktop" | "mobile"; + +export type RequirementsScope = "mail" | "workbook" | "document" | "presentation"; + +export interface ExtensionAutoRunEventsArray { + requirements?: RequirementsExtensionElement; + /** + * Specifies the type of event. For supported types, please see: + * https://learn.microsoft.com/en-us/office/dev/add-ins/outlook/autolaunch?tabs=xmlmanifest#supported-events. + */ + events: Event[]; +} + +export interface Event { + type: string; + /** + * The ID of an action defined in runtimes. Maximum length is 64 characters. + */ + actionId: string; + /** + * Configures how Outlook responds to the event. + */ + options?: Options; +} + +/** + * Configures how Outlook responds to the event. + */ +export interface Options { + sendMode: SendMode; +} + +export type SendMode = "promptUser" | "softBlock" | "block"; + +/** + * Content runtime is for 'ContentApp', which can be embedded directly into Excel or + * PowerPoint documents. + */ +export interface ExtensionContentRuntimeArray { + /** + * Specifies the Office requirement sets for content add-in runtime. If the user's Office + * version doesn't support the specified requirements, the component will not be available + * in that client. + */ + requirements?: ContentRuntimeRequirements; + /** + * A unique identifier for this runtime within the app. This is developer specified. + */ + id: string; + /** + * Specifies the location of code for this runtime. Depending on the runtime.type, add-ins + * use either a JavaScript file or an HTML page with an embedded