@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
@@ -0,0 +1,215 @@
1
+ import type { AiProviderConfig, AISDKGlobalConfig, AISDKStorageData } from '../../types/intelligence'
2
+ import { StorageList } from '../../common/storage/constants'
3
+ import {
4
+
5
+ AiProviderType,
6
+
7
+ DEFAULT_CAPABILITIES,
8
+ DEFAULT_GLOBAL_CONFIG,
9
+ DEFAULT_PROVIDERS,
10
+ } from '../../types/intelligence'
11
+ import { createStorageProxy, TouchStorage } from './base-storage'
12
+
13
+ // Re-export types for convenience
14
+ export { AiProviderType }
15
+ export type { AiProviderConfig, AISDKGlobalConfig }
16
+
17
+ const defaultIntelligenceData: AISDKStorageData = {
18
+ providers: [...DEFAULT_PROVIDERS],
19
+ globalConfig: { ...DEFAULT_GLOBAL_CONFIG },
20
+ capabilities: { ...DEFAULT_CAPABILITIES },
21
+ version: 1,
22
+ }
23
+
24
+ const INTELLIGENCE_STORAGE_KEY = `storage:${StorageList.IntelligenceConfig}`
25
+
26
+ class IntelligenceStorage extends TouchStorage<AISDKStorageData> {
27
+ constructor() {
28
+ super(StorageList.IntelligenceConfig, defaultIntelligenceData)
29
+ this.setAutoSave(true)
30
+ }
31
+
32
+ /**
33
+ * 添加新的提供商
34
+ */
35
+ addProvider(provider: AiProviderConfig): void {
36
+ const currentData = this.get()
37
+ const updatedProviders = [...currentData.providers, provider]
38
+ this.set({
39
+ ...currentData,
40
+ providers: updatedProviders,
41
+ })
42
+ }
43
+
44
+ /**
45
+ * 更新提供商配置
46
+ */
47
+ updateProvider(id: string, updatedProvider: Partial<AiProviderConfig>): void {
48
+ const currentData = this.get()
49
+ const providerIndex = currentData.providers.findIndex(p => p.id === id)
50
+
51
+ if (providerIndex !== -1) {
52
+ const updatedProviders = [...currentData.providers]
53
+ updatedProviders[providerIndex] = {
54
+ ...updatedProviders[providerIndex],
55
+ ...updatedProvider,
56
+ }
57
+
58
+ this.set({
59
+ ...currentData,
60
+ providers: updatedProviders,
61
+ })
62
+ }
63
+ }
64
+
65
+ /**
66
+ * 删除提供商
67
+ */
68
+ removeProvider(id: string): void {
69
+ const currentData = this.get()
70
+ const updatedProviders = currentData.providers.filter(p => p.id !== id)
71
+
72
+ this.set({
73
+ ...currentData,
74
+ providers: updatedProviders,
75
+ })
76
+ }
77
+
78
+ /**
79
+ * 更新全局配置
80
+ */
81
+ updateGlobalConfig(config: Partial<AISDKGlobalConfig>): void {
82
+ const currentData = this.get()
83
+
84
+ this.set({
85
+ ...currentData,
86
+ globalConfig: {
87
+ ...currentData.globalConfig,
88
+ ...config,
89
+ },
90
+ })
91
+ }
92
+
93
+ /**
94
+ * 获取特定类型的提供商
95
+ */
96
+ getProvidersByType(type: AiProviderType): AiProviderConfig[] {
97
+ return this.get().providers.filter(p => p.type === type)
98
+ }
99
+
100
+ /**
101
+ * 获取启用的提供商
102
+ */
103
+ getEnabledProviders(): AiProviderConfig[] {
104
+ return this.get().providers.filter(p => p.enabled)
105
+ }
106
+
107
+ /**
108
+ * 检查提供商是否已配置
109
+ */
110
+ isProviderConfigured(id: string): boolean {
111
+ const provider = this.get().providers.find(p => p.id === id)
112
+ if (!provider || !provider.enabled)
113
+ return false
114
+
115
+ // 检查是否有必要的配置项
116
+ const hasApiKey = provider.type === AiProviderType.LOCAL || !!provider.apiKey
117
+ const hasModels = !!(provider.models && provider.models.length > 0)
118
+
119
+ return hasApiKey && hasModels
120
+ }
121
+ }
122
+
123
+ /**
124
+ * Lazy-initialized Intelligence storage.
125
+ * The actual instance is created only when first accessed AND after initStorageChannel() is called.
126
+ */
127
+ export const intelligenceStorage = createStorageProxy<IntelligenceStorage>(
128
+ INTELLIGENCE_STORAGE_KEY,
129
+ () => new IntelligenceStorage(),
130
+ )
131
+
132
+ /**
133
+ * Alias for backward compatibility
134
+ * @deprecated Use intelligenceStorage instead
135
+ */
136
+ export const aisdkStorage = intelligenceStorage
137
+
138
+ /**
139
+ * Alias for backward compatibility
140
+ * @deprecated Use intelligenceStorage instead
141
+ */
142
+ export const intelligenceSettings = intelligenceStorage
143
+
144
+ export async function migrateIntelligenceSettings(): Promise<void> {
145
+ console.log('[Intelligence Storage] Starting migration check...')
146
+ const currentData = intelligenceStorage.data
147
+
148
+ if (!currentData.version || currentData.version < 1) {
149
+ console.log('[Intelligence Storage] Migrating settings to version 1')
150
+
151
+ const migratedProviders = currentData.providers.map(provider => ({
152
+ ...provider,
153
+ enabled: provider.enabled ?? false,
154
+ priority: provider.priority ?? 2,
155
+ timeout: provider.timeout ?? 30000,
156
+ rateLimit: provider.rateLimit ?? {},
157
+ models: provider.models ?? [],
158
+ capabilities: provider.capabilities ?? [],
159
+ }))
160
+
161
+ const storedStrategy = currentData.globalConfig?.defaultStrategy
162
+ const normalizedStrategy
163
+ = storedStrategy === 'priority' ? 'rule-based-default' : storedStrategy ?? 'adaptive-default'
164
+
165
+ const migratedGlobalConfig: AISDKGlobalConfig = {
166
+ defaultStrategy: normalizedStrategy,
167
+ enableAudit: currentData.globalConfig?.enableAudit ?? false,
168
+ enableCache: currentData.globalConfig?.enableCache ?? true,
169
+ cacheExpiration: currentData.globalConfig?.cacheExpiration ?? 3600,
170
+ }
171
+
172
+ const migratedCapabilities = currentData.capabilities ?? { ...DEFAULT_CAPABILITIES }
173
+
174
+ intelligenceStorage.applyData({
175
+ providers: migratedProviders,
176
+ globalConfig: migratedGlobalConfig,
177
+ capabilities: migratedCapabilities,
178
+ version: 1,
179
+ })
180
+
181
+ await intelligenceStorage.saveToRemote({ force: true })
182
+
183
+ console.log('[Intelligence Storage] Migration complete')
184
+ }
185
+ else {
186
+ console.log('[Intelligence Storage] No migration needed, current version:', currentData.version)
187
+ }
188
+
189
+ console.log('[Intelligence Storage] Final providers count:', intelligenceStorage.data.providers.length)
190
+ }
191
+
192
+ /**
193
+ * @deprecated Use migrateIntelligenceSettings instead
194
+ */
195
+ export const migrateAISDKSettings = migrateIntelligenceSettings
196
+
197
+ export async function resetIntelligenceConfig(): Promise<void> {
198
+ console.log('[Intelligence Storage] Resetting to default configuration')
199
+
200
+ intelligenceStorage.applyData({
201
+ providers: [...DEFAULT_PROVIDERS],
202
+ globalConfig: { ...DEFAULT_GLOBAL_CONFIG },
203
+ capabilities: { ...DEFAULT_CAPABILITIES },
204
+ version: 1,
205
+ })
206
+
207
+ await intelligenceStorage.saveToRemote({ force: true })
208
+
209
+ console.log('[Intelligence Storage] Reset complete')
210
+ }
211
+
212
+ /**
213
+ * @deprecated Use resetIntelligenceConfig instead
214
+ */
215
+ export const resetAISDKConfig = resetIntelligenceConfig
@@ -1,5 +1,6 @@
1
- import { TouchStorage } from '.'
2
- import { openersOriginData, StorageList, type OpenersMap } from '../..'
1
+ import type { OpenersMap } from '../..'
2
+ import { openersOriginData, StorageList } from '../..'
3
+ import { createStorageProxy, TouchStorage } from './base-storage'
3
4
 
