diff --git a/samples/da-typespec-powerautomate/.gitignore b/samples/da-typespec-powerautomate/.gitignore new file mode 100644 index 000000000..5bc64fdc3 --- /dev/null +++ b/samples/da-typespec-powerautomate/.gitignore @@ -0,0 +1,19 @@ +# TeamsFx files +env/.env.*.user +env/.env.local +.localConfigs +appPackage/build +build + +# dependencies +node_modules/ + +# misc +.env +.deployment +.DS_Store + +# generated files +appPackage/.generated +# generated environment variables +src/agent/env.tsp \ No newline at end of file diff --git a/samples/da-typespec-powerautomate/.vscode/extensions.json b/samples/da-typespec-powerautomate/.vscode/extensions.json new file mode 100644 index 000000000..1397851d6 --- /dev/null +++ b/samples/da-typespec-powerautomate/.vscode/extensions.json @@ -0,0 +1,6 @@ +{ + "recommendations": [ + "TeamsDevApp.ms-teams-vscode-extension", + "typespec.typespec-vscode" + ] +} diff --git a/samples/da-typespec-powerautomate/.vscode/launch.json b/samples/da-typespec-powerautomate/.vscode/launch.json new file mode 100644 index 000000000..a59d7931a --- /dev/null +++ b/samples/da-typespec-powerautomate/.vscode/launch.json @@ -0,0 +1,91 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Launch Agent in Copilot (Edge)", + "type": "msedge", + "request": "launch", + "url": "https://m365.cloud.microsoft/chat/entity1-d870f6cd-4aa5-4d42-9626-ab690c041429/${local:agent-hint}?auth=2&developerMode=Basic", + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen", + "runtimeArgs": [ + "--remote-debugging-port=9222", + "--no-first-run" + ] + }, + { + "name": "Launch Agent in Copilot (Chrome)", + "type": "chrome", + "request": "launch", + "url": "https://m365.cloud.microsoft/chat/entity1-d870f6cd-4aa5-4d42-9626-ab690c041429/${local:agent-hint}?auth=2&developerMode=Basic", + "presentation": { + "group": "all", + "hidden": true + }, + "internalConsoleOptions": "neverOpen", + "runtimeArgs": [ + "--remote-debugging-port=9223", + "--no-first-run" + ] + }, + { + "name": "Preview in Copilot (Edge)", + "type": "msedge", + "request": "launch", + "url": "https://m365.cloud.microsoft/chat/entity1-d870f6cd-4aa5-4d42-9626-ab690c041429/${agent-hint}?auth=2&developerMode=Basic", + "presentation": { + "group": "remote", + "order": 1 + }, + "internalConsoleOptions": "neverOpen", + "runtimeArgs": [ + "--remote-debugging-port=9224", + "--no-first-run" + ] + }, + { + "name": "Preview in Copilot (Chrome)", + "type": "chrome", + "request": "launch", + "url": "https://m365.cloud.microsoft/chat/entity1-d870f6cd-4aa5-4d42-9626-ab690c041429/${agent-hint}?auth=2&developerMode=Basic", + "presentation": { + "group": "remote", + "order": 2 + }, + "internalConsoleOptions": "neverOpen", + "runtimeArgs": [ + "--remote-debugging-port=9225", + "--no-first-run" + ] + } + ], + "compounds": [ + { + "name": "Preview Local in Copilot (Edge)", + "configurations": [ + "Launch Agent in Copilot (Edge)", + ], + "preLaunchTask": "Start Agent Locally", + "presentation": { + "group": "all", + "order": 1 + }, + "stopAll": true + }, + { + "name": "Preview Local in Copilot (Chrome)", + "configurations": [ + "Launch Agent in Copilot (Chrome)", + ], + "preLaunchTask": "Start Agent Locally", + "presentation": { + "group": "all", + "order": 1 + }, + "stopAll": true + } + ] +} diff --git a/samples/da-typespec-powerautomate/.vscode/settings.json b/samples/da-typespec-powerautomate/.vscode/settings.json new file mode 100644 index 000000000..a4e385dd1 --- /dev/null +++ b/samples/da-typespec-powerautomate/.vscode/settings.json @@ -0,0 +1,15 @@ +{ + "debug.onTaskErrors": "abort", + "json.schemas": [ + { + "fileMatch": [ + "/aad.*.json" + ], + "schema": {} + } + ], + "files.readonlyInclude": { + "appPackage/.generated/**/*": true, + "src/agent/env.tsp": true + } +} diff --git a/samples/da-typespec-powerautomate/.vscode/tasks.json b/samples/da-typespec-powerautomate/.vscode/tasks.json new file mode 100644 index 000000000..961fd9a60 --- /dev/null +++ b/samples/da-typespec-powerautomate/.vscode/tasks.json @@ -0,0 +1,44 @@ +// This file is automatically generated by Microsoft 365 Agents Toolkit. +// The teamsfx tasks defined in this file require Microsoft 365 Agents Toolkit version >= 5.0.0. +// See https://aka.ms/teamsfx-tasks for details on how to customize each task. +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Start Agent Locally", + "dependsOn": [ + "Validate prerequisites", + "Create resources" + ], + "dependsOrder": "sequence" + }, + { + "label": "Validate prerequisites", + "type": "teamsfx", + "command": "debug-check-prerequisites", + "args": { + "prerequisites": [ + "m365Account" + ] + } + }, + { + "label": "Create resources", + "type": "teamsfx", + "command": "provision", + "args": { + "env": "local" + } + }, + { + "label": "Install dependencies", + "type": "shell", + "command": "npm install", + "presentation": { + "reveal": "silent", + "panel": "new" + }, + "runOptions": { "runOn": "folderOpen" } + } + ] +} \ No newline at end of file diff --git a/samples/da-typespec-powerautomate/AGENTS.md b/samples/da-typespec-powerautomate/AGENTS.md new file mode 100644 index 000000000..bb667e04d --- /dev/null +++ b/samples/da-typespec-powerautomate/AGENTS.md @@ -0,0 +1,745 @@ +--- +description: 'Expert guidance for building declarative agents with TypeSpec for Microsoft 365 Copilot using Microsoft 365 Agents Toolkit' +applyTo: '**/*.tsp' +--- + +# TypeSpec Declarative Agent Development for Microsoft 365 Copilot + +## TypeSpec Instructions + +- Always use the latest stable version of TypeSpec compiler (`@typespec/compiler` v1.0.0+). +- Use the latest version of `@microsoft/typespec-m365-copilot` for agent-specific decorators and capabilities. +- Write clear and descriptive `@doc` comments for all operations, models, and namespaces. +- Follow semantic versioning for API operations when introducing breaking changes. + +## General Instructions + +- Make only high-confidence suggestions when reviewing TypeSpec definitions. +- Write TypeSpec with good maintainability practices, including comments explaining design decisions for complex schemas. +- Handle edge cases in action definitions and provide clear error documentation. +- For external APIs or services, document their purpose and integration points in comments. +- Always validate TypeSpec compilation (`npm run compile`) before provisioning. + +## Naming Conventions + +- Follow PascalCase for namespace names, model names, and operation names (e.g., `PoliciesAgent`, `AgentInfo`, `getAgents`). +- Use camelCase for parameter names and properties (e.g., `@path id: string`, `agentId: string`). +- Use descriptive names that reflect the operation's purpose (e.g., `getPolicies` instead of `getData`). +- Prefix enum members with their context when needed (e.g., `PolicyType.Compliance`, `AgentStatus.Active`). +- Use plural names for collection responses (e.g., `agents: AgentInfo[]` not `agent: AgentInfo[]`). + +## Formatting + +- Apply consistent indentation (2 or 4 spaces) throughout `.tsp` files. +- Group related imports together at the top of each file. +- Separate logical sections with comment dividers (e.g., `// --- Models ---`). +- Place decorators on separate lines above the element they modify. +- Use multiline format for operations with multiple parameters. +- Ensure consistent spacing around operators and colons in type annotations. +- Add a newline at the end of each file. + +## Project Setup and Structure + +- Guide users through creating a new declarative agent project using Microsoft 365 Agents Toolkit. +- Explain the purpose of each generated file: `main.tsp` (entry point), `prompts/*.tsp` (Prompts), `actions/*.tsp` (API operations), `env.tsp` (environment variables). +- Demonstrate how to organize code using separate namespaces for actions and models. +- Show proper separation of concerns: agent definition (main.tsp), actions (actions/*.tsp), data models (models.tsp). +- Explain the `m365agents.yml` configuration and how it orchestrates the build and deployment lifecycle. +- Guide users on environment-specific configurations using `env/.env.dev`, `env/.env.prod`. + +## TypeSpec Agent Fundamentals + +- Declare agents using the `@agent(name, description)` decorator in the main namespace. +- Link instructions to the agent using `@instructions(Prompts.INSTRUCTIONS)` decorator. +- Add conversation starters with `@conversationStarter(#{ title, text })` to guide users. Limit the number of conversation starters to 12. +- Expose actions as operations: `op getPolicies is PoliciesAPI.getPolicies`. +- Trust the TypeSpec type system and define strong contracts for all API operations. + +## Agent Decorators + +### @agent Decorator + +- **Purpose**: Indicates that a namespace represents an agent and provides its basic metadata. +- **Parameters**: + - `name` (string, localizable, required): The name of the declarative agent. Must contain at least one non-whitespace character and must be 100 characters or less. + - `description` (string, localizable, required): The description of the declarative agent. Must contain at least one non-whitespace character and must be 1,000 characters or less. + - `id` (string, optional): The unique identifier of the agent. +- **Usage**: + + ```typespec + @agent("Policy Assistant", "An agent that helps users find and understand company policies") + namespace PolicyAgent { + // Agent implementation + } + ``` + +- **Best practices**: + - Use clear, descriptive names that convey the agent's purpose. + - Write concise but informative descriptions that help users understand when to use the agent. + - Only specify `id` when you need to maintain a specific agent identifier across deployments. + +### @instructions Decorator + +- **Purpose**: Defines the instructions that guide the agent's behavior. +- **Parameters**: + - `instructions` (string, not localizable, required): The detailed instructions or guidelines on how the declarative agent should behave, its functions, and any behaviors to avoid. Must contain at least one non-whitespace character and must be 8,000 characters or less. +- **Usage**: + + ```typespec + @instructions(Prompts.INSTRUCTIONS) + namespace PolicyAgent { + // Agent implementation + } + ``` + +- **Best practices**: + - Store instructions in a dedicated `Prompts` namespace in `instructions.tsp`. + - Use clear, directive language with keywords like **ALWAYS**, **NEVER**, **MUST**. + - Provide concrete examples of expected behavior. + - Keep instructions focused and relevant to the agent's purpose. + +### @conversationStarter Decorator + +- **Purpose**: Defines conversation starters that guide users on how to interact with the agent. +- **Parameters**: + - `conversationStarter` (ConversationStarter object, required): An object with `title` (optional) and `text` (required) properties. +- **ConversationStarter Model**: + - `title` (string, localizable, optional): A unique title for the conversation starter. Must contain at least one non-whitespace character. + - `text` (string, localizable, required): A suggestion that the user can use to obtain the desired result. Must contain at least one non-whitespace character. +- **Usage**: + + ```typespec + @conversationStarter(#{ title: "Find Policies", text: "Show me all compliance policies" }) + @conversationStarter(#{ text: "What's the vacation policy?" }) + namespace PolicyAgent { + // Agent implementation + } + ``` + +- **Best practices**: + - Limit the number of conversation starters to 12. + - Use conversation starters to showcase the agent's key capabilities. + - Make suggestions specific and actionable. + - Cover diverse use cases to help users understand the agent's range. + +### @disclaimer Decorator + +- **Purpose**: Displays a disclaimer message to users at the start of a conversation to satisfy legal or compliance requirements. +- **Parameters**: + - `disclaimer` (Disclaimer object, required): An object with a `text` property. +- **Disclaimer Model**: + - `text` (string, required): The disclaimer message. Must contain at least 1 non-whitespace character. Characters beyond 500 may be ignored. +- **Usage**: + + ```typespec + @disclaimer(#{ text: "This agent provides general information only. Consult HR for official policy interpretations." }) + namespace PolicyAgent { + // Agent implementation + } + ``` + +- **Best practices**: + - Use disclaimers when the agent handles sensitive information or provides advice. + - Keep disclaimers concise and under 500 characters. + - Ensure disclaimers comply with your organization's legal and compliance requirements. + - Review disclaimers with legal/compliance teams before deployment. + +### @behaviorOverrides Decorator + +- **Purpose**: Defines settings that modify the behavior of the agent orchestration. +- **Parameters**: + - `behaviorOverrides` (BehaviorOverrides object, required): An object with optional properties to control agent behavior. +- **BehaviorOverrides Model**: + - `discourageModelKnowledge` (boolean, optional): Indicates whether the declarative agent should be discouraged from using model knowledge when generating responses. + - `disableSuggestions` (boolean, optional): Indicates whether the suggestions feature is disabled. +- **Usage**: + + ```typespec + @behaviorOverrides(#{ discourageModelKnowledge: true, disableSuggestions: false }) + namespace PolicyAgent { + // Agent implementation + } + ``` + +- **Best practices**: + - Use `discourageModelKnowledge: true` when you want the agent to rely primarily on provided knowledge sources rather than pre-trained knowledge. + - Use `disableSuggestions: false` (default) to keep the suggestions feature enabled for better user experience. + - Test behavior overrides thoroughly to ensure they produce the desired agent behavior. + - Document the reasons for using behavior overrides in your agent documentation. + +### @customExtension Decorator + +- **Purpose**: Allows adding custom extension properties to the agent for future extensibility. +- **Parameters**: + - `key` (string, required): The key name for the custom extension property. + - `value` (unknown, required): The value for the custom extension property (can be any type). +- **Usage**: + + ```typespec + @customExtension("customProperty", "customValue") + @customExtension("featureFlag", true) + namespace PolicyAgent { + // Agent implementation + } + ``` + +- **Best practices**: + - Use custom extensions sparingly and only when needed for specific scenarios. + - Document the purpose and expected values of custom extensions clearly. + - Coordinate with Microsoft documentation or support to understand supported custom extensions. + - Be prepared for custom extensions to be ignored if not recognized by the platform. + +## Action Definitions + +- Define actions in dedicated namespaces decorated with `@service` and `@server(url)`. +- Use `@actions(metadata)` decorator to provide human-readable names and descriptions. +- Include `descriptionForModel` in action metadata to help the LLM understand when to invoke the action. +- Define operations using HTTP method decorators: `@get`, `@post`, `@put`, `@delete`. +- Specify routes with `@route("/path/{param}")` decorator. +- Use `@path`, `@query`, `@body`, `@header` decorators to define parameter sources. +- Provide default values for optional parameters (e.g., `@query type: PolicyType = PolicyType.Compliance`). +- Document all parameters with `@doc` comments explaining their purpose and constraints. +- Explain error scenarios in operation documentation (e.g., `404: Policy not found`). + +## Model Design + +- Create reusable models in a dedicated `models.tsp` file. +- Import the `models.tsp` file in the relevant `actions/*.tsp` files. +- Use descriptive model names that reflect their purpose (e.g., `PolicyInfo`, `PolicyResponse`). +- Define enums for fixed value sets (e.g., `enum AgentStatus { Active: "Active", Inactive: "Inactive" }`). +- Use proper TypeSpec primitive types: `string`, `int32`, `int64`, `float64`, `boolean`, `datetime`. +- Nest models when appropriate to avoid repetition and improve clarity. +- Add `@doc` comments to all model properties explaining their meaning and constraints. +- Use optional properties with `?` when fields may be absent (e.g., `days?: int32`). +- Leverage union types for fields that can have multiple types when needed. + +## Instruction Crafting + +- Write instructions in a dedicated `Prompts` namespace in `instructions.tsp`. +- Structure instructions with clear sections: GUIDELINES, EXAMPLES, SUGGESTIONS. +- Use strong directive keywords: **ALWAYS**, **NEVER**, **MUST** for critical rules. +- Provide concrete examples showing input, function calls, and expected output. +- Explain multi-step workflows explicitly (e.g., "First call getPolicies, then use the ID to call getStatus"). +- Include guidance on visualization when using CodeInterpreter capability. +- Document error handling strategies (e.g., "If action fails, explain the issue to the user"). +- Keep instructions concise and focused on behavior that the LLM should follow. +- Reference actions by their operation names to create clear associations. + +## Environment Configuration + +- Never manually edit `env.tsp` — it's auto-generated from `.env` files. +- Store environment-specific values in `env/.env.local`, `env/.env.dev`, `env/.env.prod`, etc. +- Run `npm run generate:env` after modifying `.env` files to regenerate `env.tsp`. +- All environment variables are in the `Environment` namespace. +- Reference environment constants using `Environment.CONSTANT_NAME` in TypeSpec files. +- Use uppercase snake_case for environment variable names (e.g., `APP_NAME_SHORT`, `POLICIES_API_ENDPOINT`). +- Never commit secrets or API keys in `.env` files — use secure storage (e.g., Azure Key Vault). +- Document required environment variables in the project README. + +## Validation and Testing + +- Always compile TypeSpec before provisioning: `npm run compile`. +- Fix all compilation errors and warnings before moving forward. +- Provision to local environment first: `atk provision --env local`. +- Test the agent in Microsoft 365 Copilot playground with diverse queries. +- Validate that the agent follows instructions (e.g., calls actions in the correct order). +- Test error scenarios: missing parameters, invalid IDs, API failures. +- Verify CodeInterpreter visualizations render correctly. +- Confirm conversation starters appear and work as expected. +- Test with multiple phrasings to ensure consistent agent behavior. +- Create test cases for critical workflows and validate after instruction changes. + +## Multi-Step Workflows + +- Guide the agent through multi-step workflows with explicit instructions. +- Example: "When the user asks about policies by agent name: 1- Call getAgents to get all agents IDs, 2- Match the user's requested name to an ID, 3- Call getAgentPolicy with that ID." +- Document prerequisite data fetching requirements in instructions. +- Explain fallback behavior when prerequisites fail (e.g., agent not found). +- Use action chaining judiciously to avoid overly complex workflows. + +## Capabilities Best Practices + +Microsoft 365 Copilot agents support multiple capabilities that extend the agent's functionality. Enable only the capabilities your agent needs. + +### General Capability Guidelines + +- Enable capabilities explicitly using `op capabilityName is AgentCapabilities.CapabilityName` syntax. +- Only enable capabilities that your agent will actively use — unnecessary capabilities increase complexity. +- Test each capability thoroughly in the Microsoft 365 Copilot playground before deployment. +- Document in your instructions how and when the agent should use each enabled capability. +- Combine capabilities strategically to create powerful multi-modal experiences. +- DO NOT add instructions related to the capabilities. + +### WebSearch Capability + +- **Enable (unscoped)**: `op webSearch is AgentCapabilities.WebSearch` +- **Enable (scoped)**: + + ```typescript + op webSearch is AgentCapabilities.WebSearch + ``` + +- **Purpose**: Allows the agent to search the public web for current information. +- **Scoping**: + - **CRITICAL**: Scoping is done via the `TSites` property in the capability definition, **NOT** in instructions. + - **NOT scoped**: Omit `TSites` array to allow searching all web content. + - **Scoped**: Specify `TSites` array with URLs to restrict web search to specific domains/sites. + - The agent will only search content from the specified URLs when scoped. + - A maximum of 4 URLs can be used. +- **Best practices**: + - Use when your agent needs real-time or recent information not available in your APIs. + - Scope to specific domains when you want to limit search to trusted sources (e.g., company documentation sites). + - Instruct the agent on when to prefer web search vs. internal actions (e.g., "Use web search only if internal data is unavailable"). + - Guide the agent to cite sources from web results in responses. + - Be aware that web search results may vary and are not under your control. + - Consider privacy implications when combining web data with internal data. +- **Example instruction**: "If the user asks about current events or recent news, use web search. Always cite your sources." +- **Example (scoped to Microsoft Learn)**: + + ```typescript + op webSearch is AgentCapabilities.WebSearch + ``` + +### OneDriveAndSharePoint Capability + +- **Enable (unscoped)**: `op oneDriveAndSharePoint is AgentCapabilities.OneDriveAndSharePoint` +- **Enable (scoped by URL)**: + + ```typescript + op od_sp is AgentCapabilities.OneDriveAndSharePoint + ``` + +- **Enable (scoped by SharePoint ID)**: + + ```typescript + op od_sp is AgentCapabilities.OneDriveAndSharePoint + ``` + +- **Purpose**: Enables the agent to search and access files in the user's OneDrive and SharePoint. +- **Scoping**: + - **CRITICAL**: Scoping is done via `ItemsByUrl` or `ItemsBySharePointIds` properties in the capability definition, **NOT** in instructions. + - **NOT scoped**: Omit both `ItemsByUrl` and `ItemsBySharePointIds` arrays to allow access to all OneDrive and SharePoint content available to the user. + - **Scoped by URL**: Use `ItemsByUrl` with full paths to SharePoint sites, document libraries, folders, or files. + - **Scoped by SharePoint ID**: Use `ItemsBySharePointIds` for more precise control using SharePoint internal IDs. + - URLs should be full paths (use "Copy direct link" in SharePoint: right-click → Details → Path → copy icon). +- **Best practices**: + - Use when your agent needs to work with user documents, spreadsheets, or presentations. + - Scope to specific sites/folders when you want to limit access to relevant content areas. + - Respect user permissions — the agent can only access files the user can access. + - Instruct the agent on file type preferences (e.g., "Prioritize Excel files for financial data"). + - Guide the agent to summarize file contents rather than returning raw data. + - Combine with CodeInterpreter to analyze data from files (e.g., Excel sheets). + - Be explicit about file name patterns or document types in instructions. +- **Example instruction**: "When the user asks about project documentation, search SharePoint for files matching the project name. Summarize key findings." +- **Example (scoped to Audits folder)**: + + ```typescript + op odsp is AgentCapabilities.OneDriveAndSharePoint + ``` + +### TeamsMessages Capability + +- **Enable (unscoped)**: `op teamsMessages is AgentCapabilities.TeamsMessages` +- **Enable (scoped)**: + + ```typescript + op teamsMessages is AgentCapabilities.TeamsMessages + ``` + +- **Purpose**: Allows the agent to use Teams channels, teams, and meeting chats as knowledge sources. +- **Scoping**: + - **CRITICAL**: Scoping is done via the `TeamsMessagesByUrl` property in the capability definition, **NOT** in instructions. + - **NOT scoped**: Omit `TeamsMessagesByUrl` array to allow access to all Teams channels, teams, meetings, 1:1 chats, and group chats available to the user. + - **Scoped**: Specify `TeamsMessagesByUrl` array with well-formed Teams URLs to restrict access to specific teams, channels, or chats. + - URLs must be valid Teams links (copy from Teams: team/channel → "..." menu → "Get link to channel/team"). +- **Best practices**: + - Use when your agent needs context from team conversations or project discussions. + - Scope to specific teams/channels when you want to limit to project-specific or department-specific conversations. + - Respect user permissions — the agent can only access messages the user can see. + - Instruct the agent to respect conversation context and thread relationships. + - Guide the agent to cite message authors and timestamps when referencing Teams content. + - Be aware of privacy and confidentiality when using Teams messages as knowledge. + - Consider combining with People capability to provide context about message authors. +- **Example instruction**: "When the user asks about project decisions, search Teams messages for discussions related to the topic. Cite the author and date of relevant messages." +- **Example (scoped to Engineering team)**: + + ```typescript + op teamsMessages is AgentCapabilities.TeamsMessages + ``` + +### Email Capability + +- **Enable (unscoped user mailbox)**: `op email is AgentCapabilities.Email` +- **Enable (scoped to specific folders)**: + + ```typescript + op email is AgentCapabilities.Email + ``` + +- **Enable (scoped to shared mailbox)**: + + ```typescript + op email is AgentCapabilities.Email + ``` + +- **Purpose**: Allows the agent to use email from the user's mailbox or a shared mailbox as a knowledge source. +- **Scoping**: + - **CRITICAL**: Scoping is done via `Folders` and `SharedMailbox` properties in the capability definition, **NOT** in instructions. + - **NOT scoped**: Omit `Folders` array to allow access to the entire mailbox. + - **Scoped by folders**: Use `Folders` array with folder IDs (e.g., "Inbox", "SentItems", "Drafts", custom folder names). + - **Scoped to shared mailbox**: Use `SharedMailbox` property with the shared mailbox email address. + - Can combine shared mailbox with folder scoping for precise control. +- **Best practices**: + - Use when your agent needs to answer questions based on email correspondence. + - Scope to specific folders when you want to limit to relevant email categories (e.g., only customer support emails). + - Use shared mailboxes for team-wide email knowledge (e.g., support@, sales@). + - Respect user permissions — the agent can only access emails the user can access. + - Instruct the agent on how to handle sensitive information in emails. + - Guide the agent to cite sender, date, and subject when referencing emails. + - Be aware of privacy and confidentiality when using email as knowledge. + - Consider date range instructions to focus on recent communications. +- **Example instruction**: "When the user asks about customer inquiries, search emails for relevant correspondence. Summarize key points and include sender and date." +- **Example (scoped to support shared mailbox Inbox)**: + + ```typescript + op email is AgentCapabilities.Email + ``` + +### People Capability + +- **Enable**: `op people is AgentCapabilities.People` +- **Purpose**: Allows the agent to answer questions about individuals in the organization. +- **Scoping**: + - **NOTE**: This capability does not support scoping parameters. + - The agent can access information about all people in the organization directory that the user has permission to view. +- **Best practices**: + - Use when your agent needs to provide information about team members, org structure, or contact details. + - Instruct the agent on what people-related queries to handle (e.g., "Find contact info", "Who reports to X?"). + - Guide the agent to respect privacy and only share publicly available directory information. + - Combine with other capabilities to provide context (e.g., Teams messages + People to understand who said what). + - Be clear about what information is appropriate to share about people. + - Consider compliance and privacy regulations when enabling this capability. +- **Example instruction**: "When the user asks about team members or contacts, use the People capability to find relevant individuals. Provide names, roles, and contact information." +- **Example**: + + ```typescript + op people is AgentCapabilities.People; + ``` + +### GraphicArt Capability + +- **Enable**: `op graphicArt is AgentCapabilities.GraphicArt` +- **Purpose**: Enables the agent to generate images based on user prompts. +- **Scoping**: + - **NOTE**: This capability does not support scoping parameters. + - The agent can generate images based on any user prompt. +- **Best practices**: + - Use when your agent needs to create visual content, diagrams, or illustrations. + - Instruct the agent on when to generate images vs. describe content textually. + - Guide the agent on image style preferences (e.g., "Generate professional diagrams", "Use corporate color scheme"). + - Set expectations about generation time and potential limitations. + - Provide examples of appropriate image generation requests in instructions. + - Consider content policy and appropriateness of generated images. + - Inform users that generated images are AI-created and may need review. +- **Example instruction**: "When the user requests visual representations, diagrams, or illustrations, use the GraphicArt capability to generate images. Always describe what the image will show before generating." +- **Example**: + + ```typescript + op graphicArt is AgentCapabilities.GraphicArt; + ``` + +### CopilotConnectors Capability + +- **Enable (unscoped)**: `op graphConnectors is AgentCapabilities.CopilotConnectors` +- **Enable (scoped)**: + + ```typespec + op copilotConnectors is AgentCapabilities.CopilotConnectors + ``` + +- **Purpose**: Allows the agent to search content ingested via Microsoft Graph connectors. +- **Scoping**: + - **CRITICAL**: Scoping is done via the `Connections` generic parameter in the capability definition, **NOT** in instructions. + - **NOT scoped**: Omit `Connections` parameter to allow access to all Graph connectors available to the user. + - **Scoped**: Specify `Connections` parameter with connection IDs to restrict to specific connectors. + - Connection IDs can be found using Microsoft Graph API or admin tools. +- **Best practices**: + - Use when your organization has external data sources connected via Graph connectors. + - Scope to specific connectors when you want to limit to relevant external data sources. + - Ensure Graph connectors are properly configured and content is indexed before enabling. + - Document the types of data available through each Graph connector in your agent documentation. + - Guide the agent on when to prefer Graph connector data vs. direct API calls. + - Test with real indexed content to validate search quality and relevance. + - Monitor connector health and data freshness. +- **Example instruction**: "Search Graph connectors for customer support tickets when the user asks about customer issues. Provide ticket numbers and summaries." +- **Example (scoped to policies connector)**: + + ```typespec + op copilotConnectors is AgentCapabilities.CopilotConnectors + ``` + +### CodeInterpreter Capability + +- **Enable**: `op codeInterpreter is AgentCapabilities.CodeInterpreter` +- **Purpose**: Enables the agent to write and execute Python code for data analysis and visualization. +- **Scoping**: + - **NOTE**: This capability does not support scoping parameters. + - The agent can execute Python code for any user request. +- **Best practices**: + - Use when your agent needs to perform calculations, data transformations, or create visualizations. + - Ensure data returned from actions is in a format compatible with Python libraries (JSON, CSV-style arrays). + - Instruct the agent on preferred visualization types (e.g., "Use line charts for trends, bar charts for comparisons"). + - Guide formatting requirements: "Always start y-axis at 0", "Add descriptive titles and axis labels". + - Test visualizations with sample data to confirm proper rendering. + - Provide fallback instructions if visualization fails (e.g., "If chart generation fails, provide data in a table"). + - Be aware of execution timeouts for long-running computations. + - Document any data preparation requirements (e.g., "Ensure dates are in ISO 8601 format"). +- **Example instruction**: "When displaying usage trends, use CodeInterpreter to create a line chart with dates on x-axis and usage count on y-axis. Always include a descriptive title." +- **Example**: + + ```typespec + op codeInterpreter is AgentCapabilities.CodeInterpreter; + ``` + +### Meetings Capability + +- **Enable**: `op meetings is AgentCapabilities.Meetings` +- **Purpose**: Allows the agent to search meeting content. +- **Scoping**: + - **NOTE**: This capability does not support scoping parameters. + - The agent can search through meeting content that the user has access to. +- **Best practices**: + - Use when your agent needs to access information from meeting transcripts, recordings, or notes. + - Respect user permissions — the agent can only access meetings the user can see. + - Guide the agent to cite meeting titles, dates, and participants when referencing meeting content. + - Consider combining with People capability to provide context about meeting participants. + - Be aware of privacy and confidentiality when using meeting content as knowledge. +- **Example instruction**: "When the user asks about decisions made in meetings, search meeting content for relevant discussions. Include the meeting date and key participants." +- **Example**: + + ```typespec + op meetings is AgentCapabilities.Meetings; + ``` + +### ScenarioModels Capability + +- **Enable**: + + ```typespec + op scenarioModels is AgentCapabilities.ScenarioModels + ``` + +- **Purpose**: Allows the agent to use task-specific models for specialized scenarios. +- **Scoping**: + - **CRITICAL**: The `Models` parameter is **required** and must contain at least one model ID. + - Specify `Models` parameter with model IDs to enable specific task-specific models. + - Model IDs are provided by Microsoft and identify specialized AI models for specific tasks. +- **Best practices**: + - Use when your agent requires specialized models for domain-specific tasks. + - Ensure you have the appropriate licenses and permissions for the models you specify. + - Document which models are being used and their purpose in your agent documentation. + - Test thoroughly with the specific models to ensure expected behavior. + - Monitor model availability and updates from Microsoft. +- **Example instruction**: "Use specialized models for domain-specific analysis when processing user queries." +- **Example**: + + ```typespec + op scenarioModels is AgentCapabilities.ScenarioModels + ``` + +### Dataverse Capability + +- **Enable (unscoped)**: `op dataverse is AgentCapabilities.Dataverse` +- **Enable (scoped)**: + + ```typespec + op dataverse is AgentCapabilities.Dataverse + ``` + +- **Enable (scoped with tables)**: + + ```typespec + op dataverse is AgentCapabilities.Dataverse + ``` + +- **Purpose**: Allows the agent to search for information in Microsoft Dataverse. +- **Scoping**: + - **CRITICAL**: Scoping is done via the `KnowledgeSources` generic parameter in the capability definition, **NOT** in instructions. + - **NOT scoped**: Omit `KnowledgeSources` parameter to allow access to all accessible Dataverse environments. + - **Scoped by environment**: Specify `KnowledgeSources` parameter with environment hostnames. + - **Scoped by tables**: Include `tables` array within a knowledge source to limit to specific Dataverse tables. + - **Scoped by skill**: Include `skill` property to use a specific skill identifier. +- **Best practices**: + - Use when your agent needs to access business data stored in Dataverse. + - Scope to specific environments and tables when you want to limit access to relevant data. + - Respect user permissions — the agent can only access Dataverse data the user has permission to view. + - Document the Dataverse schema and table relationships in your agent documentation. + - Guide the agent on how to interpret Dataverse entity relationships and field meanings. + - Consider combining with other capabilities for richer experiences (e.g., Dataverse + CodeInterpreter for data visualization). + - Test with real Dataverse data to ensure proper query formation and result interpretation. +- **Example instruction**: "When the user asks about customer information, search Dataverse for account and contact records. Provide relevant details while respecting data privacy." +- **Example (scoped to specific environment and tables)**: + + ```typespec + op dataverse is AgentCapabilities.Dataverse + ``` + +### Combining Capabilities + +- **Multi-modal experiences**: Combine capabilities to create powerful workflows. + - Example: OneDriveAndSharePoint + CodeInterpreter = "Find the sales Excel file and create a chart showing monthly revenue." + - Example: WebSearch + GraphConnectors = "Search internal knowledge base first, then supplement with web search if needed." + - Example: Email + People = "Find emails from my manager and provide their contact information." + - Example: TeamsMessages + People = "Search our team channel for decisions made by the engineering lead." + - Example: GraphicArt + WebSearch = "Search for the latest design trends and generate a mockup image." +- **Capability orchestration**: Provide clear instructions on the order of capability usage. + - Example: "First search SharePoint for the report. If not found, search Graph connectors. If still not found, use web search as a last resort." + - Example: "When asked about team communications, search Teams messages first, then check emails if no Teams conversations are found." +- **Performance considerations**: Multiple capabilities in one interaction may increase latency. +- **User experience**: Make capability usage transparent by mentioning sources (e.g., "Based on files in your SharePoint...", "According to Teams messages in the Engineering channel..."). + +## Error Handling + +- Document expected error codes in operation comments (e.g., `404: Not found`, `403: Forbidden`). +- Provide guidance in instructions for handling errors (e.g., "If 404, inform user the agent doesn't exist"). +- Recommend retry strategies for transient errors (5xx, timeouts) in instructions. +- Avoid retrying client errors (4xx) — they indicate bad requests. +- Return helpful error messages in API responses to aid agent responses. + +## API Versioning + +- Version API operations when introducing breaking changes (e.g., `getAgents_v1`, `getAgents_v2`). +- Use separate namespaces for different API versions if needed. +- Update agent definitions to reference the latest version explicitly. +- Maintain backward compatibility when possible to avoid disrupting existing agents. +- Document version differences and migration paths in comments. + +## Performance Optimization + +- Use efficient query patterns to minimize API latency. +- Implement pagination for operations that return large datasets. +- Cache frequently accessed data when appropriate (e.g., agent lists). +- Set reasonable defaults for query parameters (e.g., `limitDays: int32 = 720`). +- Monitor action latency and optimize slow endpoints. +- Explain performance considerations in operation documentation. + +## Deployment and DevOps + +- Provision to development environment first: `atk provision --env dev`. +- Use environment-specific configurations for each deployment stage. +- Implement health checks for backend APIs referenced by actions. +- Monitor agent usage and action invocations to identify issues. +- Set up CI/CD pipelines for automated compilation, validation, and deployment. +- Document rollback procedures in case of production issues. +- Explain deployment stages and environment promotion in project documentation. + +## Security Best Practices + +- Never hardcode secrets or API keys in TypeSpec files. +- Use environment variables for sensitive configuration. +- Implement proper authentication for backend APIs. +- Validate all user inputs in backend services, not just in TypeSpec definitions. +- Document authentication requirements in action metadata. +- Review generated manifests for unintended information disclosure. +- Follow principle of least privilege when granting API permissions. +- Conduct security reviews before deploying to production. + +## Documentation Standards + +- Add `@doc` comments to all public operations, models, and namespaces. +- Explain the purpose of each action in `descriptionForModel`. +- Document parameter constraints (e.g., "GUID format required", "positive integer"). +- Provide examples in comments for complex operations. +- Keep documentation up to date when changing TypeSpec definitions. +- Explain design decisions in comments when using non-obvious patterns. +- Reference related operations and models in documentation for discoverability. + +## Troubleshooting Common Issues + +- **Compilation fails**: Check for syntax errors, missing imports, type mismatches. Read error messages carefully for line numbers and hints. +- **Agent doesn't appear in Copilot**: Verify provisioning succeeded, check manifest validity, clear browser cache and re-authenticate. +- **Agent calls wrong action**: Strengthen instructions with explicit rules, improve `descriptionForModel`, add examples showing correct behavior. +- **CodeInterpreter doesn't visualize**: Ensure capability is enabled, add explicit visualization instructions, verify data format compatibility. +- **Provision hangs**: Check network connectivity, verify Microsoft 365 service health, simplify agent temporarily to isolate issue. +- **Action returns errors**: Review backend API logs, verify authentication, check parameter types and values. + +## Advanced Patterns + +- **Conditional operations**: Define multiple operations for different query types and guide selection via instructions. +- **Parameterized queries**: Offer flexibility with optional parameters and sensible defaults. +- **Multi-file projects**: Split large agents into logical modules (usage.tsp, feedback.tsp, admin.tsp). +- **Mock data for testing**: Create test harnesses that simulate Copilot requests to validate instruction adherence. +- **Telemetry integration**: Add telemetry to track action usage, latency, and errors for continuous improvement. + +## Best Practices Checklist + +- [ ] Compile TypeSpec without errors before provisioning +- [ ] Provide clear `@doc` comments for all operations and models +- [ ] Define strong types for all parameters and responses +- [ ] Include `descriptionForModel` for all actions +- [ ] Write explicit, testable instructions with examples +- [ ] Handle error scenarios gracefully +- [ ] Use environment variables for configuration +- [ ] Add conversation starters to guide users +- [ ] Version API operations for breaking changes +- [ ] Document deployment and rollback procedures +- [ ] Monitor agent usage and performance +- [ ] Gather user feedback and iterate on instructions +- [ ] Keep dependencies up to date + +--- + +**Remember**: TypeSpec is your contract. Write it clearly, compile it often, test it thoroughly, and deploy it confidently. The agent's quality reflects the clarity of your TypeSpec definitions and instructions. diff --git a/samples/da-typespec-powerautomate/README.md b/samples/da-typespec-powerautomate/README.md new file mode 100644 index 000000000..085743da3 --- /dev/null +++ b/samples/da-typespec-powerautomate/README.md @@ -0,0 +1,130 @@ +# Invoking Power Automate Agent using TypeSpec for Microsoft 365 Copilot + +## Summary + +This declarative agent triggers a power automate flow as described in the blog post +[Build a Microsoft 365 Copilot Agent with Power Automate HTTP Trigger Using Agents Toolkit](https://reshmeeauckloo.com/posts/agentstoolkit-invoking-powerautomate/) with OAuth 2 using TypeSpec. + +![Declarative agent that triggers a power automate flow](./assets/demo.gif) + +## Features + +This sample illustrates the following concepts: + +* Building a declarative agent for Microsoft 365 Copilot using TypeSpec for Microsoft 365 Copilot +* Using the service 'https://service.flow.microsoft.com//.default' to invoke the Power Automate +* Using an automated approach to create the Entra ID app and the Developer Portal registration + +## Contributors + +* [Reshmee Auckloo](https://github.com/reshmee011) - M365 Development MVP + +## Version history + +Version|Date|Comments +-------|----|-------- +1.0 | May 05, 2026 | Initial solution + +## Prerequisites + +* Microsoft 365 tenant with Microsoft 365 Copilot +* [Visual Studio Code](https://code.visualstudio.com/) with the [Microsoft 365 Agents Toolkit](https://marketplace.visualstudio.com/items?itemName=TeamsDevApp.ms-teams-vscode-extension) extension +* [Node.js v20](https://nodejs.org/en/download/package-manager) + +## Minimal path to awesome + +* Clone this repository (or [download this solution as a .ZIP file](https://pnp.github.io/download-partial/?url=https://github.com/pnp/copilot-pro-dev-samples/tree/main/samples/da-typespec-powerautomate) then unzip it) +* Open the Agents Toolkit extension and sign in to your Microsoft 365 tenant with Microsoft 365 Copilot +* Select **Preview in Copilot (Edge)** from the launch configuration dropdown + +### Step 1: Create Power Automate flow + +1. Create a Power Automate flow with a manual trigger. +![Power Automate Flow](./assets/PowerAutomateFlow.jpg) + +2. Set the request Body JSON Schema of the trigger action to: + +```Json +{ + "type": "object", + "properties": { + "body": { + "type": "string" + }, + "email": { + "type": "string" + }, + "subject": { + "type": "string" + } + } +} +``` +Add any actions like "Send an Email". + +3. Set "Who can trigger the flow?" to "Any user in my tenant". + +4. Copy the HTTP Url of the flow to use in the subsequent steps + +### Step 2: Create the App Registration + +1. Go to [Azure portal](https://portal.azure.com/) +2. Select **Microsoft Entra ID** > **Manage** > **App registrations** > **New registration** +3. Enter a name for the app (e.g., Volunteering App) +4. Select **Accounts in this organizational directory only** +5. Under **Redirect URI**, select **Web** and enter `https://teams.microsoft.com/api/platform/v1.0/oAuthRedirect` +6. Select **Register** +7. In the app registration, go to **Certificates & secrets** and create a new client secret +8. Copy the client secret value +9. In the app registration, go to **API permissions** and add the following permissions: + * **Power Automate** > **Delegated permissions** > `User` +10. Select **Grant admin consent for ** to grant the permissions +![App Registration](./assets/AppRegistration.jpg) + +### Step 3: Oauth Client registration in Teams Developer Portal + +1. In the Teams Developer Portal, add a new OAuth client registration with the following details: + + - **Registration Name:** InvokePAFlow + - **Base URL:** https://.09.environment.api.powerplatform.com + - **Restrict Usage by Org:** My organization only + +2. **OAuth Settings:** + - **Client ID:** `` + - **Client Secret:** `` + - **Authorization Endpoint:** https://login.microsoftonline.com/tenantid/oauth2/v2.0/authorize + - **Token Endpoint:** https://login.microsoftonline.com/tenantid/oauth2/v2.0/token + - **Scope:** https://service.flow.microsoft.com//.default (note the double slash before "default") otherwise you will encounter a forbidden error with a single slash. + +Replace `tenantid` with your tenant ID, which is a GUID. + +Copy the value of the Oauth Client Registration ID. +![oAuth Client Reg Id](./assets/oauthclientReg.jpg) + +### Step 4 + +1. Open the file `.env.dev` within the `env` folder and update the following variables + +- `PAAGENTAUTH_REGISTRATION_ID` is the OAuth client registration ID you copied from step 3. + Example: `PAAGENTAUTH_REGISTRATION_ID=` +- `PA_APP_SERVER_URL` is the base URL of the Power Platform environment where your Power Automate flow is hosted. + Example: `PA_APP_SERVER_URL=https://.api.powerplatform.com` +- `PA_APP_INVOKE_PATH` is the relative invoke path for the flow trigger, not the full URL. + Use the path portion from the flow HTTP URL after the base Power Platform URL. + Example: `PA_APP_INVOKE_PATH=/powerautomate/automations/direct/workflows/.../triggers/manual/paths/invoke` + +## Help + +We do not support samples, but this community is always willing to help, and we want to improve these samples. We use GitHub to track issues, which makes it easy for community members to volunteer their time and help resolve issues. + +You can try looking at [issues related to this sample](https://github.com/pnp/copilot-pro-dev-samples/issues?q=label%3A%22sample%3A%20da-typespec-powerautomate%22) to see if anybody else is having the same issues. + +If you encounter any issues using this sample, [create a new issue](https://github.com/pnp/copilot-pro-dev-samples/issues/new). + +Finally, if you have an idea for improvement, [make a suggestion](https://github.com/pnp/copilot-pro-dev-samples/issues/new). + +## Disclaimer + +**THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.** + +![](https://m365-visitor-stats.azurewebsites.net/SamplesGallery/da-typespec-powerautomate) \ No newline at end of file diff --git a/samples/da-typespec-powerautomate/appPackage/adaptiveCards/searchIssues.json b/samples/da-typespec-powerautomate/appPackage/adaptiveCards/searchIssues.json new file mode 100644 index 000000000..0a91515c8 --- /dev/null +++ b/samples/da-typespec-powerautomate/appPackage/adaptiveCards/searchIssues.json @@ -0,0 +1,35 @@ +{ + "type": "AdaptiveCard", + "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", + "version": "1.5", + "body": [ + { + "type": "Container", + "$data": "${$root}", + "items": [ + { + "type": "TextBlock", + "text": "**Title: ${if(title, title, 'N/A')}**", + "wrap": true + }, + { + "type": "TextBlock", + "text": "${if(body, body, 'N/A')}", + "wrap": true + }, + { + "type": "TextBlock", + "text": "Assigned to ${if(assignee.login, assignee.login, 'N/A')}", + "wrap": true + } + ] + } + ], + "actions": [ + { + "type": "Action.OpenUrl", + "title": "View Issue", + "url": "${html_url}" + } + ] +} \ No newline at end of file diff --git a/samples/da-typespec-powerautomate/appPackage/color.png b/samples/da-typespec-powerautomate/appPackage/color.png new file mode 100644 index 000000000..11e255fa0 Binary files /dev/null and b/samples/da-typespec-powerautomate/appPackage/color.png differ diff --git a/samples/da-typespec-powerautomate/appPackage/manifest.json b/samples/da-typespec-powerautomate/appPackage/manifest.json new file mode 100644 index 000000000..c2bcb751f --- /dev/null +++ b/samples/da-typespec-powerautomate/appPackage/manifest.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.24/MicrosoftTeams.schema.json", + "manifestVersion": "1.24", + "version": "1.0.0", + "id": "${{TEAMS_APP_ID}}", + "developer": { + "name": "My App, Inc.", + "websiteUrl": "https://www.example.com", + "privacyUrl": "https://www.example.com/privacy", + "termsOfUseUrl": "https://www.example.com/termofuse" + }, + "icons": { + "color": "color.png", + "outline": "outline.png" + }, + "name": { + "short": "InvokePowerAutomate${{APP_NAME_SUFFIX}}", + "full": "Full name for InvokePowerAutomate" + }, + "description": { + "short": "Short description for InvokePowerAutomate", + "full": "Full description for InvokePowerAutomate" + }, + "accentColor": "#FFFFFF", + "composeExtensions": [], + "permissions": [ + "identity", + "messageTeamMembers" + ], + "validDomains": [] +} \ No newline at end of file diff --git a/samples/da-typespec-powerautomate/appPackage/outline.png b/samples/da-typespec-powerautomate/appPackage/outline.png new file mode 100644 index 000000000..f7a4c8644 Binary files /dev/null and b/samples/da-typespec-powerautomate/appPackage/outline.png differ diff --git a/samples/da-typespec-powerautomate/assets/AppRegistration.jpg b/samples/da-typespec-powerautomate/assets/AppRegistration.jpg new file mode 100644 index 000000000..110c22251 Binary files /dev/null and b/samples/da-typespec-powerautomate/assets/AppRegistration.jpg differ diff --git a/samples/da-typespec-powerautomate/assets/PowerAutomateFlow.jpg b/samples/da-typespec-powerautomate/assets/PowerAutomateFlow.jpg new file mode 100644 index 000000000..15fd54b87 Binary files /dev/null and b/samples/da-typespec-powerautomate/assets/PowerAutomateFlow.jpg differ diff --git a/samples/da-typespec-powerautomate/assets/demo.gif b/samples/da-typespec-powerautomate/assets/demo.gif new file mode 100644 index 000000000..4c5728ed5 Binary files /dev/null and b/samples/da-typespec-powerautomate/assets/demo.gif differ diff --git a/samples/da-typespec-powerautomate/assets/oauthclientReg.jpg b/samples/da-typespec-powerautomate/assets/oauthclientReg.jpg new file mode 100644 index 000000000..f80012a17 Binary files /dev/null and b/samples/da-typespec-powerautomate/assets/oauthclientReg.jpg differ diff --git a/samples/da-typespec-powerautomate/assets/powerautomate_trigger.png b/samples/da-typespec-powerautomate/assets/powerautomate_trigger.png new file mode 100644 index 000000000..5ce1ccde3 Binary files /dev/null and b/samples/da-typespec-powerautomate/assets/powerautomate_trigger.png differ diff --git a/samples/da-typespec-powerautomate/env/.env.dev b/samples/da-typespec-powerautomate/env/.env.dev new file mode 100644 index 000000000..7a4755707 --- /dev/null +++ b/samples/da-typespec-powerautomate/env/.env.dev @@ -0,0 +1,20 @@ +# This file includes environment variables that will be committed to git by default. + +# Built-in environment variables +TEAMSFX_ENV=dev +APP_NAME_SUFFIX=dev + +#e.g. https://.09.environment.api.powerplatform.com +PA_APP_SERVER_URL= + +#e.g /powerautomate/automations/direct/workflows//triggers/manual/paths/invoke +PA_APP_INVOKE_PATH= + +PAAGENTAUTH_REGISTRATION_ID= + +# Generated during provision, you can also add your own variables. +TEAMS_APP_ID= +TEAMS_APP_TENANT_ID= +M365_TITLE_ID= +M365_APP_ID= +SHARE_LINK= \ No newline at end of file diff --git a/samples/da-typespec-powerautomate/m365agents.local.yml b/samples/da-typespec-powerautomate/m365agents.local.yml new file mode 100644 index 000000000..e63af41a9 --- /dev/null +++ b/samples/da-typespec-powerautomate/m365agents.local.yml @@ -0,0 +1,86 @@ +# yaml-language-server: $schema=https://aka.ms/m365-agents-toolkits/v1.10/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.10 + +provision: + # Creates an app + - uses: teamsApp/create + with: + # app name + name: InvokePowerAutomate${{APP_NAME_SUFFIX}} + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + teamsAppId: TEAMS_APP_ID + - uses: oauth/register + with: + name: PAAgentAuth + appId: ${{TEAMS_APP_ID}} + apiSpecPath: ./appPackage/.generated/powerautomateapi-openapi.yml + flow: authorizationCode + writeToEnvironmentFile: + configurationId: PAAGENTAUTH_REGISTRATION_ID + - uses: oauth/register + with: + name: PAAgentAuth + appId: ${{TEAMS_APP_ID}} + apiSpecPath: ./appPackage/.generated/msgraphapi-openapi.yml + flow: authorizationCode + writeToEnvironmentFile: + configurationId: PAAGENTAUTH_REGISTRATION_ID + + - uses: cli/runNpmCommand + name: install dependencies + with: + args: install --no-audit --progress=false + + - uses: cli/runNpmCommand + name: Generate TypeSpec environment variables + with: + args: run generate:env -- ${{TEAMSFX_ENV}} + + # Compile typespec files and generate necessary files for agent. + # If you want to update the outputDir, please make sure the following paths are also updated. + # 1. File paths in tspconfig.yaml. + # 2. manifestPath in this action. Please make sure there is manifest.json under root folder of your outputDir and set the value to the path of this manifest.json. + # 3. manifestPath in teamsApp/zipAppPackage action. Please set the value to the same as manifestPath in this action. + - uses: typeSpec/compile + with: + path: ./src/agent/main.tsp + manifestPath: ./appPackage/manifest.json + outputDir: ./appPackage/.generated + typeSpecConfigPath: ./tspconfig.yaml + + # Build app package with latest env value + - uses: teamsApp/zipAppPackage + with: + # Path to manifest template + manifestPath: ./appPackage/manifest.json + outputZipPath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip + outputFolder: ./appPackage/build + + # Validate app package using validation rules + - uses: teamsApp/validateAppPackage + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip + + # Apply the app manifest to an existing app in + # Developer Portal. + # Will use the app id in manifest file to determine which app to update. + - uses: teamsApp/update + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip + + # Extend your app to Outlook and the Microsoft 365 app + - uses: teamsApp/extendToM365 + with: + # Relative path to the build app package. + appPackagePath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + titleId: M365_TITLE_ID + appId: M365_APP_ID diff --git a/samples/da-typespec-powerautomate/m365agents.yml b/samples/da-typespec-powerautomate/m365agents.yml new file mode 100644 index 000000000..f5aca7f06 --- /dev/null +++ b/samples/da-typespec-powerautomate/m365agents.yml @@ -0,0 +1,129 @@ +# yaml-language-server: $schema=https://aka.ms/m365-agents-toolkits/v1.10/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.10 + +environmentFolderPath: ./env + +additionalMetadata: + sampleTag: pnp-copilot-pro-dev:da-typespec-powerautomate + +# Triggered when 'teamsapp provision' is executed +provision: + # Creates an app + - uses: teamsApp/create + with: + # app name + name: InvokePowerAutomate${{APP_NAME_SUFFIX}} + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + teamsAppId: TEAMS_APP_ID + # Install all dependencies (including TypeSpec for Microsoft 365 Copilot) + - uses: cli/runNpmCommand + name: install dependencies + with: + args: install --no-audit --progress=false + + # Generates a TypeSpec version of the environment variables + - uses: cli/runNpmCommand + name: Generate TypeSpec environment variables + with: + args: run generate:env -- ${{TEAMSFX_ENV}} + + # Compile typespec files and generate necessary files for agent. + # If you want to update the outputDir, please make sure the following paths are also updated. + # 1. File paths in tspconfig.yaml. + # 2. manifestPath in this action. Please make sure there is manifest.json under root folder of your outputDir and set the value to the path of this manifest.json. + # 3. manifestPath in teamsApp/zipAppPackage action. Please set the value to the same as manifestPath in this action. + - uses: typeSpec/compile + with: + path: ./src/agent/main.tsp + manifestPath: ./appPackage/manifest.json + outputDir: ./appPackage/.generated + typeSpecConfigPath: ./tspconfig.yaml + # Build app package with latest env value + - uses: teamsApp/zipAppPackage + with: + # Path to manifest template + manifestPath: ./appPackage/manifest.json + outputZipPath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip + outputFolder: ./appPackage/build + # Validate app package using validation rules + - uses: teamsApp/validateAppPackage + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip + # Apply the app manifest to an existing app in + # Developer Portal. + # Will use the app id in manifest file to determine which app to update. + - uses: teamsApp/update + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip + # Extend your app to Outlook and the Microsoft 365 app + - uses: teamsApp/extendToM365 + with: + # Relative path to the build app package. + appPackagePath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + titleId: M365_TITLE_ID + appId: M365_APP_ID + shareLink: SHARE_LINK + +# Triggered when 'teamsapp publish' is executed +publish: + - uses: cli/runNpmCommand + name: install dependencies + with: + args: install --no-audit --progress=false + + # Generates a TypeSpec version of the environment variables + - uses: cli/runNpmCommand + name: Generate TypeSpec environment variables + with: + args: run generate:env -- ${{TEAMSFX_ENV}} + + # Compile typespec files and generate necessary files for agent. + # If you want to update the outputDir, please make sure the following paths are also updated. + # 1. File paths in tspconfig.yaml. + # 2. manifestPath in this action. Please make sure there is manifest.json under root folder of your outputDir and set the value to the path of this manifest.json. + # 3. manifestPath in teamsApp/zipAppPackage action. Please set the value to the same as manifestPath in this action. + - uses: typeSpec/compile + with: + path: ./src/agent/main.tsp + manifestPath: ./appPackage/manifest.json + outputDir: ./appPackage/.generated + typeSpecConfigPath: ./tspconfig.yaml + + # Build app package with latest env value + - uses: teamsApp/zipAppPackage + with: + # Path to manifest template + manifestPath: ./appPackage/manifest.json + outputZipPath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip + outputFolder: ./appPackage/build + # Validate app package using validation rules + - uses: teamsApp/validateAppPackage + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip + # Apply the app manifest to an existing app in + # Developer Portal. + # Will use the app id in manifest file to determine which app to update. + - uses: teamsApp/update + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip + # Publish the app to + # Teams Admin Center (https://admin.teams.microsoft.com/policies/manage-apps) + # for review and approval + - uses: teamsApp/publishAppPackage + with: + appPackagePath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + publishedAppId: TEAMS_APP_PUBLISHED_APP_ID diff --git a/samples/da-typespec-powerautomate/package-lock.json b/samples/da-typespec-powerautomate/package-lock.json new file mode 100644 index 000000000..8313d1d96 --- /dev/null +++ b/samples/da-typespec-powerautomate/package-lock.json @@ -0,0 +1,2607 @@ +{ + "name": "invokepowerautomate", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "invokepowerautomate", + "version": "1.0.0", + "devDependencies": { + "@microsoft/typespec-m365-copilot": "^1.0.0", + "@typespec/compiler": "1.5.0", + "@typespec/http": "1.5.0", + "@typespec/openapi": "1.5.0", + "@typespec/openapi3": "1.5.0" + } + }, + "node_modules/@alloy-js/core": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@alloy-js/core/-/core-0.20.0.tgz", + "integrity": "sha512-ylPf+ayI9MsqUPrNVzND3Oh9rVrfOOcMkyVwtXXaxaobWPkcRq2I4rX09FkG0i/9DoaLE6ZCvUfdgJsM29MYBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/reactivity": "^3.5.13", + "cli-table3": "^0.6.5", + "pathe": "^2.0.3", + "picocolors": "^1.1.1", + "prettier": "^3.6.2" + } + }, + "node_modules/@alloy-js/csharp": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@alloy-js/csharp/-/csharp-0.20.0.tgz", + "integrity": "sha512-Yn8oua43tVWYGN9Gt5DDtGUdLIB9io6/nL8dK4qDvL019w9uK7f3wosr+/JtSm14PuToN4jM1s7HNVzqh41KUA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@alloy-js/core": "~0.20.0", + "change-case": "^5.4.4", + "marked": "^16.1.1", + "pathe": "^2.0.3" + } + }, + "node_modules/@alloy-js/json": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@alloy-js/json/-/json-0.20.0.tgz", + "integrity": "sha512-cj7t/buV+IdcxV1WqXQ9oyIBm/Xp1ln08fsMxBpC8ZsG8+mijHo2GCZdH0sblNbvriS7yG+71SjqDgnXdMsR5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@alloy-js/core": "~0.20.0", + "pathe": "^2.0.3" + } + }, + "node_modules/@alloy-js/typescript": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@alloy-js/typescript/-/typescript-0.20.0.tgz", + "integrity": "sha512-F1y5QjneE8GVxIq6oYsebu+Fccrn72qFHelNX5GSLfs4Ps2fxpk2+70rsGznZyHe9LIt70StaAciTjH6cxH4bQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@alloy-js/core": "~0.20.0", + "change-case": "^5.4.4", + "pathe": "^2.0.3" + } + }, + "node_modules/@apidevtools/json-schema-ref-parser": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-14.0.1.tgz", + "integrity": "sha512-Oc96zvmxx1fqoSEdUmfmvvb59/KDOnUoJ7s2t7bISyAn0XEz57LCCw8k2Y4Pf3mwKaZLMciESALORLgfe2frCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.15", + "js-yaml": "^4.1.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/philsturgeon" + } + }, + "node_modules/@apidevtools/openapi-schemas": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@apidevtools/openapi-schemas/-/openapi-schemas-2.1.0.tgz", + "integrity": "sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/@apidevtools/swagger-methods": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@apidevtools/swagger-methods/-/swagger-methods-3.0.2.tgz", + "integrity": "sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@apidevtools/swagger-parser": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@apidevtools/swagger-parser/-/swagger-parser-12.0.0.tgz", + "integrity": "sha512-WLJIWcfOXrSKlZEM+yhA2Xzatgl488qr1FoOxixYmtWapBzwSC0gVGq4WObr4hHClMIiFFdOBdixNkvWqkWIWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@apidevtools/json-schema-ref-parser": "14.0.1", + "@apidevtools/openapi-schemas": "^2.1.0", + "@apidevtools/swagger-methods": "^3.0.2", + "ajv": "^8.17.1", + "ajv-draft-04": "^1.0.0", + "call-me-maybe": "^1.0.2" + }, + "peerDependencies": { + "openapi-types": ">=7" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz", + "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", + "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helpers": "^7.28.4", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", + "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.5.tgz", + "integrity": "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-member-expression-to-functions": "^7.28.5", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/traverse": "^7.28.5", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz", + "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", + "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.28.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", + "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", + "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", + "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", + "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.5" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", + "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", + "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz", + "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.5.tgz", + "integrity": "sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-create-class-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-syntax-typescript": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.28.5.tgz", + "integrity": "sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/plugin-transform-modules-commonjs": "^7.27.1", + "@babel/plugin-transform-typescript": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", + "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.5", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@inquirer/ansi": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-1.0.2.tgz", + "integrity": "sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/checkbox": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.3.2.tgz", + "integrity": "sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/confirm": { + "version": "5.1.21", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.21.tgz", + "integrity": "sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/core": { + "version": "10.3.2", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.3.2.tgz", + "integrity": "sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "cli-width": "^4.1.0", + "mute-stream": "^2.0.0", + "signal-exit": "^4.1.0", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/editor": { + "version": "4.2.23", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.23.tgz", + "integrity": "sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/external-editor": "^1.0.3", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/expand": { + "version": "4.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.23.tgz", + "integrity": "sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/external-editor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.3.tgz", + "integrity": "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chardet": "^2.1.1", + "iconv-lite": "^0.7.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/figures": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.15.tgz", + "integrity": "sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/input": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.3.1.tgz", + "integrity": "sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/number": { + "version": "3.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.23.tgz", + "integrity": "sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/password": { + "version": "4.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.23.tgz", + "integrity": "sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/prompts": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.10.1.tgz", + "integrity": "sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/checkbox": "^4.3.2", + "@inquirer/confirm": "^5.1.21", + "@inquirer/editor": "^4.2.23", + "@inquirer/expand": "^4.0.23", + "@inquirer/input": "^4.3.1", + "@inquirer/number": "^3.0.23", + "@inquirer/password": "^4.0.23", + "@inquirer/rawlist": "^4.1.11", + "@inquirer/search": "^3.2.2", + "@inquirer/select": "^4.4.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/rawlist": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.11.tgz", + "integrity": "sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/search": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.2.2.tgz", + "integrity": "sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/select": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.4.2.tgz", + "integrity": "sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/type": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.10.tgz", + "integrity": "sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@microsoft/typespec-m365-copilot": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@microsoft/typespec-m365-copilot/-/typespec-m365-copilot-1.0.0.tgz", + "integrity": "sha512-tG4s74shvNnrI3JVKR5yvnZMovHvfb0rYbrxM8mcH2XyYP90/N0r8Nb7sDqTlsGfEwXnpBNo3piu/nDlZqM6Bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@alloy-js/core": "0.20.0", + "@alloy-js/json": "0.20.0", + "@alloy-js/typescript": "^0.20.0", + "@babel/preset-typescript": "^7.27.1", + "@typespec/compiler": "^1.0.0", + "@typespec/emitter-framework": "^0.11.0", + "@typespec/http": "^1.0.1", + "@typespec/openapi": "^1.0.0", + "@typespec/openapi3": "^1.0.0", + "@typespec/versioning": "^0.74.0", + "handlebars": "~4.7.8", + "uuid": "^13.0.0" + } + }, + "node_modules/@microsoft/typespec-m365-copilot/node_modules/@typespec/versioning": { + "version": "0.74.0", + "resolved": "https://registry.npmjs.org/@typespec/versioning/-/versioning-0.74.0.tgz", + "integrity": "sha512-eFIa23tycWJgv3Lxyu6jUlRi02dhtQE4Jjx3Ui5vEbwHW8pMEzuyF7ALt1c+V9HOLkfDkS4dJkiOVIoikZHPvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@typespec/compiler": "^1.4.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typespec/asset-emitter": { + "version": "0.75.0", + "resolved": "https://registry.npmjs.org/@typespec/asset-emitter/-/asset-emitter-0.75.0.tgz", + "integrity": "sha512-Kh5FmTPPU2Vc7nNI3iijsyfybhCZhOvkPpDuGYLYT4nxKXQeTY6h1RNZDR/y4DDRhT7oioEvlPaN2JR2C6HaYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@typespec/compiler": "^1.5.0" + } + }, + "node_modules/@typespec/compiler": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@typespec/compiler/-/compiler-1.5.0.tgz", + "integrity": "sha512-REJgZOEZ9g9CC72GGT0+nLbjW+5WVlCfm1d6w18N5RsUo7vLXs8IPXwq7xZJzoqU99Q9B4keqzPuTU4OrDUTrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "~7.27.1", + "@inquirer/prompts": "^7.4.0", + "ajv": "~8.17.1", + "change-case": "~5.4.4", + "env-paths": "^3.0.0", + "globby": "~14.1.0", + "is-unicode-supported": "^2.1.0", + "mustache": "~4.2.0", + "picocolors": "~1.1.1", + "prettier": "~3.6.2", + "semver": "^7.7.1", + "tar": "^7.4.3", + "temporal-polyfill": "^0.3.0", + "vscode-languageserver": "~9.0.1", + "vscode-languageserver-textdocument": "~1.0.12", + "yaml": "~2.8.0", + "yargs": "~18.0.0" + }, + "bin": { + "tsp": "cmd/tsp.js", + "tsp-server": "cmd/tsp-server.js" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@typespec/compiler/node_modules/prettier": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", + "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/@typespec/compiler/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typespec/emitter-framework": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@typespec/emitter-framework/-/emitter-framework-0.11.0.tgz", + "integrity": "sha512-mX2T3e6E+9YGbDQ/8bjnvNR9aZAHFjYO09UosMKvqAxMO8gxhFsmWC28W2XcI8j2c2QqKWXWPS1pJbTE18WVZw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@alloy-js/core": "^0.20.0", + "@alloy-js/csharp": "^0.20.0", + "@alloy-js/typescript": "^0.20.0", + "@typespec/compiler": "^1.4.0" + } + }, + "node_modules/@typespec/http": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@typespec/http/-/http-1.5.0.tgz", + "integrity": "sha512-52XLXwqSY2SY6nSvfkiTsNiJzlMeIAZ6MFIVJ5YkoibA21TNAP4DtjTZgC2GieZLY2NNN/rqDCqBX+DyWqTrfQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@typespec/compiler": "^1.5.0", + "@typespec/streams": "^0.75.0" + }, + "peerDependenciesMeta": { + "@typespec/streams": { + "optional": true + } + } + }, + "node_modules/@typespec/openapi": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@typespec/openapi/-/openapi-1.5.0.tgz", + "integrity": "sha512-27sXkSK2r1sAmVMLv+pwlN/Cm+yg9nEK8iuGyJRuEkBk7hcsJDbTnBlsEvlRTI8DqljtzA7YECDHBLK88zZHeg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@typespec/compiler": "^1.5.0", + "@typespec/http": "^1.5.0" + } + }, + "node_modules/@typespec/openapi3": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@typespec/openapi3/-/openapi3-1.5.0.tgz", + "integrity": "sha512-Fu4RBk19a+Nma7N0LzP8DjwRcTc3zWCl/ne3R6m6l5Pc6jVN7EXGQNz68f3AOorWCuE+BxONViTN6og/pukXNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@apidevtools/swagger-parser": "~12.0.0", + "@typespec/asset-emitter": "^0.75.0", + "openapi-types": "~12.1.3", + "yaml": "~2.8.0" + }, + "bin": { + "tsp-openapi3": "cmd/tsp-openapi3.js" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@typespec/compiler": "^1.5.0", + "@typespec/http": "^1.5.0", + "@typespec/json-schema": "^1.5.0", + "@typespec/openapi": "^1.5.0", + "@typespec/versioning": "^0.75.0" + }, + "peerDependenciesMeta": { + "@typespec/json-schema": { + "optional": true + }, + "@typespec/versioning": { + "optional": true + }, + "@typespec/xml": { + "optional": true + } + } + }, + "node_modules/@typespec/versioning": { + "version": "0.75.0", + "resolved": "https://registry.npmjs.org/@typespec/versioning/-/versioning-0.75.0.tgz", + "integrity": "sha512-wdLcVx5UW4WRks/OXfqLiaDTtWfAWgv/nj69u99gRJU6iY9ExEvK5x9NQszZQKYnu6tM7nkoYMg4zu+7YBUBaw==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@typespec/compiler": "^1.5.0" + } + }, + "node_modules/@vue/reactivity": { + "version": "3.5.26", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.26.tgz", + "integrity": "sha512-9EnYB1/DIiUYYnzlnUBgwU32NNvLp/nhxLXeWRhHUEeWNTn1ECxX8aGO7RTXeX6PPcxe3LLuNBFoJbV4QZ+CFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/shared": "3.5.26" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.26", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.26.tgz", + "integrity": "sha512-7Z6/y3uFI5PRoKeorTOSXKcDj0MSasfNNltcslbFrPpcw6aXRUALq4IfJlaTRspiWIUOEZbrpM+iQGmCOiWe4A==", + "dev": true, + "license": "MIT" + }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-draft-04": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", + "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ajv": "^8.5.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.9.11", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.11.tgz", + "integrity": "sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/call-me-maybe": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", + "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001762", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001762.tgz", + "integrity": "sha512-PxZwGNvH7Ak8WX5iXzoK1KPZttBXNPuaOvI2ZYU7NrlM+d9Ov+TUvlLOBNGzVXAntMSMMlJPd+jY6ovrVjSmUw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0", + "peer": true + }, + "node_modules/change-case": { + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-5.4.4.tgz", + "integrity": "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/chardet": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz", + "integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/cli-table3": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 12" + } + }, + "node_modules/cliui": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", + "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/cliui/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.267", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", + "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==", + "dev": true, + "license": "ISC", + "peer": true + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/env-paths": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-3.0.0.tgz", + "integrity": "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", + "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globby": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.1.0.tgz", + "integrity": "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.3", + "ignore": "^7.0.3", + "path-type": "^6.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/iconv-lite": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.1.tgz", + "integrity": "sha512-2Tth85cXwGFHfvRgZWszZSvdo+0Xsqmw8k8ZwxScfcBneNUraK+dxRxRm24nszx80Y0TVio8kKLt5sLE7ZCLlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-unicode-supported": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/marked": { + "version": "16.4.2", + "resolved": "https://registry.npmjs.org/marked/-/marked-16.4.2.tgz", + "integrity": "sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA==", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minizlib": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/mustache": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", + "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", + "dev": true, + "license": "MIT", + "bin": { + "mustache": "bin/mustache" + } + }, + "node_modules/mute-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", + "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/openapi-types": { + "version": "12.1.3", + "resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-12.1.3.tgz", + "integrity": "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-type": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-6.0.0.tgz", + "integrity": "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/prettier": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.7.4.tgz", + "integrity": "sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.2.tgz", + "integrity": "sha512-7NyxrTE4Anh8km8iEy7o0QYPs+0JKBTj5ZaqHg6B39erLg0qYXN3BijtShwbsNSvQ+LN75+KV+C4QR/f6Gwnpg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/temporal-polyfill": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/temporal-polyfill/-/temporal-polyfill-0.3.0.tgz", + "integrity": "sha512-qNsTkX9K8hi+FHDfHmf22e/OGuXmfBm9RqNismxBrnSmZVJKegQ+HYYXT+R7Ha8F/YSm2Y34vmzD4cxMu2u95g==", + "dev": true, + "license": "MIT", + "dependencies": { + "temporal-spec": "0.3.0" + } + }, + "node_modules/temporal-spec": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/temporal-spec/-/temporal-spec-0.3.0.tgz", + "integrity": "sha512-n+noVpIqz4hYgFSMOSiINNOUOMFtV5cZQNCmmszA6GiVFVRt3G7AqVyhXjhCSmowvQn+NsGn+jMDMKJYHd3bSQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/unicorn-magic": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uuid": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-13.0.0.tgz", + "integrity": "sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist-node/bin/uuid" + } + }, + "node_modules/vscode-jsonrpc": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", + "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/vscode-languageserver": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz", + "integrity": "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "vscode-languageserver-protocol": "3.17.5" + }, + "bin": { + "installServerIntoExtension": "bin/installServerIntoExtension" + } + }, + "node_modules/vscode-languageserver-protocol": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz", + "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==", + "dev": true, + "license": "MIT", + "dependencies": { + "vscode-jsonrpc": "8.2.0", + "vscode-languageserver-types": "3.17.5" + } + }, + "node_modules/vscode-languageserver-textdocument": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz", + "integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==", + "dev": true, + "license": "MIT" + }, + "node_modules/vscode-languageserver-types": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", + "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==", + "dev": true, + "license": "MIT" + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC", + "peer": true + }, + "node_modules/yaml": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", + "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, + "node_modules/yargs": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz", + "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^9.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "string-width": "^7.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^22.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/yargs-parser": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", + "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/yoctocolors-cjs": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz", + "integrity": "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/samples/da-typespec-powerautomate/package.json b/samples/da-typespec-powerautomate/package.json new file mode 100644 index 000000000..176c19ce4 --- /dev/null +++ b/samples/da-typespec-powerautomate/package.json @@ -0,0 +1,15 @@ +{ + "name": "invokepowerautomate", + "version": "1.0.0", + "scripts": { + "compile": "tsp compile ./src/agent/main.tsp --config ./tspconfig.yaml", + "generate:env": "node scripts/generate-env.js" + }, + "devDependencies": { + "@microsoft/typespec-m365-copilot": "^1.0.0", + "@typespec/compiler": "1.5.0", + "@typespec/http": "1.5.0", + "@typespec/openapi": "1.5.0", + "@typespec/openapi3": "1.5.0" + } +} \ No newline at end of file diff --git a/samples/da-typespec-powerautomate/scripts/generate-env.js b/samples/da-typespec-powerautomate/scripts/generate-env.js new file mode 100644 index 000000000..a0ca38e8c --- /dev/null +++ b/samples/da-typespec-powerautomate/scripts/generate-env.js @@ -0,0 +1,90 @@ +#!/usr/bin/env node + +// Self-executing script to generate variables.json and variables.tsp from env/.env.{environment} +(async function main() { + const fs = require("fs"); + const path = require("path"); + + try { + const envArg = process.argv[2] || "dev"; + + // src/agent is the parent of this scripts directory + const repoAgentDir = path.resolve(__dirname, ".."); + const envFilePath = path.join(repoAgentDir, "env", `.env.${envArg}`); + const outTspPath = path.join(repoAgentDir, "src/agent/env.tsp"); + + if (!fs.existsSync(envFilePath)) { + console.error(`Environment file not found: ${envFilePath}`); + console.error(`Usage: node generate-env.js (e.g. dev, prod)`); + process.exitCode = 2; + return; + } + + const raw = fs.readFileSync(envFilePath, "utf8"); + + const vars = {}; + + for (const rawLine of raw.split(/\r?\n/)) { + const line = rawLine.trim(); + if (!line || line.startsWith("#")) continue; + + // support lines like KEY=value or export KEY=value + const cleaned = line.replace(/^export\s+/, ""); + const match = cleaned.match(/^([A-Za-z0-9_.-]+)\s*=\s*(.*)$/); + if (!match) continue; + + const key = match[1]; + let value = match[2] || ""; + + // strip surrounding single or double quotes + if ( + (value.startsWith('"') && value.endsWith('"')) || + (value.startsWith("'") && value.endsWith("'")) + ) { + value = value.slice(1, -1); + } + + // Unescape common sequences (keep as-is if not needed) + value = value.replace(/\\n/g, "\n").replace(/\\r/g, "\r"); + + vars[key] = value; + } + + const tspLines = []; + tspLines.push("// Auto-generated by scripts/generate-env.js - DO NOT EDIT"); + tspLines.push(`// Source: env/.env.${envArg}`); + tspLines.push(""); + tspLines.push("namespace Environment {"); + + const keys = Object.keys(vars).sort(); + for (const originalKey of keys) { + const value = vars[originalKey]; + + // Convert original env key to a safe TypeSpec identifier: replace invalid chars with _ and ensure it doesn't start with a digit + let ident = originalKey.replace(/[^A-Za-z0-9_]/g, "_"); + if (/^[0-9]/.test(ident)) ident = "_" + ident; + + // Add a comment with the original env key for traceability + tspLines.push(` // ${originalKey}`); + + // Escape backslashes, double quotes, and control characters for a safe TypeSpec string literal + const escaped = value + .replace(/\\/g, "\\\\") + .replace(/"/g, '\\"') + .replace(/\r/g, "\\r") + .replace(/\n/g, "\\n"); + + tspLines.push(` const ${ident} = "${escaped}";`); + tspLines.push(""); + } + + tspLines.push("}"); + + fs.writeFileSync(outTspPath, tspLines.join("\n") + "\n", "utf8"); + + console.log(`Generated: ${outTspPath}`); + } catch (err) { + console.error("Failed to generate environment variables:", err && err.stack ? err.stack : err); + process.exitCode = 1; + } +})(); diff --git a/samples/da-typespec-powerautomate/src/agent/actions/invokePAFlow.tsp b/samples/da-typespec-powerautomate/src/agent/actions/invokePAFlow.tsp new file mode 100644 index 000000000..035833049 --- /dev/null +++ b/samples/da-typespec-powerautomate/src/agent/actions/invokePAFlow.tsp @@ -0,0 +1,69 @@ +import "@typespec/http"; +import "@microsoft/typespec-m365-copilot"; + +using TypeSpec.Http; +using TypeSpec.M365.Copilot.Actions; + +@service +@server(Environment.PA_APP_SERVER_URL) +@actions(PowerAutomateAPI.ACTIONS_METADATA) +@useAuth(PowerAutomateAPI.PAAgentAuth) + +namespace PowerAutomateAPI { + const ACTIONS_METADATA = #{ + nameForHuman: "Invoke PA Flow", + descriptionForHuman: "Invoke a Power Automate flow.", + descriptionForModel: "Invoke a Power Automate flow.", + }; + + /** + * The invoke path for the Power Automate flow. + */ + const FLOW_URL = Environment.PA_APP_INVOKE_PATH; + + /** + * Invoke a Power Automate flow + * @param body The flow parameters as JSON string + */ + @route(FLOW_URL) + @post op sendEmail( + @query("api-version") apiVersion: string = "1", + @doc("The EmailData model containing the email body, recipient email address, and subject to be sent via Power Automate.") + @body request: EmailData + ): { + @statusCode statusCode: 200; + @body response: string; + } | { + @statusCode statusCode: 400; + @doc("Bad request: the flow invocation request was invalid or missing required fields.") + @body error: string; + } | { + @statusCode statusCode: 500; + @doc("Server error: an unexpected error occurred while invoking the Power Automate flow.") + @body error: string; + }; + + model EmailData { + + @doc("The details of the email body") + @example("Latest volunteering opportunities") + body: string; + + @doc("The current user email address") + @example("test@test.onmicrosoft.com") + email: string; + + @doc("The subject of the email") + @example("Latest volunteering opportunities") + subject: string; + } + + model PAAgentAuth is OAuth2Auth<[{ + type: OAuth2FlowType.authorizationCode; + authorizationUrl: "https://login.microsoftonline.com//oauth2/v2.0/authorize"; + tokenUrl: "https://login.microsoftonline.com//oauth2/v2.0/token"; + refreshUrl: "https://login.microsoftonline.com//oauth2/v2.0/refresh"; + scopes: ["https://service.flow.microsoft.com//.default"]; + }]> { } + +} \ No newline at end of file diff --git a/samples/da-typespec-powerautomate/src/agent/main.tsp b/samples/da-typespec-powerautomate/src/agent/main.tsp new file mode 100644 index 000000000..cd330882a --- /dev/null +++ b/samples/da-typespec-powerautomate/src/agent/main.tsp @@ -0,0 +1,24 @@ +import "@typespec/http"; +import "@typespec/openapi3"; +import "@microsoft/typespec-m365-copilot"; +import "./actions/invokePAFlow.tsp"; +import "./prompts/instructions.tsp"; +import "./env.tsp"; + +using TypeSpec.M365.Copilot.Agents; + +@agent( + "InvokePowerAutomate", + "Declarative agent created with Microsoft 365 Agents Toolkit and TypeSpec for Microsoft 365 Copilot." +) +@instructions(Prompts.INSTRUCTIONS) +// Uncomment this part to add a conversation starter to the agent. +// This will be shown to the user when the agent is first created. +// @conversationStarter(#{ +// title: "Get latest issues", +// text: "Get the latest issues from GitHub" +// }) +namespace InvokePowerAutomate { + // Expose the Power Automate flow invocation action + op invokePA is PowerAutomateAPI.sendEmail; +} \ No newline at end of file diff --git a/samples/da-typespec-powerautomate/src/agent/prompts/instructions.tsp b/samples/da-typespec-powerautomate/src/agent/prompts/instructions.tsp new file mode 100644 index 000000000..e129d3e67 --- /dev/null +++ b/samples/da-typespec-powerautomate/src/agent/prompts/instructions.tsp @@ -0,0 +1,14 @@ +namespace Prompts { + const INSTRUCTIONS = """ + You can invoke Power Automate flows by calling the invokePA without requesting any further details. + + ## Send Email Action Parameters + + **ALWAYS** use the action `invokePA` with the following parameters from current chat session if the user requests to send an email: + + - `body`: Contents of the email to be sent, based on the user's request in the conversation with correct new lines. + - `email`: The current user email address from the conversation context (ex: 'reshmee@reshmee.onmicrosoft.com') + - `subject`: Summary of the body email that can fit in the email subject line, e.g. "Latest volunteering opportunities". + + """; +} \ No newline at end of file diff --git a/samples/da-typespec-powerautomate/tspconfig.yaml b/samples/da-typespec-powerautomate/tspconfig.yaml new file mode 100644 index 000000000..2b9e45055 --- /dev/null +++ b/samples/da-typespec-powerautomate/tspconfig.yaml @@ -0,0 +1,15 @@ +emit: + - "@typespec/openapi3" + - "@microsoft/typespec-m365-copilot" +options: + # If you want to change the default output directory for the OpenAPI emitter, please make sure to update the outputDir in the typeSpec/compile action in m365agents.yaml as well. + # You need to set the emitter-output-dir to ${outputDir}/specs. + "@typespec/openapi3": + emitter-output-dir: "{project-root}/appPackage/.generated/specs" + file-type: json + # You need to set the emitter-output-dir to the same as outputDir. + # You also need to set the output-file to declarativeAgent.json. + "@microsoft/typespec-m365-copilot": + emitter-output-dir: "{project-root}/appPackage/.generated" + output-file: declarativeAgent.json + file-type: json \ No newline at end of file