@talex-touch/utils 1.0.30 → 1.0.32

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.
Files changed (113) hide show
  1. package/animation/window-node.ts +205 -0
  2. package/animation/window.ts +19 -15
  3. package/auth/clerk-types.ts +1 -1
  4. package/auth/index.ts +1 -1
  5. package/auth/useAuthState.ts +6 -5
  6. package/auth/useClerkConfig.ts +6 -6
  7. package/auth/useClerkProvider.ts +3 -2
  8. package/channel/index.ts +28 -21
  9. package/common/file-scan-constants.ts +137 -121
  10. package/common/file-scan-utils.ts +49 -25
  11. package/common/index.ts +3 -3
  12. package/common/search/gather.ts +1 -1
  13. package/common/search/index.ts +5 -6
  14. package/common/storage/constants.ts +3 -2
  15. package/common/storage/entity/app-settings.ts +19 -3
  16. package/common/storage/entity/shortcut-settings.ts +10 -10
  17. package/common/storage/shortcut-storage.ts +6 -4
  18. package/common/utils/file.ts +15 -4
  19. package/common/utils/index.ts +62 -52
  20. package/common/utils/polling.ts +114 -63
  21. package/common/utils/task-queue.ts +11 -10
  22. package/common/utils/time.ts +50 -47
  23. package/common/utils/timing.ts +41 -37
  24. package/core-box/builder/index.ts +1 -1
  25. package/core-box/builder/tuff-builder.ts +255 -230
  26. package/core-box/index.ts +3 -6
  27. package/core-box/preview/index.ts +1 -0
  28. package/core-box/preview/types.ts +43 -0
  29. package/core-box/tuff/index.ts +1 -1
  30. package/core-box/tuff/tuff-dsl.ts +419 -253
  31. package/electron/clipboard-helper.ts +20 -12
  32. package/electron/download-manager.ts +43 -42
  33. package/electron/env-tool.ts +19 -18
  34. package/electron/file-parsers/index.ts +2 -2
  35. package/electron/file-parsers/parsers/text-parser.ts +15 -14
  36. package/electron/file-parsers/registry.ts +9 -7
  37. package/electron/file-parsers/types.ts +4 -4
  38. package/electron/index.ts +1 -1
  39. package/eventbus/index.ts +11 -11
  40. package/index.ts +6 -5
  41. package/intelligence/client.ts +87 -0
  42. package/intelligence/index.ts +1 -0
  43. package/package.json +14 -14
  44. package/permission/index.ts +8 -8
  45. package/plugin/channel.ts +77 -68
  46. package/plugin/index.ts +113 -84
  47. package/plugin/install.ts +8 -8
  48. package/plugin/log/types.ts +5 -5
  49. package/plugin/node/index.ts +1 -1
  50. package/plugin/node/logger-manager.ts +14 -11
  51. package/plugin/node/logger.ts +8 -8
  52. package/plugin/plugin-source.ts +11 -11
  53. package/plugin/preload.ts +6 -3
  54. package/plugin/providers/registry.ts +8 -7
  55. package/plugin/providers/types.ts +6 -6
  56. package/plugin/sdk/channel.ts +20 -20
  57. package/plugin/sdk/clipboard.ts +8 -6
  58. package/plugin/sdk/common.ts +10 -6
  59. package/plugin/sdk/core-box.ts +2 -3
  60. package/plugin/sdk/division-box.ts +266 -0
  61. package/plugin/sdk/enum/bridge-event.ts +1 -1
  62. package/plugin/sdk/examples/storage-onDidChange-example.js +1 -1
  63. package/plugin/sdk/features.ts +34 -26
  64. package/plugin/sdk/hooks/bridge.ts +3 -6
  65. package/plugin/sdk/hooks/index.ts +1 -1
  66. package/plugin/sdk/hooks/life-cycle.ts +4 -10
  67. package/plugin/sdk/index.ts +9 -13
  68. package/plugin/sdk/service/index.ts +3 -3
  69. package/plugin/sdk/storage.ts +4 -4
  70. package/plugin/sdk/system.ts +1 -1
  71. package/plugin/sdk/types.ts +169 -143
  72. package/plugin/sdk/window/index.ts +8 -5
  73. package/preload/loading.ts +6 -6
  74. package/preload/renderer.ts +4 -2
  75. package/renderer/hooks/arg-mapper.ts +1 -2
  76. package/renderer/hooks/index.ts +2 -0
  77. package/renderer/hooks/initialize.ts +10 -8
  78. package/renderer/hooks/performance.ts +4 -4
  79. package/renderer/hooks/use-channel.ts +150 -0
  80. package/renderer/hooks/use-intelligence.ts +236 -0
  81. package/renderer/index.ts +6 -1
  82. package/renderer/ref.ts +32 -36
  83. package/renderer/slots.ts +29 -26
  84. package/renderer/storage/app-settings.ts +16 -6
  85. package/renderer/storage/base-storage.ts +236 -88
  86. package/renderer/storage/index.ts +3 -0
  87. package/renderer/storage/intelligence-storage.ts +215 -0
  88. package/renderer/storage/openers.ts +13 -3
  89. package/renderer/touch-sdk/env.ts +41 -41
  90. package/renderer/touch-sdk/index.ts +1 -1
  91. package/renderer/touch-sdk/terminal.ts +5 -5
  92. package/renderer/touch-sdk/utils.ts +4 -3
  93. package/search/levenshtein-utils.ts +11 -11
  94. package/search/types.ts +102 -103
  95. package/service/index.ts +11 -11
  96. package/service/protocol/index.ts +217 -14
  97. package/types/division-box.ts +248 -0
  98. package/types/download.ts +72 -34
  99. package/types/icon.ts +2 -1
  100. package/types/index.ts +3 -1
  101. package/types/intelligence.ts +413 -0
  102. package/types/modules/base.ts +16 -16
  103. package/types/modules/index.ts +1 -1
  104. package/types/modules/module-lifecycle.ts +21 -21
  105. package/types/modules/module-manager.ts +11 -11
  106. package/types/modules/module.ts +16 -16
  107. package/types/storage.ts +0 -1
  108. package/types/touch-app-core.ts +32 -32
  109. package/types/update.ts +79 -21
  110. package/core-box/README.md +0 -218
  111. package/core-box/builder/tuff-builder.example.ts.bak +0 -258
  112. package/core-box/run-tests.sh +0 -7
  113. package/core-box/search.ts +0 -1
