@talex-touch/utils 1.0.32 → 1.0.34
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/common/file-scan-utils.ts +0 -1
- package/common/storage/constants.ts +1 -0
- package/common/utils/polling.ts +2 -1
- package/core-box/index.ts +1 -0
- package/core-box/recommendation.ts +77 -0
- package/electron/index.ts +1 -1
- package/index.ts +1 -0
- package/market/constants.ts +95 -0
- package/market/index.ts +2 -0
- package/market/types.ts +118 -0
- package/package.json +1 -1
- package/plugin/index.ts +1 -0
- package/plugin/sdk/README.md +216 -0
- package/plugin/sdk/box-sdk.ts +219 -0
- package/plugin/sdk/feature-sdk.ts +235 -0
- package/plugin/sdk/index.ts +2 -0
- package/plugin/sdk/types.ts +21 -8
- package/plugin/widget.ts +25 -0
- package/renderer/storage/intelligence-storage.ts +12 -9
- package/renderer/storage/storage-subscription.ts +196 -0
- package/types/icon.ts +7 -0
- package/types/intelligence.ts +198 -4
- package/types/update.ts +12 -0
- package/electron/clipboard-helper.ts +0 -207
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Box SDK for Plugin Development
|
|
3
|
+
*
|
|
4
|
+
* Provides a unified API for plugins to control the CoreBox window behavior,
|
|
5
|
+
* including visibility, size, input field control, and input value access.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Expand options for CoreBox window
|
|
10
|
+
*/
|
|
11
|
+
export interface BoxExpandOptions {
|
|
12
|
+
/** Number of items to show (affects window height) */
|
|
13
|
+
length?: number
|
|
14
|
+
/** Force maximum expansion */
|
|
15
|
+
forceMax?: boolean
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Box SDK interface for plugins
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* // Hide CoreBox
|
|
24
|
+
* plugin.box.hide()
|
|
25
|
+
*
|
|
26
|
+
* // Show CoreBox
|
|
27
|
+
* plugin.box.show()
|
|
28
|
+
*
|
|
29
|
+
* // Expand to show 10 items
|
|
30
|
+
* plugin.box.expand({ length: 10 })
|
|
31
|
+
*
|
|
32
|
+
* // Get current input
|
|
33
|
+
* const input = plugin.box.getInput()
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export interface BoxSDK {
|
|
37
|
+
/**
|
|
38
|
+
* Hides the CoreBox window
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```typescript
|
|
42
|
+
* plugin.box.hide()
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
hide(): void
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Shows the CoreBox window
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* plugin.box.show()
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
show(): void
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Expands the CoreBox window
|
|
59
|
+
*
|
|
60
|
+
* @param options - Optional expansion configuration
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```typescript
|
|
64
|
+
* // Expand to show 10 items
|
|
65
|
+
* plugin.box.expand({ length: 10 })
|
|
66
|
+
*
|
|
67
|
+
* // Force maximum expansion
|
|
68
|
+
* plugin.box.expand({ forceMax: true })
|
|
69
|
+
*
|
|
70
|
+
* // Default expansion
|
|
71
|
+
* plugin.box.expand()
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
expand(options?: BoxExpandOptions): Promise<void>
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Shrinks the CoreBox window to compact size
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```typescript
|
|
81
|
+
* plugin.box.shrink()
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
shrink(): Promise<void>
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Hides the input field in CoreBox
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```typescript
|
|
91
|
+
* plugin.box.hideInput()
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
hideInput(): Promise<void>
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Shows the input field in CoreBox
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```typescript
|
|
101
|
+
* plugin.box.showInput()
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
showInput(): Promise<void>
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Gets the current input value from CoreBox search field
|
|
108
|
+
*
|
|
109
|
+
* @returns Promise resolving to the current input string
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```typescript
|
|
113
|
+
* const input = await plugin.box.getInput()
|
|
114
|
+
* console.log('Current input:', input)
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
getInput(): Promise<string>
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Creates a Box SDK instance for plugin use
|
|
122
|
+
*
|
|
123
|
+
* @param channel - The plugin channel bridge for IPC communication
|
|
124
|
+
* @returns Configured Box SDK instance
|
|
125
|
+
*
|
|
126
|
+
* @internal
|
|
127
|
+
*/
|
|
128
|
+
export function createBoxSDK(channel: any): BoxSDK {
|
|
129
|
+
const sendFn = channel.sendToMain || channel.send
|
|
130
|
+
|
|
131
|
+
if (!sendFn) {
|
|
132
|
+
throw new Error('[Box SDK] Channel send function not available')
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return {
|
|
136
|
+
hide(): void {
|
|
137
|
+
sendFn('core-box:hide').catch((error: any) => {
|
|
138
|
+
console.error('[Box SDK] Failed to hide CoreBox:', error)
|
|
139
|
+
})
|
|
140
|
+
},
|
|
141
|
+
|
|
142
|
+
show(): void {
|
|
143
|
+
sendFn('core-box:show').catch((error: any) => {
|
|
144
|
+
console.error('[Box SDK] Failed to show CoreBox:', error)
|
|
145
|
+
})
|
|
146
|
+
},
|
|
147
|
+
|
|
148
|
+
async expand(options?: BoxExpandOptions): Promise<void> {
|
|
149
|
+
try {
|
|
150
|
+
await sendFn('core-box:expand', options || {})
|
|
151
|
+
} catch (error) {
|
|
152
|
+
console.error('[Box SDK] Failed to expand CoreBox:', error)
|
|
153
|
+
throw error
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
|
|
157
|
+
async shrink(): Promise<void> {
|
|
158
|
+
try {
|
|
159
|
+
await sendFn('core-box:expand', { mode: 'collapse' })
|
|
160
|
+
} catch (error) {
|
|
161
|
+
console.error('[Box SDK] Failed to shrink CoreBox:', error)
|
|
162
|
+
throw error
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
|
|
166
|
+
async hideInput(): Promise<void> {
|
|
167
|
+
try {
|
|
168
|
+
await sendFn('core-box:hide-input')
|
|
169
|
+
} catch (error) {
|
|
170
|
+
console.error('[Box SDK] Failed to hide input:', error)
|
|
171
|
+
throw error
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
|
|
175
|
+
async showInput(): Promise<void> {
|
|
176
|
+
try {
|
|
177
|
+
await sendFn('core-box:show-input')
|
|
178
|
+
} catch (error) {
|
|
179
|
+
console.error('[Box SDK] Failed to show input:', error)
|
|
180
|
+
throw error
|
|
181
|
+
}
|
|
182
|
+
},
|
|
183
|
+
|
|
184
|
+
async getInput(): Promise<string> {
|
|
185
|
+
try {
|
|
186
|
+
const result = await sendFn('core-box:get-input')
|
|
187
|
+
return result?.data?.input || result?.input || ''
|
|
188
|
+
} catch (error) {
|
|
189
|
+
console.error('[Box SDK] Failed to get input:', error)
|
|
190
|
+
throw error
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Hook for using Box SDK in plugin context
|
|
198
|
+
*
|
|
199
|
+
* @returns Box SDK instance
|
|
200
|
+
*
|
|
201
|
+
* @example
|
|
202
|
+
* ```typescript
|
|
203
|
+
* const box = useBox()
|
|
204
|
+
*
|
|
205
|
+
* box.hide()
|
|
206
|
+
* box.expand({ length: 10 })
|
|
207
|
+
* const input = await box.getInput()
|
|
208
|
+
* ```
|
|
209
|
+
*/
|
|
210
|
+
export function useBox(): BoxSDK {
|
|
211
|
+
// @ts-ignore - window.$channel is injected by the plugin system
|
|
212
|
+
const channel = window.$channel
|
|
213
|
+
|
|
214
|
+
if (!channel) {
|
|
215
|
+
throw new Error('[Box SDK] Channel not available. Make sure this is called in a plugin context.')
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
return createBoxSDK(channel)
|
|
219
|
+
}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Feature SDK for Plugin Development
|
|
3
|
+
*
|
|
4
|
+
* Provides a unified API for plugins to manage search result items (TuffItems)
|
|
5
|
+
* in the CoreBox interface. This SDK handles item lifecycle, updates, and
|
|
6
|
+
* input change notifications.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { TuffItem } from '../../core-box/tuff'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Input change event handler
|
|
13
|
+
*/
|
|
14
|
+
export type InputChangeHandler = (input: string) => void
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Feature SDK interface for plugins
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* // Push items to CoreBox
|
|
22
|
+
* plugin.feature.pushItems([
|
|
23
|
+
* { id: 'item-1', title: 'Result 1', ... },
|
|
24
|
+
* { id: 'item-2', title: 'Result 2', ... }
|
|
25
|
+
* ])
|
|
26
|
+
*
|
|
27
|
+
* // Update a specific item
|
|
28
|
+
* plugin.feature.updateItem('item-1', { title: 'Updated Title' })
|
|
29
|
+
*
|
|
30
|
+
* // Listen for input changes
|
|
31
|
+
* plugin.feature.onInputChange((input) => {
|
|
32
|
+
* console.log('User typed:', input)
|
|
33
|
+
* })
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export interface FeatureSDK {
|
|
37
|
+
/**
|
|
38
|
+
* Pushes multiple items to the CoreBox search results
|
|
39
|
+
*
|
|
40
|
+
* @param items - Array of TuffItem objects to display
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```typescript
|
|
44
|
+
* plugin.feature.pushItems([
|
|
45
|
+
* {
|
|
46
|
+
* id: 'calc-result',
|
|
47
|
+
* title: { text: '42' },
|
|
48
|
+
* subtitle: { text: 'Calculation result' },
|
|
49
|
+
* source: { id: 'calculator', name: 'Calculator' }
|
|
50
|
+
* }
|
|
51
|
+
* ])
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
pushItems(items: TuffItem[]): void
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Updates a specific item by ID
|
|
58
|
+
*
|
|
59
|
+
* @param id - The unique ID of the item to update
|
|
60
|
+
* @param updates - Partial TuffItem with fields to update
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```typescript
|
|
64
|
+
* // Update title and subtitle
|
|
65
|
+
* plugin.feature.updateItem('item-1', {
|
|
66
|
+
* title: { text: 'New Title' },
|
|
67
|
+
* subtitle: { text: 'Updated subtitle' }
|
|
68
|
+
* })
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
updateItem(id: string, updates: Partial<TuffItem>): void
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Removes a specific item by ID
|
|
75
|
+
*
|
|
76
|
+
* @param id - The unique ID of the item to remove
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```typescript
|
|
80
|
+
* plugin.feature.removeItem('item-1')
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
removeItem(id: string): void
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Clears all items pushed by this plugin
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```typescript
|
|
90
|
+
* plugin.feature.clearItems()
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
clearItems(): void
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Gets all items currently pushed by this plugin
|
|
97
|
+
*
|
|
98
|
+
* @returns Array of TuffItem objects
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```typescript
|
|
102
|
+
* const items = plugin.feature.getItems()
|
|
103
|
+
* console.log(`Currently showing ${items.length} items`)
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
getItems(): TuffItem[]
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Registers a listener for input changes in the CoreBox search field
|
|
110
|
+
*
|
|
111
|
+
* @param handler - Callback function invoked when input changes
|
|
112
|
+
* @returns Unsubscribe function
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* ```typescript
|
|
116
|
+
* const unsubscribe = plugin.feature.onInputChange((input) => {
|
|
117
|
+
* console.log('User typed:', input)
|
|
118
|
+
* // Perform real-time search
|
|
119
|
+
* performSearch(input)
|
|
120
|
+
* })
|
|
121
|
+
*
|
|
122
|
+
* // Later, unsubscribe
|
|
123
|
+
* unsubscribe()
|
|
124
|
+
* ```
|
|
125
|
+
*/
|
|
126
|
+
onInputChange(handler: InputChangeHandler): () => void
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Creates a Feature SDK instance for plugin use
|
|
131
|
+
*
|
|
132
|
+
* @param boxItemsAPI - The boxItems API object from plugin context
|
|
133
|
+
* @param channel - The plugin channel bridge for IPC communication
|
|
134
|
+
* @returns Configured Feature SDK instance
|
|
135
|
+
*
|
|
136
|
+
* @internal
|
|
137
|
+
*/
|
|
138
|
+
export function createFeatureSDK(boxItemsAPI: any, channel: any): FeatureSDK {
|
|
139
|
+
const inputChangeHandlers: Set<InputChangeHandler> = new Set()
|
|
140
|
+
|
|
141
|
+
// Register listener for input change events from main process
|
|
142
|
+
const registerListener = () => {
|
|
143
|
+
if (channel.onMain) {
|
|
144
|
+
// Main process plugin context
|
|
145
|
+
channel.onMain('core-box:input-changed', (event: any) => {
|
|
146
|
+
const input = event.data?.input || event.input || ''
|
|
147
|
+
inputChangeHandlers.forEach(handler => handler(input))
|
|
148
|
+
})
|
|
149
|
+
} else if (channel.on) {
|
|
150
|
+
// Renderer process context
|
|
151
|
+
channel.on('core-box:input-changed', (data: any) => {
|
|
152
|
+
const input = data?.input || data || ''
|
|
153
|
+
inputChangeHandlers.forEach(handler => handler(input))
|
|
154
|
+
})
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
registerListener()
|
|
159
|
+
|
|
160
|
+
return {
|
|
161
|
+
pushItems(items: TuffItem[]): void {
|
|
162
|
+
if (!boxItemsAPI || !boxItemsAPI.pushItems) {
|
|
163
|
+
throw new Error('[Feature SDK] boxItems API not available')
|
|
164
|
+
}
|
|
165
|
+
boxItemsAPI.pushItems(items)
|
|
166
|
+
},
|
|
167
|
+
|
|
168
|
+
updateItem(id: string, updates: Partial<TuffItem>): void {
|
|
169
|
+
if (!boxItemsAPI || !boxItemsAPI.update) {
|
|
170
|
+
throw new Error('[Feature SDK] boxItems API not available')
|
|
171
|
+
}
|
|
172
|
+
boxItemsAPI.update(id, updates)
|
|
173
|
+
},
|
|
174
|
+
|
|
175
|
+
removeItem(id: string): void {
|
|
176
|
+
if (!boxItemsAPI || !boxItemsAPI.remove) {
|
|
177
|
+
throw new Error('[Feature SDK] boxItems API not available')
|
|
178
|
+
}
|
|
179
|
+
boxItemsAPI.remove(id)
|
|
180
|
+
},
|
|
181
|
+
|
|
182
|
+
clearItems(): void {
|
|
183
|
+
if (!boxItemsAPI || !boxItemsAPI.clear) {
|
|
184
|
+
throw new Error('[Feature SDK] boxItems API not available')
|
|
185
|
+
}
|
|
186
|
+
boxItemsAPI.clear()
|
|
187
|
+
},
|
|
188
|
+
|
|
189
|
+
getItems(): TuffItem[] {
|
|
190
|
+
if (!boxItemsAPI || !boxItemsAPI.getItems) {
|
|
191
|
+
throw new Error('[Feature SDK] boxItems API not available')
|
|
192
|
+
}
|
|
193
|
+
return boxItemsAPI.getItems()
|
|
194
|
+
},
|
|
195
|
+
|
|
196
|
+
onInputChange(handler: InputChangeHandler): () => void {
|
|
197
|
+
inputChangeHandlers.add(handler)
|
|
198
|
+
|
|
199
|
+
return () => {
|
|
200
|
+
inputChangeHandlers.delete(handler)
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Hook for using Feature SDK in plugin context
|
|
208
|
+
*
|
|
209
|
+
* @returns Feature SDK instance
|
|
210
|
+
*
|
|
211
|
+
* @example
|
|
212
|
+
* ```typescript
|
|
213
|
+
* const feature = useFeature()
|
|
214
|
+
*
|
|
215
|
+
* feature.pushItems([
|
|
216
|
+
* { id: '1', title: { text: 'Item 1' }, ... }
|
|
217
|
+
* ])
|
|
218
|
+
* ```
|
|
219
|
+
*/
|
|
220
|
+
export function useFeature(): FeatureSDK {
|
|
221
|
+
// @ts-ignore - window.$boxItems and window.$channel are injected by the plugin system
|
|
222
|
+
const boxItemsAPI = window.$boxItems
|
|
223
|
+
// @ts-ignore
|
|
224
|
+
const channel = window.$channel
|
|
225
|
+
|
|
226
|
+
if (!boxItemsAPI) {
|
|
227
|
+
throw new Error('[Feature SDK] boxItems API not available. Make sure this is called in a plugin context.')
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (!channel) {
|
|
231
|
+
throw new Error('[Feature SDK] Channel not available. Make sure this is called in a plugin context.')
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return createFeatureSDK(boxItemsAPI, channel)
|
|
235
|
+
}
|
package/plugin/sdk/index.ts
CHANGED
|
@@ -7,10 +7,12 @@ export interface ITouchSDK {
|
|
|
7
7
|
|
|
8
8
|
// Note: Window.$touchSDK is declared in ../preload.ts to avoid duplicate declarations
|
|
9
9
|
|
|
10
|
+
export * from './box-sdk'
|
|
10
11
|
export * from './channel'
|
|
11
12
|
export * from './clipboard'
|
|
12
13
|
export * from './core-box'
|
|
13
14
|
export * from './division-box'
|
|
15
|
+
export * from './feature-sdk'
|
|
14
16
|
export { createFeaturesManager, useFeatures } from './features'
|
|
15
17
|
|
|
16
18
|
export * from './hooks/index'
|
package/plugin/sdk/types.ts
CHANGED
|
@@ -183,6 +183,18 @@ export interface IPluginUtils {
|
|
|
183
183
|
*/
|
|
184
184
|
divisionBox: import('./division-box').DivisionBoxSDK
|
|
185
185
|
|
|
186
|
+
/**
|
|
187
|
+
* Box SDK for controlling CoreBox window behavior
|
|
188
|
+
* @see {@link BoxSDK}
|
|
189
|
+
*/
|
|
190
|
+
box: import('./box-sdk').BoxSDK
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Feature SDK for managing search result items
|
|
194
|
+
* @see {@link FeatureSDK}
|
|
195
|
+
*/
|
|
196
|
+
feature: import('./feature-sdk').FeatureSDK
|
|
197
|
+
|
|
186
198
|
/**
|
|
187
199
|
* Opens a URL in the default browser
|
|
188
200
|
* @param url - The URL to open
|
|
@@ -190,21 +202,22 @@ export interface IPluginUtils {
|
|
|
190
202
|
openUrl: (url: string) => void
|
|
191
203
|
|
|
192
204
|
/**
|
|
193
|
-
*
|
|
194
|
-
* @
|
|
205
|
+
* @deprecated Use plugin.feature.pushItems() instead
|
|
206
|
+
* @throws Error indicating the API is deprecated
|
|
195
207
|
*/
|
|
196
|
-
pushItems: (items: any[]) =>
|
|
208
|
+
pushItems: (items: any[]) => never
|
|
197
209
|
|
|
198
210
|
/**
|
|
199
|
-
*
|
|
211
|
+
* @deprecated Use plugin.feature.clearItems() instead
|
|
212
|
+
* @throws Error indicating the API is deprecated
|
|
200
213
|
*/
|
|
201
|
-
clearItems: () =>
|
|
214
|
+
clearItems: () => never
|
|
202
215
|
|
|
203
216
|
/**
|
|
204
|
-
*
|
|
205
|
-
* @
|
|
217
|
+
* @deprecated Use plugin.feature.getItems() instead
|
|
218
|
+
* @throws Error indicating the API is deprecated
|
|
206
219
|
*/
|
|
207
|
-
getItems: () =>
|
|
220
|
+
getItems: () => never
|
|
208
221
|
|
|
209
222
|
/**
|
|
210
223
|
* Features manager for dynamic feature management
|
package/plugin/widget.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export const DEFAULT_WIDGET_RENDERERS = {
|
|
2
|
+
CORE_PREVIEW_CARD: 'core-preview-card',
|
|
3
|
+
CORE_INTELLIGENCE_ANSWER: 'core-intelligence-answer',
|
|
4
|
+
} as const
|
|
5
|
+
|
|
6
|
+
const values = Object.values(DEFAULT_WIDGET_RENDERERS)
|
|
7
|
+
export const DEFAULT_WIDGET_RENDERER_IDS = new Set<string>(values)
|
|
8
|
+
|
|
9
|
+
export function isDefaultWidgetRenderer(id: string | undefined): boolean {
|
|
10
|
+
return Boolean(id) && DEFAULT_WIDGET_RENDERER_IDS.has(id!)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface WidgetRegistrationPayload {
|
|
14
|
+
widgetId: string
|
|
15
|
+
pluginName: string
|
|
16
|
+
featureId: string
|
|
17
|
+
filePath: string
|
|
18
|
+
code: string
|
|
19
|
+
styles: string
|
|
20
|
+
hash: string
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function makeWidgetId(pluginName: string, featureId: string): string {
|
|
24
|
+
return `${pluginName}::${featureId}`
|
|
25
|
+
}
|
|
@@ -18,7 +18,7 @@ const defaultIntelligenceData: AISDKStorageData = {
|
|
|
18
18
|
providers: [...DEFAULT_PROVIDERS],
|
|
19
19
|
globalConfig: { ...DEFAULT_GLOBAL_CONFIG },
|
|
20
20
|
capabilities: { ...DEFAULT_CAPABILITIES },
|
|
21
|
-
version:
|
|
21
|
+
version: 2,
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
const INTELLIGENCE_STORAGE_KEY = `storage:${StorageList.IntelligenceConfig}`
|
|
@@ -145,8 +145,9 @@ export async function migrateIntelligenceSettings(): Promise<void> {
|
|
|
145
145
|
console.log('[Intelligence Storage] Starting migration check...')
|
|
146
146
|
const currentData = intelligenceStorage.data
|
|
147
147
|
|
|
148
|
-
|
|
149
|
-
|
|
148
|
+
// Version 2: Force update capabilities to include all new ones
|
|
149
|
+
if (!currentData.version || currentData.version < 2) {
|
|
150
|
+
console.log('[Intelligence Storage] Migrating settings to version 2')
|
|
150
151
|
|
|
151
152
|
const migratedProviders = currentData.providers.map(provider => ({
|
|
152
153
|
...provider,
|
|
@@ -169,24 +170,26 @@ export async function migrateIntelligenceSettings(): Promise<void> {
|
|
|
169
170
|
cacheExpiration: currentData.globalConfig?.cacheExpiration ?? 3600,
|
|
170
171
|
}
|
|
171
172
|
|
|
172
|
-
|
|
173
|
-
|
|
173
|
+
// Force update to latest DEFAULT_CAPABILITIES (version 2)
|
|
174
|
+
console.log('[Intelligence Storage] Updating capabilities to latest defaults')
|
|
175
|
+
|
|
174
176
|
intelligenceStorage.applyData({
|
|
175
177
|
providers: migratedProviders,
|
|
176
178
|
globalConfig: migratedGlobalConfig,
|
|
177
|
-
capabilities:
|
|
178
|
-
version:
|
|
179
|
+
capabilities: { ...DEFAULT_CAPABILITIES },
|
|
180
|
+
version: 2,
|
|
179
181
|
})
|
|
180
182
|
|
|
181
183
|
await intelligenceStorage.saveToRemote({ force: true })
|
|
182
184
|
|
|
183
|
-
console.log('[Intelligence Storage] Migration complete')
|
|
185
|
+
console.log('[Intelligence Storage] Migration to v2 complete, capabilities count:', Object.keys(DEFAULT_CAPABILITIES).length)
|
|
184
186
|
}
|
|
185
187
|
else {
|
|
186
188
|
console.log('[Intelligence Storage] No migration needed, current version:', currentData.version)
|
|
187
189
|
}
|
|
188
190
|
|
|
189
191
|
console.log('[Intelligence Storage] Final providers count:', intelligenceStorage.data.providers.length)
|
|
192
|
+
console.log('[Intelligence Storage] Final capabilities count:', Object.keys(intelligenceStorage.data.capabilities).length)
|
|
190
193
|
}
|
|
191
194
|
|
|
192
195
|
/**
|
|
@@ -201,7 +204,7 @@ export async function resetIntelligenceConfig(): Promise<void> {
|
|
|
201
204
|
providers: [...DEFAULT_PROVIDERS],
|
|
202
205
|
globalConfig: { ...DEFAULT_GLOBAL_CONFIG },
|
|
203
206
|
capabilities: { ...DEFAULT_CAPABILITIES },
|
|
204
|
-
version:
|
|
207
|
+
version: 2,
|
|
205
208
|
})
|
|
206
209
|
|
|
207
210
|
await intelligenceStorage.saveToRemote({ force: true })
|