From 6f6ac8f2e88c11bc5534aeed784290380b42c4a0 Mon Sep 17 00:00:00 2001 From: Ning Tang Date: Fri, 5 Dec 2025 14:16:25 +0800 Subject: [PATCH 01/20] feat: add cli command to generate config files --- packages/cli/src/commands/engine.ts | 3 +- .../cli/src/commands/models/addAuthConfig.ts | 6 +-- packages/cli/src/commands/models/init/init.ts | 32 +++++++++++++++ .../src/commands/models/init/initOption.ts | 41 +++++++++++++++++++ packages/cli/src/commands/models/root.ts | 2 + packages/cli/src/resource/commands.json | 3 ++ .../cli/src/telemetry/cliTelemetryEvents.ts | 3 ++ packages/fx-core/src/common/featureFlags.ts | 6 +++ packages/fx-core/src/core/FxCore.ts | 22 +++++++++- .../fx-core/src/core/generateConfigFiles.ts | 20 +++++++++ 10 files changed, 132 insertions(+), 6 deletions(-) create mode 100644 packages/cli/src/commands/models/init/init.ts create mode 100644 packages/cli/src/commands/models/init/initOption.ts create mode 100644 packages/fx-core/src/core/generateConfigFiles.ts diff --git a/packages/cli/src/commands/engine.ts b/packages/cli/src/commands/engine.ts index ed086c9d1b8..d83ef515281 100644 --- a/packages/cli/src/commands/engine.ts +++ b/packages/cli/src/commands/engine.ts @@ -21,14 +21,13 @@ import { IncompatibleProjectError, VersionState, assembleError, - telemetryUtils, getHashedEnv, isUserCancelError, maskSecret, + telemetryUtils, } from "@microsoft/teamsfx-core"; import { cloneDeep, pick } from "lodash"; import path from "path"; -import * as uuid from "uuid"; import { getFxCore } from "../activate"; import { TextType, colorize } from "../colorize"; import { tryDetectCICDPlatform } from "../commonlib/common/cicdPlatformDetector"; diff --git a/packages/cli/src/commands/models/addAuthConfig.ts b/packages/cli/src/commands/models/addAuthConfig.ts index acb0b215159..d56c3812a3d 100644 --- a/packages/cli/src/commands/models/addAuthConfig.ts +++ b/packages/cli/src/commands/models/addAuthConfig.ts @@ -1,12 +1,12 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. import { CLICommand } from "@microsoft/teamsfx-api"; +import { AddAuthActionInputs, AddAuthActionOptions } from "@microsoft/teamsfx-core"; +import { getFxCore } from "../../activate"; +import { logger } from "../../commonlib/logger"; import { commands, strings } from "../../resource"; import { TelemetryEvent } from "../../telemetry/cliTelemetryEvents"; import { ProjectFolderOption } from "../common"; -import { getFxCore } from "../../activate"; -import { AddAuthActionInputs, AddAuthActionOptions } from "@microsoft/teamsfx-core"; -import { logger } from "../../commonlib/logger"; export const addAuthConfigCommand: CLICommand = { name: "auth-config", diff --git a/packages/cli/src/commands/models/init/init.ts b/packages/cli/src/commands/models/init/init.ts new file mode 100644 index 00000000000..4f1c6e16e06 --- /dev/null +++ b/packages/cli/src/commands/models/init/init.ts @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +import { CLICommand, err, Inputs, ok } from "@microsoft/teamsfx-api"; +import { getFxCore } from "../../../activate"; +import { commands } from "../../../resource"; +import { TelemetryEvent } from "../../../telemetry/cliTelemetryEvents"; +import { TeamsAppManifestFileOption } from "../../common"; +import { localDebugOption, programmingLanguageOption, remoteDeployOption } from "./initOption"; + +export const initCommand: CLICommand = { + name: "init", + description: commands.init.description, + options: [ + localDebugOption, + remoteDeployOption, + programmingLanguageOption, + { ...TeamsAppManifestFileOption, required: true }, + ], + defaultInteractiveOption: false, + telemetry: { + event: TelemetryEvent.GenerateConfig, + }, + handler: async (ctx) => { + const inputs = ctx.optionValues; + const core = getFxCore(); + const result = await core.generateConfigFiles(inputs as Inputs); + if (result.isErr()) { + return err(result.error); + } + return ok(undefined); + }, +}; diff --git a/packages/cli/src/commands/models/init/initOption.ts b/packages/cli/src/commands/models/init/initOption.ts new file mode 100644 index 00000000000..20f9356dfa4 --- /dev/null +++ b/packages/cli/src/commands/models/init/initOption.ts @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { CLICommandOption } from "@microsoft/teamsfx-api"; + +export const playgroundOption: CLICommandOption = { + name: "playground", + questionName: "include-playground", + description: "include playground configuration files.", + type: "boolean", + required: true, + default: true, +}; + +export const localDebugOption: CLICommandOption = { + name: "local", + questionName: "include-local", + description: "include local debug configuration files.", + type: "boolean", + required: true, + default: true, +}; + +export const remoteDeployOption: CLICommandOption = { + name: "remote", + questionName: "include-remote", + description: "include remote deploy configuration files.", + type: "boolean", + required: true, + default: false, +}; + +export const programmingLanguageOption: CLICommandOption = { + name: "language", + questionName: "programming-language", + description: "specify the programming language.", + type: "string", + required: true, + default: "typescript", + choices: ["typescript"], +}; diff --git a/packages/cli/src/commands/models/root.ts b/packages/cli/src/commands/models/root.ts index 6e0ed68a73e..8ae27be5cf9 100644 --- a/packages/cli/src/commands/models/root.ts +++ b/packages/cli/src/commands/models/root.ts @@ -14,6 +14,7 @@ import { getCreateCommand } from "./create"; import { deployCommand } from "./deploy"; import { entraAppCommand } from "./entraAppUpdate"; import { envCommand } from "./env"; +import { initCommand } from "./init/init"; import { listCommand } from "./list"; import { m365LaunchInfoCommand } from "./m365LaunchInfo"; import { m365SideloadingCommand } from "./m365Sideloading"; @@ -58,6 +59,7 @@ export const rootCommand: CLICommand = { envCommand, permissionCommand, upgradeCommand, + ...(featureFlagManager.getBooleanValue(FeatureFlags.GenerateConfigFiles) ? [initCommand] : []), listCommand, helpCommand, teamsappUpdateCommand, diff --git a/packages/cli/src/resource/commands.json b/packages/cli/src/resource/commands.json index 8fa27052b0c..84afe64df62 100644 --- a/packages/cli/src/resource/commands.json +++ b/packages/cli/src/resource/commands.json @@ -116,6 +116,9 @@ "env.reset": { "description": "Reset environment file." }, + "init": { + "description": "Initialize an existing project to Microsoft 365 Agents Toolkit project." + }, "list": { "description": "List available app templates and samples." }, diff --git a/packages/cli/src/telemetry/cliTelemetryEvents.ts b/packages/cli/src/telemetry/cliTelemetryEvents.ts index 1d7578bbc7f..6f3fab290b7 100644 --- a/packages/cli/src/telemetry/cliTelemetryEvents.ts +++ b/packages/cli/src/telemetry/cliTelemetryEvents.ts @@ -130,6 +130,9 @@ export enum TelemetryEvent { AddAuthAction = "add-auth-action", SetSensitivityLabel = "set-sensitivity-label", + + GenerateConfigStart = "generate-config-start", + GenerateConfig = "generate-config", } export enum TelemetryProperty { diff --git a/packages/fx-core/src/common/featureFlags.ts b/packages/fx-core/src/common/featureFlags.ts index 58ea3006337..5bcf3cc570f 100644 --- a/packages/fx-core/src/common/featureFlags.ts +++ b/packages/fx-core/src/common/featureFlags.ts @@ -38,6 +38,8 @@ export class FeatureFlagName { static readonly DAMetaOS = "TEAMSFX_DA_METAOS"; static readonly CFShortcutMetaOS = "TEAMSFX_CF_SHORTCUT_METAOS"; static readonly MCPForDA = "TEAMSFX_MCP_FOR_DA"; + // Add config files to existing project to make it toolkit compatible + static readonly GenerateConfigFiles = "TEAMSFX_GENERATE_CONFIG_FILES"; } export interface FeatureFlag { @@ -136,6 +138,10 @@ export class FeatureFlags { name: FeatureFlagName.MCPForDA, defaultValue: "true", }; + static readonly GenerateConfigFiles = { + name: FeatureFlagName.GenerateConfigFiles, + defaultValue: "false", + }; } export class FeatureFlagManager { diff --git a/packages/fx-core/src/core/FxCore.ts b/packages/fx-core/src/core/FxCore.ts index 12425a3b2ba..46132e3da55 100644 --- a/packages/fx-core/src/core/FxCore.ts +++ b/packages/fx-core/src/core/FxCore.ts @@ -91,6 +91,7 @@ import { YamlParser } from "../component/configManager/parser"; import { AadConstants, KiotaLastCommands, + LocalMcpPrefix, SingleSignOnOptionItem, ViewAadAppHelpLinkV5, } from "../component/constants"; @@ -202,6 +203,7 @@ import { } from "./collaborator"; import { LocalCrypto } from "./crypto"; import { environmentNameManager } from "./environmentName"; +import { generateConfigFiles } from "./generateConfigFiles"; import { ConcurrentLockerMW } from "./middleware/concurrentLocker"; import { ContextInjectorMW } from "./middleware/contextInjector"; import { ErrorHandlerMW } from "./middleware/errorHandler"; @@ -216,7 +218,6 @@ import { import { addSharedUsers, removeShareAccess, shareWithTenant } from "./share"; import { CoreTelemetryEvent, CoreTelemetryProperty } from "./telemetry"; import { CoreHookContext, PreProvisionResForVS, VersionCheckRes } from "./types"; -import { LocalMcpPrefix } from "../component/constants"; export class FxCore { constructor(tools: Tools) { @@ -3244,6 +3245,25 @@ export class FxCore { } } + /** + * dynamic template metadata download + */ + @hooks([ErrorContextMW({ component: "FxCore", stage: "generateConfigFiles" }), ErrorHandlerMW]) + async generateConfigFiles(inputs: Inputs): Promise> { + const appManifestFilePath = inputs[QuestionNames.ManifestPath] as string; + const includePlayground = inputs["include-playground"]; + const includeLocalDebug = inputs["include-local"]; + const includeRemoteDeploy = inputs["include-remote"]; + const programmingLanguage = inputs["programming-language"]; + return await generateConfigFiles( + appManifestFilePath, + programmingLanguage, + includePlayground, + includeLocalDebug, + includeRemoteDeploy + ); + } + private async updateAuthActionInYaml( authName: string | undefined, authScheme: AuthType | undefined, diff --git a/packages/fx-core/src/core/generateConfigFiles.ts b/packages/fx-core/src/core/generateConfigFiles.ts new file mode 100644 index 00000000000..b8e4811c287 --- /dev/null +++ b/packages/fx-core/src/core/generateConfigFiles.ts @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +import { FxError, Result, ok } from "@microsoft/teamsfx-api"; +import "reflect-metadata"; +import { TOOLS } from "../common/globalVars"; + +export async function generateConfigFiles( + appManifestFilePath: string, + programmingLanguage: string, + includePlayground: boolean, + includeLocalDebug: boolean, + includeRemoteDeploy: boolean +): Promise> { + await TOOLS.ui?.showMessage( + "info", + `${includePlayground.toString()} ${includeLocalDebug.toString()} ${includeRemoteDeploy.toString()} ${programmingLanguage}`, + false + ); + return ok(undefined); +} From ceb984c7a305024d369a51c6f4644f629a451cc1 Mon Sep 17 00:00:00 2001 From: Ning Tang Date: Wed, 5 Nov 2025 16:38:53 +0800 Subject: [PATCH 02/20] feat: support v1.24 manifest --- .../manifest/src/generated-types/index.ts | 15 + .../teams/TeamsManifestV1D23.ts | 3068 ++++++++++++++++ .../teams/TeamsManifestV1D24.ts | 3187 +++++++++++++++++ .../MicrosoftTeams.Localization.schema.json | 306 ++ ...eams.ResponseRenderingTemplate.schema.json | 89 + .../teams/v1.23/MicrosoftTeams.schema.json | 3056 ++++++++++++++++ .../MicrosoftTeams.Localization.schema.json | 310 ++ ...eams.ResponseRenderingTemplate.schema.json | 89 + .../teams/v1.24/MicrosoftTeams.schema.json | 3175 ++++++++++++++++ 9 files changed, 13295 insertions(+) create mode 100644 packages/manifest/src/generated-types/teams/TeamsManifestV1D23.ts create mode 100644 packages/manifest/src/generated-types/teams/TeamsManifestV1D24.ts create mode 100644 packages/manifest/src/json-schemas/teams/v1.23/MicrosoftTeams.Localization.schema.json create mode 100644 packages/manifest/src/json-schemas/teams/v1.23/MicrosoftTeams.ResponseRenderingTemplate.schema.json create mode 100644 packages/manifest/src/json-schemas/teams/v1.23/MicrosoftTeams.schema.json create mode 100644 packages/manifest/src/json-schemas/teams/v1.24/MicrosoftTeams.Localization.schema.json create mode 100644 packages/manifest/src/json-schemas/teams/v1.24/MicrosoftTeams.ResponseRenderingTemplate.schema.json create mode 100644 packages/manifest/src/json-schemas/teams/v1.24/MicrosoftTeams.schema.json diff --git a/packages/manifest/src/generated-types/index.ts b/packages/manifest/src/generated-types/index.ts index 6ad682fc788..3d93c53429f 100644 --- a/packages/manifest/src/generated-types/index.ts +++ b/packages/manifest/src/generated-types/index.ts @@ -31,6 +31,8 @@ import * as TeamsManifestV1D2 from "./teams/TeamsManifestV1D2"; import * as TeamsManifestV1D20 from "./teams/TeamsManifestV1D20"; import * as TeamsManifestV1D21 from "./teams/TeamsManifestV1D21"; import * as TeamsManifestV1D22 from "./teams/TeamsManifestV1D22"; +import * as TeamsManifestV1D23 from "./teams/TeamsManifestV1D23"; +import * as TeamsManifestV1D24 from "./teams/TeamsManifestV1D24"; import * as TeamsManifestV1D3 from "./teams/TeamsManifestV1D3"; import * as TeamsManifestV1D4 from "./teams/TeamsManifestV1D4"; import * as TeamsManifestV1D5 from "./teams/TeamsManifestV1D5"; @@ -63,6 +65,9 @@ export { TeamsManifestV1D2, TeamsManifestV1D20, TeamsManifestV1D21, + TeamsManifestV1D22, + TeamsManifestV1D23, + TeamsManifestV1D24, TeamsManifestV1D3, TeamsManifestV1D4, TeamsManifestV1D5, @@ -97,6 +102,8 @@ export type TeamsManifest = | TeamsManifestV1D20.TeamsManifestV1D20 | TeamsManifestV1D21.TeamsManifestV1D21 | TeamsManifestV1D22.TeamsManifestV1D22 + | TeamsManifestV1D23.TeamsManifestV1D23 + | TeamsManifestV1D24.TeamsManifestV1D24 | TeamsManifestVDevPreview.TeamsManifestVDevPreview; export type TeamsManifestLatest = TeamsManifestV1D21.TeamsManifestV1D21; @@ -210,6 +217,14 @@ const TeamsManifestConverterMap: Converters = { TeamsManifestV1D22.Convert.toTeamsManifestV1D22, TeamsManifestV1D22.Convert.teamsManifestV1D22ToJson, ], + "1.23": [ + TeamsManifestV1D23.Convert.toTeamsManifestV1D23, + TeamsManifestV1D23.Convert.teamsManifestV1D23ToJson, + ], + "1.24": [ + TeamsManifestV1D24.Convert.toTeamsManifestV1D24, + TeamsManifestV1D24.Convert.teamsManifestV1D24ToJson, + ], devPreview: [ TeamsManifestVDevPreview.Convert.toTeamsManifestVDevPreview, TeamsManifestVDevPreview.Convert.teamsManifestVDevPreviewToJson, diff --git a/packages/manifest/src/generated-types/teams/TeamsManifestV1D23.ts b/packages/manifest/src/generated-types/teams/TeamsManifestV1D23.ts new file mode 100644 index 00000000000..b8a0e87cddd --- /dev/null +++ b/packages/manifest/src/generated-types/teams/TeamsManifestV1D23.ts @@ -0,0 +1,3068 @@ +// To parse this data: +// +// import { Convert, TeamsManifestV1D23 } from "./file"; +// +// const teamsManifestV1D23 = Convert.toTeamsManifestV1D23(json); +// +// These functions will throw an error if the JSON doesn't +// match the expected interface, even if the JSON is valid. + +export interface TeamsManifestV1D23 { + $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.23"; + /** + * 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 list of tenant configured properties for an app + */ + configurableProperties?: ConfigurableProperty[]; + /** + * 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 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?: TeamsManifestV1D23Authorization; + 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[]; + copilotAgents?: CopilotAgents; + /** + * The Intune-related properties for the app. + */ + intuneInfo?: IntuneInfo; + 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[]; +} + +/** + * Specify and consolidates authorization related information for the App. + */ +export interface TeamsManifestV1D23Authorization { + /** + * 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 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"; + +/** + * 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; +} + +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; + /** + * Semantic description for the command. + */ + semanticDescription?: string; + parameters?: Parameter[]; + taskInfo?: TaskInfo; +} + +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; + /** + * Initial value for the parameter + */ + value?: string; + /** + * The value indicates if this parameter is a required field. + */ + isRequired?: boolean; + /** + * Semantic description for the parameter. + */ + semanticDescription?: string; + /** + * The choice options for the parameter + */ + choices?: Choice[]; +} + +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: Value; +} + +/** + * Type of the message handler + */ + +export interface Value { + /** + * 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; +} + +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[]; + 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; + [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; +} + +export interface Prefer { + comAddin?: COMAddin; + xllCustomFunctions?: ExtensionXllCustomFunctions; + [property: string]: any; +} + +export interface COMAddin { + /** + * Program ID of the alternate com extension. Maximum length is 64 characters. + */ + progId: string; +} + +export interface ExtensionXllCustomFunctions { + 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://review.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