@stina/extension-api 1.0.0 → 1.6.0

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-ZB7GJUPS.js.map
9
+ //# sourceMappingURL=chunk-3Q3YXWOH.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 VoiceSessionOptions,\n VoiceSessionDescriptor,\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 | ProviderVoiceSessionRequestMessage\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 ProviderVoiceSessionRequestMessage {\n type: 'provider-voice-session-request'\n id: string\n payload: {\n providerId: string\n /**\n * `signal` is dropped on the way across: an AbortSignal cannot be\n * structured-cloned into a worker. Cancellation is handled by the host\n * rejecting the pending request instead.\n */\n options: Omit<VoiceSessionOptions, 'signal'>\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 | ProviderVoiceSessionResponseMessage\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 ProviderVoiceSessionResponseMessage {\n type: 'provider-voice-session-response'\n payload: {\n requestId: string\n /** Absent when `error` is set. */\n descriptor?: VoiceSessionDescriptor\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' | 'completed' | '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":";AAmZO,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 VoiceSessionOptions,\n VoiceSessionDescriptor,\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 | ProviderVoiceSessionRequestMessage\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 ProviderVoiceSessionRequestMessage {\n type: 'provider-voice-session-request'\n id: string\n payload: {\n providerId: string\n /**\n * `signal` is dropped on the way across: an AbortSignal cannot be\n * structured-cloned into a worker. Cancellation is handled by the host\n * rejecting the pending request instead.\n */\n options: Omit<VoiceSessionOptions, 'signal'>\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 | ProviderVoiceSessionResponseMessage\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 // Attachments\n | 'attachments.read'\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 ProviderVoiceSessionResponseMessage {\n type: 'provider-voice-session-response'\n payload: {\n requestId: string\n /** Absent when `error` is set. */\n descriptor?: VoiceSessionDescriptor\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' | 'completed' | '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":";AAqZO,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 ToolSettingsViewDefinition,\n ToolSettingsView,\n ToolSettingsListView,\n ToolSettingsListMapping,\n ToolSettingsComponentView,\n ToolSettingsActionDataSource,\n PanelDefinition,\n StatusCardDefinition,\n PanelView,\n PanelComponentView,\n PanelActionDataSource,\n PanelUnknownView,\n ProviderDefinition,\n ProviderConfigView,\n PromptContribution,\n PromptSection,\n ToolDefinition,\n ToolConfirmationConfig,\n CommandDefinition,\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 ConversationPresentation,\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 ModelCapabilities,\n ChatMessage,\n ChatImage,\n ChatOptions,\n GetModelsOptions,\n StreamEvent,\n ToolCall,\n\n // Duplex voice\n VoiceSessionOptions,\n VoiceSessionDescriptor,\n VoiceTransportRequest,\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 PasswordInputProps,\n NumberInputProps,\n TextAreaProps,\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 // Purpose-built display components\n WeatherCondition,\n WeatherWind,\n WeatherNowProps,\n WeatherForecastStep,\n WeatherForecastProps,\n ChartKind,\n ChartSeries,\n ChartProps,\n StatTrend,\n StatTileProps,\n ProgressShape,\n ProgressColor,\n ProgressBarProps,\n KeyValueRow,\n KeyValueListProps,\n TimelineVariant,\n TimelineEntry,\n TimelineProps,\n NoteVariant,\n NoteProps,\n CalendarEventStatus,\n CalendarEventProps,\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 VoiceSessionOptions,\n VoiceSessionDescriptor,\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 | ProviderVoiceSessionRequestMessage\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 ProviderVoiceSessionRequestMessage {\n type: 'provider-voice-session-request'\n id: string\n payload: {\n providerId: string\n /**\n * `signal` is dropped on the way across: an AbortSignal cannot be\n * structured-cloned into a worker. Cancellation is handled by the host\n * rejecting the pending request instead.\n */\n options: Omit<VoiceSessionOptions, 'signal'>\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 | ProviderVoiceSessionResponseMessage\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 ProviderVoiceSessionResponseMessage {\n type: 'provider-voice-session-response'\n payload: {\n requestId: string\n /** Absent when `error` is set. */\n descriptor?: VoiceSessionDescriptor\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' | 'completed' | '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;;;AC6WO,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 ToolSettingsViewDefinition,\n ToolSettingsView,\n ToolSettingsListView,\n ToolSettingsListMapping,\n ToolSettingsComponentView,\n ToolSettingsActionDataSource,\n PanelDefinition,\n StatusCardDefinition,\n PanelView,\n PanelComponentView,\n PanelActionDataSource,\n PanelUnknownView,\n ProviderDefinition,\n ProviderConfigView,\n PromptContribution,\n PromptSection,\n ToolDefinition,\n ToolConfirmationConfig,\n CommandDefinition,\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 ConversationPresentation,\n AttachmentsAPI,\n AttachmentContent,\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 ModelCapabilities,\n ChatMessage,\n ChatImage,\n ChatFile,\n ChatOptions,\n GetModelsOptions,\n StreamEvent,\n ToolCall,\n\n // Duplex voice\n VoiceSessionOptions,\n VoiceSessionDescriptor,\n VoiceTransportRequest,\n\n // Tools\n Tool,\n ToolResult,\n ToolAttachment,\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 ClockProps,\n ParagraphProps,\n ButtonProps,\n TextInputProps,\n PasswordInputProps,\n NumberInputProps,\n TextAreaProps,\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 // Purpose-built display components\n WeatherCondition,\n WeatherWind,\n WeatherNowProps,\n WeatherForecastStep,\n WeatherForecastProps,\n ChartKind,\n ChartSeries,\n ChartProps,\n StatTrend,\n StatTileProps,\n ProgressShape,\n ProgressColor,\n ProgressBarProps,\n KeyValueRow,\n KeyValueListProps,\n TimelineVariant,\n TimelineEntry,\n TimelineProps,\n NoteVariant,\n NoteProps,\n CalendarEventStatus,\n CalendarEventProps,\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 VoiceSessionOptions,\n VoiceSessionDescriptor,\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 | ProviderVoiceSessionRequestMessage\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 ProviderVoiceSessionRequestMessage {\n type: 'provider-voice-session-request'\n id: string\n payload: {\n providerId: string\n /**\n * `signal` is dropped on the way across: an AbortSignal cannot be\n * structured-cloned into a worker. Cancellation is handled by the host\n * rejecting the pending request instead.\n */\n options: Omit<VoiceSessionOptions, 'signal'>\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 | ProviderVoiceSessionResponseMessage\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 // Attachments\n | 'attachments.read'\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 ProviderVoiceSessionResponseMessage {\n type: 'provider-voice-session-response'\n payload: {\n requestId: string\n /** Absent when `error` is set. */\n descriptor?: VoiceSessionDescriptor\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' | 'completed' | '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;;;AC+WO,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 { H as HugeIconName, E as ExtensionContributions, S as SchedulerFirePayload, C as ChatMessage, a as ChatOptions, G as GetModelsOptions, V as VoiceSessionOptions, b as StreamEvent, M as ModelInfo, c as VoiceSessionDescriptor, T as ToolResult, A as ActionResult } from './types.tools-CQrbET-n.cjs';
2
- export { a8 as AIProvider, ae as Action, B as ActionsAPI, ag as AllowedCSSProperty, a1 as BackgroundRestartPolicy, _ as BackgroundTaskCallback, Z as BackgroundTaskConfig, $ as BackgroundTaskContext, a0 as BackgroundTaskHealth, Y as BackgroundWorkersAPI, as as ButtonProps, be as CalendarEventProps, bd as CalendarEventStatus, a_ as ChartKind, b0 as ChartProps, a$ as ChartSeries, Q as ChatAPI, aa as ChatImage, R as ChatInstructionMessage, aQ as CheckboxProps, aK as CollapsibleProps, v as CommandDefinition, aU as ConditionalGroupProps, W as ConversationPresentation, ax as DateTimeInputProps, D as Disposable, aD as DividerProps, F as EventsAPI, al as ExtensionActionCall, am as ExtensionActionRef, ak as ExtensionComponentChildren, ai as ExtensionComponentData, aj as ExtensionComponentIterator, ah as ExtensionComponentStyle, w as ExtensionContext, an as ExtensionDataSource, af as ExtensionModule, ao as ExtensionPanelDefinition, aM as FrameProps, aL as FrameVariant, aC as GridProps, ap as HeaderProps, aB as HorizontalStackProps, aG as IconButtonProps, aF as IconButtonType, az as IconPickerProps, aE as IconProps, b7 as KeyValueListProps, b6 as KeyValueRow, aq as LabelProps, aN as ListProps, L as LocalizedString, X as LogAPI, aR as MarkdownProps, aT as ModalProps, a9 as ModelCapabilities, N as NetworkAPI, bc as NoteProps, bb as NoteVariant, av as NumberInputProps, aH as PanelAction, m as PanelActionDataSource, l as PanelComponentView, P as PanelDefinition, aI as PanelProps, n as PanelUnknownView, k as PanelView, ar as ParagraphProps, au as PasswordInputProps, aP as PillProps, aO as PillVariant, b5 as ProgressBarProps, b4 as ProgressColor, b3 as ProgressShape, q as PromptContribution, s as PromptSection, p as ProviderConfigView, o as ProviderDefinition, y as ProvidersAPI, a2 as Query, a3 as QueryOptions, I as SchedulerAPI, J as SchedulerJobRequest, K as SchedulerSchedule, a5 as SecretsAPI, ay as SelectProps, x as SettingsAPI, b2 as StatTileProps, b1 as StatTrend, j as StatusCardDefinition, a4 as StorageAPI, a6 as StorageCollectionConfig, a7 as StorageContributions, aw as TextAreaProps, at as TextInputProps, aS as TextPreviewProps, b9 as TimelineEntry, ba as TimelineProps, b8 as TimelineVariant, aJ as ToggleProps, ad as Tool, ab as ToolCall, u as ToolConfirmationConfig, t as ToolDefinition, i as ToolSettingsActionDataSource, h as ToolSettingsComponentView, g as ToolSettingsListMapping, f as ToolSettingsListView, e as ToolSettingsView, d as ToolSettingsViewDefinition, z as ToolsAPI, U as UserAPI, O as UserProfile, aA as VerticalStackProps, ac as VoiceTransportRequest, aV as WeatherCondition, aZ as WeatherForecastProps, aY as WeatherForecastStep, aX as WeatherNowProps, aW as WeatherWind, r as resolveLocalizedString } from './types.tools-CQrbET-n.cjs';
1
+ import { H as HugeIconName, E as ExtensionContributions, S as SchedulerFirePayload, C as ChatMessage, a as ChatOptions, G as GetModelsOptions, V as VoiceSessionOptions, b as StreamEvent, M as ModelInfo, c as VoiceSessionDescriptor, T as ToolResult, A as ActionResult } from './types.tools-R0xGhiBa.cjs';
2
+ export { aa as AIProvider, ai as Action, B as ActionsAPI, ak as AllowedCSSProperty, Y as AttachmentContent, X as AttachmentsAPI, a3 as BackgroundRestartPolicy, a0 as BackgroundTaskCallback, $ as BackgroundTaskConfig, a1 as BackgroundTaskContext, a2 as BackgroundTaskHealth, _ as BackgroundWorkersAPI, ax as ButtonProps, bj as CalendarEventProps, bi as CalendarEventStatus, b3 as ChartKind, b5 as ChartProps, b4 as ChartSeries, Q as ChatAPI, ad as ChatFile, ac as ChatImage, R as ChatInstructionMessage, aV as CheckboxProps, av as ClockProps, aP as CollapsibleProps, v as CommandDefinition, aZ as ConditionalGroupProps, W as ConversationPresentation, aC as DateTimeInputProps, D as Disposable, aI as DividerProps, F as EventsAPI, ap as ExtensionActionCall, aq as ExtensionActionRef, ao as ExtensionComponentChildren, am as ExtensionComponentData, an as ExtensionComponentIterator, al as ExtensionComponentStyle, w as ExtensionContext, ar as ExtensionDataSource, aj as ExtensionModule, as as ExtensionPanelDefinition, aR as FrameProps, aQ as FrameVariant, aH as GridProps, at as HeaderProps, aG as HorizontalStackProps, aL as IconButtonProps, aK as IconButtonType, aE as IconPickerProps, aJ as IconProps, bc as KeyValueListProps, bb as KeyValueRow, au as LabelProps, aS as ListProps, L as LocalizedString, Z as LogAPI, aW as MarkdownProps, aY as ModalProps, ab as ModelCapabilities, N as NetworkAPI, bh as NoteProps, bg as NoteVariant, aA as NumberInputProps, aM as PanelAction, m as PanelActionDataSource, l as PanelComponentView, P as PanelDefinition, aN as PanelProps, n as PanelUnknownView, k as PanelView, aw as ParagraphProps, az as PasswordInputProps, aU as PillProps, aT as PillVariant, ba as ProgressBarProps, b9 as ProgressColor, b8 as ProgressShape, q as PromptContribution, s as PromptSection, p as ProviderConfigView, o as ProviderDefinition, y as ProvidersAPI, a4 as Query, a5 as QueryOptions, I as SchedulerAPI, J as SchedulerJobRequest, K as SchedulerSchedule, a7 as SecretsAPI, aD as SelectProps, x as SettingsAPI, b7 as StatTileProps, b6 as StatTrend, j as StatusCardDefinition, a6 as StorageAPI, a8 as StorageCollectionConfig, a9 as StorageContributions, aB as TextAreaProps, ay as TextInputProps, aX as TextPreviewProps, be as TimelineEntry, bf as TimelineProps, bd as TimelineVariant, aO as ToggleProps, ag as Tool, ah as ToolAttachment, ae as ToolCall, u as ToolConfirmationConfig, t as ToolDefinition, i as ToolSettingsActionDataSource, h as ToolSettingsComponentView, g as ToolSettingsListMapping, f as ToolSettingsListView, e as ToolSettingsView, d as ToolSettingsViewDefinition, z as ToolsAPI, U as UserAPI, O as UserProfile, aF as VerticalStackProps, af as VoiceTransportRequest, a_ as WeatherCondition, b2 as WeatherForecastProps, b1 as WeatherForecastStep, b0 as WeatherNowProps, a$ as WeatherWind, r as resolveLocalizedString } from './types.tools-R0xGhiBa.cjs';
3
3
 