package/plugin/index.ts CHANGED
@@ -1,6 +1,10 @@
1
- import { Arch, SupportOS } from './../base/index';
2
- import type { IPluginLogger } from './log/types';
3
- import type { PluginInstallRequest, PluginInstallSummary } from './providers';
1
+ import type { FSWatcher } from 'chokidar'
2
+ import type { ITuffIcon } from '../types/icon'
3
+ import type { Arch, SupportOS } from './../base/index'
4
+
5
+ import type { IPluginLogger } from './log/types'
6
+
7
+ import type { PluginInstallRequest, PluginInstallSummary } from './providers'
4
8
 
5
9
  export enum PluginStatus {
6
10
  DISABLED,
@@ -15,8 +19,8 @@ export enum PluginStatus {
15
19
  LOADED,
16
20
  LOAD_FAILED,
17
21
 
18
- DEV_DISCONNECTED, // Dev Server 断连
19
- DEV_RECONNECTING, // 正在重连
22
+ DEV_DISCONNECTED, // Dev Server 断连
23
+ DEV_RECONNECTING, // 正在重连
20
24
  }
21
25
 
22
26
  export interface PluginIssue {
@@ -36,9 +40,6 @@ export interface DevServerHealthCheckResult {
36
40
  error?: string
37
41
  }
38
42
 
39
- import type { ITuffIcon } from '../types/icon'
40
-
41
-
42
43
  export interface IPlatformInfo {
43
44
  enable: boolean
44
45
  arch: Arch[]
@@ -73,26 +74,27 @@ export interface ITouchPlugin extends IPluginBaseInfo {
73
74
  logger: IPluginLogger<any>
74
75
  features: IPluginFeature[]
75
76
  issues: PluginIssue[]
77
+ divisionBoxConfig?: import('../types/division-box').ManifestDivisionBoxConfig
76
78
 
77
- addFeature(feature: IPluginFeature): boolean
78
- delFeature(featureId: string): boolean
79
- getFeature(featureId: string): IPluginFeature | null
80
- getFeatures(): IPluginFeature[]
81
- triggerFeature(feature: IPluginFeature, query: any): void
82
- triggerInputChanged(feature: IPluginFeature, query: any): void
79
+ addFeature: (feature: IPluginFeature) => boolean
80
+ delFeature: (featureId: string) => boolean
81
+ getFeature: (featureId: string) => IPluginFeature | null
82
+ getFeatures: () => IPluginFeature[]
83
+ triggerFeature: (feature: IPluginFeature, query: any) => void
84
+ triggerInputChanged: (feature: IPluginFeature, query: any) => void
83
85
 
84
86
  get status(): PluginStatus
85
87
  set status(v: PluginStatus)
86
88
 
87
- enable(): Promise<boolean>
88
- disable(): Promise<boolean>
89
+ enable: () => Promise<boolean>
90
+ disable: () => Promise<boolean>
89
91
 
90
92
  /**
91
93
  * Get the plugin file.
92
94
  * @param fileName The name of the file.
93
95
  * @returns The content of the file.
94
96
  */
95
- getPluginFile(fileName: string): object
97
+ getPluginFile: (fileName: string) => object
96
98
 
97
99
  /**
98
100
  * Save the plugin file.
@@ -100,39 +102,39 @@ export interface ITouchPlugin extends IPluginBaseInfo {
100
102
  * @param content The content of the file.
101
103
  * @returns The result of the save operation.
102
104
  */
103
- savePluginFile(fileName: string, content: object): { success: boolean; error?: string }
105
+ savePluginFile: (fileName: string, content: object) => { success: boolean, error?: string }
104
106
 
105
107
  /**
106
108
  * Delete the plugin file.
107
109
  * @param fileName The name of the file.
108
110
  * @returns The result of the delete operation.
109
111
  */
110
- deletePluginFile(fileName: string): { success: boolean; error?: string }
112
+ deletePluginFile: (fileName: string) => { success: boolean, error?: string }
111
113
 
112
114
  /**
113
115
  * List all files in the plugin.
114
116
  * @returns The list of files.
115
117
  */
116
- listPluginFiles(): string[]
118
+ listPluginFiles: () => string[]
117
119
 
118
120
  /**
119
121
  * Get the plugin configuration.
120
122
  * @returns The configuration content.
121
123
  */
122
- getPluginConfig(): object
124
+ getPluginConfig: () => object
123
125
 
124
126
  /**
125
127
  * Save the plugin configuration.
126
128
  * @param content The configuration content.
127
129
  * @returns The result of the save operation.
128
130
  */
129
- savePluginConfig(content: object): { success: boolean; error?: string }
131
+ savePluginConfig: (content: object) => { success: boolean, error?: string }
130
132
  }
131
133
 
132
134
  export interface IFeatureCommand {
133
- type: "match" | "contain" | "regex" | "function" | "over" | "image" | "files" | "directory" | "window"
135
+ type: 'match' | 'contain' | 'regex' | 'function' | 'over' | 'image' | 'files' | 'directory' | 'window'
134
136
  value: string | string[] | RegExp | Function
135
- onTrigger(): void
137
+ onTrigger: () => void
136
138
  }
137
139
 
138
140
  export interface IPluginFeature {
@@ -150,9 +152,18 @@ export interface IPluginFeature {
150
152
  * Default is 0
151
153
  */
152
154
  priority?: number
155
+ /**
156
+ * Accepted input types for this feature
157
+ * @description Declares which types of inputs this feature can accept and process.
158
+ * If not specified, defaults to ['text'] only (backward compatible).
159
+ * When query contains inputs, only features accepting those input types will be shown.
160
+ * @example ['text', 'image'] - Feature accepts both text and images
161
+ * @example ['image', 'files'] - Feature only accepts images and files (no text-only queries)
162
+ */
163
+ acceptedInputTypes?: Array<'text' | 'image' | 'files' | 'html'>
153
164
  }
154
165
 
155
- export type IFeatureInteraction = {
166
+ export interface IFeatureInteraction {
156
167
  type: 'webcontent' | 'widget'
157
168
  /**
158
169
  * The relative path to the html file from the plugin root.
@@ -169,36 +180,39 @@ export interface IFeatureLifeCycle {
169
180
  * onInit is called when the feature is initialized.
170
181
  * Can be used to prepare data or UI specific to this session.
171
182
  */
172
- onInit?(): void
183
+ onInit?: () => void
173
184
 
174
185
  /**
175
186
  * Called when a message is received from the main application.
176
187
  * @param key - The key of the message
177
188
  * @param info - The information of the message
178
189
  */
179
- onMessage?(key: string, info: any): void
190
+ onMessage?: (key: string, info: any) => void
180
191
  /**
181
192
  * Called when a feature is actively launched from the launcher.
182
193
  * Can be used to prepare data or UI specific to this session.
183
194
  * @param feature - The feature instance being launched
184
195
  */
185
- onLaunch?(feature: IPluginFeature): void
196
+ onLaunch?: (feature: IPluginFeature) => void
186
197
 
187
198
  /**
188
199
  * Called when a feature is triggered via a matching command.
189
200
  * @param id - Feature ID
190
- * @param data - The triggering payload
201
+ * @param data - The triggering payload. Can be:
202
+ * - string: Plain text query (backward compatible)
203
+ * - TuffQuery object: Complete query with text and optional inputs array containing clipboard data (images, files, HTML)
191
204
  * @param feature - The full feature definition
192
205
  * @param signal - An AbortSignal to cancel the operation
206
+ * @returns If returns false, the feature will not enter activation state (e.g., just opens browser and exits)
193
207
  */
194
- onFeatureTriggered(id: string, data: any, feature: IPluginFeature, signal?: AbortSignal): void
208
+ onFeatureTriggered: (id: string, data: any, feature: IPluginFeature, signal?: AbortSignal) => boolean | void
195
209
 
196
210
  /**
197
211
  * Called when user input changes within this feature’s input box.
198
212
  * For example, search text or commands typed.
199
213
  * @param input - The new input value
200
214
  */
201
- onInputChanged?(input: string): void
215
+ onInputChanged?: (input: string) => void
202
216
 
203
217
  /**
204
218
  * Called when a user selects or clicks an actionable item inside the feature.
@@ -206,14 +220,14 @@ export interface IFeatureLifeCycle {
206
220
  * @param actionId - A string identifier for the clicked action
207
221
  * @param data - Optional payload associated with that action
208
222
  */
209
- onActionClick?(actionId: string, data?: any): void
223
+ onActionClick?: (actionId: string, data?: any) => void
210
224
 
211
225
  /**
212
226
  * Called when the feature is manually closed by the user or by the system.
213
227
  * Useful for cleanup or state saving.
214
228
  * @param feature - The feature instance being closed
215
229
  */
216
- onClose?(feature: IPluginFeature): void
230
+ onClose?: (feature: IPluginFeature) => void
217
231
 
218
232
  /**
219
233
  * Called when an item generated by this feature is executed.
@@ -222,7 +236,7 @@ export interface IFeatureLifeCycle {
222
236
  * @param item The TuffItem that was executed.
223
237
  * @returns Object indicating whether to activate the feature and any activation data
224
238
  */
225
- onItemAction?(item: any): Promise<{
239
+ onItemAction?: (item: any) => Promise<{
226
240
  /** Whether the action executed an external operation (e.g., opened browser) */
227
241
  externalAction?: boolean
228
242
  /** Whether the feature should be activated after this action */
@@ -236,7 +250,7 @@ export interface IFeatureLifeCycle {
236
250
  * @param key - The storage key that changed
237
251
  * @param value - The new value (undefined if key was removed)
238
252
  */
239
- onStorageChange?(key: string, value: any): void
253
+ onStorageChange?: (key: string, value: any) => void
240
254
  }
241
255
 
242
256
  /**
@@ -249,21 +263,24 @@ export interface ITargetFeatureLifeCycle {
249
263
  * Can be used to prepare data or UI specific to this session.
250
264
  * @param feature - The feature instance being launched
251
265
  */
252
- onLaunch?(feature: IPluginFeature): void
266
+ onLaunch?: (feature: IPluginFeature) => void
253
267
 
254
268
  /**
255
269
  * Called when the feature is triggered via a matching command.
256
- * @param data - The triggering payload
270
+ * @param data - The triggering payload. Can be:
271
+ * - string: Plain text query (backward compatible)
272
+ * - TuffQuery object: Complete query with text and optional inputs array containing clipboard data (images, files, HTML)
257
273
  * @param feature - The full feature definition
274
+ * @returns If returns false, the feature will not enter activation state (e.g., just opens browser and exits)
258
275
  */
259
- onFeatureTriggered(data: any, feature: IPluginFeature): void
276
+ onFeatureTriggered: (data: any, feature: IPluginFeature) => boolean | void
260
277
 
261
278
  /**
262
279
  * Called when user input changes within this feature’s input box.
263
280
  * For example, search text or commands typed.
264
281
  * @param input - The new input value
265
282
  */
266
- onInputChanged?(input: string): void
283
+ onInputChanged?: (input: string) => void
267
284
 
268
285
  /**
269
286
  * Called when a user selects or clicks an actionable item inside the feature.
@@ -271,14 +288,14 @@ export interface ITargetFeatureLifeCycle {
271
288
  * @param actionId - A string identifier for the clicked action
272
289
  * @param data - Optional payload associated with that action
273
290
  */
274
- onActionClick?(actionId: string, data?: any): void
291
+ onActionClick?: (actionId: string, data?: any) => void
275
292
 
276
293
  /**
277
294
  * Called when the feature is manually closed by the user or by the system.
278
295
  * Useful for cleanup or state saving.
279
296
  * @param feature - The feature instance being closed
280
297
  */
281
- onClose?(feature: IPluginFeature): void
298
+ onClose?: (feature: IPluginFeature) => void
282
299
 
283
300
  /**
284
301
  * Called when an item generated by this feature is executed.
@@ -287,7 +304,7 @@ export interface ITargetFeatureLifeCycle {
287
304
  * @param item The TuffItem that was executed.
288
305
  * @returns Object indicating whether to activate the feature and any activation data
289
306
  */
290
- onItemAction?(item: any): Promise<{
307
+ onItemAction?: (item: any) => Promise<{
291
308
  /** Whether the action executed an external operation (e.g., opened browser) */
292
309
  externalAction?: boolean
293
310
  /** Whether the feature should be activated after this action */
@@ -316,8 +333,6 @@ export enum PluginSourceType {
316
333
  FILE_SYSTEM = 'file_system',
317
334
  }
318
335
 
319
- import type { FSWatcher } from 'chokidar'
320
-
321
336
  export interface IPluginManager {
322
337
  plugins: Map<string, ITouchPlugin>
323
338
  active: string | null
@@ -330,18 +345,24 @@ export interface IPluginManager {
330
345
  devWatcher: any // Temporarily any, as DevPluginWatcher is internal to core-app
331
346
  healthMonitor: any | null // DevServerHealthMonitor instance, set by PluginModule
332
347
 
333
- getPluginList(): Array<object>
334
- setActivePlugin(pluginName: string): boolean
335
- hasPlugin(name: string): boolean
336
- getPluginByName(name: string): ITouchPlugin | undefined
337
- enablePlugin(pluginName: string): Promise<boolean>
338
- disablePlugin(pluginName: string): Promise<boolean>
339
- reloadPlugin(pluginName: string): Promise<void>
340
- persistEnabledPlugins(): Promise<void>
341
- listPlugins(): Promise<Array<string>>
342
- loadPlugin(pluginName: string): Promise<boolean>
343
- unloadPlugin(pluginName: string): Promise<boolean>
344
- installFromSource(request: PluginInstallRequest): Promise<PluginInstallSummary>
348
+ getPluginList: () => Array<object>
349
+ setActivePlugin: (pluginName: string) => boolean
350
+ hasPlugin: (name: string) => boolean
351
+ getPluginByName: (name: string) => ITouchPlugin | undefined
352
+ enablePlugin: (pluginName: string) => Promise<boolean>
353
+ disablePlugin: (pluginName: string) => Promise<boolean>
354
+ reloadPlugin: (pluginName: string) => Promise<void>
355
+ persistEnabledPlugins: () => Promise<void>
356
+ listPlugins: () => Promise<Array<string>>
357
+ loadPlugin: (pluginName: string) => Promise<boolean>
358
+ unloadPlugin: (pluginName: string) => Promise<boolean>
359
+ installFromSource: (request: PluginInstallRequest) => Promise<PluginInstallSummary>
360
+ uninstallPlugin: (pluginName: string) => Promise<boolean>
361
+ /**
362
+ * Register an internal plugin that is created in code (no manifest / scanning).
363
+ * Internal plugins are always hidden from user-facing plugin lists.
364
+ */
365
+ registerInternalPlugin: (plugin: ITouchPlugin) => void
345
366
  }
346
367
 
347
368
  /**
@@ -354,48 +375,56 @@ export interface IManifest {
354
375
  * Unique identifier for the plugin.
355
376
  * This is typically the package name for npm plugins or a unique string for tpex plugins.
356
377
  */
357
- id: string;
378
+ id: string
358
379
  /**
359
380
  * Display name of the plugin.
360
381
  * This is the human-readable name shown to users.
361
382
  */
362
- name: string;
383
+ name: string
363
384
  /**
364
385
  * Version of the plugin, following semantic versioning (e.g., "1.0.0").
365
386
  */
366
- version: string;
387
+ version: string
367
388
  /**
368
389
  * Short description of the plugin's functionality.
369
390
  */
370
- description: string;
391
+ description: string
371
392
  /**
372
393
  * Author of the plugin, typically a name or email.
373
394
  */
374
- author: string;
395
+ author: string
375
396
  /**
376
397
  * Main entry file for the plugin logic, relative to the plugin's root directory.
377
398
  * This file will be loaded when the plugin is activated.
378
399
  */
379
- main: string;
400
+ main: string
380
401
  /**
381
402
  * Optional icon path or definition for the plugin.
382
403
  * This could be a file path to an image or a specific icon class/identifier.
383
404
  */
384
- icon?: string;
405
+ icon?: string
385
406
  /**
386
407
  * Optional keywords for activating the plugin, e.g., for search or command matching.
387
408
  * These keywords help users discover and launch the plugin.
388
409
  */
389
- activationKeywords?: string[];
410
+ activationKeywords?: string[]
411
+ /**
412
+ * Optional runtime development configuration, typically used when running plugins from a dev server.
413
+ */
414
+ dev?: {
415
+ enable?: boolean
416
+ address?: string
417
+ source?: boolean
418
+ }
390
419
  /**
391
420
  * Optional digital signature of the plugin package, used for verification.
392
421
  */
393
- _signature?: string;
422
+ _signature?: string
394
423
  /**
395
424
  * Optional list of files included in the plugin package.
396
425
  * This can be used for integrity checks or resource management.
397
426
  */
398
- _files?: string[];
427
+ _files?: string[]
399
428
  /**
400
429
  * Development-specific configuration for the plugin.
401
430
  * This section is used during plugin development and might not be present in production builds.
@@ -406,14 +435,14 @@ export interface IManifest {
406
435
  * Whether development mode is enabled for the plugin.
407
436
  * If true, specific development features or debugging tools might be activated.
408
437
  */
409
- enable: boolean;
438
+ enable: boolean
410
439
  /**
411
440
  * Address for development server or resources.
412
441
  * For example, a local URL where the plugin's frontend assets are served during development.
413
442
  */
414
- address: string;
415
- };
416
- };
443
+ address: string
444
+ }
445
+ }
417
446
  /**
418
447
  * Build-specific configuration for the plugin.
419
448
  * This section defines how the plugin is built, packaged, and verified.
@@ -422,14 +451,14 @@ export interface IManifest {
422
451
  /**
423
452
  * List of files to include in the build.
424
453
  */
425
- files: string[];
454
+ files: string[]
426
455
  /**
427
456
  * Secret configuration for the build process.
428
457
  */
429
458
  secret: {
430
- pos: string;
431
- addon: string[];
432
- };
459
+ pos: string
460
+ addon: string[]
461
+ }
433
462
  /**
434
463
  * Verification settings for the plugin build.
435
464
  * Defines how the authenticity and integrity of the plugin are checked.
@@ -438,12 +467,12 @@ export interface IManifest {
438
467
  /**
439
468
  * Whether online verification is enabled.
440
469
  */
441
- enable: boolean;
470
+ enable: boolean
442
471
  /**
443
472
  * Online verification strategy.
444
473
  */
445
- online: 'custom' | 'always' | 'once';
446
- };
474
+ online: 'custom' | 'always' | 'once'
475
+ }
447
476
  /**
448
477
  * Version update settings for the plugin.
449
478
  * Defines how the plugin handles updates and downgrades.
@@ -455,17 +484,17 @@ export interface IManifest {
455
484
  * - 'ask': Prompts the user before updating.
456
485
  * - 'readable': Provides a readable update notification.
457
486
  */
458
- update: 'auto' | 'ask' | 'readable';
487
+ update: 'auto' | 'ask' | 'readable'
459
488
  /**
460
489
  * Whether downgrading the plugin version is allowed.
461
490
  */
462
- downgrade: boolean;
463
- };
464
- };
491
+ downgrade: boolean
492
+ }
493
+ }
465
494
  }
