@stina/extension-api 0.30.0 → 0.30.2-alpha.d7be7bd

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,4 +6,4 @@ function generateMessageId() {
6
6
  export {
7
7
  generateMessageId
8
8
  };
9
- //# sourceMappingURL=chunk-RZGR2OKA.js.map
9
+ //# sourceMappingURL=chunk-K53YNG2W.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/messages.ts"],"sourcesContent":["/**\n * Message protocol between Extension Host and Extension Workers\n */\n\nimport type {\n ChatMessage,\n ChatOptions,\n GetModelsOptions,\n StreamEvent,\n ToolResult,\n ActionResult,\n ModelInfo,\n SchedulerFirePayload,\n} from './types.js'\n\n// ============================================================================\n// Host → Worker Messages\n// ============================================================================\n\nexport type HostToWorkerMessage =\n | ActivateMessage\n | DeactivateMessage\n | SettingsChangedMessage\n | SchedulerFireMessage\n | ProviderChatRequestMessage\n | ProviderModelsRequestMessage\n | ToolExecuteRequestMessage\n | ActionExecuteRequestMessage\n | ResponseMessage\n | StreamingFetchChunkMessage\n | BackgroundTaskStartMessage\n | BackgroundTaskStopMessage\n\nexport interface ActivateMessage {\n type: 'activate'\n id: string\n payload: {\n extensionId: string\n extensionVersion: string\n storagePath: string\n permissions: string[]\n settings: Record<string, unknown>\n }\n}\n\nexport interface DeactivateMessage {\n type: 'deactivate'\n id: string\n}\n\nexport interface SettingsChangedMessage {\n type: 'settings-changed'\n id: string\n payload: {\n key: string\n value: unknown\n }\n}\n\nexport interface SchedulerFireMessage {\n type: 'scheduler-fire'\n id: string\n payload: SchedulerFirePayload\n}\n\nexport interface ProviderChatRequestMessage {\n type: 'provider-chat-request'\n id: string\n payload: {\n providerId: string\n messages: ChatMessage[]\n options: ChatOptions\n }\n}\n\nexport interface ProviderModelsRequestMessage {\n type: 'provider-models-request'\n id: string\n payload: {\n providerId: string\n options?: GetModelsOptions\n }\n}\n\nexport interface ToolExecuteRequestMessage {\n type: 'tool-execute-request'\n id: string\n payload: {\n toolId: string\n params: Record<string, unknown>\n /** User ID if the tool is executed in a user context */\n userId?: string\n }\n}\n\nexport interface ActionExecuteRequestMessage {\n type: 'action-execute-request'\n id: string\n payload: {\n actionId: string\n params: Record<string, unknown>\n /** User ID if the action is executed in a user context */\n userId?: string\n }\n}\n\nexport interface ResponseMessage {\n type: 'response'\n id: string\n payload: {\n requestId: string\n success: boolean\n data?: unknown\n error?: string\n }\n}\n\n/**\n * Message sent from host to worker with streaming fetch data chunks.\n * Used for streaming network responses (e.g., NDJSON streams from Ollama).\n */\nexport interface StreamingFetchChunkMessage {\n type: 'streaming-fetch-chunk'\n id: string\n payload: {\n requestId: string\n chunk: string\n done: boolean\n error?: string\n }\n}\n\n/**\n * Message sent from host to worker to start a registered background task.\n */\nexport interface BackgroundTaskStartMessage {\n type: 'background-task-start'\n id: string\n payload: {\n taskId: string\n }\n}\n\n/**\n * Message sent from host to worker to stop a running background task.\n */\nexport interface BackgroundTaskStopMessage {\n type: 'background-task-stop'\n id: string\n payload: {\n taskId: string\n }\n}\n\n// ============================================================================\n// Worker → Host Messages\n// ============================================================================\n\nexport type WorkerToHostMessage =\n | ReadyMessage\n | RequestMessage\n | ProviderRegisteredMessage\n | ToolRegisteredMessage\n | ActionRegisteredMessage\n | StreamEventMessage\n | LogMessage\n | ProviderModelsResponseMessage\n | ToolExecuteResponseMessage\n | ActionExecuteResponseMessage\n | StreamingFetchAckMessage\n | BackgroundTaskRegisteredMessage\n | BackgroundTaskStatusMessage\n | BackgroundTaskHealthMessage\n\nexport interface ReadyMessage {\n type: 'ready'\n}\n\n/**\n * Message sent from worker to host to acknowledge receipt of a streaming fetch chunk.\n * This enables backpressure control to prevent unbounded memory growth.\n */\nexport interface StreamingFetchAckMessage {\n type: 'streaming-fetch-ack'\n payload: {\n requestId: string\n }\n}\n\nexport interface RequestMessage {\n type: 'request'\n id: string\n method: RequestMethod\n payload: unknown\n}\n\nexport type RequestMethod =\n | 'network.fetch'\n | 'network.fetch-stream'\n | 'settings.getAll'\n | 'settings.get'\n | 'settings.set'\n | 'user.getProfile'\n | 'events.emit'\n | 'scheduler.schedule'\n | 'scheduler.cancel'\n | 'scheduler.reportFireResult'\n | 'chat.appendInstruction'\n | 'database.execute'\n // Simple key-value storage methods\n | 'storage.set'\n | 'storage.keys'\n | 'storage.setForUser'\n | 'storage.keysForUser'\n // Collection-based storage methods\n | 'storage.put'\n | 'storage.get'\n | 'storage.delete'\n | 'storage.find'\n | 'storage.findOne'\n | 'storage.count'\n | 'storage.putMany'\n | 'storage.deleteMany'\n | 'storage.dropCollection'\n | 'storage.listCollections'\n | 'storage.putForUser'\n | 'storage.getForUser'\n | 'storage.deleteForUser'\n | 'storage.findForUser'\n | 'storage.findOneForUser'\n | 'storage.countForUser'\n | 'storage.putManyForUser'\n | 'storage.deleteManyForUser'\n | 'storage.dropCollectionForUser'\n | 'storage.listCollectionsForUser'\n // Secrets methods\n | 'secrets.set'\n | 'secrets.get'\n | 'secrets.delete'\n | 'secrets.list'\n | 'secrets.setForUser'\n | 'secrets.getForUser'\n | 'secrets.deleteForUser'\n | 'secrets.listForUser'\n // Tools cross-extension methods\n | 'tools.list'\n | 'tools.execute'\n\nexport interface ProviderRegisteredMessage {\n type: 'provider-registered'\n payload: {\n id: string\n name: string\n }\n}\n\nexport interface ToolRegisteredMessage {\n type: 'tool-registered'\n payload: {\n id: string\n name: string\n description: string\n parameters?: Record<string, unknown>\n }\n}\n\nexport interface ActionRegisteredMessage {\n type: 'action-registered'\n payload: {\n id: string\n }\n}\n\nexport interface StreamEventMessage {\n type: 'stream-event'\n payload: {\n requestId: string\n event: StreamEvent\n }\n}\n\nexport interface ProviderModelsResponseMessage {\n type: 'provider-models-response'\n payload: {\n requestId: string\n models: ModelInfo[]\n error?: string\n }\n}\n\nexport interface ToolExecuteResponseMessage {\n type: 'tool-execute-response'\n payload: {\n requestId: string\n result: ToolResult\n error?: string\n }\n}\n\nexport interface ActionExecuteResponseMessage {\n type: 'action-execute-response'\n payload: {\n requestId: string\n result: ActionResult\n error?: string\n }\n}\n\nexport interface LogMessage {\n type: 'log'\n payload: {\n level: 'debug' | 'info' | 'warn' | 'error'\n message: string\n data?: Record<string, unknown>\n }\n}\n\n/**\n * Message sent from worker to host when a background task is registered.\n */\nexport interface BackgroundTaskRegisteredMessage {\n type: 'background-task-registered'\n payload: {\n taskId: string\n name: string\n userId: string\n restartPolicy: {\n type: 'always' | 'on-failure' | 'never'\n maxRestarts?: number\n initialDelayMs?: number\n maxDelayMs?: number\n backoffMultiplier?: number\n }\n payload?: Record<string, unknown>\n }\n}\n\n/**\n * Message sent from worker to host with background task status updates.\n */\nexport interface BackgroundTaskStatusMessage {\n type: 'background-task-status'\n payload: {\n taskId: string\n status: 'running' | 'stopped' | 'failed'\n error?: string\n }\n}\n\n/**\n * Message sent from worker to host with background task health reports.\n */\nexport interface BackgroundTaskHealthMessage {\n type: 'background-task-health'\n payload: {\n taskId: string\n status: string\n timestamp: string\n }\n}\n\n// ============================================================================\n// Utility Types\n// ============================================================================\n\nexport interface PendingRequest<T = unknown> {\n resolve: (value: T) => void\n reject: (error: Error) => void\n timeout: ReturnType<typeof setTimeout>\n}\n\n/**\n * Generate a unique message ID\n */\nexport function generateMessageId(): string {\n return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`\n}\n"],"mappings":";AAsXO,SAAS,oBAA4B;AAC1C,SAAO,GAAG,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,EAAE,CAAC;AACjE;","names":[]}
1
+ {"version":3,"sources":["../src/messages.ts"],"sourcesContent":["/**\n * Message protocol between Extension Host and Extension Workers\n */\n\nimport type {\n ChatMessage,\n ChatOptions,\n GetModelsOptions,\n StreamEvent,\n ToolResult,\n ActionResult,\n ModelInfo,\n SchedulerFirePayload,\n} from './types.js'\n\n// ============================================================================\n// Host → Worker Messages\n// ============================================================================\n\nexport type HostToWorkerMessage =\n | ActivateMessage\n | DeactivateMessage\n | SettingsChangedMessage\n | SchedulerFireMessage\n | ProviderChatRequestMessage\n | ProviderModelsRequestMessage\n | ToolExecuteRequestMessage\n | ActionExecuteRequestMessage\n | ResponseMessage\n | StreamingFetchChunkMessage\n | BackgroundTaskStartMessage\n | BackgroundTaskStopMessage\n\nexport interface ActivateMessage {\n type: 'activate'\n id: string\n payload: {\n extensionId: string\n extensionVersion: string\n storagePath: string\n permissions: string[]\n settings: Record<string, unknown>\n }\n}\n\nexport interface DeactivateMessage {\n type: 'deactivate'\n id: string\n}\n\nexport interface SettingsChangedMessage {\n type: 'settings-changed'\n id: string\n payload: {\n key: string\n value: unknown\n }\n}\n\nexport interface SchedulerFireMessage {\n type: 'scheduler-fire'\n id: string\n payload: SchedulerFirePayload\n}\n\nexport interface ProviderChatRequestMessage {\n type: 'provider-chat-request'\n id: string\n payload: {\n providerId: string\n messages: ChatMessage[]\n options: ChatOptions\n }\n}\n\nexport interface ProviderModelsRequestMessage {\n type: 'provider-models-request'\n id: string\n payload: {\n providerId: string\n options?: GetModelsOptions\n }\n}\n\nexport interface ToolExecuteRequestMessage {\n type: 'tool-execute-request'\n id: string\n payload: {\n toolId: string\n params: Record<string, unknown>\n /** User ID if the tool is executed in a user context */\n userId?: string\n }\n}\n\nexport interface ActionExecuteRequestMessage {\n type: 'action-execute-request'\n id: string\n payload: {\n actionId: string\n params: Record<string, unknown>\n /** User ID if the action is executed in a user context */\n userId?: string\n }\n}\n\nexport interface ResponseMessage {\n type: 'response'\n id: string\n payload: {\n requestId: string\n success: boolean\n data?: unknown\n error?: string\n }\n}\n\n/**\n * Message sent from host to worker with streaming fetch data chunks.\n * Used for streaming network responses (e.g., NDJSON streams from Ollama).\n */\nexport interface StreamingFetchChunkMessage {\n type: 'streaming-fetch-chunk'\n id: string\n payload: {\n requestId: string\n chunk: string\n done: boolean\n error?: string\n }\n}\n\n/**\n * Message sent from host to worker to start a registered background task.\n */\nexport interface BackgroundTaskStartMessage {\n type: 'background-task-start'\n id: string\n payload: {\n taskId: string\n }\n}\n\n/**\n * Message sent from host to worker to stop a running background task.\n */\nexport interface BackgroundTaskStopMessage {\n type: 'background-task-stop'\n id: string\n payload: {\n taskId: string\n }\n}\n\n// ============================================================================\n// Worker → Host Messages\n// ============================================================================\n\nexport type WorkerToHostMessage =\n | ReadyMessage\n | RequestMessage\n | ProviderRegisteredMessage\n | ToolRegisteredMessage\n | ActionRegisteredMessage\n | StreamEventMessage\n | LogMessage\n | ProviderModelsResponseMessage\n | ToolExecuteResponseMessage\n | ActionExecuteResponseMessage\n | StreamingFetchAckMessage\n | BackgroundTaskRegisteredMessage\n | BackgroundTaskStatusMessage\n | BackgroundTaskHealthMessage\n\nexport interface ReadyMessage {\n type: 'ready'\n}\n\n/**\n * Message sent from worker to host to acknowledge receipt of a streaming fetch chunk.\n * This enables backpressure control to prevent unbounded memory growth.\n */\nexport interface StreamingFetchAckMessage {\n type: 'streaming-fetch-ack'\n payload: {\n requestId: string\n }\n}\n\nexport interface RequestMessage {\n type: 'request'\n id: string\n method: RequestMethod\n payload: unknown\n}\n\nexport type RequestMethod =\n | 'network.fetch'\n | 'network.fetch-stream'\n | 'settings.getAll'\n | 'settings.get'\n | 'settings.set'\n | 'user.getProfile'\n | 'user.listIds'\n | 'events.emit'\n | 'scheduler.schedule'\n | 'scheduler.cancel'\n | 'scheduler.reportFireResult'\n | 'chat.appendInstruction'\n | 'database.execute'\n // Simple key-value storage methods\n | 'storage.set'\n | 'storage.keys'\n | 'storage.setForUser'\n | 'storage.keysForUser'\n // Collection-based storage methods\n | 'storage.put'\n | 'storage.get'\n | 'storage.delete'\n | 'storage.find'\n | 'storage.findOne'\n | 'storage.count'\n | 'storage.putMany'\n | 'storage.deleteMany'\n | 'storage.dropCollection'\n | 'storage.listCollections'\n | 'storage.putForUser'\n | 'storage.getForUser'\n | 'storage.deleteForUser'\n | 'storage.findForUser'\n | 'storage.findOneForUser'\n | 'storage.countForUser'\n | 'storage.putManyForUser'\n | 'storage.deleteManyForUser'\n | 'storage.dropCollectionForUser'\n | 'storage.listCollectionsForUser'\n // Secrets methods\n | 'secrets.set'\n | 'secrets.get'\n | 'secrets.delete'\n | 'secrets.list'\n | 'secrets.setForUser'\n | 'secrets.getForUser'\n | 'secrets.deleteForUser'\n | 'secrets.listForUser'\n // Tools cross-extension methods\n | 'tools.list'\n | 'tools.execute'\n\nexport interface ProviderRegisteredMessage {\n type: 'provider-registered'\n payload: {\n id: string\n name: string\n }\n}\n\nexport interface ToolRegisteredMessage {\n type: 'tool-registered'\n payload: {\n id: string\n name: string\n description: string\n parameters?: Record<string, unknown>\n }\n}\n\nexport interface ActionRegisteredMessage {\n type: 'action-registered'\n payload: {\n id: string\n }\n}\n\nexport interface StreamEventMessage {\n type: 'stream-event'\n payload: {\n requestId: string\n event: StreamEvent\n }\n}\n\nexport interface ProviderModelsResponseMessage {\n type: 'provider-models-response'\n payload: {\n requestId: string\n models: ModelInfo[]\n error?: string\n }\n}\n\nexport interface ToolExecuteResponseMessage {\n type: 'tool-execute-response'\n payload: {\n requestId: string\n result: ToolResult\n error?: string\n }\n}\n\nexport interface ActionExecuteResponseMessage {\n type: 'action-execute-response'\n payload: {\n requestId: string\n result: ActionResult\n error?: string\n }\n}\n\nexport interface LogMessage {\n type: 'log'\n payload: {\n level: 'debug' | 'info' | 'warn' | 'error'\n message: string\n data?: Record<string, unknown>\n }\n}\n\n/**\n * Message sent from worker to host when a background task is registered.\n */\nexport interface BackgroundTaskRegisteredMessage {\n type: 'background-task-registered'\n payload: {\n taskId: string\n name: string\n userId: string\n restartPolicy: {\n type: 'always' | 'on-failure' | 'never'\n maxRestarts?: number\n initialDelayMs?: number\n maxDelayMs?: number\n backoffMultiplier?: number\n }\n payload?: Record<string, unknown>\n }\n}\n\n/**\n * Message sent from worker to host with background task status updates.\n */\nexport interface BackgroundTaskStatusMessage {\n type: 'background-task-status'\n payload: {\n taskId: string\n status: 'running' | 'stopped' | 'failed'\n error?: string\n }\n}\n\n/**\n * Message sent from worker to host with background task health reports.\n */\nexport interface BackgroundTaskHealthMessage {\n type: 'background-task-health'\n payload: {\n taskId: string\n status: string\n timestamp: string\n }\n}\n\n// ============================================================================\n// Utility Types\n// ============================================================================\n\nexport interface PendingRequest<T = unknown> {\n resolve: (value: T) => void\n reject: (error: Error) => void\n timeout: ReturnType<typeof setTimeout>\n}\n\n/**\n * Generate a unique message ID\n */\nexport function generateMessageId(): string {\n return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`\n}\n"],"mappings":";AAuXO,SAAS,oBAA4B;AAC1C,SAAO,GAAG,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,EAAE,CAAC;AACjE;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/types.localization.ts","../src/messages.ts"],"sourcesContent":["/**\n * @stina/extension-api\n *\n * Types and utilities for building Stina extensions.\n *\n * Extensions should import from this package for type definitions.\n * The runtime (worker-side code) should import from '@stina/extension-api/runtime'.\n */\n\n// Localization\nexport type { LocalizedString } from './types.js'\nexport { resolveLocalizedString } from './types.js'\n\n// Types\nexport type {\n // Manifest\n ExtensionManifest,\n Platform,\n ExtensionContributions,\n SettingDefinition,\n SettingOptionsMapping,\n SettingCreateMapping,\n ToolSettingsViewDefinition,\n ToolSettingsView,\n ToolSettingsListView,\n ToolSettingsListMapping,\n ToolSettingsComponentView,\n ToolSettingsActionDataSource,\n PanelDefinition,\n PanelView,\n PanelComponentView,\n PanelActionDataSource,\n PanelUnknownView,\n ProviderDefinition,\n PromptContribution,\n PromptSection,\n ToolDefinition,\n ToolConfirmationConfig,\n CommandDefinition,\n\n // Provider Configuration Schema\n ProviderConfigSchema,\n ProviderConfigProperty,\n ProviderConfigPropertyType,\n ProviderConfigSelectOption,\n ProviderConfigValidation,\n\n // Permissions\n Permission,\n NetworkPermission,\n StoragePermission,\n UserDataPermission,\n CapabilityPermission,\n SystemPermission,\n\n // Context\n ExtensionContext,\n Disposable,\n NetworkAPI,\n SettingsAPI,\n ProvidersAPI,\n ToolsAPI,\n ActionsAPI,\n EventsAPI,\n SchedulerAPI,\n SchedulerJobRequest,\n SchedulerSchedule,\n SchedulerFirePayload,\n UserAPI,\n UserProfile,\n ChatAPI,\n ChatInstructionMessage,\n LogAPI,\n\n // Background workers\n BackgroundWorkersAPI,\n BackgroundTaskConfig,\n BackgroundTaskCallback,\n BackgroundTaskContext,\n BackgroundTaskHealth,\n BackgroundRestartPolicy,\n\n // Storage and Secrets\n Query,\n QueryOptions,\n StorageAPI,\n SecretsAPI,\n StorageCollectionConfig,\n StorageContributions,\n\n // AI Provider\n AIProvider,\n ModelInfo,\n ChatMessage,\n ChatOptions,\n GetModelsOptions,\n StreamEvent,\n ToolCall,\n\n // Tools\n Tool,\n ToolResult,\n\n // Actions\n Action,\n ActionResult,\n\n // Entry point\n ExtensionModule,\n} from './types.js'\n\n// Messages (for host implementation)\nexport type {\n HostToWorkerMessage,\n WorkerToHostMessage,\n ActivateMessage,\n DeactivateMessage,\n SettingsChangedMessage,\n ProviderChatRequestMessage,\n ProviderModelsRequestMessage,\n ToolExecuteRequestMessage,\n ToolExecuteResponseMessage,\n ActionExecuteRequestMessage,\n ActionExecuteResponseMessage,\n ResponseMessage,\n ReadyMessage,\n RequestMessage,\n RequestMethod,\n ProviderRegisteredMessage,\n ToolRegisteredMessage,\n ActionRegisteredMessage,\n StreamEventMessage,\n LogMessage,\n PendingRequest,\n // Background task messages\n BackgroundTaskStartMessage,\n BackgroundTaskStopMessage,\n BackgroundTaskRegisteredMessage,\n BackgroundTaskStatusMessage,\n BackgroundTaskHealthMessage,\n} from './messages.js'\n\nexport { generateMessageId } from './messages.js'\n\n// Component types (for extension UI components)\nexport type {\n // Icon Names\n HugeIconName,\n // Styling\n AllowedCSSProperty,\n ExtensionComponentStyle,\n // Base types\n ExtensionComponentData,\n // Iteration & Children\n ExtensionComponentIterator,\n ExtensionComponentChildren,\n // Actions\n ExtensionActionCall,\n ExtensionActionRef,\n // Data Sources & Panel Definition\n ExtensionDataSource,\n ExtensionPanelDefinition,\n // Component Props\n HeaderProps,\n LabelProps,\n ParagraphProps,\n ButtonProps,\n TextInputProps,\n DateTimeInputProps,\n SelectProps,\n IconPickerProps,\n VerticalStackProps,\n HorizontalStackProps,\n GridProps,\n DividerProps,\n IconProps,\n IconButtonType,\n IconButtonProps,\n PanelAction,\n PanelProps,\n ToggleProps,\n CollapsibleProps,\n FrameVariant,\n FrameProps,\n ListProps,\n PillVariant,\n PillProps,\n CheckboxProps,\n MarkdownProps,\n TextPreviewProps,\n ModalProps,\n ConditionalGroupProps,\n} from './types.components.js'\n","/**\n * Localization Types\n *\n * Types and utilities for localized strings in extensions.\n */\n\n/**\n * A string that can be either a simple string or a map of language codes to localized strings.\n * When a simple string is provided, it's used as the default/fallback value.\n * When a map is provided, the appropriate language is selected at runtime.\n *\n * @example\n * // Simple string (backwards compatible)\n * name: \"Get Weather\"\n *\n * @example\n * // Localized strings\n * name: { en: \"Get Weather\", sv: \"Hämta väder\", de: \"Wetter abrufen\" }\n */\nexport type LocalizedString = string | Record<string, string>\n\n/**\n * Resolves a LocalizedString to an actual string value.\n * @param value The LocalizedString to resolve\n * @param lang The preferred language code (e.g., \"sv\", \"en\")\n * @param fallbackLang The fallback language code (defaults to \"en\")\n * @returns The resolved string value\n */\nexport function resolveLocalizedString(\n value: LocalizedString,\n lang: string,\n fallbackLang = 'en'\n): string {\n if (typeof value === 'string') {\n return value\n }\n // Try preferred language first, then fallback language, then first available, then empty string\n return value[lang] ?? value[fallbackLang] ?? Object.values(value)[0] ?? ''\n}\n","/**\n * Message protocol between Extension Host and Extension Workers\n */\n\nimport type {\n ChatMessage,\n ChatOptions,\n GetModelsOptions,\n StreamEvent,\n ToolResult,\n ActionResult,\n ModelInfo,\n SchedulerFirePayload,\n} from './types.js'\n\n// ============================================================================\n// Host → Worker Messages\n// ============================================================================\n\nexport type HostToWorkerMessage =\n | ActivateMessage\n | DeactivateMessage\n | SettingsChangedMessage\n | SchedulerFireMessage\n | ProviderChatRequestMessage\n | ProviderModelsRequestMessage\n | ToolExecuteRequestMessage\n | ActionExecuteRequestMessage\n | ResponseMessage\n | StreamingFetchChunkMessage\n | BackgroundTaskStartMessage\n | BackgroundTaskStopMessage\n\nexport interface ActivateMessage {\n type: 'activate'\n id: string\n payload: {\n extensionId: string\n extensionVersion: string\n storagePath: string\n permissions: string[]\n settings: Record<string, unknown>\n }\n}\n\nexport interface DeactivateMessage {\n type: 'deactivate'\n id: string\n}\n\nexport interface SettingsChangedMessage {\n type: 'settings-changed'\n id: string\n payload: {\n key: string\n value: unknown\n }\n}\n\nexport interface SchedulerFireMessage {\n type: 'scheduler-fire'\n id: string\n payload: SchedulerFirePayload\n}\n\nexport interface ProviderChatRequestMessage {\n type: 'provider-chat-request'\n id: string\n payload: {\n providerId: string\n messages: ChatMessage[]\n options: ChatOptions\n }\n}\n\nexport interface ProviderModelsRequestMessage {\n type: 'provider-models-request'\n id: string\n payload: {\n providerId: string\n options?: GetModelsOptions\n }\n}\n\nexport interface ToolExecuteRequestMessage {\n type: 'tool-execute-request'\n id: string\n payload: {\n toolId: string\n params: Record<string, unknown>\n /** User ID if the tool is executed in a user context */\n userId?: string\n }\n}\n\nexport interface ActionExecuteRequestMessage {\n type: 'action-execute-request'\n id: string\n payload: {\n actionId: string\n params: Record<string, unknown>\n /** User ID if the action is executed in a user context */\n userId?: string\n }\n}\n\nexport interface ResponseMessage {\n type: 'response'\n id: string\n payload: {\n requestId: string\n success: boolean\n data?: unknown\n error?: string\n }\n}\n\n/**\n * Message sent from host to worker with streaming fetch data chunks.\n * Used for streaming network responses (e.g., NDJSON streams from Ollama).\n */\nexport interface StreamingFetchChunkMessage {\n type: 'streaming-fetch-chunk'\n id: string\n payload: {\n requestId: string\n chunk: string\n done: boolean\n error?: string\n }\n}\n\n/**\n * Message sent from host to worker to start a registered background task.\n */\nexport interface BackgroundTaskStartMessage {\n type: 'background-task-start'\n id: string\n payload: {\n taskId: string\n }\n}\n\n/**\n * Message sent from host to worker to stop a running background task.\n */\nexport interface BackgroundTaskStopMessage {\n type: 'background-task-stop'\n id: string\n payload: {\n taskId: string\n }\n}\n\n// ============================================================================\n// Worker → Host Messages\n// ============================================================================\n\nexport type WorkerToHostMessage =\n | ReadyMessage\n | RequestMessage\n | ProviderRegisteredMessage\n | ToolRegisteredMessage\n | ActionRegisteredMessage\n | StreamEventMessage\n | LogMessage\n | ProviderModelsResponseMessage\n | ToolExecuteResponseMessage\n | ActionExecuteResponseMessage\n | StreamingFetchAckMessage\n | BackgroundTaskRegisteredMessage\n | BackgroundTaskStatusMessage\n | BackgroundTaskHealthMessage\n\nexport interface ReadyMessage {\n type: 'ready'\n}\n\n/**\n * Message sent from worker to host to acknowledge receipt of a streaming fetch chunk.\n * This enables backpressure control to prevent unbounded memory growth.\n */\nexport interface StreamingFetchAckMessage {\n type: 'streaming-fetch-ack'\n payload: {\n requestId: string\n }\n}\n\nexport interface RequestMessage {\n type: 'request'\n id: string\n method: RequestMethod\n payload: unknown\n}\n\nexport type RequestMethod =\n | 'network.fetch'\n | 'network.fetch-stream'\n | 'settings.getAll'\n | 'settings.get'\n | 'settings.set'\n | 'user.getProfile'\n | 'events.emit'\n | 'scheduler.schedule'\n | 'scheduler.cancel'\n | 'scheduler.reportFireResult'\n | 'chat.appendInstruction'\n | 'database.execute'\n // Simple key-value storage methods\n | 'storage.set'\n | 'storage.keys'\n | 'storage.setForUser'\n | 'storage.keysForUser'\n // Collection-based storage methods\n | 'storage.put'\n | 'storage.get'\n | 'storage.delete'\n | 'storage.find'\n | 'storage.findOne'\n | 'storage.count'\n | 'storage.putMany'\n | 'storage.deleteMany'\n | 'storage.dropCollection'\n | 'storage.listCollections'\n | 'storage.putForUser'\n | 'storage.getForUser'\n | 'storage.deleteForUser'\n | 'storage.findForUser'\n | 'storage.findOneForUser'\n | 'storage.countForUser'\n | 'storage.putManyForUser'\n | 'storage.deleteManyForUser'\n | 'storage.dropCollectionForUser'\n | 'storage.listCollectionsForUser'\n // Secrets methods\n | 'secrets.set'\n | 'secrets.get'\n | 'secrets.delete'\n | 'secrets.list'\n | 'secrets.setForUser'\n | 'secrets.getForUser'\n | 'secrets.deleteForUser'\n | 'secrets.listForUser'\n // Tools cross-extension methods\n | 'tools.list'\n | 'tools.execute'\n\nexport interface ProviderRegisteredMessage {\n type: 'provider-registered'\n payload: {\n id: string\n name: string\n }\n}\n\nexport interface ToolRegisteredMessage {\n type: 'tool-registered'\n payload: {\n id: string\n name: string\n description: string\n parameters?: Record<string, unknown>\n }\n}\n\nexport interface ActionRegisteredMessage {\n type: 'action-registered'\n payload: {\n id: string\n }\n}\n\nexport interface StreamEventMessage {\n type: 'stream-event'\n payload: {\n requestId: string\n event: StreamEvent\n }\n}\n\nexport interface ProviderModelsResponseMessage {\n type: 'provider-models-response'\n payload: {\n requestId: string\n models: ModelInfo[]\n error?: string\n }\n}\n\nexport interface ToolExecuteResponseMessage {\n type: 'tool-execute-response'\n payload: {\n requestId: string\n result: ToolResult\n error?: string\n }\n}\n\nexport interface ActionExecuteResponseMessage {\n type: 'action-execute-response'\n payload: {\n requestId: string\n result: ActionResult\n error?: string\n }\n}\n\nexport interface LogMessage {\n type: 'log'\n payload: {\n level: 'debug' | 'info' | 'warn' | 'error'\n message: string\n data?: Record<string, unknown>\n }\n}\n\n/**\n * Message sent from worker to host when a background task is registered.\n */\nexport interface BackgroundTaskRegisteredMessage {\n type: 'background-task-registered'\n payload: {\n taskId: string\n name: string\n userId: string\n restartPolicy: {\n type: 'always' | 'on-failure' | 'never'\n maxRestarts?: number\n initialDelayMs?: number\n maxDelayMs?: number\n backoffMultiplier?: number\n }\n payload?: Record<string, unknown>\n }\n}\n\n/**\n * Message sent from worker to host with background task status updates.\n */\nexport interface BackgroundTaskStatusMessage {\n type: 'background-task-status'\n payload: {\n taskId: string\n status: 'running' | 'stopped' | 'failed'\n error?: string\n }\n}\n\n/**\n * Message sent from worker to host with background task health reports.\n */\nexport interface BackgroundTaskHealthMessage {\n type: 'background-task-health'\n payload: {\n taskId: string\n status: string\n timestamp: string\n }\n}\n\n// ============================================================================\n// Utility Types\n// ============================================================================\n\nexport interface PendingRequest<T = unknown> {\n resolve: (value: T) => void\n reject: (error: Error) => void\n timeout: ReturnType<typeof setTimeout>\n}\n\n/**\n * Generate a unique message ID\n */\nexport function generateMessageId(): string {\n return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AC4BO,SAAS,uBACd,OACA,MACA,eAAe,MACP;AACR,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO;AAAA,EACT;AAEA,SAAO,MAAM,IAAI,KAAK,MAAM,YAAY,KAAK,OAAO,OAAO,KAAK,EAAE,CAAC,KAAK;AAC1E;;;ACgVO,SAAS,oBAA4B;AAC1C,SAAO,GAAG,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,EAAE,CAAC;AACjE;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/types.localization.ts","../src/messages.ts"],"sourcesContent":["/**\n * @stina/extension-api\n *\n * Types and utilities for building Stina extensions.\n *\n * Extensions should import from this package for type definitions.\n * The runtime (worker-side code) should import from '@stina/extension-api/runtime'.\n */\n\n// Localization\nexport type { LocalizedString } from './types.js'\nexport { resolveLocalizedString } from './types.js'\n\n// Types\nexport type {\n // Manifest\n ExtensionManifest,\n Platform,\n ExtensionContributions,\n SettingDefinition,\n SettingOptionsMapping,\n SettingCreateMapping,\n ToolSettingsViewDefinition,\n ToolSettingsView,\n ToolSettingsListView,\n ToolSettingsListMapping,\n ToolSettingsComponentView,\n ToolSettingsActionDataSource,\n PanelDefinition,\n PanelView,\n PanelComponentView,\n PanelActionDataSource,\n PanelUnknownView,\n ProviderDefinition,\n PromptContribution,\n PromptSection,\n ToolDefinition,\n ToolConfirmationConfig,\n CommandDefinition,\n\n // Provider Configuration Schema\n ProviderConfigSchema,\n ProviderConfigProperty,\n ProviderConfigPropertyType,\n ProviderConfigSelectOption,\n ProviderConfigValidation,\n\n // Permissions\n Permission,\n NetworkPermission,\n StoragePermission,\n UserDataPermission,\n CapabilityPermission,\n SystemPermission,\n\n // Context\n ExtensionContext,\n Disposable,\n NetworkAPI,\n SettingsAPI,\n ProvidersAPI,\n ToolsAPI,\n ActionsAPI,\n EventsAPI,\n SchedulerAPI,\n SchedulerJobRequest,\n SchedulerSchedule,\n SchedulerFirePayload,\n UserAPI,\n UserProfile,\n ChatAPI,\n ChatInstructionMessage,\n LogAPI,\n\n // Background workers\n BackgroundWorkersAPI,\n BackgroundTaskConfig,\n BackgroundTaskCallback,\n BackgroundTaskContext,\n BackgroundTaskHealth,\n BackgroundRestartPolicy,\n\n // Storage and Secrets\n Query,\n QueryOptions,\n StorageAPI,\n SecretsAPI,\n StorageCollectionConfig,\n StorageContributions,\n\n // AI Provider\n AIProvider,\n ModelInfo,\n ChatMessage,\n ChatOptions,\n GetModelsOptions,\n StreamEvent,\n ToolCall,\n\n // Tools\n Tool,\n ToolResult,\n\n // Actions\n Action,\n ActionResult,\n\n // Entry point\n ExtensionModule,\n} from './types.js'\n\n// Messages (for host implementation)\nexport type {\n HostToWorkerMessage,\n WorkerToHostMessage,\n ActivateMessage,\n DeactivateMessage,\n SettingsChangedMessage,\n ProviderChatRequestMessage,\n ProviderModelsRequestMessage,\n ToolExecuteRequestMessage,\n ToolExecuteResponseMessage,\n ActionExecuteRequestMessage,\n ActionExecuteResponseMessage,\n ResponseMessage,\n ReadyMessage,\n RequestMessage,\n RequestMethod,\n ProviderRegisteredMessage,\n ToolRegisteredMessage,\n ActionRegisteredMessage,\n StreamEventMessage,\n LogMessage,\n PendingRequest,\n // Background task messages\n BackgroundTaskStartMessage,\n BackgroundTaskStopMessage,\n BackgroundTaskRegisteredMessage,\n BackgroundTaskStatusMessage,\n BackgroundTaskHealthMessage,\n} from './messages.js'\n\nexport { generateMessageId } from './messages.js'\n\n// Component types (for extension UI components)\nexport type {\n // Icon Names\n HugeIconName,\n // Styling\n AllowedCSSProperty,\n ExtensionComponentStyle,\n // Base types\n ExtensionComponentData,\n // Iteration & Children\n ExtensionComponentIterator,\n ExtensionComponentChildren,\n // Actions\n ExtensionActionCall,\n ExtensionActionRef,\n // Data Sources & Panel Definition\n ExtensionDataSource,\n ExtensionPanelDefinition,\n // Component Props\n HeaderProps,\n LabelProps,\n ParagraphProps,\n ButtonProps,\n TextInputProps,\n DateTimeInputProps,\n SelectProps,\n IconPickerProps,\n VerticalStackProps,\n HorizontalStackProps,\n GridProps,\n DividerProps,\n IconProps,\n IconButtonType,\n IconButtonProps,\n PanelAction,\n PanelProps,\n ToggleProps,\n CollapsibleProps,\n FrameVariant,\n FrameProps,\n ListProps,\n PillVariant,\n PillProps,\n CheckboxProps,\n MarkdownProps,\n TextPreviewProps,\n ModalProps,\n ConditionalGroupProps,\n} from './types.components.js'\n","/**\n * Localization Types\n *\n * Types and utilities for localized strings in extensions.\n */\n\n/**\n * A string that can be either a simple string or a map of language codes to localized strings.\n * When a simple string is provided, it's used as the default/fallback value.\n * When a map is provided, the appropriate language is selected at runtime.\n *\n * @example\n * // Simple string (backwards compatible)\n * name: \"Get Weather\"\n *\n * @example\n * // Localized strings\n * name: { en: \"Get Weather\", sv: \"Hämta väder\", de: \"Wetter abrufen\" }\n */\nexport type LocalizedString = string | Record<string, string>\n\n/**\n * Resolves a LocalizedString to an actual string value.\n * @param value The LocalizedString to resolve\n * @param lang The preferred language code (e.g., \"sv\", \"en\")\n * @param fallbackLang The fallback language code (defaults to \"en\")\n * @returns The resolved string value\n */\nexport function resolveLocalizedString(\n value: LocalizedString,\n lang: string,\n fallbackLang = 'en'\n): string {\n if (typeof value === 'string') {\n return value\n }\n // Try preferred language first, then fallback language, then first available, then empty string\n return value[lang] ?? value[fallbackLang] ?? Object.values(value)[0] ?? ''\n}\n","/**\n * Message protocol between Extension Host and Extension Workers\n */\n\nimport type {\n ChatMessage,\n ChatOptions,\n GetModelsOptions,\n StreamEvent,\n ToolResult,\n ActionResult,\n ModelInfo,\n SchedulerFirePayload,\n} from './types.js'\n\n// ============================================================================\n// Host → Worker Messages\n// ============================================================================\n\nexport type HostToWorkerMessage =\n | ActivateMessage\n | DeactivateMessage\n | SettingsChangedMessage\n | SchedulerFireMessage\n | ProviderChatRequestMessage\n | ProviderModelsRequestMessage\n | ToolExecuteRequestMessage\n | ActionExecuteRequestMessage\n | ResponseMessage\n | StreamingFetchChunkMessage\n | BackgroundTaskStartMessage\n | BackgroundTaskStopMessage\n\nexport interface ActivateMessage {\n type: 'activate'\n id: string\n payload: {\n extensionId: string\n extensionVersion: string\n storagePath: string\n permissions: string[]\n settings: Record<string, unknown>\n }\n}\n\nexport interface DeactivateMessage {\n type: 'deactivate'\n id: string\n}\n\nexport interface SettingsChangedMessage {\n type: 'settings-changed'\n id: string\n payload: {\n key: string\n value: unknown\n }\n}\n\nexport interface SchedulerFireMessage {\n type: 'scheduler-fire'\n id: string\n payload: SchedulerFirePayload\n}\n\nexport interface ProviderChatRequestMessage {\n type: 'provider-chat-request'\n id: string\n payload: {\n providerId: string\n messages: ChatMessage[]\n options: ChatOptions\n }\n}\n\nexport interface ProviderModelsRequestMessage {\n type: 'provider-models-request'\n id: string\n payload: {\n providerId: string\n options?: GetModelsOptions\n }\n}\n\nexport interface ToolExecuteRequestMessage {\n type: 'tool-execute-request'\n id: string\n payload: {\n toolId: string\n params: Record<string, unknown>\n /** User ID if the tool is executed in a user context */\n userId?: string\n }\n}\n\nexport interface ActionExecuteRequestMessage {\n type: 'action-execute-request'\n id: string\n payload: {\n actionId: string\n params: Record<string, unknown>\n /** User ID if the action is executed in a user context */\n userId?: string\n }\n}\n\nexport interface ResponseMessage {\n type: 'response'\n id: string\n payload: {\n requestId: string\n success: boolean\n data?: unknown\n error?: string\n }\n}\n\n/**\n * Message sent from host to worker with streaming fetch data chunks.\n * Used for streaming network responses (e.g., NDJSON streams from Ollama).\n */\nexport interface StreamingFetchChunkMessage {\n type: 'streaming-fetch-chunk'\n id: string\n payload: {\n requestId: string\n chunk: string\n done: boolean\n error?: string\n }\n}\n\n/**\n * Message sent from host to worker to start a registered background task.\n */\nexport interface BackgroundTaskStartMessage {\n type: 'background-task-start'\n id: string\n payload: {\n taskId: string\n }\n}\n\n/**\n * Message sent from host to worker to stop a running background task.\n */\nexport interface BackgroundTaskStopMessage {\n type: 'background-task-stop'\n id: string\n payload: {\n taskId: string\n }\n}\n\n// ============================================================================\n// Worker → Host Messages\n// ============================================================================\n\nexport type WorkerToHostMessage =\n | ReadyMessage\n | RequestMessage\n | ProviderRegisteredMessage\n | ToolRegisteredMessage\n | ActionRegisteredMessage\n | StreamEventMessage\n | LogMessage\n | ProviderModelsResponseMessage\n | ToolExecuteResponseMessage\n | ActionExecuteResponseMessage\n | StreamingFetchAckMessage\n | BackgroundTaskRegisteredMessage\n | BackgroundTaskStatusMessage\n | BackgroundTaskHealthMessage\n\nexport interface ReadyMessage {\n type: 'ready'\n}\n\n/**\n * Message sent from worker to host to acknowledge receipt of a streaming fetch chunk.\n * This enables backpressure control to prevent unbounded memory growth.\n */\nexport interface StreamingFetchAckMessage {\n type: 'streaming-fetch-ack'\n payload: {\n requestId: string\n }\n}\n\nexport interface RequestMessage {\n type: 'request'\n id: string\n method: RequestMethod\n payload: unknown\n}\n\nexport type RequestMethod =\n | 'network.fetch'\n | 'network.fetch-stream'\n | 'settings.getAll'\n | 'settings.get'\n | 'settings.set'\n | 'user.getProfile'\n | 'user.listIds'\n | 'events.emit'\n | 'scheduler.schedule'\n | 'scheduler.cancel'\n | 'scheduler.reportFireResult'\n | 'chat.appendInstruction'\n | 'database.execute'\n // Simple key-value storage methods\n | 'storage.set'\n | 'storage.keys'\n | 'storage.setForUser'\n | 'storage.keysForUser'\n // Collection-based storage methods\n | 'storage.put'\n | 'storage.get'\n | 'storage.delete'\n | 'storage.find'\n | 'storage.findOne'\n | 'storage.count'\n | 'storage.putMany'\n | 'storage.deleteMany'\n | 'storage.dropCollection'\n | 'storage.listCollections'\n | 'storage.putForUser'\n | 'storage.getForUser'\n | 'storage.deleteForUser'\n | 'storage.findForUser'\n | 'storage.findOneForUser'\n | 'storage.countForUser'\n | 'storage.putManyForUser'\n | 'storage.deleteManyForUser'\n | 'storage.dropCollectionForUser'\n | 'storage.listCollectionsForUser'\n // Secrets methods\n | 'secrets.set'\n | 'secrets.get'\n | 'secrets.delete'\n | 'secrets.list'\n | 'secrets.setForUser'\n | 'secrets.getForUser'\n | 'secrets.deleteForUser'\n | 'secrets.listForUser'\n // Tools cross-extension methods\n | 'tools.list'\n | 'tools.execute'\n\nexport interface ProviderRegisteredMessage {\n type: 'provider-registered'\n payload: {\n id: string\n name: string\n }\n}\n\nexport interface ToolRegisteredMessage {\n type: 'tool-registered'\n payload: {\n id: string\n name: string\n description: string\n parameters?: Record<string, unknown>\n }\n}\n\nexport interface ActionRegisteredMessage {\n type: 'action-registered'\n payload: {\n id: string\n }\n}\n\nexport interface StreamEventMessage {\n type: 'stream-event'\n payload: {\n requestId: string\n event: StreamEvent\n }\n}\n\nexport interface ProviderModelsResponseMessage {\n type: 'provider-models-response'\n payload: {\n requestId: string\n models: ModelInfo[]\n error?: string\n }\n}\n\nexport interface ToolExecuteResponseMessage {\n type: 'tool-execute-response'\n payload: {\n requestId: string\n result: ToolResult\n error?: string\n }\n}\n\nexport interface ActionExecuteResponseMessage {\n type: 'action-execute-response'\n payload: {\n requestId: string\n result: ActionResult\n error?: string\n }\n}\n\nexport interface LogMessage {\n type: 'log'\n payload: {\n level: 'debug' | 'info' | 'warn' | 'error'\n message: string\n data?: Record<string, unknown>\n }\n}\n\n/**\n * Message sent from worker to host when a background task is registered.\n */\nexport interface BackgroundTaskRegisteredMessage {\n type: 'background-task-registered'\n payload: {\n taskId: string\n name: string\n userId: string\n restartPolicy: {\n type: 'always' | 'on-failure' | 'never'\n maxRestarts?: number\n initialDelayMs?: number\n maxDelayMs?: number\n backoffMultiplier?: number\n }\n payload?: Record<string, unknown>\n }\n}\n\n/**\n * Message sent from worker to host with background task status updates.\n */\nexport interface BackgroundTaskStatusMessage {\n type: 'background-task-status'\n payload: {\n taskId: string\n status: 'running' | 'stopped' | 'failed'\n error?: string\n }\n}\n\n/**\n * Message sent from worker to host with background task health reports.\n */\nexport interface BackgroundTaskHealthMessage {\n type: 'background-task-health'\n payload: {\n taskId: string\n status: string\n timestamp: string\n }\n}\n\n// ============================================================================\n// Utility Types\n// ============================================================================\n\nexport interface PendingRequest<T = unknown> {\n resolve: (value: T) => void\n reject: (error: Error) => void\n timeout: ReturnType<typeof setTimeout>\n}\n\n/**\n * Generate a unique message ID\n */\nexport function generateMessageId(): string {\n return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AC4BO,SAAS,uBACd,OACA,MACA,eAAe,MACP;AACR,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO;AAAA,EACT;AAEA,SAAO,MAAM,IAAI,KAAK,MAAM,YAAY,KAAK,OAAO,OAAO,KAAK,EAAE,CAAC,KAAK;AAC1E;;;ACiVO,SAAS,oBAA4B;AAC1C,SAAO,GAAG,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,EAAE,CAAC;AACjE;","names":[]}
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { E as ExtensionContributions, S as SchedulerFirePayload, C as ChatMessage, a as ChatOptions, G as GetModelsOptions, b as StreamEvent, M as ModelInfo, T as ToolResult, A as ActionResult } from './types.tools-CmclZz5I.cjs';
2
- export { aa as AIProvider, ad as Action, K as ActionsAPI, ag as AllowedCSSProperty, a3 as BackgroundRestartPolicy, a0 as BackgroundTaskCallback, $ as BackgroundTaskConfig, a1 as BackgroundTaskContext, a2 as BackgroundTaskHealth, _ as BackgroundWorkersAPI, as as ButtonProps, X as ChatAPI, Y as ChatInstructionMessage, aN as CheckboxProps, aH as CollapsibleProps, v as CommandDefinition, aR as ConditionalGroupProps, au as DateTimeInputProps, F as Disposable, aA as DividerProps, O as EventsAPI, al as ExtensionActionCall, am as ExtensionActionRef, ak as ExtensionComponentChildren, ai as ExtensionComponentData, aj as ExtensionComponentIterator, ah as ExtensionComponentStyle, D as ExtensionContext, an as ExtensionDataSource, ae as ExtensionModule, ao as ExtensionPanelDefinition, aJ as FrameProps, aI as FrameVariant, az as GridProps, ap as HeaderProps, ay as HorizontalStackProps, af as HugeIconName, aD as IconButtonProps, aC as IconButtonType, aw as IconPickerProps, aB as IconProps, aq as LabelProps, aK as ListProps, L as LocalizedString, Z as LogAPI, aO as MarkdownProps, aQ as ModalProps, N as NetworkAPI, aE as PanelAction, n as PanelActionDataSource, m as PanelComponentView, P as PanelDefinition, aF as PanelProps, o as PanelUnknownView, l as PanelView, ar as ParagraphProps, aM as PillProps, aL as PillVariant, q as PromptContribution, s as PromptSection, x as ProviderConfigProperty, y as ProviderConfigPropertyType, w as ProviderConfigSchema, z as ProviderConfigSelectOption, B as ProviderConfigValidation, p as ProviderDefinition, I as ProvidersAPI, a4 as Query, a5 as QueryOptions, Q as SchedulerAPI, R as SchedulerJobRequest, U as SchedulerSchedule, a7 as SecretsAPI, av as SelectProps, e as SettingCreateMapping, c as SettingDefinition, d as SettingOptionsMapping, H as SettingsAPI, a6 as StorageAPI, a8 as StorageCollectionConfig, a9 as StorageContributions, at as TextInputProps, aP as TextPreviewProps, aG as ToggleProps, ac as Tool, ab as ToolCall, u as ToolConfirmationConfig, t as ToolDefinition, k as ToolSettingsActionDataSource, j as ToolSettingsComponentView, i as ToolSettingsListMapping, h as ToolSettingsListView, g as ToolSettingsView, f as ToolSettingsViewDefinition, J as ToolsAPI, V as UserAPI, W as UserProfile, ax as VerticalStackProps, r as resolveLocalizedString } from './types.tools-CmclZz5I.cjs';
1
+ import { E as ExtensionContributions, S as SchedulerFirePayload, C as ChatMessage, a as ChatOptions, G as GetModelsOptions, b as StreamEvent, M as ModelInfo, T as ToolResult, A as ActionResult } from './types.tools-B8gimq24.cjs';
2
+ export { aa as AIProvider, ad as Action, K as ActionsAPI, ag as AllowedCSSProperty, a3 as BackgroundRestartPolicy, a0 as BackgroundTaskCallback, $ as BackgroundTaskConfig, a1 as BackgroundTaskContext, a2 as BackgroundTaskHealth, _ as BackgroundWorkersAPI, as as ButtonProps, X as ChatAPI, Y as ChatInstructionMessage, aN as CheckboxProps, aH as CollapsibleProps, v as CommandDefinition, aR as ConditionalGroupProps, au as DateTimeInputProps, F as Disposable, aA as DividerProps, O as EventsAPI, al as ExtensionActionCall, am as ExtensionActionRef, ak as ExtensionComponentChildren, ai as ExtensionComponentData, aj as ExtensionComponentIterator, ah as ExtensionComponentStyle, D as ExtensionContext, an as ExtensionDataSource, ae as ExtensionModule, ao as ExtensionPanelDefinition, aJ as FrameProps, aI as FrameVariant, az as GridProps, ap as HeaderProps, ay as HorizontalStackProps, af as HugeIconName, aD as IconButtonProps, aC as IconButtonType, aw as IconPickerProps, aB as IconProps, aq as LabelProps, aK as ListProps, L as LocalizedString, Z as LogAPI, aO as MarkdownProps, aQ as ModalProps, N as NetworkAPI, aE as PanelAction, n as PanelActionDataSource, m as PanelComponentView, P as PanelDefinition, aF as PanelProps, o as PanelUnknownView, l as PanelView, ar as ParagraphProps, aM as PillProps, aL as PillVariant, q as PromptContribution, s as PromptSection, x as ProviderConfigProperty, y as ProviderConfigPropertyType, w as ProviderConfigSchema, z as ProviderConfigSelectOption, B as ProviderConfigValidation, p as ProviderDefinition, I as ProvidersAPI, a4 as Query, a5 as QueryOptions, Q as SchedulerAPI, R as SchedulerJobRequest, U as SchedulerSchedule, a7 as SecretsAPI, av as SelectProps, e as SettingCreateMapping, c as SettingDefinition, d as SettingOptionsMapping, H as SettingsAPI, a6 as StorageAPI, a8 as StorageCollectionConfig, a9 as StorageContributions, at as TextInputProps, aP as TextPreviewProps, aG as ToggleProps, ac as Tool, ab as ToolCall, u as ToolConfirmationConfig, t as ToolDefinition, k as ToolSettingsActionDataSource, j as ToolSettingsComponentView, i as ToolSettingsListMapping, h as ToolSettingsListView, g as ToolSettingsView, f as ToolSettingsViewDefinition, J as ToolsAPI, V as UserAPI, W as UserProfile, ax as VerticalStackProps, r as resolveLocalizedString } from './types.tools-B8gimq24.cjs';
3
3
 
4
4
  /**
5
5
  * Permission Types
@@ -12,7 +12,7 @@ type NetworkPermission = 'network:*' | `network:localhost` | `network:localhost:
12
12
  /** Storage permissions */
13
13
  type StoragePermission = 'storage.collections' | 'secrets.manage';
14
14
  /** User data permissions */
15
- type UserDataPermission = 'user.profile.read' | 'user.location.read' | 'chat.history.read' | 'chat.current.read';
15
+ type UserDataPermission = 'user.profile.read' | 'user.list' | 'user.location.read' | 'chat.history.read' | 'chat.current.read';
16
16
  /** Capability permissions */
17
17
  type CapabilityPermission = 'provider.register' | 'tools.register' | 'tools.list' | 'tools.execute' | 'actions.register' | 'settings.register' | 'commands.register' | 'panels.register' | 'events.emit' | 'scheduler.register' | 'chat.message.write' | 'background.workers';
18
18
  /** System permissions */
@@ -194,7 +194,7 @@ interface RequestMessage {
194
194
  method: RequestMethod;
195
195
  payload: unknown;
196
196
  }
197
- type RequestMethod = 'network.fetch' | 'network.fetch-stream' | 'settings.getAll' | 'settings.get' | 'settings.set' | 'user.getProfile' | 'events.emit' | 'scheduler.schedule' | 'scheduler.cancel' | 'scheduler.reportFireResult' | 'chat.appendInstruction' | 'database.execute' | 'storage.set' | 'storage.keys' | 'storage.setForUser' | 'storage.keysForUser' | 'storage.put' | 'storage.get' | 'storage.delete' | 'storage.find' | 'storage.findOne' | 'storage.count' | 'storage.putMany' | 'storage.deleteMany' | 'storage.dropCollection' | 'storage.listCollections' | 'storage.putForUser' | 'storage.getForUser' | 'storage.deleteForUser' | 'storage.findForUser' | 'storage.findOneForUser' | 'storage.countForUser' | 'storage.putManyForUser' | 'storage.deleteManyForUser' | 'storage.dropCollectionForUser' | 'storage.listCollectionsForUser' | 'secrets.set' | 'secrets.get' | 'secrets.delete' | 'secrets.list' | 'secrets.setForUser' | 'secrets.getForUser' | 'secrets.deleteForUser' | 'secrets.listForUser' | 'tools.list' | 'tools.execute';
197
+ type RequestMethod = 'network.fetch' | 'network.fetch-stream' | 'settings.getAll' | 'settings.get' | 'settings.set' | 'user.getProfile' | 'user.listIds' | 'events.emit' | 'scheduler.schedule' | 'scheduler.cancel' | 'scheduler.reportFireResult' | 'chat.appendInstruction' | 'database.execute' | 'storage.set' | 'storage.keys' | 'storage.setForUser' | 'storage.keysForUser' | 'storage.put' | 'storage.get' | 'storage.delete' | 'storage.find' | 'storage.findOne' | 'storage.count' | 'storage.putMany' | 'storage.deleteMany' | 'storage.dropCollection' | 'storage.listCollections' | 'storage.putForUser' | 'storage.getForUser' | 'storage.deleteForUser' | 'storage.findForUser' | 'storage.findOneForUser' | 'storage.countForUser' | 'storage.putManyForUser' | 'storage.deleteManyForUser' | 'storage.dropCollectionForUser' | 'storage.listCollectionsForUser' | 'secrets.set' | 'secrets.get' | 'secrets.delete' | 'secrets.list' | 'secrets.setForUser' | 'secrets.getForUser' | 'secrets.deleteForUser' | 'secrets.listForUser' | 'tools.list' | 'tools.execute';
198
198
  interface ProviderRegisteredMessage {
199
199
  type: 'provider-registered';
200
200
  payload: {
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { E as ExtensionContributions, S as SchedulerFirePayload, C as ChatMessage, a as ChatOptions, G as GetModelsOptions, b as StreamEvent, M as ModelInfo, T as ToolResult, A as ActionResult } from './types.tools-CmclZz5I.js';
2
- export { aa as AIProvider, ad as Action, K as ActionsAPI, ag as AllowedCSSProperty, a3 as BackgroundRestartPolicy, a0 as BackgroundTaskCallback, $ as BackgroundTaskConfig, a1 as BackgroundTaskContext, a2 as BackgroundTaskHealth, _ as BackgroundWorkersAPI, as as ButtonProps, X as ChatAPI, Y as ChatInstructionMessage, aN as CheckboxProps, aH as CollapsibleProps, v as CommandDefinition, aR as ConditionalGroupProps, au as DateTimeInputProps, F as Disposable, aA as DividerProps, O as EventsAPI, al as ExtensionActionCall, am as ExtensionActionRef, ak as ExtensionComponentChildren, ai as ExtensionComponentData, aj as ExtensionComponentIterator, ah as ExtensionComponentStyle, D as ExtensionContext, an as ExtensionDataSource, ae as ExtensionModule, ao as ExtensionPanelDefinition, aJ as FrameProps, aI as FrameVariant, az as GridProps, ap as HeaderProps, ay as HorizontalStackProps, af as HugeIconName, aD as IconButtonProps, aC as IconButtonType, aw as IconPickerProps, aB as IconProps, aq as LabelProps, aK as ListProps, L as LocalizedString, Z as LogAPI, aO as MarkdownProps, aQ as ModalProps, N as NetworkAPI, aE as PanelAction, n as PanelActionDataSource, m as PanelComponentView, P as PanelDefinition, aF as PanelProps, o as PanelUnknownView, l as PanelView, ar as ParagraphProps, aM as PillProps, aL as PillVariant, q as PromptContribution, s as PromptSection, x as ProviderConfigProperty, y as ProviderConfigPropertyType, w as ProviderConfigSchema, z as ProviderConfigSelectOption, B as ProviderConfigValidation, p as ProviderDefinition, I as ProvidersAPI, a4 as Query, a5 as QueryOptions, Q as SchedulerAPI, R as SchedulerJobRequest, U as SchedulerSchedule, a7 as SecretsAPI, av as SelectProps, e as SettingCreateMapping, c as SettingDefinition, d as SettingOptionsMapping, H as SettingsAPI, a6 as StorageAPI, a8 as StorageCollectionConfig, a9 as StorageContributions, at as TextInputProps, aP as TextPreviewProps, aG as ToggleProps, ac as Tool, ab as ToolCall, u as ToolConfirmationConfig, t as ToolDefinition, k as ToolSettingsActionDataSource, j as ToolSettingsComponentView, i as ToolSettingsListMapping, h as ToolSettingsListView, g as ToolSettingsView, f as ToolSettingsViewDefinition, J as ToolsAPI, V as UserAPI, W as UserProfile, ax as VerticalStackProps, r as resolveLocalizedString } from './types.tools-CmclZz5I.js';
1
+ import { E as ExtensionContributions, S as SchedulerFirePayload, C as ChatMessage, a as ChatOptions, G as GetModelsOptions, b as StreamEvent, M as ModelInfo, T as ToolResult, A as ActionResult } from './types.tools-B8gimq24.js';
2
+ export { aa as AIProvider, ad as Action, K as ActionsAPI, ag as AllowedCSSProperty, a3 as BackgroundRestartPolicy, a0 as BackgroundTaskCallback, $ as BackgroundTaskConfig, a1 as BackgroundTaskContext, a2 as BackgroundTaskHealth, _ as BackgroundWorkersAPI, as as ButtonProps, X as ChatAPI, Y as ChatInstructionMessage, aN as CheckboxProps, aH as CollapsibleProps, v as CommandDefinition, aR as ConditionalGroupProps, au as DateTimeInputProps, F as Disposable, aA as DividerProps, O as EventsAPI, al as ExtensionActionCall, am as ExtensionActionRef, ak as ExtensionComponentChildren, ai as ExtensionComponentData, aj as ExtensionComponentIterator, ah as ExtensionComponentStyle, D as ExtensionContext, an as ExtensionDataSource, ae as ExtensionModule, ao as ExtensionPanelDefinition, aJ as FrameProps, aI as FrameVariant, az as GridProps, ap as HeaderProps, ay as HorizontalStackProps, af as HugeIconName, aD as IconButtonProps, aC as IconButtonType, aw as IconPickerProps, aB as IconProps, aq as LabelProps, aK as ListProps, L as LocalizedString, Z as LogAPI, aO as MarkdownProps, aQ as ModalProps, N as NetworkAPI, aE as PanelAction, n as PanelActionDataSource, m as PanelComponentView, P as PanelDefinition, aF as PanelProps, o as PanelUnknownView, l as PanelView, ar as ParagraphProps, aM as PillProps, aL as PillVariant, q as PromptContribution, s as PromptSection, x as ProviderConfigProperty, y as ProviderConfigPropertyType, w as ProviderConfigSchema, z as ProviderConfigSelectOption, B as ProviderConfigValidation, p as ProviderDefinition, I as ProvidersAPI, a4 as Query, a5 as QueryOptions, Q as SchedulerAPI, R as SchedulerJobRequest, U as SchedulerSchedule, a7 as SecretsAPI, av as SelectProps, e as SettingCreateMapping, c as SettingDefinition, d as SettingOptionsMapping, H as SettingsAPI, a6 as StorageAPI, a8 as StorageCollectionConfig, a9 as StorageContributions, at as TextInputProps, aP as TextPreviewProps, aG as ToggleProps, ac as Tool, ab as ToolCall, u as ToolConfirmationConfig, t as ToolDefinition, k as ToolSettingsActionDataSource, j as ToolSettingsComponentView, i as ToolSettingsListMapping, h as ToolSettingsListView, g as ToolSettingsView, f as ToolSettingsViewDefinition, J as ToolsAPI, V as UserAPI, W as UserProfile, ax as VerticalStackProps, r as resolveLocalizedString } from './types.tools-B8gimq24.js';
3
3
 
4
4
  /**
5
5
  * Permission Types
@@ -12,7 +12,7 @@ type NetworkPermission = 'network:*' | `network:localhost` | `network:localhost:
12
12
  /** Storage permissions */
13
13
  type StoragePermission = 'storage.collections' | 'secrets.manage';
14
14
  /** User data permissions */
15
- type UserDataPermission = 'user.profile.read' | 'user.location.read' | 'chat.history.read' | 'chat.current.read';
15
+ type UserDataPermission = 'user.profile.read' | 'user.list' | 'user.location.read' | 'chat.history.read' | 'chat.current.read';
16
16
  /** Capability permissions */
17
17
  type CapabilityPermission = 'provider.register' | 'tools.register' | 'tools.list' | 'tools.execute' | 'actions.register' | 'settings.register' | 'commands.register' | 'panels.register' | 'events.emit' | 'scheduler.register' | 'chat.message.write' | 'background.workers';
18
18
  /** System permissions */
@@ -194,7 +194,7 @@ interface RequestMessage {
194
194
  method: RequestMethod;
195
195
  payload: unknown;
196
196
  }
197
- type RequestMethod = 'network.fetch' | 'network.fetch-stream' | 'settings.getAll' | 'settings.get' | 'settings.set' | 'user.getProfile' | 'events.emit' | 'scheduler.schedule' | 'scheduler.cancel' | 'scheduler.reportFireResult' | 'chat.appendInstruction' | 'database.execute' | 'storage.set' | 'storage.keys' | 'storage.setForUser' | 'storage.keysForUser' | 'storage.put' | 'storage.get' | 'storage.delete' | 'storage.find' | 'storage.findOne' | 'storage.count' | 'storage.putMany' | 'storage.deleteMany' | 'storage.dropCollection' | 'storage.listCollections' | 'storage.putForUser' | 'storage.getForUser' | 'storage.deleteForUser' | 'storage.findForUser' | 'storage.findOneForUser' | 'storage.countForUser' | 'storage.putManyForUser' | 'storage.deleteManyForUser' | 'storage.dropCollectionForUser' | 'storage.listCollectionsForUser' | 'secrets.set' | 'secrets.get' | 'secrets.delete' | 'secrets.list' | 'secrets.setForUser' | 'secrets.getForUser' | 'secrets.deleteForUser' | 'secrets.listForUser' | 'tools.list' | 'tools.execute';
197
+ type RequestMethod = 'network.fetch' | 'network.fetch-stream' | 'settings.getAll' | 'settings.get' | 'settings.set' | 'user.getProfile' | 'user.listIds' | 'events.emit' | 'scheduler.schedule' | 'scheduler.cancel' | 'scheduler.reportFireResult' | 'chat.appendInstruction' | 'database.execute' | 'storage.set' | 'storage.keys' | 'storage.setForUser' | 'storage.keysForUser' | 'storage.put' | 'storage.get' | 'storage.delete' | 'storage.find' | 'storage.findOne' | 'storage.count' | 'storage.putMany' | 'storage.deleteMany' | 'storage.dropCollection' | 'storage.listCollections' | 'storage.putForUser' | 'storage.getForUser' | 'storage.deleteForUser' | 'storage.findForUser' | 'storage.findOneForUser' | 'storage.countForUser' | 'storage.putManyForUser' | 'storage.deleteManyForUser' | 'storage.dropCollectionForUser' | 'storage.listCollectionsForUser' | 'secrets.set' | 'secrets.get' | 'secrets.delete' | 'secrets.list' | 'secrets.setForUser' | 'secrets.getForUser' | 'secrets.deleteForUser' | 'secrets.listForUser' | 'tools.list' | 'tools.execute';
198
198
  interface ProviderRegisteredMessage {
199
199
  type: 'provider-registered';
200
200
  payload: {
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  generateMessageId
3
- } from "./chunk-RZGR2OKA.js";
3
+ } from "./chunk-K53YNG2W.js";
4
4
  import "./chunk-DGUM43GV.js";
5
5
 
6
6
  // src/types.localization.ts
package/dist/runtime.cjs CHANGED
@@ -850,6 +850,9 @@ function buildContext(extensionId, extensionVersion, storagePath, permissions) {
850
850
  const userApi = {
851
851
  async getProfile() {
852
852
  return sendRequest("user.getProfile", {});
853
+ },
854
+ async listIds() {
855
+ return sendRequest("user.listIds", {});
853
856
  }
854
857
  };
855
858
  context.user = userApi;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/runtime.ts","../src/background.ts","../src/messages.ts","../src/runtime/storageApi.ts","../src/runtime/secretsApi.ts","../src/runtime/executionContext.ts"],"sourcesContent":["/**\n * Extension Runtime - Runs inside the worker\n *\n * This module handles communication with the Extension Host and provides\n * the ExtensionContext to the extension's activate function.\n */\n\nimport type {\n ExecutionContext,\n ExtensionContext,\n ExtensionModule,\n Disposable,\n NetworkAPI,\n SettingsAPI,\n ProvidersAPI,\n ToolsAPI,\n ActionsAPI,\n EventsAPI,\n SchedulerAPI,\n SchedulerJobRequest,\n SchedulerFirePayload,\n UserAPI,\n UserProfile,\n ChatAPI,\n ChatInstructionMessage,\n StorageAPI,\n SecretsAPI,\n LogAPI,\n AIProvider,\n Tool,\n ToolDefinition,\n ToolResult,\n Action,\n ChatMessage,\n ChatOptions,\n GetModelsOptions,\n BackgroundWorkersAPI,\n BackgroundTaskConfig,\n BackgroundTaskCallback,\n BackgroundTaskHealth,\n} from './types.js'\n\nimport { WorkerBackgroundTaskManager } from './background.js'\n\nimport type {\n HostToWorkerMessage,\n WorkerToHostMessage,\n RequestMessage,\n PendingRequest,\n} from './messages.js'\n\nimport { generateMessageId } from './messages.js'\n\nimport {\n buildExtensionStorageAPI,\n buildUserStorageAPI,\n buildExtensionSecretsAPI,\n buildUserSecretsAPI,\n createExecutionContext,\n} from './runtime/index.js'\n\n// ============================================================================\n// Environment Detection and Message Port\n// ============================================================================\n\n/**\n * Detect if we're in Node.js Worker Thread or Web Worker\n * and get the appropriate message port\n */\ninterface MessagePort {\n postMessage(message: WorkerToHostMessage): void\n onMessage(handler: (message: HostToWorkerMessage) => void): void\n}\n\nfunction getMessagePort(): MessagePort {\n // Check if we're in Node.js Worker Thread\n if (typeof process !== 'undefined' && process.versions?.node) {\n // Node.js Worker Thread - import parentPort dynamically\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { parentPort } = require('node:worker_threads')\n return {\n postMessage: (message) => parentPort?.postMessage(message),\n onMessage: (handler) => parentPort?.on('message', handler),\n }\n }\n\n // Web Worker - use self\n return {\n postMessage: (message) => self.postMessage(message),\n onMessage: (handler) => {\n self.addEventListener('message', (event: MessageEvent<HostToWorkerMessage>) => {\n handler(event.data)\n })\n },\n }\n}\n\nconst messagePort = getMessagePort()\n\n// ============================================================================\n// Global State\n// ============================================================================\n\nlet extensionModule: ExtensionModule | null = null\nlet extensionDisposable: Disposable | null = null\nlet extensionContext: ExtensionContext | null = null\nlet backgroundTaskManager: WorkerBackgroundTaskManager | null = null\n\nconst pendingRequests = new Map<string, PendingRequest>()\nconst registeredProviders = new Map<string, AIProvider>()\nconst registeredTools = new Map<string, Tool>()\nconst registeredActions = new Map<string, Action>()\nconst settingsCallbacks: Array<(key: string, value: unknown) => void> = []\nconst schedulerCallbacks: Array<(payload: SchedulerFirePayload, context: ExecutionContext) => void | Promise<void>> = []\n\n/**\n * Tracking for streaming fetch requests.\n * Each request stores incoming chunks and signals when new data arrives.\n */\ninterface StreamingFetchRequest {\n chunks: string[]\n done: boolean\n error?: string\n resolve?: () => void\n}\nconst streamingFetchRequests = new Map<string, StreamingFetchRequest>()\n\nconst REQUEST_TIMEOUT = 30000 // 30 seconds\n\n// ============================================================================\n// Message Handling\n// ============================================================================\n\n/**\n * Send a message to the host\n */\nfunction postMessage(message: WorkerToHostMessage): void {\n messagePort.postMessage(message)\n}\n\n/**\n * Send a request to the host and wait for response\n */\nasync function sendRequest<T>(method: RequestMessage['method'], payload: unknown): Promise<T> {\n const id = generateMessageId()\n\n return new Promise<T>((resolve, reject) => {\n const timeout = setTimeout(() => {\n pendingRequests.delete(id)\n reject(new Error(`Request ${method} timed out`))\n }, REQUEST_TIMEOUT)\n\n pendingRequests.set(id, { resolve: resolve as (value: unknown) => void, reject, timeout })\n\n postMessage({\n type: 'request',\n id,\n method,\n payload,\n })\n })\n}\n\n/**\n * Handle messages from the host\n */\nasync function handleHostMessage(message: HostToWorkerMessage): Promise<void> {\n switch (message.type) {\n case 'activate':\n await handleActivate(message.payload)\n break\n\n case 'deactivate':\n await handleDeactivate()\n break\n\n case 'settings-changed':\n handleSettingsChanged(message.payload.key, message.payload.value)\n break\n\n case 'scheduler-fire':\n await handleSchedulerFire(message.payload)\n break\n\n case 'provider-chat-request':\n await handleProviderChatRequest(message.id, message.payload)\n break\n\n case 'provider-models-request':\n await handleProviderModelsRequest(message.id, message.payload)\n break\n\n case 'tool-execute-request':\n await handleToolExecuteRequest(message.id, message.payload)\n break\n\n case 'action-execute-request':\n await handleActionExecuteRequest(message.id, message.payload)\n break\n\n case 'response':\n handleResponse(message.payload)\n break\n\n case 'streaming-fetch-chunk':\n handleStreamingFetchChunk(message.payload)\n break\n\n case 'background-task-start':\n await handleBackgroundTaskStart(message.payload.taskId)\n break\n\n case 'background-task-stop':\n handleBackgroundTaskStop(message.payload.taskId)\n break\n }\n}\n\n/**\n * Handle incoming streaming fetch chunks from the host\n */\nfunction handleStreamingFetchChunk(payload: {\n requestId: string\n chunk: string\n done: boolean\n error?: string\n}): void {\n const request = streamingFetchRequests.get(payload.requestId)\n if (!request) return\n\n if (payload.error) {\n request.error = payload.error\n request.done = true\n } else if (payload.chunk) {\n request.chunks.push(payload.chunk)\n }\n\n if (payload.done) {\n request.done = true\n }\n\n // Signal that new data is available\n if (request.resolve) {\n const resolve = request.resolve\n request.resolve = undefined\n resolve()\n }\n\n // Send acknowledgment for backpressure control\n postMessage({\n type: 'streaming-fetch-ack',\n payload: { requestId: payload.requestId },\n })\n}\n\nfunction handleResponse(payload: { requestId: string; success: boolean; data?: unknown; error?: string }): void {\n const pending = pendingRequests.get(payload.requestId)\n if (!pending) return\n\n clearTimeout(pending.timeout)\n pendingRequests.delete(payload.requestId)\n\n if (payload.success) {\n pending.resolve(payload.data)\n } else {\n pending.reject(new Error(payload.error || 'Unknown error'))\n }\n}\n\n// ============================================================================\n// Activation / Deactivation\n// ============================================================================\n\nasync function handleActivate(payload: {\n extensionId: string\n extensionVersion: string\n storagePath: string\n permissions: string[]\n settings: Record<string, unknown>\n}): Promise<void> {\n const { extensionId, extensionVersion, storagePath, permissions } = payload\n\n // Build the context based on permissions\n extensionContext = buildContext(extensionId, extensionVersion, storagePath, permissions)\n\n // Import and activate the extension\n try {\n // The actual extension code should be bundled and available\n // This is called after the extension code has been loaded into the worker\n if (extensionModule?.activate) {\n const result = await extensionModule.activate(extensionContext)\n if (result && 'dispose' in result) {\n extensionDisposable = result\n }\n }\n } catch (error) {\n extensionContext.log.error('Failed to activate extension', {\n error: error instanceof Error ? error.message : String(error),\n })\n throw error\n }\n}\n\nasync function handleDeactivate(): Promise<void> {\n try {\n if (extensionModule?.deactivate) {\n await extensionModule.deactivate()\n }\n if (extensionDisposable) {\n extensionDisposable.dispose()\n }\n if (backgroundTaskManager) {\n backgroundTaskManager.dispose()\n }\n } catch (error) {\n console.error('Error during deactivation:', error)\n } finally {\n extensionModule = null\n extensionDisposable = null\n extensionContext = null\n backgroundTaskManager = null\n registeredProviders.clear()\n registeredTools.clear()\n registeredActions.clear()\n settingsCallbacks.length = 0\n schedulerCallbacks.length = 0\n }\n}\n\nfunction handleSettingsChanged(key: string, value: unknown): void {\n for (const callback of settingsCallbacks) {\n try {\n callback(key, value)\n } catch (error) {\n console.error('Error in settings change callback:', error)\n }\n }\n}\n\n// Storage and Secrets APIs are now in runtime/storageApi.ts and runtime/secretsApi.ts\n// ExecutionContext builder is in runtime/executionContext.ts\n\nasync function handleSchedulerFire(payload: SchedulerFirePayload): Promise<void> {\n const execContext = createExecutionContext(sendRequest, extensionContext!, payload.userId)\n\n // Run callbacks concurrently to avoid blocking\n const results = await Promise.allSettled(\n schedulerCallbacks.map((callback) => Promise.resolve(callback(payload, execContext))),\n )\n\n // Log any errors\n results.forEach((result, index) => {\n if (result.status === 'rejected') {\n console.error(`Error in scheduler callback ${index}:`, result.reason)\n }\n })\n\n // Report result back to host\n const failed = results.find((r) => r.status === 'rejected') as PromiseRejectedResult | undefined\n try {\n await sendRequest<void>('scheduler.reportFireResult', {\n jobId: payload.id,\n success: !failed,\n error: failed ? String(failed.reason) : undefined,\n })\n } catch {\n // Best effort — don't crash if reporting fails\n }\n}\n\n// ============================================================================\n// Background Task Handlers\n// ============================================================================\n\nasync function handleBackgroundTaskStart(taskId: string): Promise<void> {\n if (!backgroundTaskManager) {\n console.error('Background task manager not initialized')\n return\n }\n await backgroundTaskManager.handleStart(taskId)\n}\n\nfunction handleBackgroundTaskStop(taskId: string): void {\n if (!backgroundTaskManager) {\n console.error('Background task manager not initialized')\n return\n }\n backgroundTaskManager.handleStop(taskId)\n}\n\n// ============================================================================\n// Provider / Tool Requests\n// ============================================================================\n\nasync function handleProviderChatRequest(\n requestId: string,\n payload: { providerId: string; messages: ChatMessage[]; options: ChatOptions }\n): Promise<void> {\n const provider = registeredProviders.get(payload.providerId)\n if (!provider) {\n postMessage({\n type: 'request',\n id: generateMessageId(),\n method: 'network.fetch', // Dummy, we need a proper error response\n payload: { error: `Provider ${payload.providerId} not found` },\n })\n return\n }\n\n try {\n const generator = provider.chat(payload.messages, payload.options)\n let sawDone = false\n let sawError = false\n\n for await (const event of generator) {\n if (event.type === 'done') {\n sawDone = true\n } else if (event.type === 'error') {\n sawError = true\n }\n postMessage({\n type: 'stream-event',\n payload: { requestId, event },\n })\n }\n\n if (!sawDone && !sawError) {\n postMessage({\n type: 'stream-event',\n payload: {\n requestId,\n event: { type: 'done' },\n },\n })\n }\n } catch (error) {\n postMessage({\n type: 'stream-event',\n payload: {\n requestId,\n event: {\n type: 'error',\n message: error instanceof Error ? error.message : String(error),\n },\n },\n })\n }\n}\n\nasync function handleProviderModelsRequest(\n requestId: string,\n payload: { providerId: string; options?: GetModelsOptions }\n): Promise<void> {\n const provider = registeredProviders.get(payload.providerId)\n if (!provider) {\n // Send error response\n postMessage({\n type: 'provider-models-response',\n payload: {\n requestId,\n models: [],\n error: `Provider ${payload.providerId} not found`,\n },\n })\n return\n }\n\n try {\n // Pass options to getModels so provider can use settings (e.g., URL for Ollama)\n const models = await provider.getModels(payload.options)\n // Send response with models\n postMessage({\n type: 'provider-models-response',\n payload: {\n requestId,\n models,\n },\n })\n } catch (error) {\n postMessage({\n type: 'provider-models-response',\n payload: {\n requestId,\n models: [],\n error: error instanceof Error ? error.message : String(error),\n },\n })\n }\n}\n\nasync function handleToolExecuteRequest(\n requestId: string,\n payload: { toolId: string; params: Record<string, unknown>; userId?: string }\n): Promise<void> {\n const tool = registeredTools.get(payload.toolId)\n if (!tool) {\n // Send error response\n postMessage({\n type: 'tool-execute-response',\n payload: {\n requestId,\n result: { success: false, error: `Tool ${payload.toolId} not found` },\n error: `Tool ${payload.toolId} not found`,\n },\n })\n return\n }\n\n try {\n const execContext = createExecutionContext(sendRequest, extensionContext!, payload.userId)\n\n const result = await tool.execute(payload.params, execContext)\n\n // Send response with result\n postMessage({\n type: 'tool-execute-response',\n payload: {\n requestId,\n result,\n },\n })\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error)\n postMessage({\n type: 'tool-execute-response',\n payload: {\n requestId,\n result: { success: false, error: errorMessage },\n error: errorMessage,\n },\n })\n }\n}\n\nasync function handleActionExecuteRequest(\n requestId: string,\n payload: { actionId: string; params: Record<string, unknown>; userId?: string }\n): Promise<void> {\n const action = registeredActions.get(payload.actionId)\n if (!action) {\n postMessage({\n type: 'action-execute-response',\n payload: {\n requestId,\n result: { success: false, error: `Action ${payload.actionId} not found` },\n error: `Action ${payload.actionId} not found`,\n },\n })\n return\n }\n\n try {\n const execContext = createExecutionContext(sendRequest, extensionContext!, payload.userId)\n\n const result = await action.execute(payload.params, execContext)\n\n postMessage({\n type: 'action-execute-response',\n payload: {\n requestId,\n result,\n },\n })\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error)\n postMessage({\n type: 'action-execute-response',\n payload: {\n requestId,\n result: { success: false, error: errorMessage },\n error: errorMessage,\n },\n })\n }\n}\n\n// ============================================================================\n// Context Building\n// ============================================================================\n\nfunction buildContext(\n extensionId: string,\n extensionVersion: string,\n storagePath: string,\n permissions: string[]\n): ExtensionContext {\n const hasPermission = (perm: string): boolean => {\n return permissions.some((p) => {\n if (p === perm) return true\n if (p.endsWith(':*') && perm.startsWith(p.slice(0, -1))) return true\n return false\n })\n }\n\n const log: LogAPI = {\n debug: (message, data) => postMessage({ type: 'log', payload: { level: 'debug', message, data } }),\n info: (message, data) => postMessage({ type: 'log', payload: { level: 'info', message, data } }),\n warn: (message, data) => postMessage({ type: 'log', payload: { level: 'warn', message, data } }),\n error: (message, data) => postMessage({ type: 'log', payload: { level: 'error', message, data } }),\n }\n\n const context: ExtensionContext = {\n extension: {\n id: extensionId,\n version: extensionVersion,\n storagePath,\n },\n log,\n }\n\n // Add network API if permitted\n if (permissions.some((p) => p.startsWith('network:'))) {\n const networkApi: NetworkAPI = {\n async fetch(url: string, options?: RequestInit): Promise<Response> {\n const result = await sendRequest<{ status: number; statusText: string; headers: Record<string, string>; body: string }>('network.fetch', { url, options })\n return new Response(result.body, {\n status: result.status,\n statusText: result.statusText,\n headers: result.headers,\n })\n },\n\n async *fetchStream(url: string, options?: RequestInit): AsyncGenerator<string, void, unknown> {\n const requestId = generateMessageId()\n\n // Set up streaming request tracking\n const request: StreamingFetchRequest = {\n chunks: [],\n done: false,\n }\n streamingFetchRequests.set(requestId, request)\n\n // Send the streaming fetch request to the host\n postMessage({\n type: 'request',\n id: requestId,\n method: 'network.fetch-stream',\n payload: { url, options, requestId },\n })\n\n try {\n // Yield chunks as they arrive\n while (!request.done) {\n // Wait for new data\n await new Promise<void>((resolve) => {\n const resolver = () => {\n // Clear the stored resolver before resolving to avoid\n // stale callbacks being invoked for a new wait iteration.\n if (request.resolve === resolver) {\n request.resolve = undefined\n }\n resolve()\n }\n\n request.resolve = resolver\n\n // Check if we already have data or completion\n if (request.chunks.length > 0 || request.done) {\n resolver()\n }\n })\n\n // Check for errors first, before yielding any chunks\n if (request.error) {\n throw new Error(request.error)\n }\n\n // Yield all available chunks\n while (request.chunks.length > 0) {\n yield request.chunks.shift()!\n }\n }\n } finally {\n streamingFetchRequests.delete(requestId)\n }\n },\n }\n ;(context as { network: NetworkAPI }).network = networkApi\n }\n\n // Add settings API if permitted\n if (hasPermission('settings.register')) {\n const settingsApi: SettingsAPI = {\n async getAll<T extends Record<string, unknown>>(): Promise<T> {\n return sendRequest<T>('settings.getAll', {})\n },\n async get<T>(key: string): Promise<T | undefined> {\n return sendRequest<T | undefined>('settings.get', { key })\n },\n async set(key: string, value: unknown): Promise<void> {\n return sendRequest<void>('settings.set', { key, value })\n },\n onChange(callback: (key: string, value: unknown) => void): Disposable {\n settingsCallbacks.push(callback)\n return {\n dispose: () => {\n const index = settingsCallbacks.indexOf(callback)\n if (index >= 0) settingsCallbacks.splice(index, 1)\n },\n }\n },\n }\n ;(context as { settings: SettingsAPI }).settings = settingsApi\n }\n\n // Add providers API if permitted\n if (hasPermission('provider.register')) {\n const providersApi: ProvidersAPI = {\n register(provider: AIProvider): Disposable {\n registeredProviders.set(provider.id, provider)\n postMessage({\n type: 'provider-registered',\n payload: { id: provider.id, name: provider.name },\n })\n return {\n dispose: () => {\n registeredProviders.delete(provider.id)\n },\n }\n },\n }\n ;(context as { providers: ProvidersAPI }).providers = providersApi\n }\n\n // Add tools API if ANY tools permission is present\n const hasAnyToolsPermission = hasPermission('tools.register') || hasPermission('tools.list') || hasPermission('tools.execute')\n if (hasAnyToolsPermission) {\n const toolsApi: ToolsAPI = {\n register(tool: Tool): Disposable {\n if (!hasPermission('tools.register')) {\n throw new Error('tools.register permission required')\n }\n registeredTools.set(tool.id, tool)\n postMessage({\n type: 'tool-registered',\n payload: {\n id: tool.id,\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n },\n })\n return {\n dispose: () => {\n registeredTools.delete(tool.id)\n },\n }\n },\n async list(): Promise<ToolDefinition[]> {\n if (!hasPermission('tools.list')) {\n throw new Error('tools.list permission required')\n }\n return sendRequest<ToolDefinition[]>('tools.list', {})\n },\n async execute(toolId: string, params: Record<string, unknown>, userId?: string): Promise<ToolResult> {\n if (!hasPermission('tools.execute')) {\n throw new Error('tools.execute permission required')\n }\n return sendRequest<ToolResult>('tools.execute', { toolId, params, userId })\n },\n }\n ;(context as { tools: ToolsAPI }).tools = toolsApi\n }\n\n // Add actions API if permitted\n if (hasPermission('actions.register')) {\n const actionsApi: ActionsAPI = {\n register(action: Action): Disposable {\n registeredActions.set(action.id, action)\n postMessage({\n type: 'action-registered',\n payload: {\n id: action.id,\n },\n })\n return {\n dispose: () => {\n registeredActions.delete(action.id)\n },\n }\n },\n }\n ;(context as { actions: ActionsAPI }).actions = actionsApi\n }\n\n // Add events API if permitted\n if (hasPermission('events.emit')) {\n const eventsApi: EventsAPI = {\n async emit(name: string, payload?: Record<string, unknown>): Promise<void> {\n await sendRequest<void>('events.emit', { name, payload })\n },\n }\n ;(context as { events: EventsAPI }).events = eventsApi\n }\n\n // Add scheduler API if permitted\n if (hasPermission('scheduler.register')) {\n const schedulerApi: SchedulerAPI = {\n async schedule(job: SchedulerJobRequest): Promise<void> {\n // Extensions must explicitly set job.userId if they want user-scoped jobs\n // Use context.userId from the ExecutionContext in tool/action execute\n await sendRequest<void>('scheduler.schedule', { job })\n },\n async cancel(jobId: string): Promise<void> {\n await sendRequest<void>('scheduler.cancel', { jobId })\n },\n onFire(callback: (payload: SchedulerFirePayload, context: ExecutionContext) => void | Promise<void>): Disposable {\n schedulerCallbacks.push(callback)\n return {\n dispose: () => {\n const index = schedulerCallbacks.indexOf(callback)\n if (index >= 0) schedulerCallbacks.splice(index, 1)\n },\n }\n },\n }\n ;(context as { scheduler: SchedulerAPI }).scheduler = schedulerApi\n }\n\n // Add user profile API if permitted\n if (hasPermission('user.profile.read')) {\n const userApi: UserAPI = {\n async getProfile(): Promise<UserProfile> {\n return sendRequest<UserProfile>('user.getProfile', {})\n },\n }\n ;(context as { user: UserAPI }).user = userApi\n }\n\n // Add chat API if permitted\n if (hasPermission('chat.message.write')) {\n const chatApi: ChatAPI = {\n async appendInstruction(message: ChatInstructionMessage): Promise<void> {\n // Extensions must explicitly set message.userId if they want user-scoped messages\n // Use context.userId from the ExecutionContext in tool/action execute\n await sendRequest<void>('chat.appendInstruction', message)\n },\n }\n ;(context as { chat: ChatAPI }).chat = chatApi\n }\n\n // Add storage API if permitted (new collection-based storage)\n if (hasPermission('storage.collections')) {\n ;(context as { storage: StorageAPI }).storage = buildExtensionStorageAPI(sendRequest)\n }\n\n // Add secrets API if permitted\n if (hasPermission('secrets.manage')) {\n ;(context as { secrets: SecretsAPI }).secrets = buildExtensionSecretsAPI(sendRequest)\n }\n\n // Add background workers API if permitted\n if (hasPermission('background.workers')) {\n // Initialize the background task manager if not already done\n if (!backgroundTaskManager) {\n backgroundTaskManager = new WorkerBackgroundTaskManager({\n extensionId,\n extensionVersion,\n storagePath,\n sendTaskRegistered: (taskId, name, userId, restartPolicy, payload) => {\n postMessage({\n type: 'background-task-registered',\n payload: {\n taskId,\n name,\n userId,\n restartPolicy,\n payload,\n },\n })\n },\n sendTaskStatus: (taskId, status, error) => {\n postMessage({\n type: 'background-task-status',\n payload: {\n taskId,\n status,\n error,\n },\n })\n },\n sendHealthReport: (taskId, status, timestamp) => {\n postMessage({\n type: 'background-task-health',\n payload: {\n taskId,\n status,\n timestamp,\n },\n })\n },\n createLogAPI: (taskId) => ({\n debug: (message, data) =>\n postMessage({ type: 'log', payload: { level: 'debug', message: `[${taskId}] ${message}`, data } }),\n info: (message, data) =>\n postMessage({ type: 'log', payload: { level: 'info', message: `[${taskId}] ${message}`, data } }),\n warn: (message, data) =>\n postMessage({ type: 'log', payload: { level: 'warn', message: `[${taskId}] ${message}`, data } }),\n error: (message, data) =>\n postMessage({ type: 'log', payload: { level: 'error', message: `[${taskId}] ${message}`, data } }),\n }),\n createStorageAPI: () => buildExtensionStorageAPI(sendRequest),\n createUserStorageAPI: (userId) => buildUserStorageAPI(sendRequest, userId),\n createSecretsAPI: () => buildExtensionSecretsAPI(sendRequest),\n createUserSecretsAPI: (userId) => buildUserSecretsAPI(sendRequest, userId),\n })\n }\n\n const backgroundWorkersApi: BackgroundWorkersAPI = {\n async start(config: BackgroundTaskConfig, callback: BackgroundTaskCallback): Promise<Disposable> {\n return backgroundTaskManager!.start(config, callback)\n },\n async stop(taskId: string): Promise<void> {\n backgroundTaskManager!.stop(taskId)\n },\n async getStatus(): Promise<BackgroundTaskHealth[]> {\n return backgroundTaskManager!.getStatus()\n },\n }\n ;(context as { backgroundWorkers: BackgroundWorkersAPI }).backgroundWorkers = backgroundWorkersApi\n }\n\n return context\n}\n\n// ============================================================================\n// Initialization\n// ============================================================================\n\n/**\n * Initialize the extension runtime\n * This should be called by the extension's entry point\n */\nexport function initializeExtension(module: ExtensionModule): void {\n extensionModule = module\n\n // Set up message listener using the appropriate message port\n messagePort.onMessage(async (message: HostToWorkerMessage) => {\n try {\n await handleHostMessage(message)\n } catch (error) {\n console.error('Error handling message:', error)\n }\n })\n\n // Signal that we're ready\n postMessage({ type: 'ready' })\n}\n\n// Re-export types for extensions to use\nexport type {\n ExecutionContext,\n ExtensionContext,\n ExtensionModule,\n Disposable,\n AIProvider,\n Tool,\n ToolDefinition,\n ToolResult,\n ToolCall,\n Action,\n ActionResult,\n ModelInfo,\n ChatMessage,\n ChatOptions,\n GetModelsOptions,\n StreamEvent,\n // Storage and secrets\n StorageAPI,\n SecretsAPI,\n Query,\n QueryOptions,\n // Background workers\n BackgroundWorkersAPI,\n BackgroundTaskConfig,\n BackgroundTaskCallback,\n BackgroundTaskContext,\n BackgroundTaskHealth,\n BackgroundRestartPolicy,\n} from './types.js'\n","/**\n * Background Task Manager (Worker-side)\n *\n * Manages background tasks running inside the extension worker.\n * Handles task execution, AbortController management, and health reporting.\n */\n\nimport type {\n BackgroundTaskConfig,\n BackgroundTaskCallback,\n BackgroundTaskContext,\n BackgroundTaskHealth,\n Disposable,\n LogAPI,\n StorageAPI,\n SecretsAPI,\n} from './types.js'\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Internal representation of a registered task\n */\ninterface RegisteredTask {\n config: BackgroundTaskConfig\n callback: BackgroundTaskCallback\n abortController: AbortController | null\n status: 'pending' | 'running' | 'stopped' | 'failed'\n lastHealthStatus?: string\n lastHealthTime?: string\n error?: string\n}\n\n/**\n * Options for the WorkerBackgroundTaskManager\n */\nexport interface WorkerBackgroundTaskManagerOptions {\n extensionId: string\n extensionVersion: string\n storagePath: string\n /** Send a message to the host */\n sendTaskRegistered: (\n taskId: string,\n name: string,\n userId: string,\n restartPolicy: BackgroundTaskConfig['restartPolicy'],\n payload?: Record<string, unknown>\n ) => void\n /** Send status update to host */\n sendTaskStatus: (taskId: string, status: 'running' | 'stopped' | 'failed', error?: string) => void\n /** Send health report to host */\n sendHealthReport: (taskId: string, status: string, timestamp: string) => void\n /** Create a log API for a task */\n createLogAPI: (taskId: string) => LogAPI\n /** Create extension-scoped storage API */\n createStorageAPI: () => StorageAPI\n /** Create user-scoped storage API */\n createUserStorageAPI: (userId: string) => StorageAPI\n /** Create extension-scoped secrets API */\n createSecretsAPI: () => SecretsAPI\n /** Create user-scoped secrets API */\n createUserSecretsAPI: (userId: string) => SecretsAPI\n}\n\n// ============================================================================\n// WorkerBackgroundTaskManager\n// ============================================================================\n\n/**\n * Manages background tasks within the extension worker.\n */\nexport class WorkerBackgroundTaskManager {\n private readonly tasks = new Map<string, RegisteredTask>()\n private readonly options: WorkerBackgroundTaskManagerOptions\n\n constructor(options: WorkerBackgroundTaskManagerOptions) {\n this.options = options\n }\n\n /**\n * Register and start a background task.\n * @returns A disposable that stops the task when disposed\n */\n async start(config: BackgroundTaskConfig, callback: BackgroundTaskCallback): Promise<Disposable> {\n const { id: taskId } = config\n\n if (this.tasks.has(taskId)) {\n throw new Error(`Background task with id '${taskId}' is already registered`)\n }\n\n const task: RegisteredTask = {\n config,\n callback,\n abortController: null,\n status: 'pending',\n }\n\n this.tasks.set(taskId, task)\n\n // Notify host about the registration\n this.options.sendTaskRegistered(\n taskId,\n config.name,\n config.userId,\n config.restartPolicy,\n config.payload\n )\n\n // Return a disposable that stops the task\n // Task removal should be coordinated with the host to avoid race conditions\n return {\n dispose: () => {\n this.stop(taskId)\n // Don't immediately delete - let the task finish aborting\n // The task will be cleaned up when the extension is deactivated\n },\n }\n }\n\n /**\n * Stop a running task.\n */\n stop(taskId: string): void {\n const task = this.tasks.get(taskId)\n if (!task) {\n return\n }\n\n // Abort the task if it's running\n if (task.abortController) {\n task.abortController.abort()\n task.abortController = null\n }\n\n task.status = 'stopped'\n\n // Notify host that the task has been stopped\n this.options.sendTaskStatus(taskId, 'stopped')\n }\n\n /**\n * Handle start message from host.\n * This is called when the host tells us to actually run the task.\n */\n async handleStart(taskId: string): Promise<void> {\n const task = this.tasks.get(taskId)\n if (!task) {\n return\n }\n\n // If there's already an execution running, abort it first\n if (task.abortController) {\n task.abortController.abort()\n task.abortController = null\n }\n\n // Create new AbortController for this run\n task.abortController = new AbortController()\n task.status = 'running'\n task.error = undefined\n\n // Build the task context\n const context = this.buildTaskContext(task)\n\n // Notify host that we're running\n this.options.sendTaskStatus(taskId, 'running')\n\n try {\n // Execute the callback\n await task.callback(context)\n\n // Task completed normally (or was aborted)\n if (task.abortController?.signal.aborted) {\n task.status = 'stopped'\n this.options.sendTaskStatus(taskId, 'stopped')\n } else {\n // Task finished without being aborted - treat as stopped\n task.status = 'stopped'\n this.options.sendTaskStatus(taskId, 'stopped')\n }\n } catch (error) {\n // Task failed with an error\n const errorMessage = error instanceof Error ? error.message : String(error)\n task.status = 'failed'\n task.error = errorMessage\n this.options.sendTaskStatus(taskId, 'failed', errorMessage)\n } finally {\n task.abortController = null\n }\n }\n\n /**\n * Handle stop message from host.\n */\n handleStop(taskId: string): void {\n this.stop(taskId)\n }\n\n /**\n * Build the execution context for a task.\n */\n private buildTaskContext(task: RegisteredTask): BackgroundTaskContext {\n const { config, abortController } = task\n const signal = abortController!.signal\n\n const log = this.options.createLogAPI(config.id)\n\n // Create storage and secrets APIs\n const storage = this.options.createStorageAPI()\n const userStorage = config.userId\n ? this.options.createUserStorageAPI(config.userId)\n : storage\n const secrets = this.options.createSecretsAPI()\n const userSecrets = config.userId\n ? this.options.createUserSecretsAPI(config.userId)\n : secrets\n\n const context: BackgroundTaskContext = {\n userId: config.userId,\n extension: {\n id: this.options.extensionId,\n version: this.options.extensionVersion,\n storagePath: this.options.storagePath,\n },\n storage,\n userStorage,\n secrets,\n userSecrets,\n signal,\n reportHealth: (status: string) => {\n const timestamp = new Date().toISOString()\n task.lastHealthStatus = status\n task.lastHealthTime = timestamp\n this.options.sendHealthReport(config.id, status, timestamp)\n },\n log,\n }\n\n return context\n }\n\n /**\n * Get the status of all tasks.\n */\n getStatus(): BackgroundTaskHealth[] {\n const result: BackgroundTaskHealth[] = []\n\n for (const task of this.tasks.values()) {\n result.push({\n taskId: task.config.id,\n name: task.config.name,\n userId: task.config.userId,\n status: task.status,\n restartCount: 0, // Worker doesn't track restarts, host does\n lastHealthStatus: task.lastHealthStatus,\n lastHealthTime: task.lastHealthTime,\n error: task.error,\n })\n }\n\n return result\n }\n\n /**\n * Check if a task exists.\n */\n hasTask(taskId: string): boolean {\n return this.tasks.has(taskId)\n }\n\n /**\n * Clean up all tasks.\n * Called during extension deactivation.\n */\n dispose(): void {\n for (const task of this.tasks.values()) {\n if (task.abortController) {\n task.abortController.abort()\n }\n }\n this.tasks.clear()\n }\n}\n","/**\n * Message protocol between Extension Host and Extension Workers\n */\n\nimport type {\n ChatMessage,\n ChatOptions,\n GetModelsOptions,\n StreamEvent,\n ToolResult,\n ActionResult,\n ModelInfo,\n SchedulerFirePayload,\n} from './types.js'\n\n// ============================================================================\n// Host → Worker Messages\n// ============================================================================\n\nexport type HostToWorkerMessage =\n | ActivateMessage\n | DeactivateMessage\n | SettingsChangedMessage\n | SchedulerFireMessage\n | ProviderChatRequestMessage\n | ProviderModelsRequestMessage\n | ToolExecuteRequestMessage\n | ActionExecuteRequestMessage\n | ResponseMessage\n | StreamingFetchChunkMessage\n | BackgroundTaskStartMessage\n | BackgroundTaskStopMessage\n\nexport interface ActivateMessage {\n type: 'activate'\n id: string\n payload: {\n extensionId: string\n extensionVersion: string\n storagePath: string\n permissions: string[]\n settings: Record<string, unknown>\n }\n}\n\nexport interface DeactivateMessage {\n type: 'deactivate'\n id: string\n}\n\nexport interface SettingsChangedMessage {\n type: 'settings-changed'\n id: string\n payload: {\n key: string\n value: unknown\n }\n}\n\nexport interface SchedulerFireMessage {\n type: 'scheduler-fire'\n id: string\n payload: SchedulerFirePayload\n}\n\nexport interface ProviderChatRequestMessage {\n type: 'provider-chat-request'\n id: string\n payload: {\n providerId: string\n messages: ChatMessage[]\n options: ChatOptions\n }\n}\n\nexport interface ProviderModelsRequestMessage {\n type: 'provider-models-request'\n id: string\n payload: {\n providerId: string\n options?: GetModelsOptions\n }\n}\n\nexport interface ToolExecuteRequestMessage {\n type: 'tool-execute-request'\n id: string\n payload: {\n toolId: string\n params: Record<string, unknown>\n /** User ID if the tool is executed in a user context */\n userId?: string\n }\n}\n\nexport interface ActionExecuteRequestMessage {\n type: 'action-execute-request'\n id: string\n payload: {\n actionId: string\n params: Record<string, unknown>\n /** User ID if the action is executed in a user context */\n userId?: string\n }\n}\n\nexport interface ResponseMessage {\n type: 'response'\n id: string\n payload: {\n requestId: string\n success: boolean\n data?: unknown\n error?: string\n }\n}\n\n/**\n * Message sent from host to worker with streaming fetch data chunks.\n * Used for streaming network responses (e.g., NDJSON streams from Ollama).\n */\nexport interface StreamingFetchChunkMessage {\n type: 'streaming-fetch-chunk'\n id: string\n payload: {\n requestId: string\n chunk: string\n done: boolean\n error?: string\n }\n}\n\n/**\n * Message sent from host to worker to start a registered background task.\n */\nexport interface BackgroundTaskStartMessage {\n type: 'background-task-start'\n id: string\n payload: {\n taskId: string\n }\n}\n\n/**\n * Message sent from host to worker to stop a running background task.\n */\nexport interface BackgroundTaskStopMessage {\n type: 'background-task-stop'\n id: string\n payload: {\n taskId: string\n }\n}\n\n// ============================================================================\n// Worker → Host Messages\n// ============================================================================\n\nexport type WorkerToHostMessage =\n | ReadyMessage\n | RequestMessage\n | ProviderRegisteredMessage\n | ToolRegisteredMessage\n | ActionRegisteredMessage\n | StreamEventMessage\n | LogMessage\n | ProviderModelsResponseMessage\n | ToolExecuteResponseMessage\n | ActionExecuteResponseMessage\n | StreamingFetchAckMessage\n | BackgroundTaskRegisteredMessage\n | BackgroundTaskStatusMessage\n | BackgroundTaskHealthMessage\n\nexport interface ReadyMessage {\n type: 'ready'\n}\n\n/**\n * Message sent from worker to host to acknowledge receipt of a streaming fetch chunk.\n * This enables backpressure control to prevent unbounded memory growth.\n */\nexport interface StreamingFetchAckMessage {\n type: 'streaming-fetch-ack'\n payload: {\n requestId: string\n }\n}\n\nexport interface RequestMessage {\n type: 'request'\n id: string\n method: RequestMethod\n payload: unknown\n}\n\nexport type RequestMethod =\n | 'network.fetch'\n | 'network.fetch-stream'\n | 'settings.getAll'\n | 'settings.get'\n | 'settings.set'\n | 'user.getProfile'\n | 'events.emit'\n | 'scheduler.schedule'\n | 'scheduler.cancel'\n | 'scheduler.reportFireResult'\n | 'chat.appendInstruction'\n | 'database.execute'\n // Simple key-value storage methods\n | 'storage.set'\n | 'storage.keys'\n | 'storage.setForUser'\n | 'storage.keysForUser'\n // Collection-based storage methods\n | 'storage.put'\n | 'storage.get'\n | 'storage.delete'\n | 'storage.find'\n | 'storage.findOne'\n | 'storage.count'\n | 'storage.putMany'\n | 'storage.deleteMany'\n | 'storage.dropCollection'\n | 'storage.listCollections'\n | 'storage.putForUser'\n | 'storage.getForUser'\n | 'storage.deleteForUser'\n | 'storage.findForUser'\n | 'storage.findOneForUser'\n | 'storage.countForUser'\n | 'storage.putManyForUser'\n | 'storage.deleteManyForUser'\n | 'storage.dropCollectionForUser'\n | 'storage.listCollectionsForUser'\n // Secrets methods\n | 'secrets.set'\n | 'secrets.get'\n | 'secrets.delete'\n | 'secrets.list'\n | 'secrets.setForUser'\n | 'secrets.getForUser'\n | 'secrets.deleteForUser'\n | 'secrets.listForUser'\n // Tools cross-extension methods\n | 'tools.list'\n | 'tools.execute'\n\nexport interface ProviderRegisteredMessage {\n type: 'provider-registered'\n payload: {\n id: string\n name: string\n }\n}\n\nexport interface ToolRegisteredMessage {\n type: 'tool-registered'\n payload: {\n id: string\n name: string\n description: string\n parameters?: Record<string, unknown>\n }\n}\n\nexport interface ActionRegisteredMessage {\n type: 'action-registered'\n payload: {\n id: string\n }\n}\n\nexport interface StreamEventMessage {\n type: 'stream-event'\n payload: {\n requestId: string\n event: StreamEvent\n }\n}\n\nexport interface ProviderModelsResponseMessage {\n type: 'provider-models-response'\n payload: {\n requestId: string\n models: ModelInfo[]\n error?: string\n }\n}\n\nexport interface ToolExecuteResponseMessage {\n type: 'tool-execute-response'\n payload: {\n requestId: string\n result: ToolResult\n error?: string\n }\n}\n\nexport interface ActionExecuteResponseMessage {\n type: 'action-execute-response'\n payload: {\n requestId: string\n result: ActionResult\n error?: string\n }\n}\n\nexport interface LogMessage {\n type: 'log'\n payload: {\n level: 'debug' | 'info' | 'warn' | 'error'\n message: string\n data?: Record<string, unknown>\n }\n}\n\n/**\n * Message sent from worker to host when a background task is registered.\n */\nexport interface BackgroundTaskRegisteredMessage {\n type: 'background-task-registered'\n payload: {\n taskId: string\n name: string\n userId: string\n restartPolicy: {\n type: 'always' | 'on-failure' | 'never'\n maxRestarts?: number\n initialDelayMs?: number\n maxDelayMs?: number\n backoffMultiplier?: number\n }\n payload?: Record<string, unknown>\n }\n}\n\n/**\n * Message sent from worker to host with background task status updates.\n */\nexport interface BackgroundTaskStatusMessage {\n type: 'background-task-status'\n payload: {\n taskId: string\n status: 'running' | 'stopped' | 'failed'\n error?: string\n }\n}\n\n/**\n * Message sent from worker to host with background task health reports.\n */\nexport interface BackgroundTaskHealthMessage {\n type: 'background-task-health'\n payload: {\n taskId: string\n status: string\n timestamp: string\n }\n}\n\n// ============================================================================\n// Utility Types\n// ============================================================================\n\nexport interface PendingRequest<T = unknown> {\n resolve: (value: T) => void\n reject: (error: Error) => void\n timeout: ReturnType<typeof setTimeout>\n}\n\n/**\n * Generate a unique message ID\n */\nexport function generateMessageId(): string {\n return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`\n}\n","/**\n * Storage API builders for extension and user-scoped storage.\n */\n\nimport type { StorageAPI, Query, QueryOptions } from '../types.js'\nimport type { RequestMessage } from '../messages.js'\n\ntype SendRequest = <T>(method: RequestMessage['method'], payload: unknown) => Promise<T>\n\n/**\n * Create a storage API that delegates to the host via request messages.\n * Used for both extension-scoped and user-scoped storage by varying the method prefix.\n */\nfunction buildStorageAPI(\n sendRequest: SendRequest,\n methodSuffix: '' | 'ForUser',\n userId?: string\n): StorageAPI {\n const extraPayload = userId ? { userId } : {}\n\n return {\n async put<T extends object>(collection: string, id: string, data: T): Promise<void> {\n return sendRequest<void>(`storage.put${methodSuffix}`, { ...extraPayload, collection, id, data })\n },\n async get<T>(collection: string, id: string): Promise<T | undefined> {\n return sendRequest<T | undefined>(`storage.get${methodSuffix}`, { ...extraPayload, collection, id })\n },\n async delete(collection: string, id: string): Promise<boolean> {\n return sendRequest<boolean>(`storage.delete${methodSuffix}`, { ...extraPayload, collection, id })\n },\n async find<T>(collection: string, query?: Query, options?: QueryOptions): Promise<T[]> {\n return sendRequest<T[]>(`storage.find${methodSuffix}`, { ...extraPayload, collection, query, options })\n },\n async findOne<T>(collection: string, query: Query): Promise<T | undefined> {\n return sendRequest<T | undefined>(`storage.findOne${methodSuffix}`, { ...extraPayload, collection, query })\n },\n async count(collection: string, query?: Query): Promise<number> {\n return sendRequest<number>(`storage.count${methodSuffix}`, { ...extraPayload, collection, query })\n },\n async putMany<T extends object>(collection: string, docs: Array<{ id: string; data: T }>): Promise<void> {\n return sendRequest<void>(`storage.putMany${methodSuffix}`, { ...extraPayload, collection, docs })\n },\n async deleteMany(collection: string, query: Query): Promise<number> {\n return sendRequest<number>(`storage.deleteMany${methodSuffix}`, { ...extraPayload, collection, query })\n },\n async dropCollection(collection: string): Promise<void> {\n return sendRequest<void>(`storage.dropCollection${methodSuffix}`, { ...extraPayload, collection })\n },\n async listCollections(): Promise<string[]> {\n return sendRequest<string[]>(`storage.listCollections${methodSuffix}`, { ...extraPayload })\n },\n }\n}\n\n/**\n * Build extension-scoped storage API (shared across all users).\n */\nexport function buildExtensionStorageAPI(sendRequest: SendRequest): StorageAPI {\n return buildStorageAPI(sendRequest, '')\n}\n\n/**\n * Build user-scoped storage API (isolated per user).\n */\nexport function buildUserStorageAPI(sendRequest: SendRequest, userId: string): StorageAPI {\n return buildStorageAPI(sendRequest, 'ForUser', userId)\n}\n","/**\n * Secrets API builders for extension and user-scoped secrets.\n */\n\nimport type { SecretsAPI } from '../types.js'\nimport type { RequestMessage } from '../messages.js'\n\ntype SendRequest = <T>(method: RequestMessage['method'], payload: unknown) => Promise<T>\n\n/**\n * Build extension-scoped secrets API (shared across all users).\n */\nexport function buildExtensionSecretsAPI(sendRequest: SendRequest): SecretsAPI {\n return {\n async set(key: string, value: string): Promise<void> {\n return sendRequest<void>('secrets.set', { key, value })\n },\n async get(key: string): Promise<string | undefined> {\n return sendRequest<string | undefined>('secrets.get', { key })\n },\n async delete(key: string): Promise<boolean> {\n return sendRequest<boolean>('secrets.delete', { key })\n },\n async list(): Promise<string[]> {\n return sendRequest<string[]>('secrets.list', {})\n },\n }\n}\n\n/**\n * Build user-scoped secrets API (isolated per user).\n */\nexport function buildUserSecretsAPI(sendRequest: SendRequest, userId: string): SecretsAPI {\n return {\n async set(key: string, value: string): Promise<void> {\n return sendRequest<void>('secrets.setForUser', { userId, key, value })\n },\n async get(key: string): Promise<string | undefined> {\n return sendRequest<string | undefined>('secrets.getForUser', { userId, key })\n },\n async delete(key: string): Promise<boolean> {\n return sendRequest<boolean>('secrets.deleteForUser', { userId, key })\n },\n async list(): Promise<string[]> {\n return sendRequest<string[]>('secrets.listForUser', { userId })\n },\n }\n}\n","/**\n * Shared execution context builder for tool, action, and scheduler operations.\n */\n\nimport type { ExecutionContext, ExtensionContext } from '../types.js'\nimport type { RequestMessage } from '../messages.js'\nimport { buildExtensionStorageAPI, buildUserStorageAPI } from './storageApi.js'\nimport { buildExtensionSecretsAPI, buildUserSecretsAPI } from './secretsApi.js'\n\ntype SendRequest = <T>(method: RequestMessage['method'], payload: unknown) => Promise<T>\n\n/**\n * Create a request-scoped ExecutionContext with storage and secrets.\n * Used by scheduler fire, tool execution, and action execution handlers.\n */\nexport function createExecutionContext(\n sendRequest: SendRequest,\n extensionContext: ExtensionContext,\n userId?: string\n): ExecutionContext {\n return {\n userId,\n extension: {\n id: extensionContext.extension.id,\n version: extensionContext.extension.version,\n storagePath: extensionContext.extension.storagePath,\n },\n storage: buildExtensionStorageAPI(sendRequest),\n userStorage: userId\n ? buildUserStorageAPI(sendRequest, userId)\n : buildExtensionStorageAPI(sendRequest),\n secrets: buildExtensionSecretsAPI(sendRequest),\n userSecrets: userId\n ? buildUserSecretsAPI(sendRequest, userId)\n : buildExtensionSecretsAPI(sendRequest),\n }\n}\n"],"mappings":"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","names":["sendRequest","sendRequest","sendRequest","extensionContext","module"]}
1
+ {"version":3,"sources":["../src/runtime.ts","../src/background.ts","../src/messages.ts","../src/runtime/storageApi.ts","../src/runtime/secretsApi.ts","../src/runtime/executionContext.ts"],"sourcesContent":["/**\n * Extension Runtime - Runs inside the worker\n *\n * This module handles communication with the Extension Host and provides\n * the ExtensionContext to the extension's activate function.\n */\n\nimport type {\n ExecutionContext,\n ExtensionContext,\n ExtensionModule,\n Disposable,\n NetworkAPI,\n SettingsAPI,\n ProvidersAPI,\n ToolsAPI,\n ActionsAPI,\n EventsAPI,\n SchedulerAPI,\n SchedulerJobRequest,\n SchedulerFirePayload,\n UserAPI,\n UserProfile,\n ChatAPI,\n ChatInstructionMessage,\n StorageAPI,\n SecretsAPI,\n LogAPI,\n AIProvider,\n Tool,\n ToolDefinition,\n ToolResult,\n Action,\n ChatMessage,\n ChatOptions,\n GetModelsOptions,\n BackgroundWorkersAPI,\n BackgroundTaskConfig,\n BackgroundTaskCallback,\n BackgroundTaskHealth,\n} from './types.js'\n\nimport { WorkerBackgroundTaskManager } from './background.js'\n\nimport type {\n HostToWorkerMessage,\n WorkerToHostMessage,\n RequestMessage,\n PendingRequest,\n} from './messages.js'\n\nimport { generateMessageId } from './messages.js'\n\nimport {\n buildExtensionStorageAPI,\n buildUserStorageAPI,\n buildExtensionSecretsAPI,\n buildUserSecretsAPI,\n createExecutionContext,\n} from './runtime/index.js'\n\n// ============================================================================\n// Environment Detection and Message Port\n// ============================================================================\n\n/**\n * Detect if we're in Node.js Worker Thread or Web Worker\n * and get the appropriate message port\n */\ninterface MessagePort {\n postMessage(message: WorkerToHostMessage): void\n onMessage(handler: (message: HostToWorkerMessage) => void): void\n}\n\nfunction getMessagePort(): MessagePort {\n // Check if we're in Node.js Worker Thread\n if (typeof process !== 'undefined' && process.versions?.node) {\n // Node.js Worker Thread - import parentPort dynamically\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { parentPort } = require('node:worker_threads')\n return {\n postMessage: (message) => parentPort?.postMessage(message),\n onMessage: (handler) => parentPort?.on('message', handler),\n }\n }\n\n // Web Worker - use self\n return {\n postMessage: (message) => self.postMessage(message),\n onMessage: (handler) => {\n self.addEventListener('message', (event: MessageEvent<HostToWorkerMessage>) => {\n handler(event.data)\n })\n },\n }\n}\n\nconst messagePort = getMessagePort()\n\n// ============================================================================\n// Global State\n// ============================================================================\n\nlet extensionModule: ExtensionModule | null = null\nlet extensionDisposable: Disposable | null = null\nlet extensionContext: ExtensionContext | null = null\nlet backgroundTaskManager: WorkerBackgroundTaskManager | null = null\n\nconst pendingRequests = new Map<string, PendingRequest>()\nconst registeredProviders = new Map<string, AIProvider>()\nconst registeredTools = new Map<string, Tool>()\nconst registeredActions = new Map<string, Action>()\nconst settingsCallbacks: Array<(key: string, value: unknown) => void> = []\nconst schedulerCallbacks: Array<(payload: SchedulerFirePayload, context: ExecutionContext) => void | Promise<void>> = []\n\n/**\n * Tracking for streaming fetch requests.\n * Each request stores incoming chunks and signals when new data arrives.\n */\ninterface StreamingFetchRequest {\n chunks: string[]\n done: boolean\n error?: string\n resolve?: () => void\n}\nconst streamingFetchRequests = new Map<string, StreamingFetchRequest>()\n\nconst REQUEST_TIMEOUT = 30000 // 30 seconds\n\n// ============================================================================\n// Message Handling\n// ============================================================================\n\n/**\n * Send a message to the host\n */\nfunction postMessage(message: WorkerToHostMessage): void {\n messagePort.postMessage(message)\n}\n\n/**\n * Send a request to the host and wait for response\n */\nasync function sendRequest<T>(method: RequestMessage['method'], payload: unknown): Promise<T> {\n const id = generateMessageId()\n\n return new Promise<T>((resolve, reject) => {\n const timeout = setTimeout(() => {\n pendingRequests.delete(id)\n reject(new Error(`Request ${method} timed out`))\n }, REQUEST_TIMEOUT)\n\n pendingRequests.set(id, { resolve: resolve as (value: unknown) => void, reject, timeout })\n\n postMessage({\n type: 'request',\n id,\n method,\n payload,\n })\n })\n}\n\n/**\n * Handle messages from the host\n */\nasync function handleHostMessage(message: HostToWorkerMessage): Promise<void> {\n switch (message.type) {\n case 'activate':\n await handleActivate(message.payload)\n break\n\n case 'deactivate':\n await handleDeactivate()\n break\n\n case 'settings-changed':\n handleSettingsChanged(message.payload.key, message.payload.value)\n break\n\n case 'scheduler-fire':\n await handleSchedulerFire(message.payload)\n break\n\n case 'provider-chat-request':\n await handleProviderChatRequest(message.id, message.payload)\n break\n\n case 'provider-models-request':\n await handleProviderModelsRequest(message.id, message.payload)\n break\n\n case 'tool-execute-request':\n await handleToolExecuteRequest(message.id, message.payload)\n break\n\n case 'action-execute-request':\n await handleActionExecuteRequest(message.id, message.payload)\n break\n\n case 'response':\n handleResponse(message.payload)\n break\n\n case 'streaming-fetch-chunk':\n handleStreamingFetchChunk(message.payload)\n break\n\n case 'background-task-start':\n await handleBackgroundTaskStart(message.payload.taskId)\n break\n\n case 'background-task-stop':\n handleBackgroundTaskStop(message.payload.taskId)\n break\n }\n}\n\n/**\n * Handle incoming streaming fetch chunks from the host\n */\nfunction handleStreamingFetchChunk(payload: {\n requestId: string\n chunk: string\n done: boolean\n error?: string\n}): void {\n const request = streamingFetchRequests.get(payload.requestId)\n if (!request) return\n\n if (payload.error) {\n request.error = payload.error\n request.done = true\n } else if (payload.chunk) {\n request.chunks.push(payload.chunk)\n }\n\n if (payload.done) {\n request.done = true\n }\n\n // Signal that new data is available\n if (request.resolve) {\n const resolve = request.resolve\n request.resolve = undefined\n resolve()\n }\n\n // Send acknowledgment for backpressure control\n postMessage({\n type: 'streaming-fetch-ack',\n payload: { requestId: payload.requestId },\n })\n}\n\nfunction handleResponse(payload: { requestId: string; success: boolean; data?: unknown; error?: string }): void {\n const pending = pendingRequests.get(payload.requestId)\n if (!pending) return\n\n clearTimeout(pending.timeout)\n pendingRequests.delete(payload.requestId)\n\n if (payload.success) {\n pending.resolve(payload.data)\n } else {\n pending.reject(new Error(payload.error || 'Unknown error'))\n }\n}\n\n// ============================================================================\n// Activation / Deactivation\n// ============================================================================\n\nasync function handleActivate(payload: {\n extensionId: string\n extensionVersion: string\n storagePath: string\n permissions: string[]\n settings: Record<string, unknown>\n}): Promise<void> {\n const { extensionId, extensionVersion, storagePath, permissions } = payload\n\n // Build the context based on permissions\n extensionContext = buildContext(extensionId, extensionVersion, storagePath, permissions)\n\n // Import and activate the extension\n try {\n // The actual extension code should be bundled and available\n // This is called after the extension code has been loaded into the worker\n if (extensionModule?.activate) {\n const result = await extensionModule.activate(extensionContext)\n if (result && 'dispose' in result) {\n extensionDisposable = result\n }\n }\n } catch (error) {\n extensionContext.log.error('Failed to activate extension', {\n error: error instanceof Error ? error.message : String(error),\n })\n throw error\n }\n}\n\nasync function handleDeactivate(): Promise<void> {\n try {\n if (extensionModule?.deactivate) {\n await extensionModule.deactivate()\n }\n if (extensionDisposable) {\n extensionDisposable.dispose()\n }\n if (backgroundTaskManager) {\n backgroundTaskManager.dispose()\n }\n } catch (error) {\n console.error('Error during deactivation:', error)\n } finally {\n extensionModule = null\n extensionDisposable = null\n extensionContext = null\n backgroundTaskManager = null\n registeredProviders.clear()\n registeredTools.clear()\n registeredActions.clear()\n settingsCallbacks.length = 0\n schedulerCallbacks.length = 0\n }\n}\n\nfunction handleSettingsChanged(key: string, value: unknown): void {\n for (const callback of settingsCallbacks) {\n try {\n callback(key, value)\n } catch (error) {\n console.error('Error in settings change callback:', error)\n }\n }\n}\n\n// Storage and Secrets APIs are now in runtime/storageApi.ts and runtime/secretsApi.ts\n// ExecutionContext builder is in runtime/executionContext.ts\n\nasync function handleSchedulerFire(payload: SchedulerFirePayload): Promise<void> {\n const execContext = createExecutionContext(sendRequest, extensionContext!, payload.userId)\n\n // Run callbacks concurrently to avoid blocking\n const results = await Promise.allSettled(\n schedulerCallbacks.map((callback) => Promise.resolve(callback(payload, execContext))),\n )\n\n // Log any errors\n results.forEach((result, index) => {\n if (result.status === 'rejected') {\n console.error(`Error in scheduler callback ${index}:`, result.reason)\n }\n })\n\n // Report result back to host\n const failed = results.find((r) => r.status === 'rejected') as PromiseRejectedResult | undefined\n try {\n await sendRequest<void>('scheduler.reportFireResult', {\n jobId: payload.id,\n success: !failed,\n error: failed ? String(failed.reason) : undefined,\n })\n } catch {\n // Best effort — don't crash if reporting fails\n }\n}\n\n// ============================================================================\n// Background Task Handlers\n// ============================================================================\n\nasync function handleBackgroundTaskStart(taskId: string): Promise<void> {\n if (!backgroundTaskManager) {\n console.error('Background task manager not initialized')\n return\n }\n await backgroundTaskManager.handleStart(taskId)\n}\n\nfunction handleBackgroundTaskStop(taskId: string): void {\n if (!backgroundTaskManager) {\n console.error('Background task manager not initialized')\n return\n }\n backgroundTaskManager.handleStop(taskId)\n}\n\n// ============================================================================\n// Provider / Tool Requests\n// ============================================================================\n\nasync function handleProviderChatRequest(\n requestId: string,\n payload: { providerId: string; messages: ChatMessage[]; options: ChatOptions }\n): Promise<void> {\n const provider = registeredProviders.get(payload.providerId)\n if (!provider) {\n postMessage({\n type: 'request',\n id: generateMessageId(),\n method: 'network.fetch', // Dummy, we need a proper error response\n payload: { error: `Provider ${payload.providerId} not found` },\n })\n return\n }\n\n try {\n const generator = provider.chat(payload.messages, payload.options)\n let sawDone = false\n let sawError = false\n\n for await (const event of generator) {\n if (event.type === 'done') {\n sawDone = true\n } else if (event.type === 'error') {\n sawError = true\n }\n postMessage({\n type: 'stream-event',\n payload: { requestId, event },\n })\n }\n\n if (!sawDone && !sawError) {\n postMessage({\n type: 'stream-event',\n payload: {\n requestId,\n event: { type: 'done' },\n },\n })\n }\n } catch (error) {\n postMessage({\n type: 'stream-event',\n payload: {\n requestId,\n event: {\n type: 'error',\n message: error instanceof Error ? error.message : String(error),\n },\n },\n })\n }\n}\n\nasync function handleProviderModelsRequest(\n requestId: string,\n payload: { providerId: string; options?: GetModelsOptions }\n): Promise<void> {\n const provider = registeredProviders.get(payload.providerId)\n if (!provider) {\n // Send error response\n postMessage({\n type: 'provider-models-response',\n payload: {\n requestId,\n models: [],\n error: `Provider ${payload.providerId} not found`,\n },\n })\n return\n }\n\n try {\n // Pass options to getModels so provider can use settings (e.g., URL for Ollama)\n const models = await provider.getModels(payload.options)\n // Send response with models\n postMessage({\n type: 'provider-models-response',\n payload: {\n requestId,\n models,\n },\n })\n } catch (error) {\n postMessage({\n type: 'provider-models-response',\n payload: {\n requestId,\n models: [],\n error: error instanceof Error ? error.message : String(error),\n },\n })\n }\n}\n\nasync function handleToolExecuteRequest(\n requestId: string,\n payload: { toolId: string; params: Record<string, unknown>; userId?: string }\n): Promise<void> {\n const tool = registeredTools.get(payload.toolId)\n if (!tool) {\n // Send error response\n postMessage({\n type: 'tool-execute-response',\n payload: {\n requestId,\n result: { success: false, error: `Tool ${payload.toolId} not found` },\n error: `Tool ${payload.toolId} not found`,\n },\n })\n return\n }\n\n try {\n const execContext = createExecutionContext(sendRequest, extensionContext!, payload.userId)\n\n const result = await tool.execute(payload.params, execContext)\n\n // Send response with result\n postMessage({\n type: 'tool-execute-response',\n payload: {\n requestId,\n result,\n },\n })\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error)\n postMessage({\n type: 'tool-execute-response',\n payload: {\n requestId,\n result: { success: false, error: errorMessage },\n error: errorMessage,\n },\n })\n }\n}\n\nasync function handleActionExecuteRequest(\n requestId: string,\n payload: { actionId: string; params: Record<string, unknown>; userId?: string }\n): Promise<void> {\n const action = registeredActions.get(payload.actionId)\n if (!action) {\n postMessage({\n type: 'action-execute-response',\n payload: {\n requestId,\n result: { success: false, error: `Action ${payload.actionId} not found` },\n error: `Action ${payload.actionId} not found`,\n },\n })\n return\n }\n\n try {\n const execContext = createExecutionContext(sendRequest, extensionContext!, payload.userId)\n\n const result = await action.execute(payload.params, execContext)\n\n postMessage({\n type: 'action-execute-response',\n payload: {\n requestId,\n result,\n },\n })\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error)\n postMessage({\n type: 'action-execute-response',\n payload: {\n requestId,\n result: { success: false, error: errorMessage },\n error: errorMessage,\n },\n })\n }\n}\n\n// ============================================================================\n// Context Building\n// ============================================================================\n\nfunction buildContext(\n extensionId: string,\n extensionVersion: string,\n storagePath: string,\n permissions: string[]\n): ExtensionContext {\n const hasPermission = (perm: string): boolean => {\n return permissions.some((p) => {\n if (p === perm) return true\n if (p.endsWith(':*') && perm.startsWith(p.slice(0, -1))) return true\n return false\n })\n }\n\n const log: LogAPI = {\n debug: (message, data) => postMessage({ type: 'log', payload: { level: 'debug', message, data } }),\n info: (message, data) => postMessage({ type: 'log', payload: { level: 'info', message, data } }),\n warn: (message, data) => postMessage({ type: 'log', payload: { level: 'warn', message, data } }),\n error: (message, data) => postMessage({ type: 'log', payload: { level: 'error', message, data } }),\n }\n\n const context: ExtensionContext = {\n extension: {\n id: extensionId,\n version: extensionVersion,\n storagePath,\n },\n log,\n }\n\n // Add network API if permitted\n if (permissions.some((p) => p.startsWith('network:'))) {\n const networkApi: NetworkAPI = {\n async fetch(url: string, options?: RequestInit): Promise<Response> {\n const result = await sendRequest<{ status: number; statusText: string; headers: Record<string, string>; body: string }>('network.fetch', { url, options })\n return new Response(result.body, {\n status: result.status,\n statusText: result.statusText,\n headers: result.headers,\n })\n },\n\n async *fetchStream(url: string, options?: RequestInit): AsyncGenerator<string, void, unknown> {\n const requestId = generateMessageId()\n\n // Set up streaming request tracking\n const request: StreamingFetchRequest = {\n chunks: [],\n done: false,\n }\n streamingFetchRequests.set(requestId, request)\n\n // Send the streaming fetch request to the host\n postMessage({\n type: 'request',\n id: requestId,\n method: 'network.fetch-stream',\n payload: { url, options, requestId },\n })\n\n try {\n // Yield chunks as they arrive\n while (!request.done) {\n // Wait for new data\n await new Promise<void>((resolve) => {\n const resolver = () => {\n // Clear the stored resolver before resolving to avoid\n // stale callbacks being invoked for a new wait iteration.\n if (request.resolve === resolver) {\n request.resolve = undefined\n }\n resolve()\n }\n\n request.resolve = resolver\n\n // Check if we already have data or completion\n if (request.chunks.length > 0 || request.done) {\n resolver()\n }\n })\n\n // Check for errors first, before yielding any chunks\n if (request.error) {\n throw new Error(request.error)\n }\n\n // Yield all available chunks\n while (request.chunks.length > 0) {\n yield request.chunks.shift()!\n }\n }\n } finally {\n streamingFetchRequests.delete(requestId)\n }\n },\n }\n ;(context as { network: NetworkAPI }).network = networkApi\n }\n\n // Add settings API if permitted\n if (hasPermission('settings.register')) {\n const settingsApi: SettingsAPI = {\n async getAll<T extends Record<string, unknown>>(): Promise<T> {\n return sendRequest<T>('settings.getAll', {})\n },\n async get<T>(key: string): Promise<T | undefined> {\n return sendRequest<T | undefined>('settings.get', { key })\n },\n async set(key: string, value: unknown): Promise<void> {\n return sendRequest<void>('settings.set', { key, value })\n },\n onChange(callback: (key: string, value: unknown) => void): Disposable {\n settingsCallbacks.push(callback)\n return {\n dispose: () => {\n const index = settingsCallbacks.indexOf(callback)\n if (index >= 0) settingsCallbacks.splice(index, 1)\n },\n }\n },\n }\n ;(context as { settings: SettingsAPI }).settings = settingsApi\n }\n\n // Add providers API if permitted\n if (hasPermission('provider.register')) {\n const providersApi: ProvidersAPI = {\n register(provider: AIProvider): Disposable {\n registeredProviders.set(provider.id, provider)\n postMessage({\n type: 'provider-registered',\n payload: { id: provider.id, name: provider.name },\n })\n return {\n dispose: () => {\n registeredProviders.delete(provider.id)\n },\n }\n },\n }\n ;(context as { providers: ProvidersAPI }).providers = providersApi\n }\n\n // Add tools API if ANY tools permission is present\n const hasAnyToolsPermission = hasPermission('tools.register') || hasPermission('tools.list') || hasPermission('tools.execute')\n if (hasAnyToolsPermission) {\n const toolsApi: ToolsAPI = {\n register(tool: Tool): Disposable {\n if (!hasPermission('tools.register')) {\n throw new Error('tools.register permission required')\n }\n registeredTools.set(tool.id, tool)\n postMessage({\n type: 'tool-registered',\n payload: {\n id: tool.id,\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n },\n })\n return {\n dispose: () => {\n registeredTools.delete(tool.id)\n },\n }\n },\n async list(): Promise<ToolDefinition[]> {\n if (!hasPermission('tools.list')) {\n throw new Error('tools.list permission required')\n }\n return sendRequest<ToolDefinition[]>('tools.list', {})\n },\n async execute(toolId: string, params: Record<string, unknown>, userId?: string): Promise<ToolResult> {\n if (!hasPermission('tools.execute')) {\n throw new Error('tools.execute permission required')\n }\n return sendRequest<ToolResult>('tools.execute', { toolId, params, userId })\n },\n }\n ;(context as { tools: ToolsAPI }).tools = toolsApi\n }\n\n // Add actions API if permitted\n if (hasPermission('actions.register')) {\n const actionsApi: ActionsAPI = {\n register(action: Action): Disposable {\n registeredActions.set(action.id, action)\n postMessage({\n type: 'action-registered',\n payload: {\n id: action.id,\n },\n })\n return {\n dispose: () => {\n registeredActions.delete(action.id)\n },\n }\n },\n }\n ;(context as { actions: ActionsAPI }).actions = actionsApi\n }\n\n // Add events API if permitted\n if (hasPermission('events.emit')) {\n const eventsApi: EventsAPI = {\n async emit(name: string, payload?: Record<string, unknown>): Promise<void> {\n await sendRequest<void>('events.emit', { name, payload })\n },\n }\n ;(context as { events: EventsAPI }).events = eventsApi\n }\n\n // Add scheduler API if permitted\n if (hasPermission('scheduler.register')) {\n const schedulerApi: SchedulerAPI = {\n async schedule(job: SchedulerJobRequest): Promise<void> {\n // Extensions must explicitly set job.userId if they want user-scoped jobs\n // Use context.userId from the ExecutionContext in tool/action execute\n await sendRequest<void>('scheduler.schedule', { job })\n },\n async cancel(jobId: string): Promise<void> {\n await sendRequest<void>('scheduler.cancel', { jobId })\n },\n onFire(callback: (payload: SchedulerFirePayload, context: ExecutionContext) => void | Promise<void>): Disposable {\n schedulerCallbacks.push(callback)\n return {\n dispose: () => {\n const index = schedulerCallbacks.indexOf(callback)\n if (index >= 0) schedulerCallbacks.splice(index, 1)\n },\n }\n },\n }\n ;(context as { scheduler: SchedulerAPI }).scheduler = schedulerApi\n }\n\n // Add user profile API if permitted\n if (hasPermission('user.profile.read')) {\n const userApi: UserAPI = {\n async getProfile(): Promise<UserProfile> {\n return sendRequest<UserProfile>('user.getProfile', {})\n },\n async listIds(): Promise<string[]> {\n return sendRequest<string[]>('user.listIds', {})\n },\n }\n ;(context as { user: UserAPI }).user = userApi\n }\n\n // Add chat API if permitted\n if (hasPermission('chat.message.write')) {\n const chatApi: ChatAPI = {\n async appendInstruction(message: ChatInstructionMessage): Promise<void> {\n // Extensions must explicitly set message.userId if they want user-scoped messages\n // Use context.userId from the ExecutionContext in tool/action execute\n await sendRequest<void>('chat.appendInstruction', message)\n },\n }\n ;(context as { chat: ChatAPI }).chat = chatApi\n }\n\n // Add storage API if permitted (new collection-based storage)\n if (hasPermission('storage.collections')) {\n ;(context as { storage: StorageAPI }).storage = buildExtensionStorageAPI(sendRequest)\n }\n\n // Add secrets API if permitted\n if (hasPermission('secrets.manage')) {\n ;(context as { secrets: SecretsAPI }).secrets = buildExtensionSecretsAPI(sendRequest)\n }\n\n // Add background workers API if permitted\n if (hasPermission('background.workers')) {\n // Initialize the background task manager if not already done\n if (!backgroundTaskManager) {\n backgroundTaskManager = new WorkerBackgroundTaskManager({\n extensionId,\n extensionVersion,\n storagePath,\n sendTaskRegistered: (taskId, name, userId, restartPolicy, payload) => {\n postMessage({\n type: 'background-task-registered',\n payload: {\n taskId,\n name,\n userId,\n restartPolicy,\n payload,\n },\n })\n },\n sendTaskStatus: (taskId, status, error) => {\n postMessage({\n type: 'background-task-status',\n payload: {\n taskId,\n status,\n error,\n },\n })\n },\n sendHealthReport: (taskId, status, timestamp) => {\n postMessage({\n type: 'background-task-health',\n payload: {\n taskId,\n status,\n timestamp,\n },\n })\n },\n createLogAPI: (taskId) => ({\n debug: (message, data) =>\n postMessage({ type: 'log', payload: { level: 'debug', message: `[${taskId}] ${message}`, data } }),\n info: (message, data) =>\n postMessage({ type: 'log', payload: { level: 'info', message: `[${taskId}] ${message}`, data } }),\n warn: (message, data) =>\n postMessage({ type: 'log', payload: { level: 'warn', message: `[${taskId}] ${message}`, data } }),\n error: (message, data) =>\n postMessage({ type: 'log', payload: { level: 'error', message: `[${taskId}] ${message}`, data } }),\n }),\n createStorageAPI: () => buildExtensionStorageAPI(sendRequest),\n createUserStorageAPI: (userId) => buildUserStorageAPI(sendRequest, userId),\n createSecretsAPI: () => buildExtensionSecretsAPI(sendRequest),\n createUserSecretsAPI: (userId) => buildUserSecretsAPI(sendRequest, userId),\n })\n }\n\n const backgroundWorkersApi: BackgroundWorkersAPI = {\n async start(config: BackgroundTaskConfig, callback: BackgroundTaskCallback): Promise<Disposable> {\n return backgroundTaskManager!.start(config, callback)\n },\n async stop(taskId: string): Promise<void> {\n backgroundTaskManager!.stop(taskId)\n },\n async getStatus(): Promise<BackgroundTaskHealth[]> {\n return backgroundTaskManager!.getStatus()\n },\n }\n ;(context as { backgroundWorkers: BackgroundWorkersAPI }).backgroundWorkers = backgroundWorkersApi\n }\n\n return context\n}\n\n// ============================================================================\n// Initialization\n// ============================================================================\n\n/**\n * Initialize the extension runtime\n * This should be called by the extension's entry point\n */\nexport function initializeExtension(module: ExtensionModule): void {\n extensionModule = module\n\n // Set up message listener using the appropriate message port\n messagePort.onMessage(async (message: HostToWorkerMessage) => {\n try {\n await handleHostMessage(message)\n } catch (error) {\n console.error('Error handling message:', error)\n }\n })\n\n // Signal that we're ready\n postMessage({ type: 'ready' })\n}\n\n// Re-export types for extensions to use\nexport type {\n ExecutionContext,\n ExtensionContext,\n ExtensionModule,\n Disposable,\n AIProvider,\n Tool,\n ToolDefinition,\n ToolResult,\n ToolCall,\n Action,\n ActionResult,\n ModelInfo,\n ChatMessage,\n ChatOptions,\n GetModelsOptions,\n StreamEvent,\n // Storage and secrets\n StorageAPI,\n SecretsAPI,\n Query,\n QueryOptions,\n // Background workers\n BackgroundWorkersAPI,\n BackgroundTaskConfig,\n BackgroundTaskCallback,\n BackgroundTaskContext,\n BackgroundTaskHealth,\n BackgroundRestartPolicy,\n} from './types.js'\n","/**\n * Background Task Manager (Worker-side)\n *\n * Manages background tasks running inside the extension worker.\n * Handles task execution, AbortController management, and health reporting.\n */\n\nimport type {\n BackgroundTaskConfig,\n BackgroundTaskCallback,\n BackgroundTaskContext,\n BackgroundTaskHealth,\n Disposable,\n LogAPI,\n StorageAPI,\n SecretsAPI,\n} from './types.js'\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Internal representation of a registered task\n */\ninterface RegisteredTask {\n config: BackgroundTaskConfig\n callback: BackgroundTaskCallback\n abortController: AbortController | null\n status: 'pending' | 'running' | 'stopped' | 'failed'\n lastHealthStatus?: string\n lastHealthTime?: string\n error?: string\n}\n\n/**\n * Options for the WorkerBackgroundTaskManager\n */\nexport interface WorkerBackgroundTaskManagerOptions {\n extensionId: string\n extensionVersion: string\n storagePath: string\n /** Send a message to the host */\n sendTaskRegistered: (\n taskId: string,\n name: string,\n userId: string,\n restartPolicy: BackgroundTaskConfig['restartPolicy'],\n payload?: Record<string, unknown>\n ) => void\n /** Send status update to host */\n sendTaskStatus: (taskId: string, status: 'running' | 'stopped' | 'failed', error?: string) => void\n /** Send health report to host */\n sendHealthReport: (taskId: string, status: string, timestamp: string) => void\n /** Create a log API for a task */\n createLogAPI: (taskId: string) => LogAPI\n /** Create extension-scoped storage API */\n createStorageAPI: () => StorageAPI\n /** Create user-scoped storage API */\n createUserStorageAPI: (userId: string) => StorageAPI\n /** Create extension-scoped secrets API */\n createSecretsAPI: () => SecretsAPI\n /** Create user-scoped secrets API */\n createUserSecretsAPI: (userId: string) => SecretsAPI\n}\n\n// ============================================================================\n// WorkerBackgroundTaskManager\n// ============================================================================\n\n/**\n * Manages background tasks within the extension worker.\n */\nexport class WorkerBackgroundTaskManager {\n private readonly tasks = new Map<string, RegisteredTask>()\n private readonly options: WorkerBackgroundTaskManagerOptions\n\n constructor(options: WorkerBackgroundTaskManagerOptions) {\n this.options = options\n }\n\n /**\n * Register and start a background task.\n * @returns A disposable that stops the task when disposed\n */\n async start(config: BackgroundTaskConfig, callback: BackgroundTaskCallback): Promise<Disposable> {\n const { id: taskId } = config\n\n if (this.tasks.has(taskId)) {\n throw new Error(`Background task with id '${taskId}' is already registered`)\n }\n\n const task: RegisteredTask = {\n config,\n callback,\n abortController: null,\n status: 'pending',\n }\n\n this.tasks.set(taskId, task)\n\n // Notify host about the registration\n this.options.sendTaskRegistered(\n taskId,\n config.name,\n config.userId,\n config.restartPolicy,\n config.payload\n )\n\n // Return a disposable that stops the task\n // Task removal should be coordinated with the host to avoid race conditions\n return {\n dispose: () => {\n this.stop(taskId)\n // Don't immediately delete - let the task finish aborting\n // The task will be cleaned up when the extension is deactivated\n },\n }\n }\n\n /**\n * Stop a running task.\n */\n stop(taskId: string): void {\n const task = this.tasks.get(taskId)\n if (!task) {\n return\n }\n\n // Abort the task if it's running\n if (task.abortController) {\n task.abortController.abort()\n task.abortController = null\n }\n\n task.status = 'stopped'\n\n // Notify host that the task has been stopped\n this.options.sendTaskStatus(taskId, 'stopped')\n }\n\n /**\n * Handle start message from host.\n * This is called when the host tells us to actually run the task.\n */\n async handleStart(taskId: string): Promise<void> {\n const task = this.tasks.get(taskId)\n if (!task) {\n return\n }\n\n // If there's already an execution running, abort it first\n if (task.abortController) {\n task.abortController.abort()\n task.abortController = null\n }\n\n // Create new AbortController for this run\n task.abortController = new AbortController()\n task.status = 'running'\n task.error = undefined\n\n // Build the task context\n const context = this.buildTaskContext(task)\n\n // Notify host that we're running\n this.options.sendTaskStatus(taskId, 'running')\n\n try {\n // Execute the callback\n await task.callback(context)\n\n // Task completed normally (or was aborted)\n if (task.abortController?.signal.aborted) {\n task.status = 'stopped'\n this.options.sendTaskStatus(taskId, 'stopped')\n } else {\n // Task finished without being aborted - treat as stopped\n task.status = 'stopped'\n this.options.sendTaskStatus(taskId, 'stopped')\n }\n } catch (error) {\n // Task failed with an error\n const errorMessage = error instanceof Error ? error.message : String(error)\n task.status = 'failed'\n task.error = errorMessage\n this.options.sendTaskStatus(taskId, 'failed', errorMessage)\n } finally {\n task.abortController = null\n }\n }\n\n /**\n * Handle stop message from host.\n */\n handleStop(taskId: string): void {\n this.stop(taskId)\n }\n\n /**\n * Build the execution context for a task.\n */\n private buildTaskContext(task: RegisteredTask): BackgroundTaskContext {\n const { config, abortController } = task\n const signal = abortController!.signal\n\n const log = this.options.createLogAPI(config.id)\n\n // Create storage and secrets APIs\n const storage = this.options.createStorageAPI()\n const userStorage = config.userId\n ? this.options.createUserStorageAPI(config.userId)\n : storage\n const secrets = this.options.createSecretsAPI()\n const userSecrets = config.userId\n ? this.options.createUserSecretsAPI(config.userId)\n : secrets\n\n const context: BackgroundTaskContext = {\n userId: config.userId,\n extension: {\n id: this.options.extensionId,\n version: this.options.extensionVersion,\n storagePath: this.options.storagePath,\n },\n storage,\n userStorage,\n secrets,\n userSecrets,\n signal,\n reportHealth: (status: string) => {\n const timestamp = new Date().toISOString()\n task.lastHealthStatus = status\n task.lastHealthTime = timestamp\n this.options.sendHealthReport(config.id, status, timestamp)\n },\n log,\n }\n\n return context\n }\n\n /**\n * Get the status of all tasks.\n */\n getStatus(): BackgroundTaskHealth[] {\n const result: BackgroundTaskHealth[] = []\n\n for (const task of this.tasks.values()) {\n result.push({\n taskId: task.config.id,\n name: task.config.name,\n userId: task.config.userId,\n status: task.status,\n restartCount: 0, // Worker doesn't track restarts, host does\n lastHealthStatus: task.lastHealthStatus,\n lastHealthTime: task.lastHealthTime,\n error: task.error,\n })\n }\n\n return result\n }\n\n /**\n * Check if a task exists.\n */\n hasTask(taskId: string): boolean {\n return this.tasks.has(taskId)\n }\n\n /**\n * Clean up all tasks.\n * Called during extension deactivation.\n */\n dispose(): void {\n for (const task of this.tasks.values()) {\n if (task.abortController) {\n task.abortController.abort()\n }\n }\n this.tasks.clear()\n }\n}\n","/**\n * Message protocol between Extension Host and Extension Workers\n */\n\nimport type {\n ChatMessage,\n ChatOptions,\n GetModelsOptions,\n StreamEvent,\n ToolResult,\n ActionResult,\n ModelInfo,\n SchedulerFirePayload,\n} from './types.js'\n\n// ============================================================================\n// Host → Worker Messages\n// ============================================================================\n\nexport type HostToWorkerMessage =\n | ActivateMessage\n | DeactivateMessage\n | SettingsChangedMessage\n | SchedulerFireMessage\n | ProviderChatRequestMessage\n | ProviderModelsRequestMessage\n | ToolExecuteRequestMessage\n | ActionExecuteRequestMessage\n | ResponseMessage\n | StreamingFetchChunkMessage\n | BackgroundTaskStartMessage\n | BackgroundTaskStopMessage\n\nexport interface ActivateMessage {\n type: 'activate'\n id: string\n payload: {\n extensionId: string\n extensionVersion: string\n storagePath: string\n permissions: string[]\n settings: Record<string, unknown>\n }\n}\n\nexport interface DeactivateMessage {\n type: 'deactivate'\n id: string\n}\n\nexport interface SettingsChangedMessage {\n type: 'settings-changed'\n id: string\n payload: {\n key: string\n value: unknown\n }\n}\n\nexport interface SchedulerFireMessage {\n type: 'scheduler-fire'\n id: string\n payload: SchedulerFirePayload\n}\n\nexport interface ProviderChatRequestMessage {\n type: 'provider-chat-request'\n id: string\n payload: {\n providerId: string\n messages: ChatMessage[]\n options: ChatOptions\n }\n}\n\nexport interface ProviderModelsRequestMessage {\n type: 'provider-models-request'\n id: string\n payload: {\n providerId: string\n options?: GetModelsOptions\n }\n}\n\nexport interface ToolExecuteRequestMessage {\n type: 'tool-execute-request'\n id: string\n payload: {\n toolId: string\n params: Record<string, unknown>\n /** User ID if the tool is executed in a user context */\n userId?: string\n }\n}\n\nexport interface ActionExecuteRequestMessage {\n type: 'action-execute-request'\n id: string\n payload: {\n actionId: string\n params: Record<string, unknown>\n /** User ID if the action is executed in a user context */\n userId?: string\n }\n}\n\nexport interface ResponseMessage {\n type: 'response'\n id: string\n payload: {\n requestId: string\n success: boolean\n data?: unknown\n error?: string\n }\n}\n\n/**\n * Message sent from host to worker with streaming fetch data chunks.\n * Used for streaming network responses (e.g., NDJSON streams from Ollama).\n */\nexport interface StreamingFetchChunkMessage {\n type: 'streaming-fetch-chunk'\n id: string\n payload: {\n requestId: string\n chunk: string\n done: boolean\n error?: string\n }\n}\n\n/**\n * Message sent from host to worker to start a registered background task.\n */\nexport interface BackgroundTaskStartMessage {\n type: 'background-task-start'\n id: string\n payload: {\n taskId: string\n }\n}\n\n/**\n * Message sent from host to worker to stop a running background task.\n */\nexport interface BackgroundTaskStopMessage {\n type: 'background-task-stop'\n id: string\n payload: {\n taskId: string\n }\n}\n\n// ============================================================================\n// Worker → Host Messages\n// ============================================================================\n\nexport type WorkerToHostMessage =\n | ReadyMessage\n | RequestMessage\n | ProviderRegisteredMessage\n | ToolRegisteredMessage\n | ActionRegisteredMessage\n | StreamEventMessage\n | LogMessage\n | ProviderModelsResponseMessage\n | ToolExecuteResponseMessage\n | ActionExecuteResponseMessage\n | StreamingFetchAckMessage\n | BackgroundTaskRegisteredMessage\n | BackgroundTaskStatusMessage\n | BackgroundTaskHealthMessage\n\nexport interface ReadyMessage {\n type: 'ready'\n}\n\n/**\n * Message sent from worker to host to acknowledge receipt of a streaming fetch chunk.\n * This enables backpressure control to prevent unbounded memory growth.\n */\nexport interface StreamingFetchAckMessage {\n type: 'streaming-fetch-ack'\n payload: {\n requestId: string\n }\n}\n\nexport interface RequestMessage {\n type: 'request'\n id: string\n method: RequestMethod\n payload: unknown\n}\n\nexport type RequestMethod =\n | 'network.fetch'\n | 'network.fetch-stream'\n | 'settings.getAll'\n | 'settings.get'\n | 'settings.set'\n | 'user.getProfile'\n | 'user.listIds'\n | 'events.emit'\n | 'scheduler.schedule'\n | 'scheduler.cancel'\n | 'scheduler.reportFireResult'\n | 'chat.appendInstruction'\n | 'database.execute'\n // Simple key-value storage methods\n | 'storage.set'\n | 'storage.keys'\n | 'storage.setForUser'\n | 'storage.keysForUser'\n // Collection-based storage methods\n | 'storage.put'\n | 'storage.get'\n | 'storage.delete'\n | 'storage.find'\n | 'storage.findOne'\n | 'storage.count'\n | 'storage.putMany'\n | 'storage.deleteMany'\n | 'storage.dropCollection'\n | 'storage.listCollections'\n | 'storage.putForUser'\n | 'storage.getForUser'\n | 'storage.deleteForUser'\n | 'storage.findForUser'\n | 'storage.findOneForUser'\n | 'storage.countForUser'\n | 'storage.putManyForUser'\n | 'storage.deleteManyForUser'\n | 'storage.dropCollectionForUser'\n | 'storage.listCollectionsForUser'\n // Secrets methods\n | 'secrets.set'\n | 'secrets.get'\n | 'secrets.delete'\n | 'secrets.list'\n | 'secrets.setForUser'\n | 'secrets.getForUser'\n | 'secrets.deleteForUser'\n | 'secrets.listForUser'\n // Tools cross-extension methods\n | 'tools.list'\n | 'tools.execute'\n\nexport interface ProviderRegisteredMessage {\n type: 'provider-registered'\n payload: {\n id: string\n name: string\n }\n}\n\nexport interface ToolRegisteredMessage {\n type: 'tool-registered'\n payload: {\n id: string\n name: string\n description: string\n parameters?: Record<string, unknown>\n }\n}\n\nexport interface ActionRegisteredMessage {\n type: 'action-registered'\n payload: {\n id: string\n }\n}\n\nexport interface StreamEventMessage {\n type: 'stream-event'\n payload: {\n requestId: string\n event: StreamEvent\n }\n}\n\nexport interface ProviderModelsResponseMessage {\n type: 'provider-models-response'\n payload: {\n requestId: string\n models: ModelInfo[]\n error?: string\n }\n}\n\nexport interface ToolExecuteResponseMessage {\n type: 'tool-execute-response'\n payload: {\n requestId: string\n result: ToolResult\n error?: string\n }\n}\n\nexport interface ActionExecuteResponseMessage {\n type: 'action-execute-response'\n payload: {\n requestId: string\n result: ActionResult\n error?: string\n }\n}\n\nexport interface LogMessage {\n type: 'log'\n payload: {\n level: 'debug' | 'info' | 'warn' | 'error'\n message: string\n data?: Record<string, unknown>\n }\n}\n\n/**\n * Message sent from worker to host when a background task is registered.\n */\nexport interface BackgroundTaskRegisteredMessage {\n type: 'background-task-registered'\n payload: {\n taskId: string\n name: string\n userId: string\n restartPolicy: {\n type: 'always' | 'on-failure' | 'never'\n maxRestarts?: number\n initialDelayMs?: number\n maxDelayMs?: number\n backoffMultiplier?: number\n }\n payload?: Record<string, unknown>\n }\n}\n\n/**\n * Message sent from worker to host with background task status updates.\n */\nexport interface BackgroundTaskStatusMessage {\n type: 'background-task-status'\n payload: {\n taskId: string\n status: 'running' | 'stopped' | 'failed'\n error?: string\n }\n}\n\n/**\n * Message sent from worker to host with background task health reports.\n */\nexport interface BackgroundTaskHealthMessage {\n type: 'background-task-health'\n payload: {\n taskId: string\n status: string\n timestamp: string\n }\n}\n\n// ============================================================================\n// Utility Types\n// ============================================================================\n\nexport interface PendingRequest<T = unknown> {\n resolve: (value: T) => void\n reject: (error: Error) => void\n timeout: ReturnType<typeof setTimeout>\n}\n\n/**\n * Generate a unique message ID\n */\nexport function generateMessageId(): string {\n return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`\n}\n","/**\n * Storage API builders for extension and user-scoped storage.\n */\n\nimport type { StorageAPI, Query, QueryOptions } from '../types.js'\nimport type { RequestMessage } from '../messages.js'\n\ntype SendRequest = <T>(method: RequestMessage['method'], payload: unknown) => Promise<T>\n\n/**\n * Create a storage API that delegates to the host via request messages.\n * Used for both extension-scoped and user-scoped storage by varying the method prefix.\n */\nfunction buildStorageAPI(\n sendRequest: SendRequest,\n methodSuffix: '' | 'ForUser',\n userId?: string\n): StorageAPI {\n const extraPayload = userId ? { userId } : {}\n\n return {\n async put<T extends object>(collection: string, id: string, data: T): Promise<void> {\n return sendRequest<void>(`storage.put${methodSuffix}`, { ...extraPayload, collection, id, data })\n },\n async get<T>(collection: string, id: string): Promise<T | undefined> {\n return sendRequest<T | undefined>(`storage.get${methodSuffix}`, { ...extraPayload, collection, id })\n },\n async delete(collection: string, id: string): Promise<boolean> {\n return sendRequest<boolean>(`storage.delete${methodSuffix}`, { ...extraPayload, collection, id })\n },\n async find<T>(collection: string, query?: Query, options?: QueryOptions): Promise<T[]> {\n return sendRequest<T[]>(`storage.find${methodSuffix}`, { ...extraPayload, collection, query, options })\n },\n async findOne<T>(collection: string, query: Query): Promise<T | undefined> {\n return sendRequest<T | undefined>(`storage.findOne${methodSuffix}`, { ...extraPayload, collection, query })\n },\n async count(collection: string, query?: Query): Promise<number> {\n return sendRequest<number>(`storage.count${methodSuffix}`, { ...extraPayload, collection, query })\n },\n async putMany<T extends object>(collection: string, docs: Array<{ id: string; data: T }>): Promise<void> {\n return sendRequest<void>(`storage.putMany${methodSuffix}`, { ...extraPayload, collection, docs })\n },\n async deleteMany(collection: string, query: Query): Promise<number> {\n return sendRequest<number>(`storage.deleteMany${methodSuffix}`, { ...extraPayload, collection, query })\n },\n async dropCollection(collection: string): Promise<void> {\n return sendRequest<void>(`storage.dropCollection${methodSuffix}`, { ...extraPayload, collection })\n },\n async listCollections(): Promise<string[]> {\n return sendRequest<string[]>(`storage.listCollections${methodSuffix}`, { ...extraPayload })\n },\n }\n}\n\n/**\n * Build extension-scoped storage API (shared across all users).\n */\nexport function buildExtensionStorageAPI(sendRequest: SendRequest): StorageAPI {\n return buildStorageAPI(sendRequest, '')\n}\n\n/**\n * Build user-scoped storage API (isolated per user).\n */\nexport function buildUserStorageAPI(sendRequest: SendRequest, userId: string): StorageAPI {\n return buildStorageAPI(sendRequest, 'ForUser', userId)\n}\n","/**\n * Secrets API builders for extension and user-scoped secrets.\n */\n\nimport type { SecretsAPI } from '../types.js'\nimport type { RequestMessage } from '../messages.js'\n\ntype SendRequest = <T>(method: RequestMessage['method'], payload: unknown) => Promise<T>\n\n/**\n * Build extension-scoped secrets API (shared across all users).\n */\nexport function buildExtensionSecretsAPI(sendRequest: SendRequest): SecretsAPI {\n return {\n async set(key: string, value: string): Promise<void> {\n return sendRequest<void>('secrets.set', { key, value })\n },\n async get(key: string): Promise<string | undefined> {\n return sendRequest<string | undefined>('secrets.get', { key })\n },\n async delete(key: string): Promise<boolean> {\n return sendRequest<boolean>('secrets.delete', { key })\n },\n async list(): Promise<string[]> {\n return sendRequest<string[]>('secrets.list', {})\n },\n }\n}\n\n/**\n * Build user-scoped secrets API (isolated per user).\n */\nexport function buildUserSecretsAPI(sendRequest: SendRequest, userId: string): SecretsAPI {\n return {\n async set(key: string, value: string): Promise<void> {\n return sendRequest<void>('secrets.setForUser', { userId, key, value })\n },\n async get(key: string): Promise<string | undefined> {\n return sendRequest<string | undefined>('secrets.getForUser', { userId, key })\n },\n async delete(key: string): Promise<boolean> {\n return sendRequest<boolean>('secrets.deleteForUser', { userId, key })\n },\n async list(): Promise<string[]> {\n return sendRequest<string[]>('secrets.listForUser', { userId })\n },\n }\n}\n","/**\n * Shared execution context builder for tool, action, and scheduler operations.\n */\n\nimport type { ExecutionContext, ExtensionContext } from '../types.js'\nimport type { RequestMessage } from '../messages.js'\nimport { buildExtensionStorageAPI, buildUserStorageAPI } from './storageApi.js'\nimport { buildExtensionSecretsAPI, buildUserSecretsAPI } from './secretsApi.js'\n\ntype SendRequest = <T>(method: RequestMessage['method'], payload: unknown) => Promise<T>\n\n/**\n * Create a request-scoped ExecutionContext with storage and secrets.\n * Used by scheduler fire, tool execution, and action execution handlers.\n */\nexport function createExecutionContext(\n sendRequest: SendRequest,\n extensionContext: ExtensionContext,\n userId?: string\n): ExecutionContext {\n return {\n userId,\n extension: {\n id: extensionContext.extension.id,\n version: extensionContext.extension.version,\n storagePath: extensionContext.extension.storagePath,\n },\n storage: buildExtensionStorageAPI(sendRequest),\n userStorage: userId\n ? buildUserStorageAPI(sendRequest, userId)\n : buildExtensionStorageAPI(sendRequest),\n secrets: buildExtensionSecretsAPI(sendRequest),\n userSecrets: userId\n ? buildUserSecretsAPI(sendRequest, userId)\n : buildExtensionSecretsAPI(sendRequest),\n }\n}\n"],"mappings":"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","names":["sendRequest","sendRequest","sendRequest","extensionContext","module"]}