@stina/extension-api 0.11.2 → 0.14.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.
- package/dist/{chunk-IKJ37ZGB.js → chunk-Q7KN57DE.js} +1 -1
- package/dist/chunk-Q7KN57DE.js.map +1 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -3
- package/dist/index.d.ts +7 -3
- package/dist/index.js +1 -1
- package/dist/runtime.cjs +46 -0
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.d.cts +2 -2
- package/dist/runtime.d.ts +2 -2
- package/dist/runtime.js +47 -1
- package/dist/runtime.js.map +1 -1
- package/dist/{types-Cw9zIBl8.d.cts → types-D9nElTai.d.cts} +86 -6
- package/dist/{types-Cw9zIBl8.d.ts → types-D9nElTai.d.ts} +86 -6
- package/package.json +1 -1
- package/src/messages.ts +8 -0
- package/src/runtime.ts +59 -2
- package/src/types.ts +91 -6
- package/dist/chunk-IKJ37ZGB.js.map +0 -1
package/src/types.ts
CHANGED
|
@@ -435,7 +435,28 @@ export interface Disposable {
|
|
|
435
435
|
}
|
|
436
436
|
|
|
437
437
|
/**
|
|
438
|
-
* Context provided to extension's activate function
|
|
438
|
+
* Context provided to extension's activate function.
|
|
439
|
+
*
|
|
440
|
+
* ## User ID Context
|
|
441
|
+
*
|
|
442
|
+
* The `userId` field provides the current user context for extensions. It is set when:
|
|
443
|
+
* - A tool is executed by a user
|
|
444
|
+
* - An action is executed by a user
|
|
445
|
+
* - A scheduled job fires (if the job was created with a userId)
|
|
446
|
+
*
|
|
447
|
+
* For extension activation, `userId` is undefined since activation happens at system level.
|
|
448
|
+
* Extensions should check for `userId` in their tool/action handlers to access user-specific data.
|
|
449
|
+
*
|
|
450
|
+
* @example
|
|
451
|
+
* ```typescript
|
|
452
|
+
* // In a tool execute handler:
|
|
453
|
+
* execute: async (params, context) => {
|
|
454
|
+
* if (context.userId) {
|
|
455
|
+
* // User-specific logic
|
|
456
|
+
* const userData = await storage.getForUser(context.userId, 'preferences')
|
|
457
|
+
* }
|
|
458
|
+
* }
|
|
459
|
+
* ```
|
|
439
460
|
*/
|
|
440
461
|
export interface ExtensionContext {
|
|
441
462
|
/** Extension metadata */
|
|
@@ -445,6 +466,12 @@ export interface ExtensionContext {
|
|
|
445
466
|
readonly storagePath: string
|
|
446
467
|
}
|
|
447
468
|
|
|
469
|
+
/**
|
|
470
|
+
* Current user ID if in a user context, undefined for global/system operations.
|
|
471
|
+
* Set when tools or actions are executed by a user, or when a user-scoped job fires.
|
|
472
|
+
*/
|
|
473
|
+
readonly userId?: string
|
|
474
|
+
|
|
448
475
|
/** Network access (if permitted) */
|
|
449
476
|
readonly network?: NetworkAPI
|
|
450
477
|
|
|
@@ -573,6 +600,12 @@ export interface SchedulerJobRequest {
|
|
|
573
600
|
schedule: SchedulerSchedule
|
|
574
601
|
payload?: Record<string, unknown>
|
|
575
602
|
misfire?: 'run_once' | 'skip'
|
|
603
|
+
/**
|
|
604
|
+
* Optional user ID for user-scoped jobs.
|
|
605
|
+
* If set, the job is associated with a specific user and the userId
|
|
606
|
+
* will be passed to the extension when the job fires.
|
|
607
|
+
*/
|
|
608
|
+
userId?: string
|
|
576
609
|
}
|
|
577
610
|
|
|
578
611
|
/**
|
|
@@ -584,6 +617,8 @@ export interface SchedulerFirePayload {
|
|
|
584
617
|
scheduledFor: string
|
|
585
618
|
firedAt: string
|
|
586
619
|
delayMs: number
|
|
620
|
+
/** User ID if this is a user-scoped job, undefined if global */
|
|
621
|
+
userId?: string
|
|
587
622
|
}
|
|
588
623
|
|
|
589
624
|
/**
|
|
@@ -638,28 +673,78 @@ export interface DatabaseAPI {
|
|
|
638
673
|
}
|
|
639
674
|
|
|
640
675
|
/**
|
|
641
|
-
* Simple key-value storage API
|
|
676
|
+
* Simple key-value storage API with support for user-scoped storage.
|
|
677
|
+
*
|
|
678
|
+
* ## Global vs User-Scoped Storage
|
|
679
|
+
*
|
|
680
|
+
* Extensions have access to two types of storage:
|
|
681
|
+
* - **Global storage**: Shared across all users, accessed via `get()`, `set()`, etc.
|
|
682
|
+
* - **User-scoped storage**: Isolated per user, accessed via `getForUser()`, `setForUser()`, etc.
|
|
683
|
+
*
|
|
684
|
+
* Use global storage for extension-wide settings and user-scoped storage for
|
|
685
|
+
* user preferences, session data, or any data that should be private to a user.
|
|
686
|
+
*
|
|
687
|
+
* @example
|
|
688
|
+
* ```typescript
|
|
689
|
+
* // Global storage (extension-wide)
|
|
690
|
+
* await storage.set('apiEndpoint', 'https://api.example.com')
|
|
691
|
+
* const endpoint = await storage.get<string>('apiEndpoint')
|
|
692
|
+
*
|
|
693
|
+
* // User-scoped storage (per-user)
|
|
694
|
+
* if (context.userId) {
|
|
695
|
+
* await storage.setForUser(context.userId, 'preferences', { theme: 'dark' })
|
|
696
|
+
* const prefs = await storage.getForUser<Preferences>(context.userId, 'preferences')
|
|
697
|
+
* }
|
|
698
|
+
* ```
|
|
642
699
|
*/
|
|
643
700
|
export interface StorageAPI {
|
|
644
701
|
/**
|
|
645
|
-
* Get a value by key
|
|
702
|
+
* Get a value by key (global/extension-scoped)
|
|
646
703
|
*/
|
|
647
704
|
get<T>(key: string): Promise<T | undefined>
|
|
648
705
|
|
|
649
706
|
/**
|
|
650
|
-
* Set a value
|
|
707
|
+
* Set a value (global/extension-scoped)
|
|
651
708
|
*/
|
|
652
709
|
set(key: string, value: unknown): Promise<void>
|
|
653
710
|
|
|
654
711
|
/**
|
|
655
|
-
* Delete a key
|
|
712
|
+
* Delete a key (global/extension-scoped)
|
|
656
713
|
*/
|
|
657
714
|
delete(key: string): Promise<void>
|
|
658
715
|
|
|
659
716
|
/**
|
|
660
|
-
* Get all keys
|
|
717
|
+
* Get all keys (global/extension-scoped)
|
|
661
718
|
*/
|
|
662
719
|
keys(): Promise<string[]>
|
|
720
|
+
|
|
721
|
+
/**
|
|
722
|
+
* Get a value by key for a specific user (user-scoped)
|
|
723
|
+
* @param userId The user ID
|
|
724
|
+
* @param key The storage key
|
|
725
|
+
*/
|
|
726
|
+
getForUser<T>(userId: string, key: string): Promise<T | undefined>
|
|
727
|
+
|
|
728
|
+
/**
|
|
729
|
+
* Set a value for a specific user (user-scoped)
|
|
730
|
+
* @param userId The user ID
|
|
731
|
+
* @param key The storage key
|
|
732
|
+
* @param value The value to store
|
|
733
|
+
*/
|
|
734
|
+
setForUser(userId: string, key: string, value: unknown): Promise<void>
|
|
735
|
+
|
|
736
|
+
/**
|
|
737
|
+
* Delete a key for a specific user (user-scoped)
|
|
738
|
+
* @param userId The user ID
|
|
739
|
+
* @param key The storage key
|
|
740
|
+
*/
|
|
741
|
+
deleteForUser(userId: string, key: string): Promise<void>
|
|
742
|
+
|
|
743
|
+
/**
|
|
744
|
+
* Get all keys for a specific user (user-scoped)
|
|
745
|
+
* @param userId The user ID
|
|
746
|
+
*/
|
|
747
|
+
keysForUser(userId: string): Promise<string[]>
|
|
663
748
|
}
|
|
664
749
|
|
|
665
750
|
/**
|
|
@@ -1 +0,0 @@
|
|
|
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\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 }\n}\n\nexport interface ActionExecuteRequestMessage {\n type: 'action-execute-request'\n id: string\n payload: {\n actionId: string\n params: Record<string, unknown>\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// 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\nexport interface ReadyMessage {\n type: 'ready'\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 | 'settings.getAll'\n | 'settings.get'\n | 'settings.set'\n | 'user.getProfile'\n | 'events.emit'\n | 'scheduler.schedule'\n | 'scheduler.cancel'\n | 'chat.appendInstruction'\n | 'database.execute'\n | 'storage.get'\n | 'storage.set'\n | 'storage.delete'\n | 'storage.keys'\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// 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":";;;;;;;;AA2OO,SAAS,oBAA4B;AAC1C,SAAO,GAAG,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,EAAE,CAAC;AACjE;","names":[]}
|