466
495
 
467
- export type { LogLevel, LogItem, LogDataType, IPluginLogger } from './log/types'
468
- export * from './sdk/index'
469
- export * from './providers'
470
496
  export * from './install'
497
+ export type { IPluginLogger, LogDataType, LogItem, LogLevel } from './log/types'
498
+ export * from './providers'
471
499
  export * from './risk'
500
+ export * from './sdk/index'
package/plugin/install.ts CHANGED
@@ -1,11 +1,11 @@
1
- export type PluginInstallTaskStage =
2
- | 'queued'
3
- | 'downloading'
4
- | 'awaiting-confirmation'
5
- | 'installing'
6
- | 'completed'
7
- | 'failed'
8
- | 'cancelled'
1
+ export type PluginInstallTaskStage
2
+ = | 'queued'
3
+ | 'downloading'
4
+ | 'awaiting-confirmation'
5
+ | 'installing'
6
+ | 'completed'
7
+ | 'failed'
8
+ | 'cancelled'
9
9
 
10
10
  export interface PluginInstallProgressEvent {
11
11
  taskId: string
@@ -30,9 +30,9 @@ export interface LogItem {
30
30
  * Minimal contract for plugin loggers so web 端只依赖接口定义
31
31
  */
32
32
  export interface IPluginLogger<TManager = unknown> {
33
- info(...args: LogDataType[]): void
34
- warn(...args: LogDataType[]): void
35
- error(...args: LogDataType[]): void
36
- debug(...args: LogDataType[]): void
37
- getManager(): TManager
33
+ info: (...args: LogDataType[]) => void
34
+ warn: (...args: LogDataType[]) => void
35
+ error: (...args: LogDataType[]) => void
36
+ debug: (...args: LogDataType[]) => void
37
+ getManager: () => TManager
38
38
  }
@@ -1,4 +1,4 @@
1
1
  export * from '..'
2
+ export type { IPluginLogger, LogDataType, LogItem, LogLevel } from '../log/types'
2
3
  export { PluginLogger } from './logger'
3
4
  export { PluginLoggerManager } from './logger-manager'
4
- export type { LogLevel, LogItem, LogDataType, IPluginLogger } from '../log/types'
@@ -1,7 +1,7 @@
1
- import fs from 'fs'
2
- import path from 'path'
3
- import { LogItem } from '../log/types'
4
- import { ITouchPlugin } from '..'
1
+ import type { ITouchPlugin } from '..'
2
+ import type { LogItem } from '../log/types'
3
+ import fs from 'node:fs'
4
+ import path from 'node:path'
5
5
  import { structuredStrictStringify } from '@talex-touch/utils'
6
6
 
7
7
  /**
@@ -28,7 +28,7 @@ export class PluginLoggerManager {
28
28
  this.onLogAppend = onLogAppend
29
29
  this.sessionStart = new Date().toISOString()
30
30
  const timestamp = this.sessionStart.replace(/[:.]/g, '-')
31
- const sessionFolder = `${timestamp}_${pluginInfo.name.replace(/[^a-zA-Z0-9-_]/g, '_')}`
31
+ const sessionFolder = `${timestamp}_${pluginInfo.name.replace(/[^\w-]/g, '_')}`
32
32
 
33
33
  this.pluginLogDir = path.resolve(baseDir, 'logs', sessionFolder)
34
34
  this.sessionLogPath = path.resolve(this.pluginLogDir, 'session.log')
@@ -51,14 +51,17 @@ export class PluginLoggerManager {
51
51
  * Flushes all buffered log items to the current session log file.
52
52
  */
53
53
  flush(): void {
54
- if (this.buffer.length === 0) return
55
- const lines = this.buffer.map((item) => structuredStrictStringify(item)).join('\n') + '\n'
54
+ if (this.buffer.length === 0)
55
+ return
56
+ const lines = `${this.buffer.map(item => structuredStrictStringify(item)).join('\n')}\n`
56
57
  try {
57
58
  this.ensureLogEnvironment()
58
59
  fs.appendFileSync(this.sessionLogPath, lines)
59
60
  this.buffer = []
60
- } catch (error) {
61
- if ((error as NodeJS.ErrnoException)?.code !== 'ENOENT') throw error
61
+ }
62
+ catch (error) {
63
+ if ((error as NodeJS.ErrnoException)?.code !== 'ENOENT')
64
+ throw error
62
65
  // Directory or file was removed; rebuild and retry once.
63
66
  this.ensureLogEnvironment(true)
64
67
  fs.appendFileSync(this.sessionLogPath, lines)
@@ -105,8 +108,8 @@ export class PluginLoggerManager {
105
108
  features: this.pluginInfo.features.map(feature => ({
106
109
  id: feature.id,
107
110
  name: feature.name,
108
- desc: feature.desc
109
- }))
111
+ desc: feature.desc,
112
+ })),
110
113
  }
111
114
 
112
115
  fs.writeFileSync(this.pluginInfoPath, JSON.stringify(pluginInfo, null, 2))
@@ -1,5 +1,5 @@
1
- import { IPluginLogger, LogLevel, LogItem, LogDataType } from '../log/types'
2
- import { PluginLoggerManager } from './logger-manager'
1
+ import type { IPluginLogger, LogDataType, LogItem, LogLevel } from '../log/types'
2
+ import type { PluginLoggerManager } from './logger-manager'
3
3
  import chalk from 'chalk'
4
4
 
5
5
  /**
@@ -71,7 +71,7 @@ export class PluginLogger implements IPluginLogger<PluginLoggerManager> {
71
71
  : 'INFO')
72
72
  if (resolvedLevel === 'INFO' && normalizedLevel !== 'INFO') {
73
73
  console.warn(
74
- `${chalk.bgMagenta('[PluginLog]')} ${chalk.bgYellow('WARN')} ${this.pluginName} - Unknown log level "${String(level)}", fallback to INFO`
74
+ `${chalk.bgMagenta('[PluginLog]')} ${chalk.bgYellow('WARN')} ${this.pluginName} - Unknown log level "${String(level)}", fallback to INFO`,
75
75
  )
76
76
  }
77
77
 
@@ -79,7 +79,7 @@ export class PluginLogger implements IPluginLogger<PluginLoggerManager> {
79
79
  INFO: chalk.bgBlue,
80
80
  WARN: chalk.bgYellow,
81
81
  ERROR: chalk.bgRed,
82
- DEBUG: chalk.bgGray
82
+ DEBUG: chalk.bgGray,
83
83
  }
84
84
  const colorize = levelColorMap[resolvedLevel] ?? ((input: string) => input)
85
85
 
@@ -96,14 +96,14 @@ export class PluginLogger implements IPluginLogger<PluginLoggerManager> {
96
96
  if (resolvedLevel === 'DEBUG') {
97
97
  console.debug(
98
98
  `${chalk.bgMagenta('[PluginLog]')} ${colorize(resolvedLevel)} ${this.pluginName} - ${message}`,
99
- ...data
99
+ ...data,
100
100
  )
101
- } else {
101
+ }
102
+ else {
102
103
  console.log(
103
104
  `${chalk.bgMagenta('[PluginLog]')} ${colorize(resolvedLevel)} ${this.pluginName} - ${message}`,
104
- ...data
105
+ ...data,
105
106
  )
106
107
  }
107
-
108
108
  }
109
109
  }
@@ -1,4 +1,4 @@
1
- import { IManifest } from '@talex-touch/utils/plugin'
1
+ import type { IManifest } from '@talex-touch/utils/plugin'
2
2
 
3
3
  /**
4
4
  * Interface for plugin download options.
@@ -7,15 +7,15 @@ export interface IDownloadOptions {
7
7
  /**
8
8
  * Timeout configuration for download in milliseconds.
9
9
  */
10
- timeout?: number;
10
+ timeout?: number
11
11
  /**
12
12
  * List of fallback download URLs.
13
13
  */
14
- fallbackUrls?: string[];
14
+ fallbackUrls?: string[]
15
15
  /**
16
16
  * Callback function for download progress, with progress value (0-100).
17
17
  */
18
- onProgress?: (progress: number) => void;
18
+ onProgress?: (progress: number) => void
19
19
  }
