### Manual Plugin Installation (Bash) Source: https://github.com/yetone/alma-plugins/blob/main/plugins/openai-codex-auth/README.md Instructions for manually installing the OpenAI Codex Auth Plugin by cloning the repository into the Alma plugins directory. This method is an alternative to searching and installing directly through the Alma Settings. ```bash # Clone to your plugins directory git clone https://github.com/alma-plugins/openai-codex-auth ~/.config/alma/plugins/openai-codex-auth ``` -------------------------------- ### Install alma-plugin-api with npm Source: https://github.com/yetone/alma-plugins/blob/main/packages/plugin-api/README.md This command installs the 'alma-plugin-api' package as a development dependency for your project. This package provides the necessary TypeScript type definitions for creating Alma plugins. ```bash npm install -D alma-plugin-api ``` -------------------------------- ### Clone Antigravity Auth Plugin Repository Source: https://github.com/yetone/alma-plugins/blob/main/plugins/antigravity-auth/README.md Installs the Antigravity Auth plugin by cloning its Git repository to the specified Alma plugins directory. This is an alternative to manual installation through Alma's plugin manager. ```bash git clone https://github.com/alma-plugins/antigravity-auth ~/.config/alma/plugins/antigravity-auth ``` -------------------------------- ### Secret Storage for API Keys in TypeScript Source: https://context7.com/yetone/alma-plugins/llms.txt This example shows how to securely store and retrieve sensitive credentials, such as API keys, using Alma's secret storage API. It includes commands to set, test, and clear API keys, providing user feedback through notifications and logging. Input validation is implemented for the API key. ```typescript import type { PluginContext, PluginActivation } from 'alma-plugin-api'; export async function activate(context: PluginContext): Promise { const { logger, storage, commands, ui } = context; // Command to set API key const setKeyCommand = commands.register('setApiKey', async () => { const apiKey = await ui.showInputBox({ title: 'Enter API Key', prompt: 'Your API key will be securely stored', password: true, validateInput: (value) => { if (!value || value.length < 10) { return 'API key must be at least 10 characters'; } return undefined; } }); if (apiKey) { await storage.secrets.set('api-key', apiKey); ui.showNotification('API key saved securely', { type: 'success' }); logger.info('API key stored in secure storage'); } }); // Command to use API key const testKeyCommand = commands.register('testApiKey', async () => { const apiKey = await storage.secrets.get('api-key'); if (!apiKey) { ui.showNotification('No API key found. Please set one first.', { type: 'warning' }); return; } logger.info('Retrieved API key from secure storage'); ui.showNotification('API key is configured', { type: 'success' }); // Use the API key for authenticated requests // Example: await fetch('https://api.example.com/data', { // headers: { 'Authorization': `Bearer ${apiKey}` } // }); }); // Command to clear API key const clearKeyCommand = commands.register('clearApiKey', async () => { const confirmed = await ui.showConfirmDialog( 'Are you sure you want to delete your API key?', { type: 'warning', confirmLabel: 'Delete' } ); if (confirmed) { await storage.secrets.delete('api-key'); ui.showNotification('API key deleted', { type: 'success' }); } }); return { dispose: () => { setKeyCommand.dispose(); testKeyCommand.dispose(); clearKeyCommand.dispose(); }, }; } ``` -------------------------------- ### Alma Plugin Activation Function (TypeScript) Source: https://context7.com/yetone/alma-plugins/llms.txt An example of a basic Alma plugin's activation function written in TypeScript. This function registers an AI tool and a command-palette command, and returns a disposable for cleanup. It utilizes the `PluginContext` to access services like logging, tool registration, command registration, and UI interactions. ```typescript import type { PluginContext, PluginActivation } from 'alma-plugin-api'; const greetParamsSchema = { type: 'object', properties: { name: { type: 'string', description: 'The name of the person to greet', }, language: { type: 'string', enum: ['en', 'zh', 'ja', 'es', 'fr'], default: 'en', description: 'The language to use for the greeting', }, }, required: ['name'], } as const; export async function activate(context: PluginContext): Promise { const { logger, tools, commands, ui } = context; logger.info('Hello World plugin activated!'); // Register a tool that can be used by the AI assistant const toolDisposable = tools.register('greet', { description: 'Say hello to the user with a personalized message', parameters: greetParamsSchema, execute: async (params, _toolContext) => { const { name, language = 'en' } = params; const greetings = { en: `Hello, ${name}! Welcome to Alma!`, zh: `你好,${name}!欢迎使用 Alma!`, ja: `こんにちは、${name}さん!Almaへようこそ!`, es: `¡Hola, ${name}! ¡Bienvenido a Alma!`, fr: `Bonjour, ${name}! Bienvenue sur Alma!`, }; return { success: true, message: greetings[language] || greetings.en, }; }, }); // Register a command that can be triggered from the command palette const commandDisposable = commands.register('sayHello', async () => { ui.showNotification('Hello from the Hello World plugin!', { type: 'info', }); }); return { dispose: () => { logger.info('Hello World plugin deactivated'); toolDisposable.dispose(); commandDisposable.dispose(); }, }; } ``` -------------------------------- ### Alma Plugin Entry Point (TypeScript) Source: https://github.com/yetone/alma-plugins/blob/main/README.md The main entry point for an Alma plugin, written in TypeScript. It uses the activate function to register tools, commands, and subscribe to events using the provided PluginContext. The activate function returns a disposable object for cleanup. ```typescript import { z } from 'zod'; import type { PluginContext, PluginActivation } from 'alma-plugin-api'; export async function activate(context: PluginContext): Promise { const { logger, tools, commands, events, ui, settings } = context; logger.info('Plugin activated!'); // Register a tool with Zod schema for parameters const toolDisposable = tools.register('myTool', { description: 'A description of what the tool does', parameters: z.object({ input: z.string().describe('The input parameter'), }), execute: async (params, toolContext) => { logger.info(`Executing with input: ${params.input}`); return { result: 'success' }; }, }); // Register a command const commandDisposable = commands.register('myCommand', async () => { ui.showNotification('Hello from my plugin!', { type: 'info' }); }); // Subscribe to events const eventDisposable = events.on('chat.message.didReceive', (input, output) => { logger.info('Message received:', input.response.content); }); return { dispose: () => { logger.info('Plugin deactivated'); toolDisposable.dispose(); commandDisposable.dispose(); eventDisposable.dispose(); }, }; } ``` -------------------------------- ### Manage Plugin Settings with Change Listeners (TypeScript) Source: https://context7.com/yetone/alma-plugins/llms.txt This snippet demonstrates how to read, write, and listen for changes to plugin settings using the Alma plugin API. It defines a typed settings interface, retrieves settings with default values, and sets up an event listener to react to configuration updates. It also includes commands to interactively modify settings like mode and threshold, and an event handler that uses the current settings. ```typescript import type { PluginContext, PluginActivation } from 'alma-plugin-api'; interface PluginSettings { enabled: boolean; mode: 'basic' | 'advanced' | 'expert'; threshold: number; customMessage: string; } export async function activate(context: PluginContext): Promise { const { logger, settings, commands, ui, events } = context; // Helper to get typed settings const getSettings = (): PluginSettings => ({ enabled: settings.get('myPlugin.enabled', true), mode: settings.get<'basic' | 'advanced' | 'expert'>('myPlugin.mode', 'basic'), threshold: settings.get('myPlugin.threshold', 100), customMessage: settings.get('myPlugin.customMessage', 'Hello!'), }); // Apply current settings let config = getSettings(); logger.info(`Plugin mode: ${config.mode}, threshold: ${config.threshold}`); // Listen for settings changes const settingsDisposable = settings.onDidChange((event) => { if (event.key.startsWith('myPlugin.')) { logger.info(`Setting changed: ${event.key}`); logger.info(` Old value: ${JSON.stringify(event.oldValue)}`); logger.info(` New value: ${JSON.stringify(event.newValue)}`); // Reload settings config = getSettings(); ui.showNotification('Settings updated', { type: 'info' }); } }); // Command to update settings const configureCommand = commands.register('configure', async () => { const mode = await ui.showQuickPick([ { label: 'Basic', description: 'Simple mode for beginners', value: 'basic' }, { label: 'Advanced', description: 'More features and options', value: 'advanced' }, { label: 'Expert', description: 'Full control', value: 'expert' } ], { title: 'Select Mode' }); if (mode) { await settings.update('myPlugin.mode', mode); const threshold = await ui.showInputBox({ title: 'Set Threshold', prompt: 'Enter a numeric threshold value', value: config.threshold.toString(), validateInput: (value) => { const num = parseInt(value, 10); if (isNaN(num) || num < 0) { return 'Please enter a valid positive number'; } return undefined; } }); if (threshold) { await settings.update('myPlugin.threshold', parseInt(threshold, 10)); } } }); // Command to toggle enabled state const toggleCommand = commands.register('toggle', async () => { const current = settings.get('myPlugin.enabled', true); await settings.update('myPlugin.enabled', !current); const status = !current ? 'enabled' : 'disabled'; ui.showNotification(`Plugin ${status}`, { type: 'success' }); }); // Use settings in event handler const eventDisposable = events.on('chat.message.didSend', (input) => { const config = getSettings(); if (!config.enabled) { return; // Plugin is disabled } logger.info(`Processing with mode: ${config.mode}`); }); return { dispose: () => { settingsDisposable.dispose(); configureCommand.dispose(); toggleCommand.dispose(); eventDisposable.dispose(); }, }; } ``` -------------------------------- ### TypeScript: Register Catppuccin Mocha Dark Theme Source: https://context7.com/yetone/alma-plugins/llms.txt This TypeScript code demonstrates how to register a custom color theme named 'Catppuccin Mocha' for a plugin. It defines the theme's properties including name, display name, type (dark), a comprehensive color palette, and a description. The 'activate' function utilizes the provided PluginContext to log information and register the theme using the ui.theme.register method, returning a Disposable object for cleanup. ```typescript interface PluginContext { logger: { info: (message: string) => void; }; ui: { theme: { register: (options: ThemeRegistrationOptions) => Disposable; }; }; } interface ThemeRegistrationOptions { name: string; displayName: string; type: 'dark' | 'light'; colors: PluginThemeColors; description?: string; } const catppuccinMocha = { background: '#1e1e2e', foreground: '#cdd6f4', card: '#181825', cardForeground: '#cdd6f4', primary: '#cba6f7', primaryForeground: '#1e1e2e', secondary: '#313244', secondaryForeground: '#cdd6f4', muted: '#313244', mutedForeground: '#a6adc8', accent: '#f5c2e7', border: '#45475a', input: '#45475a', ring: '#cba6f7', sidebar: '#11111b', sidebarForeground: '#cdd6f4', syntaxBg: '#1e1e2e', syntaxFg: '#cdd6f4', syntaxComment: '#6c7086', syntaxVariable: '#f38ba8', syntaxString: '#a6e3a1', syntaxFunction: '#89b4fa', syntaxKeyword: '#cba6f7', }; export function activate(ctx: PluginContext): PluginActivation { const { logger, ui } = ctx; const disposables: Disposable[] = []; logger.info('Registering Catppuccin themes...'); // Register dark theme disposables.push( ui.theme.register({ name: 'mocha', displayName: 'Catppuccin Mocha', type: 'dark', colors: catppuccinMocha, description: 'A warm, dark theme with pastel colors', }) ); return { dispose: () => { disposables.forEach(d => d.dispose()); }, }; } ``` -------------------------------- ### TypeScript: Enhance Chat Prompts with Settings and Timestamps Source: https://context7.com/yetone/alma-plugins/llms.txt This TypeScript code snippet demonstrates how to activate a plugin that enhances chat messages. It retrieves settings for prompt enhancement, builds enhancement text based on mode, timestamps, and custom instructions, and subscribes to the 'chat.message.willSend' event to modify outgoing messages. It also registers a command to toggle the enhancement feature and provides UI notifications. ```typescript export async function activate(context: PluginContext): Promise { const { logger, events, settings, commands, ui } = context; // Get current settings const getSettings = () => ({ enabled: settings.get('promptEnhancer.enabled', true), mode: settings.get('promptEnhancer.mode', 'standard'), addTimestamp: settings.get('promptEnhancer.addTimestamp', false), customInstructions: settings.get('promptEnhancer.customInstructions', ''), }); // Build enhancement text const buildEnhancement = (): string => { const config = getSettings(); const parts: string[] = []; if (enhancementTemplates[config.mode]) { parts.push(enhancementTemplates[config.mode]); } if (config.addTimestamp) { const now = new Date(); parts.push(` Current date and time: ${now.toISOString()}`); } if (config.customInstructions.trim()) { parts.push(` ## Custom Instructions ${config.customInstructions.trim()}`); } return parts.join('\n'); }; // Subscribe to message will send event const eventDisposable = events.on( 'chat.message.willSend', (input, output) => { const config = getSettings(); if (!config.enabled) { return; } const enhancement = buildEnhancement(); output.content = `${input.content}\n\n${enhancement}`; logger.debug(`Enhanced message for model ${input.model}`); }, { priority: 50 } ); // Register toggle command const commandDisposable = commands.register('toggle', async () => { const current = settings.get('promptEnhancer.enabled', true); await settings.update('promptEnhancer.enabled', !current); const status = !current ? 'enabled' : 'disabled'; ui.showNotification(`Prompt enhancement ${status}`, { type: 'info' }); }); return { dispose: () => { eventDisposable.dispose(); commandDisposable.dispose(); }, }; } ``` -------------------------------- ### Activate Alma Plugin with TypeScript Source: https://github.com/yetone/alma-plugins/blob/main/packages/plugin-api/README.md This TypeScript code demonstrates how to activate an Alma plugin. It imports necessary types from 'alma-plugin-api' and shows how to access context properties like logger, tools, commands, ui, and settings to register plugin functionalities and handle deactivation. ```typescript import type { PluginContext, PluginActivation } from 'alma-plugin-api'; export async function activate(context: PluginContext): Promise { const { logger, tools, commands, ui, settings } = context; logger.info('Plugin activated!'); // Register a tool const toolDisposable = tools.register('my-plugin.hello', { name: 'Hello', description: 'Say hello', parameters: { type: 'object', properties: { name: { type: 'string', description: 'Name to greet' } }, required: ['name'] }, execute: async (args) => { const { name } = args as { name: string }; return { message: `Hello, ${name}!` }; } }); // Register a command const commandDisposable = commands.register('my-plugin.greet', async () => { ui.showNotification('Hello from my plugin!', { type: 'info' }); }); return { dispose: () => { logger.info('Plugin deactivated'); toolDisposable.dispose(); commandDisposable.dispose(); } }; } ``` -------------------------------- ### Persistent Storage Operations in TypeScript Source: https://context7.com/yetone/alma-plugins/llms.txt This snippet demonstrates how to save and retrieve plugin data across sessions using Alma's storage API. It includes functions to load and save data, track tool execution statistics, and handle potential errors during storage operations. Data is stored under a specific key and version for integrity. ```typescript import type { PluginContext, PluginActivation } from 'alma-plugin-api'; interface ToolStats { calls: number; successes: number; failures: number; totalTime: number; } interface StorageData { threadStats: Record>; version: number; } const STORAGE_KEY = 'toolMonitorStats'; const STORAGE_VERSION = 1; export async function activate(context: PluginContext): Promise { const { logger, storage, events } = context; let threadStatsMap: Record> = {}; // Load stats from storage const loadFromStorage = async (): Promise => { try { const data = await storage.local.get(STORAGE_KEY); if (data && data.version === STORAGE_VERSION) { threadStatsMap = data.threadStats; logger.info(`Loaded stats for ${Object.keys(threadStatsMap).length} threads`); } } catch (error) { logger.error('Failed to load stats from storage:', error); } }; // Save stats to storage const saveToStorage = async (): Promise => { try { const data: StorageData = { threadStats: threadStatsMap, version: STORAGE_VERSION, }; await storage.local.set(STORAGE_KEY, data); } catch (error) { logger.error('Failed to save stats to storage:', error); } }; // Track tool execution const toolDisposable = events.on('tool.didExecute', (input) => { const threadId = input.context.threadId; if (!threadStatsMap[threadId]) { threadStatsMap[threadId] = {}; } if (!threadStatsMap[threadId][input.tool]) { threadStatsMap[threadId][input.tool] = { calls: 0, successes: 0, failures: 0, totalTime: 0, }; } const stats = threadStatsMap[threadId][input.tool]; stats.calls++; stats.successes++; stats.totalTime += input.duration; // Debounced save saveToStorage(); }); // Initialize from storage await loadFromStorage(); return { dispose: () => { saveToStorage(); // Final save toolDisposable.dispose(); }, }; } ``` -------------------------------- ### TypeScript: Manage Chat Threads and Messages with Alma Plugin API Source: https://context7.com/yetone/alma-plugins/llms.txt This TypeScript code demonstrates how to interact with the Alma Plugin API for chat functionalities. It includes commands to list all chat threads, analyze the current thread's messages, and create new threads. The implementation relies on `PluginContext` for accessing `chat`, `commands`, `ui`, and `logger` services. ```typescript import type { PluginContext, PluginActivation } from 'alma-plugin-api'; export async function activate(context: PluginContext): Promise { const { logger, chat, commands, ui } = context; // Command: List all threads const listThreadsCommand = commands.register('listThreads', async () => { const threads = await chat.listThreads(); const items = threads.map(thread => ({ label: thread.title || 'Untitled', description: `${thread.model || 'No model'} • ${new Date(thread.updatedAt).toLocaleDateString()}`, value: thread.id })); const selectedThreadId = await ui.showQuickPick(items, { title: 'Select a Thread', placeholder: 'Choose a conversation to view' }); if (selectedThreadId) { const messages = await chat.getMessages(selectedThreadId); ui.showNotification(`Thread has ${messages.length} messages`, { type: 'info' }); } }); // Command: Analyze current thread const analyzeThreadCommand = commands.register('analyzeThread', async () => { const activeThread = await chat.getActiveThread(); if (!activeThread) { ui.showNotification('No active thread', { type: 'warning' }); return; } const messages = await chat.getMessages(activeThread.id); const userMessages = messages.filter(m => m.role === 'user').length; const assistantMessages = messages.filter(m => m.role === 'assistant').length; const report = [ `Thread: ${activeThread.title || 'Untitled'}`, `Model: ${activeThread.model || 'Unknown'}`, `Messages: ${messages.length} total`, ` - User: ${userMessages}`, ` - Assistant: ${assistantMessages}`, `Created: ${new Date(activeThread.createdAt).toLocaleString()}`, `Updated: ${new Date(activeThread.updatedAt).toLocaleString()}` ].join('\n'); ui.showNotification(report, { duration: 0 }); }); // Command: Create new thread const createThreadCommand = commands.register('createThread', async () => { const title = await ui.showInputBox({ title: 'New Thread', prompt: 'Enter a title for the new conversation', placeholder: 'My New Conversation' }); if (title) { const thread = await chat.createThread({ title, model: 'claude-3-5-sonnet-20241022' }); ui.showNotification(`Created thread: ${thread.title}`, { type: 'success' }); logger.info(`New thread created: ${thread.id}`); } }); return { dispose: () => { listThreadsCommand.dispose(); analyzeThreadCommand.dispose(); createThreadCommand.dispose(); }, }; } ``` -------------------------------- ### Create Status Bar UI Item for Tool Execution Count Source: https://context7.com/yetone/alma-plugins/llms.txt This code creates an interactive status bar item that displays the total number of tool executions. It updates the display when tool execution events occur and allows users to reset the counter via a quick pick menu. Dependencies include 'alma-plugin-api'. ```typescript import type { PluginContext, PluginActivation } from 'alma-plugin-api'; export async function activate(context: PluginContext): Promise { const { logger, events, ui, commands } = context; let executionCount = 0; // Create status bar item const statusBarItem = ui.createStatusBarItem({ id: 'tool-counter', alignment: 'right', priority: 100, }); // Update status bar display const updateStatusBar = () => { statusBarItem.text = `Tools: ${executionCount}`; statusBarItem.tooltip = `Total tool executions: ${executionCount}`; statusBarItem.show(); }; // Track tool executions const toolDisposable = events.on('tool.didExecute', (input) => { executionCount++; updateStatusBar(); logger.info(`Tool executed: ${input.tool} (${input.duration}ms)`); }); // Register command for status bar click const commandDisposable = commands.register('showToolStats', async () => { const items = [ { label: 'View Details', description: `${executionCount} executions`, value: 'view' }, { label: 'Reset Counter', description: 'Clear statistics', value: 'reset' } ]; const action = await ui.showQuickPick(items, { title: 'Tool Statistics' }); if (action === 'reset') { executionCount = 0; updateStatusBar(); ui.showNotification('Statistics reset', { type: 'success' }); } }); // Set click handler statusBarItem.command = 'showToolStats'; // Initialize updateStatusBar(); return { dispose: () => { toolDisposable.dispose(); commandDisposable.dispose(); statusBarItem.dispose(); }, }; } ``` -------------------------------- ### Subscribe to Chat Events for Token Usage Tracking Source: https://context7.com/yetone/alma-plugins/llms.txt This code subscribes to 'chat.message.didReceive' events to track token usage and calculate estimated costs based on provided pricing information. It also logs thread activation and tool execution events. Dependencies include 'alma-plugin-api'. ```typescript import type { PluginContext, PluginActivation } from 'alma-plugin-api'; export async function activate(context: PluginContext): Promise { const { logger, events, ui, storage } = context; let totalTokens = 0; // Subscribe to message receive events const messageDisposable = events.on('chat.message.didReceive', (input, _output) => { const { threadId, pricing } = input; if (input.response.usage) { const usage = input.response.usage; totalTokens += usage.totalTokens; logger.info(`Token usage: ${usage.promptTokens} input, ${usage.completionTokens} output`); // Calculate cost if pricing available if (pricing && pricing.input && pricing.output) { const inputCost = (usage.promptTokens / 1_000_000) * pricing.input; const outputCost = (usage.completionTokens / 1_000_000) * pricing.output; const totalCost = inputCost + outputCost; logger.info(`Estimated cost: $${totalCost.toFixed(4)}`); } } }); // Subscribe to thread activation events const threadDisposable = events.on('thread.activated', (input, _output) => { logger.info(`Switched to thread: ${input.threadId}`); // Initialize stats from historical usage if provided if (input.usage) { logger.info(`Historical usage: ${input.usage.totalTokens} tokens`); } }); // Subscribe to tool execution events const toolDisposable = events.on('tool.didExecute', (input, _output) => { logger.info(`Tool ${input.tool} executed in ${input.duration}ms`); }); return { dispose: () => { messageDisposable.dispose(); threadDisposable.dispose(); toolDisposable.dispose(); }, }; } ``` -------------------------------- ### Alma Plugin manifest.json Structure Source: https://github.com/yetone/alma-plugins/blob/main/README.md Defines the metadata and configuration for an Alma plugin, including its ID, name, version, author, main entry point, supported Alma engine version, type, permissions, activation events, and contributions. ```json { "id": "my-plugin", "name": "My Plugin", "version": "1.0.0", "description": "A description of what the plugin does", "author": { "name": "Your Name", "email": "your@email.com" }, "main": "main.js", "engines": { "alma": "^0.1.0" }, "type": "tool", "permissions": ["notifications"], "activationEvents": ["onStartup"], "contributes": { "tools": [...], "commands": [...], "configuration": {...} } } ``` -------------------------------- ### Intercept and Modify AI Messages with Templates Source: https://context7.com/yetone/alma-plugins/llms.txt This plugin intercepts messages before they are sent to the AI and applies pre-defined templates to enhance the responses. It supports 'minimal', 'standard', and 'detailed' enhancement modes. Dependencies include 'alma-plugin-api'. ```typescript import type { PluginContext, PluginActivation } from 'alma-plugin-api'; type EnhancementMode = 'minimal' | 'standard' | 'detailed'; const enhancementTemplates: Record = { minimal: 'Please provide clear, concise responses.', standard: `## Response Guidelines - Be clear and concise in your explanations - Use code blocks with appropriate language tags when showing code - Structure your response with headings when addressing multiple topics - Provide practical examples when helpful`, detailed: `## Response Guidelines ### Communication Style - Be clear, concise, and professional - Use simple language and avoid unnecessary jargon - Structure complex responses with headings and bullet points ### Content Requirements - Ensure accuracy and relevance - Cite sources when necessary - Offer actionable insights or solutions ### Formatting - Use Markdown for structure and emphasis - Employ code blocks for code snippets - Use lists for enumerations or steps ### Tone - Maintain a helpful and informative tone - Avoid overly casual or informal language` }; export async function activate(context: PluginContext): Promise { const { events, logger } = context; const enhancementMode: EnhancementMode = 'standard'; // Example: set to 'standard' mode const messageDisposable = events.on('chat.message.willBeSent', (input) => { const template = enhancementTemplates[enhancementMode]; if (template) { // Prepend the template to the user's message input.message = `${template}\n\nUser: ${input.message}`; logger.info(`Message enhanced with template: ${enhancementMode}`); } }); return { dispose: () => { messageDisposable.dispose(); }, }; } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.