4
5
  class OpenersStorage extends TouchStorage<OpenersMap> {
5
6
  constructor() {
@@ -8,4 +9,13 @@ class OpenersStorage extends TouchStorage<OpenersMap> {
8
9
  }
9
10
  }
10
11
 
11
- export const openersStorage = new OpenersStorage()
12
+ const OPENERS_STORAGE_KEY = `storage:${StorageList.OPENERS}`
13
+
14
+ /**
15
+ * Lazy-initialized openers storage.
16
+ * The actual instance is created only when first accessed AND after initStorageChannel() is called.
17
+ */
18
+ export const openersStorage = createStorageProxy<OpenersStorage>(
19
+ OPENERS_STORAGE_KEY,
20
+ () => new OpenersStorage(),
21
+ )
@@ -1,30 +1,30 @@
1
+ import type { ITouchClientChannel } from '@talex-touch/utils/channel'
1
2
  import { Terminal } from './terminal'
2
- import { ITouchClientChannel } from '@talex-touch/utils/channel'
3
3
 
4
4
  export class EnvDetector {
5
- private static channel: ITouchClientChannel;
5
+ private static channel: ITouchClientChannel
6
6
 
7
7
  public static init(channel: ITouchClientChannel) {
8
- this.channel = channel;
8
+ this.channel = channel
9
9
  }
10
10
 
11
11
  private static async checkCommand(
12
12
  command: string,
13
13
  versionArgs: string = '--version',
14
- versionRegex: RegExp = /(\d+\.\d+\.\d+)/
14
+ versionRegex: RegExp = /(\d+\.\d+\.\d+)/,
15
15
  ): Promise<string | false> {
16
16
  if (!this.channel) {
17
- throw new Error("EnvDetector not initialized. Call EnvDetector.init(channel) first.");
17
+ throw new Error('EnvDetector not initialized. Call EnvDetector.init(channel) first.')
18
18
  }
19
19
  return new Promise((resolve) => {
20
20
  const terminal = new Terminal(this.channel)
21
21
  let output = ''
22
- let resolved = false;
22
+ let resolved = false
23
23
 
24
24
  const resolveOnce = (value: string | false) => {
25
25
  if (!resolved) {
26
- resolved = true;
27
- resolve(value);
26
+ resolved = true
27
+ resolve(value)
28
28
  // For child_process, there's no explicit disconnect/kill needed after it exits.
29
29
  // The process lifecycle is managed by the OS once it's started and exits.
30
30
  }
@@ -51,7 +51,7 @@ export class EnvDetector {
51
51
  // Timeout in case the command hangs or never returns
52
52
  setTimeout(() => {
53
53
  resolveOnce(false)
54
- }, 2000);
54
+ }, 2000)
55
55
  })
56
56
  }
57
57
 
@@ -69,38 +69,38 @@ export class EnvDetector {
69
69
 
70
70
  static async getDegit(): Promise<boolean> {
71
71
  if (!this.channel) {
72
- throw new Error("EnvDetector not initialized. Call EnvDetector.init(channel) first.");
72
+ throw new Error('EnvDetector not initialized. Call EnvDetector.init(channel) first.')
73
73
  }
74
74
  return new Promise((resolve) => {
75
- const terminal = new Terminal(this.channel)
76
- let receivedOutput = false;
77
- let resolved = false;
78
-
79
- const resolveOnce = (value: boolean) => {
80
- if (!resolved) {
81
- resolved = true;
82
- resolve(value);
83
- // For child_process, there's no explicit disconnect/kill needed after it exits.
84
- }
85
- }
86
-
87
- terminal.onData(() => {
88
- receivedOutput = true;
89
- resolveOnce(true); // As soon as we get any output, we know it's there.
90
- })
91
-
92
- terminal.onExit(() => {
93
- resolveOnce(receivedOutput)
94
- })
95
-
96
- // Execute degit with --help
97
- terminal.exec('degit', ['--help']).catch(() => {
98
- resolveOnce(false)
99
- })
100
-
101
- setTimeout(() => {
102
- resolveOnce(receivedOutput);
103
- }, 2000)
104
- });
75
+ const terminal = new Terminal(this.channel)
76
+ let receivedOutput = false
77
+ let resolved = false
78
+
79
+ const resolveOnce = (value: boolean) => {
80
+ if (!resolved) {
81
+ resolved = true
82
+ resolve(value)
83
+ // For child_process, there's no explicit disconnect/kill needed after it exits.
84
+ }
85
+ }
86
+
87
+ terminal.onData(() => {
88
+ receivedOutput = true
89
+ resolveOnce(true) // As soon as we get any output, we know it's there.
90
+ })
91
+
92
+ terminal.onExit(() => {
93
+ resolveOnce(receivedOutput)
94
+ })
95
+
96
+ // Execute degit with --help
97
+ terminal.exec('degit', ['--help']).catch(() => {
98
+ resolveOnce(false)
99
+ })
100
+
101
+ setTimeout(() => {
102
+ resolveOnce(receivedOutput)
103
+ }, 2000)
104
+ })
105
105
  }
106
- }
106
+ }
@@ -1,4 +1,4 @@
1
- import { ITouchClientChannel } from '@talex-touch/utils/channel'
1
+ import type { ITouchClientChannel } from '@talex-touch/utils/channel'
2
2
 