4
4
  /**
5
5
  * Permission Types
@@ -12,7 +12,14 @@ 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.list' | '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
+ /**
17
+ * Read the bytes of a file attached to one of this user's conversations, given
18
+ * its id. For handing a file on — mailing the PDF she was shown, printing it —
19
+ * not for reading what it says, which `core_read_attachment` does without an
20
+ * extension.
21
+ */
22
+ | 'attachments.read';
16
23
  /** Capability permissions */
17
24
  type CapabilityPermission = 'provider.register' | 'tools.register' | 'tools.list' | 'tools.execute' | 'actions.register' | 'settings.register' | 'commands.register' | 'panels.register' | 'statusCards.register' | 'events.emit' | 'scheduler.register' | 'chat.message.write' | 'background.workers';
18
25
  /** System permissions */
@@ -213,7 +220,7 @@ interface RequestMessage {
213
220
  method: RequestMethod;
214
221
  payload: unknown;
215
222
  }
216
- 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';
223
+ 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' | 'attachments.read';
217
224
  interface ProviderRegisteredMessage {
218
225
  type: 'provider-registered';
219
226
  payload: {
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { H as HugeIconName, E as ExtensionContributions, S as SchedulerFirePayload, C as ChatMessage, a as ChatOptions, G as GetModelsOptions, V as VoiceSessionOptions, b as StreamEvent, M as ModelInfo, c as VoiceSessionDescriptor, T as ToolResult, A as ActionResult } from './types.tools-CQrbET-n.js';
2
- export { a8 as AIProvider, ae as Action, B as ActionsAPI, ag as AllowedCSSProperty, a1 as BackgroundRestartPolicy, _ as BackgroundTaskCallback, Z as BackgroundTaskConfig, $ as BackgroundTaskContext, a0 as BackgroundTaskHealth, Y as BackgroundWorkersAPI, as as ButtonProps, be as CalendarEventProps, bd as CalendarEventStatus, a_ as ChartKind, b0 as ChartProps, a$ as ChartSeries, Q as ChatAPI, aa as ChatImage, R as ChatInstructionMessage, aQ as CheckboxProps, aK as CollapsibleProps, v as CommandDefinition, aU as ConditionalGroupProps, W as ConversationPresentation, ax as DateTimeInputProps, D as Disposable, aD as DividerProps, F as EventsAPI, al as ExtensionActionCall, am as ExtensionActionRef, ak as ExtensionComponentChildren, ai as ExtensionComponentData, aj as ExtensionComponentIterator, ah as ExtensionComponentStyle, w as ExtensionContext, an as ExtensionDataSource, af as ExtensionModule, ao as ExtensionPanelDefinition, aM as FrameProps, aL as FrameVariant, aC as GridProps, ap as HeaderProps, aB as HorizontalStackProps, aG as IconButtonProps, aF as IconButtonType, az as IconPickerProps, aE as IconProps, b7 as KeyValueListProps, b6 as KeyValueRow, aq as LabelProps, aN as ListProps, L as LocalizedString, X as LogAPI, aR as MarkdownProps, aT as ModalProps, a9 as ModelCapabilities, N as NetworkAPI, bc as NoteProps, bb as NoteVariant, av as NumberInputProps, aH as PanelAction, m as PanelActionDataSource, l as PanelComponentView, P as PanelDefinition, aI as PanelProps, n as PanelUnknownView, k as PanelView, ar as ParagraphProps, au as PasswordInputProps, aP as PillProps, aO as PillVariant, b5 as ProgressBarProps, b4 as ProgressColor, b3 as ProgressShape, q as PromptContribution, s as PromptSection, p as ProviderConfigView, o as ProviderDefinition, y as ProvidersAPI, a2 as Query, a3 as QueryOptions, I as SchedulerAPI, J as SchedulerJobRequest, K as SchedulerSchedule, a5 as SecretsAPI, ay as SelectProps, x as SettingsAPI, b2 as StatTileProps, b1 as StatTrend, j as StatusCardDefinition, a4 as StorageAPI, a6 as StorageCollectionConfig, a7 as StorageContributions, aw as TextAreaProps, at as TextInputProps, aS as TextPreviewProps, b9 as TimelineEntry, ba as TimelineProps, b8 as TimelineVariant, aJ as ToggleProps, ad as Tool, ab as ToolCall, u as ToolConfirmationConfig, t as ToolDefinition, i as ToolSettingsActionDataSource, h as ToolSettingsComponentView, g as ToolSettingsListMapping, f as ToolSettingsListView, e as ToolSettingsView, d as ToolSettingsViewDefinition, z as ToolsAPI, U as UserAPI, O as UserProfile, aA as VerticalStackProps, ac as VoiceTransportRequest, aV as WeatherCondition, aZ as WeatherForecastProps, aY as WeatherForecastStep, aX as WeatherNowProps, aW as WeatherWind, r as resolveLocalizedString } from './types.tools-CQrbET-n.js';
1
+ import { H as HugeIconName, E as ExtensionContributions, S as SchedulerFirePayload, C as ChatMessage, a as ChatOptions, G as GetModelsOptions, V as VoiceSessionOptions, b as StreamEvent, M as ModelInfo, c as VoiceSessionDescriptor, T as ToolResult, A as ActionResult } from './types.tools-R0xGhiBa.js';
2
+ export { aa as AIProvider, ai as Action, B as ActionsAPI, ak as AllowedCSSProperty, Y as AttachmentContent, X as AttachmentsAPI, a3 as BackgroundRestartPolicy, a0 as BackgroundTaskCallback, $ as BackgroundTaskConfig, a1 as BackgroundTaskContext, a2 as BackgroundTaskHealth, _ as BackgroundWorkersAPI, ax as ButtonProps, bj as CalendarEventProps, bi as CalendarEventStatus, b3 as ChartKind, b5 as ChartProps, b4 as ChartSeries, Q as ChatAPI, ad as ChatFile, ac as ChatImage, R as ChatInstructionMessage, aV as CheckboxProps, av as ClockProps, aP as CollapsibleProps, v as CommandDefinition, aZ as ConditionalGroupProps, W as ConversationPresentation, aC as DateTimeInputProps, D as Disposable, aI as DividerProps, F as EventsAPI, ap as ExtensionActionCall, aq as ExtensionActionRef, ao as ExtensionComponentChildren, am as ExtensionComponentData, an as ExtensionComponentIterator, al as ExtensionComponentStyle, w as ExtensionContext, ar as ExtensionDataSource, aj as ExtensionModule, as as ExtensionPanelDefinition, aR as FrameProps, aQ as FrameVariant, aH as GridProps, at as HeaderProps, aG as HorizontalStackProps, aL as IconButtonProps, aK as IconButtonType, aE as IconPickerProps, aJ as IconProps, bc as KeyValueListProps, bb as KeyValueRow, au as LabelProps, aS as ListProps, L as LocalizedString, Z as LogAPI, aW as MarkdownProps, aY as ModalProps, ab as ModelCapabilities, N as NetworkAPI, bh as NoteProps, bg as NoteVariant, aA as NumberInputProps, aM as PanelAction, m as PanelActionDataSource, l as PanelComponentView, P as PanelDefinition, aN as PanelProps, n as PanelUnknownView, k as PanelView, aw as ParagraphProps, az as PasswordInputProps, aU as PillProps, aT as PillVariant, ba as ProgressBarProps, b9 as ProgressColor, b8 as ProgressShape, q as PromptContribution, s as PromptSection, p as ProviderConfigView, o as ProviderDefinition, y as ProvidersAPI, a4 as Query, a5 as QueryOptions, I as SchedulerAPI, J as SchedulerJobRequest, K as SchedulerSchedule, a7 as SecretsAPI, aD as SelectProps, x as SettingsAPI, b7 as StatTileProps, b6 as StatTrend, j as StatusCardDefinition, a6 as StorageAPI, a8 as StorageCollectionConfig, a9 as StorageContributions, aB as TextAreaProps, ay as TextInputProps, aX as TextPreviewProps, be as TimelineEntry, bf as TimelineProps, bd as TimelineVariant, aO as ToggleProps, ag as Tool, ah as ToolAttachment, ae as ToolCall, u as ToolConfirmationConfig, t as ToolDefinition, i as ToolSettingsActionDataSource, h as ToolSettingsComponentView, g as ToolSettingsListMapping, f as ToolSettingsListView, e as ToolSettingsView, d as ToolSettingsViewDefinition, z as ToolsAPI, U as UserAPI, O as UserProfile, aF as VerticalStackProps, af as VoiceTransportRequest, a_ as WeatherCondition, b2 as WeatherForecastProps, b1 as WeatherForecastStep, b0 as WeatherNowProps, a$ as WeatherWind, r as resolveLocalizedString } from './types.tools-R0xGhiBa.js';
3
3
 
4
4
  /**
5
5
  * Permission Types
@@ -12,7 +12,14 @@ 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.list' | '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
+ /**
17
+ * Read the bytes of a file attached to one of this user's conversations, given
18
+ * its id. For handing a file on — mailing the PDF she was shown, printing it —
19
+ * not for reading what it says, which `core_read_attachment` does without an
20
+ * extension.
21
+ */
22
+ | 'attachments.read';
16
23
  /** Capability permissions */
17
24
  type CapabilityPermission = 'provider.register' | 'tools.register' | 'tools.list' | 'tools.execute' | 'actions.register' | 'settings.register' | 'commands.register' | 'panels.register' | 'statusCards.register' | 'events.emit' | 'scheduler.register' | 'chat.message.write' | 'background.workers';
18
25
  /** System permissions */
@@ -213,7 +220,7 @@ interface RequestMessage {
213
220
  method: RequestMethod;
214
221
  payload: unknown;
215
222
  }
216
- 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';
223
+ 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' | 'attachments.read';
217
224
  interface ProviderRegisteredMessage {
218
225
  type: 'provider-registered';
219
226
  payload: {
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  generateMessageId
3
- } from "./chunk-ZB7GJUPS.js";
3
+ } from "./chunk-3Q3YXWOH.js";
4
4
  import "./chunk-DGUM43GV.js";
5
5
 
6
6
  // src/types.localization.ts
package/dist/runtime.cjs CHANGED
@@ -273,7 +273,7 @@ function buildUserSecretsAPI(sendRequest2, userId) {
273
273
  }
274
274
 
275
275
  // src/runtime/executionContext.ts
276
- function createExecutionContext(sendRequest2, extensionContext2, userId) {
276
+ function createExecutionContext(sendRequest2, extensionContext2, userId, canReadAttachments = false) {
277
277
  return {
278
278
  userId,
279
279
  extension: {
@@ -284,7 +284,19 @@ function createExecutionContext(sendRequest2, extensionContext2, userId) {
284
284
  storage: buildExtensionStorageAPI(sendRequest2),
285
285
  userStorage: userId ? buildUserStorageAPI(sendRequest2, userId) : buildExtensionStorageAPI(sendRequest2),
286
286
  secrets: buildExtensionSecretsAPI(sendRequest2),
287
- userSecrets: userId ? buildUserSecretsAPI(sendRequest2, userId) : buildExtensionSecretsAPI(sendRequest2)
287
+ userSecrets: userId ? buildUserSecretsAPI(sendRequest2, userId) : buildExtensionSecretsAPI(sendRequest2),
288
+ // Only with a user to scope it to. An attachment belongs to somebody, and a
289
+ // request that cannot say whose work it is doing has no business reading one.
290
+ ...canReadAttachments && userId ? {
291
+ attachments: {
292
+ async read(attachmentId) {
293
+ return sendRequest2("attachments.read", {
294
+ attachmentId,
295
+ userId
296
+ });
297
+ }
298
+ }
299
+ } : {}
288
300
  };
289
301
  }
290
302
 
@@ -310,6 +322,7 @@ var messagePort = getMessagePort();
310
322
  var extensionModule = null;
311
323
  var extensionDisposable = null;
312
324
  var extensionContext = null;
325
+ var grantedPermissions = [];
313
326
  var backgroundTaskManager = null;
314
327
  var pendingRequests = /* @__PURE__ */ new Map();
315
328
  var registeredProviders = /* @__PURE__ */ new Map();
@@ -416,6 +429,7 @@ function handleResponse(payload) {
416
429
  }
417
430
  async function handleActivate(payload) {
418
431
  const { extensionId, extensionVersion, storagePath, permissions } = payload;
432
+ grantedPermissions = permissions;
419
433
  extensionContext = buildContext(extensionId, extensionVersion, storagePath, permissions);
420
434
  try {
421
435
  if (extensionModule?.activate) {
@@ -466,7 +480,12 @@ function handleSettingsChanged(key, value) {
466
480
  }
467
481
  }
468
482
  async function handleSchedulerFire(payload) {
469
- const execContext = createExecutionContext(sendRequest, extensionContext, payload.userId);
483
+ const execContext = createExecutionContext(
484
+ sendRequest,
485
+ extensionContext,
486
+ payload.userId,
487
+ grantedPermissions.includes("attachments.read")
488
+ );
470
489
  const results = await Promise.allSettled(
471
490
  schedulerCallbacks.map((callback) => Promise.resolve(callback(payload, execContext)))
472
491
  );
@@ -613,7 +632,12 @@ async function handleToolExecuteRequest(requestId, payload) {
613
632
  return;
614
633
  }
615
634
  try {
616
- const execContext = createExecutionContext(sendRequest, extensionContext, payload.userId);
635
+ const execContext = createExecutionContext(
636
+ sendRequest,
637
+ extensionContext,
638
+ payload.userId,
639
+ grantedPermissions.includes("attachments.read")
640
+ );
617
641
  const result = await tool.execute(payload.params, execContext);
618
642
  postMessage({
619
643
  type: "tool-execute-response",
@@ -648,7 +672,12 @@ async function handleActionExecuteRequest(requestId, payload) {
648
672
  return;
649
673
  }
650
674
  try {
651
- const execContext = createExecutionContext(sendRequest, extensionContext, payload.userId);
675
+ const execContext = createExecutionContext(
676
+ sendRequest,
677
+ extensionContext,
678
+ payload.userId,
679
+ grantedPermissions.includes("attachments.read")
680
+ );
652
681
  const result = await action.execute(payload.params, execContext);
653
682
  postMessage({
654
683
  type: "action-execute-response",
@@ -695,10 +724,18 @@ function buildContext(extensionId, extensionVersion, storagePath, permissions) {
695
724
  const networkApi = {
696
725
  async fetch(url, options) {
697
726
  const result = await sendRequest("network.fetch", { url, options });
698
- return new Response(result.body, {
727
+ const isBase64 = result.bodyEncoding === "base64";
728
+ const body = isBase64 ? Uint8Array.from(atob(result.body), (char) => char.charCodeAt(0)) : result.body;
729
+ const headers = { ...result.headers };
730
+ if (isBase64) {
731
+ for (const name of Object.keys(headers)) {
732
+ if (name.toLowerCase() === "x-stina-body-encoding") delete headers[name];
733
+ }
734
+ }
735
+ return new Response(body, {
699
736
  status: result.status,
700
737
  statusText: result.statusText,
701
- headers: result.headers
738
+ headers
702
739
  });
703
740
  },
704
741
  async *fetchStream(url, options) {