20
20
 
21
21
  /**
@@ -25,7 +25,7 @@ export interface IDownloadResult {
25
25
  /**
26
26
  * Local file path after download, which can be the plugin's compressed package or the unzipped folder path.
27
27
  */
28
- filePath?: string;
28
+ filePath?: string
29
29
  }
30
30
 
31
31
  /**
@@ -43,16 +43,16 @@ export interface IPluginSource {
43
43
  * Get the name of the plugin source.
44
44
  * @returns The name of the plugin source.
45
45
  */
46
- getSourceName(): string;
46
+ getSourceName: () => string
47
47
  /**
48
48
  * Get the description of the plugin source.
49
49
  * @returns The description of the plugin source.
50
50
  */
51
- getSourceDesc(): string;
51
+ getSourceDesc: () => string
52
52
  /**
53
53
  * Timestamp of the last update for this plugin source.
54
54
  */
55
- lastUpdateTime?: number;
55
+ lastUpdateTime?: number
56
56
 
57
57
  /**
58
58
  * Attempts to resolve a plugin manifest from the specified path or URL.
@@ -62,7 +62,7 @@ export interface IPluginSource {
62
62
  * @param options Resolution options.
63
63
  * @returns A Promise containing the plugin manifest, or undefined if resolution fails.
64
64
  */
65
- resolveManifest(sourcePath: string, options?: IResolveManifestOptions): Promise<IManifest | undefined>
65
+ resolveManifest: (sourcePath: string, options?: IResolveManifestOptions) => Promise<IManifest | undefined>
66
66
 
67
67
  /**
68
68
  * Downloads the plugin source.
@@ -70,5 +70,5 @@ export interface IPluginSource {
70
70
  * @param options Download options.
71
71
  * @returns A Promise containing the download result. The filePath must be the path to the plugin's compressed package or unzipped folder.
72
72
  */
73
- downloadPlugin(sourceUrl: string, options?: IDownloadOptions): Promise<IDownloadResult>
74
- }
73
+ downloadPlugin: (sourceUrl: string, options?: IDownloadOptions) => Promise<IDownloadResult>
74
+ }