3
3
  export interface TouchSDKOptions {
4
4
  channel: ITouchClientChannel
@@ -1,4 +1,4 @@
1
- import { ITouchClientChannel } from '@talex-touch/utils/channel'
1
+ import type { ITouchClientChannel } from '@talex-touch/utils/channel'
2
2
 
3
3
  type DataCallback = (data: string) => void
4
4
  type ExitCallback = (exitCode: number | null) => void
@@ -25,10 +25,10 @@ export class Terminal {
25
25
  // If there's an existing process, it should ideally be killed first.
26
26
  // However, for simplicity in this refactor, we'll assume exec is called for a new, independent command.
27
27
  // A more robust implementation might track multiple concurrent processes.
28
-
28
+
29
29
  const { id } = await this.channel.send('terminal:create', { command, args })
30
30
  this.id = id
31
-
31
+
32
32
  // Re-register listeners for the new process ID
33
33
  this.channel.regChannel('terminal:data', (channelData) => {
34
34
  if (this.id === channelData.data.id && this.onDataCallback) {
@@ -42,7 +42,7 @@ export class Terminal {
42
42
  this.id = null
43
43
  }
44
44
  })
45
-
45
+
46
46
  return id
47
47
  }
48
48
 
@@ -82,4 +82,4 @@ export class Terminal {
82
82
  public onExit(callback: ExitCallback): void {
83
83
  this.onExitCallback = callback
84
84
  }
85
- }
85
+ }
@@ -1,4 +1,5 @@
1
- import { TouchSDK, TouchSDKOptions } from './index'
1
+ import type { TouchSDKOptions } from './index'
2
+ import { TouchSDK } from './index'
2
3
 
3
4
  /**
4
5
  * Factory function to create a TouchSDK instance
@@ -26,7 +27,7 @@ export function getTouchSDK(): TouchSDK {
26
27
 
27
28
  export function useTouchSDK(options?: TouchSDKOptions) {
28
29
  if (!sdkInstance) {
29
- if ( !options ) {
30
+ if (!options) {
30
31
  throw new Error('TouchSDK not initialized. Call initTouchSDK first. Cannot use hook here.')
31
32
  }
32
33
  initTouchSDK(options)
@@ -57,5 +58,5 @@ export const TouchUtils = {
57
58
 
58
59
  async openPluginFolder(pluginName: string): Promise<void> {
59
60
  return getTouchSDK().openPluginFolder(pluginName)
60
- }
61
+ },
61
62
  }
@@ -7,33 +7,33 @@
7
7
  * @returns The Levenshtein distance.
8
8
  */
9
9
  export function levenshteinDistance(s1: string, s2: string): number {
10
- const m = s1.length;
11
- const n = s2.length;
10
+ const m = s1.length
11
+ const n = s2.length
12
12
 
13
13
  // Create a 2D array (m+1)x(n+1) to store distances
14
- const dp: number[][] = Array(m + 1)
14
+ const dp: number[][] = new Array(m + 1)
15
15
  .fill(0)
16
- .map(() => Array(n + 1).fill(0));
16
+ .map(() => new Array(n + 1).fill(0))
17
17
 
18
18
  // Initialize the DP table
19
19
  for (let i = 0; i <= m; i++) {
20
- dp[i][0] = i;
20
+ dp[i][0] = i
21
21
  }
22
22
  for (let j = 0; j <= n; j++) {
23
- dp[0][j] = j;
23
+ dp[0][j] = j
24
24
  }
25
25
 
26
26
  // Fill the DP table
27
27
  for (let i = 1; i <= m; i++) {
28
28
  for (let j = 1; j <= n; j++) {
29
- const cost = s1[i - 1] === s2[j - 1] ? 0 : 1;
29
+ const cost = s1[i - 1] === s2[j - 1] ? 0 : 1
30
30
  dp[i][j] = Math.min(
31
31
  dp[i - 1][j] + 1, // Deletion
32
32
  dp[i][j - 1] + 1, // Insertion
33
- dp[i - 1][j - 1] + cost // Substitution
34
- );
33
+ dp[i - 1][j - 1] + cost, // Substitution
34
+ )
35
35
  }
36
36
  }
37
37
 
38
- return dp[m][n];
39
- }
38
+ return dp[m][n]
39
+ }