@talex-touch/utils 1.0.40 → 1.0.44

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 (235) hide show
  1. package/.eslintcache +1 -0
  2. package/__tests__/cloud-sync-sdk.test.ts +442 -0
  3. package/__tests__/icons/icons.test.ts +84 -0
  4. package/__tests__/plugin-sdk-lifecycle.test.ts +130 -0
  5. package/__tests__/power-sdk.test.ts +143 -0
  6. package/__tests__/preset-export-types.test.ts +108 -0
  7. package/__tests__/search/fuzzy-match.test.ts +137 -0
  8. package/__tests__/transport/port-policy.test.ts +44 -0
  9. package/__tests__/transport-domain-sdks.test.ts +152 -0
  10. package/__tests__/types/update.test.ts +67 -0
  11. package/account/account-sdk.ts +915 -0
  12. package/account/index.ts +2 -0
  13. package/account/types.ts +321 -0
  14. package/analytics/client.ts +136 -0
  15. package/analytics/index.ts +2 -0
  16. package/analytics/types.ts +156 -0
  17. package/animation/auto-resize.ts +322 -0
  18. package/animation/window-node.ts +26 -19
  19. package/auth/clerk-types.ts +12 -30
  20. package/auth/index.ts +0 -2
  21. package/auth/useAuthState.ts +6 -14
  22. package/base/index.ts +2 -0
  23. package/base/log-level.ts +105 -0
  24. package/channel/index.ts +170 -69
  25. package/cloud-sync/cloud-sync-sdk.ts +450 -0
  26. package/cloud-sync/index.ts +1 -0
  27. package/common/file-scan-utils.ts +17 -9
  28. package/common/index.ts +4 -0
  29. package/common/logger/index.ts +46 -0
  30. package/common/logger/logger-manager.ts +303 -0
  31. package/common/logger/module-logger.ts +270 -0
  32. package/common/logger/transport-logger.ts +234 -0
  33. package/common/logger/types.ts +93 -0
  34. package/common/search/gather.ts +48 -6
  35. package/common/search/index.ts +8 -0
  36. package/common/storage/constants.ts +13 -0
  37. package/common/storage/entity/app-settings.ts +245 -0
  38. package/common/storage/entity/index.ts +3 -0
  39. package/common/storage/entity/layout-atom-types.ts +147 -0
  40. package/common/storage/entity/openers.ts +1 -0
  41. package/common/storage/entity/preset-cloud-api.ts +132 -0
  42. package/common/storage/entity/preset-export-types.ts +256 -0
  43. package/common/storage/entity/shortcut-settings.ts +1 -0
  44. package/common/storage/shortcut-storage.ts +11 -0
  45. package/common/utils/clone-diagnostics.ts +105 -0
  46. package/common/utils/file.ts +16 -8
  47. package/common/utils/index.ts +6 -2
  48. package/common/utils/payload-preview.ts +173 -0
  49. package/common/utils/polling.ts +167 -13
  50. package/common/utils/safe-path.ts +103 -0
  51. package/common/utils/safe-shell.ts +115 -0
  52. package/common/utils/task-queue.ts +4 -1
  53. package/core-box/builder/tuff-builder.ts +0 -1
  54. package/core-box/index.ts +1 -1
  55. package/core-box/recommendation.ts +38 -1
  56. package/core-box/tuff/tuff-dsl.ts +97 -0
  57. package/electron/download-manager.ts +10 -7
  58. package/electron/env-tool.ts +42 -40
  59. package/electron/index.ts +0 -1
  60. package/env/index.ts +156 -0
  61. package/eslint.config.js +55 -0
  62. package/i18n/index.ts +62 -0
  63. package/i18n/locales/en.json +226 -0
  64. package/i18n/locales/zh.json +226 -0
  65. package/i18n/message-keys.ts +236 -0
  66. package/i18n/resolver.ts +181 -0
  67. package/icons/index.ts +257 -0
  68. package/icons/svg.ts +69 -0
  69. package/index.ts +9 -1
  70. package/intelligence/client.ts +72 -42
  71. package/market/constants.ts +21 -3
  72. package/market/index.ts +1 -1
  73. package/market/types.ts +20 -5
  74. package/package.json +15 -5
  75. package/permission/index.ts +143 -46
  76. package/permission/legacy.ts +26 -0
  77. package/permission/registry.ts +304 -0
  78. package/permission/types.ts +164 -0
  79. package/plugin/channel.ts +68 -39
  80. package/plugin/index.ts +82 -8
  81. package/plugin/install.ts +3 -0
  82. package/plugin/log/types.ts +22 -5
  83. package/plugin/node/logger-manager.ts +11 -3
  84. package/plugin/node/logger.ts +24 -17
  85. package/plugin/preload.ts +25 -2
  86. package/plugin/providers/index.ts +4 -0
  87. package/plugin/providers/market-client.ts +218 -0
  88. package/plugin/providers/npm-provider.ts +228 -0
  89. package/plugin/providers/tpex-provider.ts +297 -0
  90. package/plugin/providers/tpex-types.ts +34 -0
  91. package/plugin/sdk/box-items.ts +14 -0
  92. package/plugin/sdk/box-sdk.ts +64 -0
  93. package/plugin/sdk/channel.ts +119 -4
  94. package/plugin/sdk/clipboard.ts +26 -12
  95. package/plugin/sdk/cloud-sync.ts +113 -0
  96. package/plugin/sdk/common.ts +19 -11
  97. package/plugin/sdk/core-box.ts +6 -15
  98. package/plugin/sdk/division-box.ts +160 -65
  99. package/plugin/sdk/examples/storage-onDidChange-example.js +5 -2
  100. package/plugin/sdk/feature-sdk.ts +111 -76
  101. package/plugin/sdk/flow.ts +146 -45
  102. package/plugin/sdk/hooks/bridge.ts +113 -49
  103. package/plugin/sdk/hooks/life-cycle.ts +35 -16
  104. package/plugin/sdk/index.ts +14 -3
  105. package/plugin/sdk/intelligence.ts +87 -0
  106. package/plugin/sdk/meta/README.md +179 -0
  107. package/plugin/sdk/meta-sdk.ts +244 -0
  108. package/plugin/sdk/notification.ts +9 -0
  109. package/plugin/sdk/performance.ts +1 -16
  110. package/plugin/sdk/plugin-info.ts +64 -0
  111. package/plugin/sdk/power.ts +155 -0
  112. package/plugin/sdk/recommend.ts +21 -0
  113. package/plugin/sdk/service/index.ts +12 -8
  114. package/plugin/sdk/sqlite.ts +141 -0
  115. package/plugin/sdk/storage.ts +2 -6
  116. package/plugin/sdk/system.ts +2 -9
  117. package/plugin/sdk/temp-files.ts +41 -0
  118. package/plugin/sdk/touch-sdk.ts +18 -0
  119. package/plugin/sdk/types.ts +44 -4
  120. package/plugin/sdk/window/index.ts +12 -9
  121. package/plugin/sdk-version.ts +231 -0
  122. package/preload/renderer.ts +3 -2
  123. package/renderer/hooks/arg-mapper.ts +34 -6
  124. package/renderer/hooks/index.ts +13 -0
  125. package/renderer/hooks/initialize.ts +2 -1
  126. package/renderer/hooks/use-agent-market-sdk.ts +7 -0
  127. package/renderer/hooks/use-agent-market.ts +106 -0
  128. package/renderer/hooks/use-agents-sdk.ts +7 -0
  129. package/renderer/hooks/use-app-sdk.ts +7 -0
  130. package/renderer/hooks/use-channel.ts +33 -4
  131. package/renderer/hooks/use-download-sdk.ts +21 -0
  132. package/renderer/hooks/use-intelligence-sdk.ts +7 -0
  133. package/renderer/hooks/use-intelligence-stats.ts +290 -0
  134. package/renderer/hooks/use-intelligence.ts +202 -104
  135. package/renderer/hooks/use-market-sdk.ts +16 -0
  136. package/renderer/hooks/use-notification-sdk.ts +7 -0
  137. package/renderer/hooks/use-permission-sdk.ts +7 -0
  138. package/renderer/hooks/use-permission.ts +325 -0
  139. package/renderer/hooks/use-platform-sdk.ts +7 -0
  140. package/renderer/hooks/use-plugin-sdk.ts +16 -0
  141. package/renderer/hooks/use-settings-sdk.ts +7 -0
  142. package/renderer/hooks/use-update-sdk.ts +21 -0
  143. package/renderer/index.ts +1 -0
  144. package/renderer/ref.ts +19 -10
  145. package/renderer/shared/components/SharedPluginDetailContent.vue +84 -0
  146. package/renderer/shared/components/SharedPluginDetailHeader.vue +116 -0
  147. package/renderer/shared/components/SharedPluginDetailMetaList.vue +39 -0
  148. package/renderer/shared/components/SharedPluginDetailReadme.vue +45 -0
  149. package/renderer/shared/components/SharedPluginDetailVersions.vue +98 -0
  150. package/renderer/shared/components/index.ts +5 -0
  151. package/renderer/shared/components/shims-vue.d.ts +5 -0
  152. package/renderer/shared/index.ts +2 -0
  153. package/renderer/shared/plugin-detail.ts +62 -0
  154. package/renderer/storage/app-settings.ts +3 -1
  155. package/renderer/storage/base-storage.ts +508 -82
  156. package/renderer/storage/intelligence-storage.ts +37 -46
  157. package/renderer/storage/openers.ts +3 -1
  158. package/renderer/storage/storage-subscription.ts +126 -42
  159. package/renderer/touch-sdk/env.ts +10 -10
  160. package/renderer/touch-sdk/index.ts +114 -18
  161. package/renderer/touch-sdk/terminal.ts +24 -13
  162. package/search/feature-matcher.ts +279 -0
  163. package/search/fuzzy-match.ts +64 -34
  164. package/search/index.ts +10 -0
  165. package/search/levenshtein-utils.ts +17 -11
  166. package/transport/errors.ts +310 -0
  167. package/transport/event/builder.ts +378 -0
  168. package/transport/event/index.ts +7 -0
  169. package/transport/event/types.ts +292 -0
  170. package/transport/events/index.ts +2670 -0
  171. package/transport/events/meta-overlay.ts +79 -0
  172. package/transport/events/types/agents.ts +177 -0
  173. package/transport/events/types/app-index.ts +9 -0
  174. package/transport/events/types/app.ts +475 -0
  175. package/transport/events/types/box-item.ts +222 -0
  176. package/transport/events/types/clipboard.ts +80 -0
  177. package/transport/events/types/core-box.ts +534 -0
  178. package/transport/events/types/device-idle.ts +7 -0
  179. package/transport/events/types/division-box.ts +99 -0
  180. package/transport/events/types/download.ts +115 -0
  181. package/transport/events/types/file-index.ts +73 -0
  182. package/transport/events/types/flow.ts +149 -0
  183. package/transport/events/types/index.ts +70 -0
  184. package/transport/events/types/market.ts +39 -0
  185. package/transport/events/types/meta-overlay.ts +184 -0
  186. package/transport/events/types/notification.ts +140 -0
  187. package/transport/events/types/permission.ts +90 -0
  188. package/transport/events/types/platform.ts +8 -0
  189. package/transport/events/types/plugin.ts +620 -0
  190. package/transport/events/types/sentry.ts +20 -0
  191. package/transport/events/types/storage.ts +208 -0
  192. package/transport/events/types/transport.ts +60 -0
  193. package/transport/events/types/tray.ts +16 -0
  194. package/transport/events/types/update.ts +78 -0
  195. package/transport/index.ts +139 -0
  196. package/transport/main.ts +2 -0
  197. package/transport/sdk/constants.ts +29 -0
  198. package/transport/sdk/domains/agents-market.ts +47 -0
  199. package/transport/sdk/domains/agents.ts +62 -0
  200. package/transport/sdk/domains/app.ts +48 -0
  201. package/transport/sdk/domains/disposable.ts +35 -0
  202. package/transport/sdk/domains/download.ts +139 -0
  203. package/transport/sdk/domains/index.ts +13 -0
  204. package/transport/sdk/domains/intelligence.ts +616 -0
  205. package/transport/sdk/domains/market.ts +35 -0
  206. package/transport/sdk/domains/notification.ts +62 -0
  207. package/transport/sdk/domains/permission.ts +85 -0
  208. package/transport/sdk/domains/platform.ts +19 -0
  209. package/transport/sdk/domains/plugin.ts +144 -0
  210. package/transport/sdk/domains/settings.ts +92 -0
  211. package/transport/sdk/domains/update.ts +64 -0
  212. package/transport/sdk/index.ts +60 -0
  213. package/transport/sdk/main-transport.ts +710 -0
  214. package/transport/sdk/main.ts +9 -0
  215. package/transport/sdk/plugin-transport.ts +654 -0
  216. package/transport/sdk/port-policy.ts +38 -0
  217. package/transport/sdk/renderer-transport.ts +1165 -0
  218. package/transport/types.ts +605 -0
  219. package/types/agent.ts +399 -0
  220. package/types/cloud-sync.ts +157 -0
  221. package/types/division-box.ts +47 -27
  222. package/types/download.ts +1 -0
  223. package/types/flow.ts +63 -12
  224. package/types/icon.ts +2 -1
  225. package/types/index.ts +5 -0
  226. package/types/intelligence.ts +1492 -81
  227. package/types/modules/base.ts +2 -0
  228. package/types/path-browserify.d.ts +5 -0
  229. package/types/platform.ts +12 -0
  230. package/types/startup-info.ts +32 -0
  231. package/types/touch-app-core.ts +8 -8
  232. package/types/update.ts +94 -1
  233. package/vitest.config.ts +25 -0
  234. package/auth/useClerkConfig.ts +0 -40
  235. package/auth/useClerkProvider.ts +0 -52
@@ -1,13 +1,26 @@
1
- import { BridgeEventForCoreBox } from '../enum/bridge-event'
1
+ import { getLogger } from '../../../common/logger'
2
2
  import { ensureRendererChannel } from '../channel'
3
+ import { BridgeEventForCoreBox } from '../enum/bridge-event'
3
4
 
4
5
  export type BridgeEvent = BridgeEventForCoreBox
5
6
 
6
- /**
7
- * Defines the shape of a bridge hook function.
8
- * @template T The type of data the hook will receive.
9
- */
10
- export type BridgeHook<T = any> = (data: T) => void
7
+ export interface BridgeEventMeta {
8
+ timestamp: number
9
+ fromCache: boolean
10
+ }
11
+
12
+ export interface BridgeEventPayload<T = any> {
13
+ data: T
14
+ meta: BridgeEventMeta
15
+ }
16
+
17
+ /** @template T The type of data the hook will receive. */
18
+ export type BridgeHook<T = any> = (payload: BridgeEventPayload<T>) => void
19
+
20
+ interface CachedEvent<T = any> {
21
+ data: T
22
+ timestamp: number
23
+ }
11
24
 
12
25
  const __hooks: Record<BridgeEvent, Array<BridgeHook>> = {
13
26
  [BridgeEventForCoreBox.CORE_BOX_INPUT_CHANGE]: [],
@@ -15,42 +28,91 @@ const __hooks: Record<BridgeEvent, Array<BridgeHook>> = {
15
28
  [BridgeEventForCoreBox.CORE_BOX_KEY_EVENT]: [],
16
29
  }
17
30
 
18
- /**
19
- * Injects a hook for a given bridge event.
20
- * @param type The bridge event type.
21
- * @param hook The hook function to inject.
22
- * @returns The wrapped hook function.
23
- * @internal
24
- * @template T The type of data the hook will receive.
25
- */
26
- export function injectBridgeEvent<T>(type: BridgeEvent, hook: BridgeHook<T>) {
27
- const hooks: Array<BridgeHook<T>> = __hooks[type] || (__hooks[type] = [])
31
+ const __eventCache: Map<BridgeEvent, CachedEvent[]> = new Map()
32
+ const __channelRegistered = new Set<BridgeEvent>()
33
+
34
+ const CACHE_MAX_SIZE: Record<BridgeEvent, number> = {
35
+ [BridgeEventForCoreBox.CORE_BOX_INPUT_CHANGE]: 1,
36
+ [BridgeEventForCoreBox.CORE_BOX_CLIPBOARD_CHANGE]: 1,
37
+ [BridgeEventForCoreBox.CORE_BOX_KEY_EVENT]: 10,
38
+ }
39
+
40
+ const bridgeLog = getLogger('plugin-sdk')
28
41
 
29
- // Only register the channel listener once per event type
30
- if (hooks.length === 0) {
31
- const channel = ensureRendererChannel('[TouchSDK] Bridge channel not available. Make sure hooks run in plugin renderer context.')
42
+ function invokeHook<T>(hook: BridgeHook<T>, data: T, fromCache: boolean, timestamp: number): void {
43
+ try {
44
+ hook({ data, meta: { timestamp, fromCache } })
45
+ }
46
+ catch (e) {
47
+ bridgeLog.error('[TouchSDK] Bridge hook error', { error: e })
48
+ }
49
+ }
50
+
51
+ function registerEarlyListener(type: BridgeEvent): void {
52
+ if (__channelRegistered.has(type))
53
+ return
54
+
55
+ try {
56
+ const channel = ensureRendererChannel()
32
57
  channel.regChannel(type, ({ data }) => {
33
- console.debug(`[TouchSDK] ${type} event received: `, data)
34
- // When the event is received, call all registered hooks for this type
35
- const registeredHooks = __hooks[type]
36
- if (registeredHooks) {
37
- registeredHooks.forEach(h => h(data))
58
+ const timestamp = Date.now()
59
+ const hooks = __hooks[type]
60
+
61
+ if (hooks && hooks.length > 0) {
62
+ hooks.forEach(h => invokeHook(h, data, false, timestamp))
63
+ }
64
+ else {
65
+ if (!__eventCache.has(type))
66
+ __eventCache.set(type, [])
67
+ const cache = __eventCache.get(type)!
68
+ const maxSize = CACHE_MAX_SIZE[type] ?? 1
69
+ cache.push({ data, timestamp })
70
+ while (cache.length > maxSize) cache.shift()
71
+ bridgeLog.debug(`[TouchSDK] ${type} cached, size: ${cache.length}`)
38
72
  }
39
73
  })
74
+ __channelRegistered.add(type)
75
+ }
76
+ catch {
77
+ // Channel not ready yet
40
78
  }
79
+ }
41
80
 
42
- const wrappedHook = (data: T) => {
43
- try {
44
- hook(data)
45
- }
46
- catch (e) {
47
- console.error(`[TouchSDK] ${type} hook error: `, e)
48
- }
81
+ /** Clears the event cache for a specific event type or all types. */
82
+ export function clearBridgeEventCache(type?: BridgeEvent): void {
83
+ if (type) {
84
+ __eventCache.delete(type)
85
+ }
86
+ else {
87
+ __eventCache.clear()
49
88
  }
89
+ }
90
+
91
+ // Auto-init on module load
92
+ ;(function initBridgeEventCache() {
93
+ setTimeout(() => {
94
+ Object.values(BridgeEventForCoreBox).forEach(e => registerEarlyListener(e as BridgeEvent))
95
+ }, 0)
96
+ })()
97
+
98
+ /**
99
+ * @internal
100
+ */
101
+ export function injectBridgeEvent<T>(type: BridgeEvent, hook: BridgeHook<T>) {
102
+ const hooks: Array<BridgeHook<T>> = __hooks[type] || (__hooks[type] = [])
103
+
104
+ // Ensure channel listener is registered
105
+ registerEarlyListener(type)
50
106
 
51
- hooks.push(wrappedHook)
107
+ // Replay cached events to this new hook
108
+ const cached = __eventCache.get(type)
109
+ if (cached && cached.length > 0) {
110
+ cached.forEach(({ data, timestamp }) => invokeHook(hook, data as T, true, timestamp))
111
+ __eventCache.delete(type)
112
+ }
52
113
 
53
- return wrappedHook
114
+ hooks.push(hook)
115
+ return hook
54
116
  }
55
117
 
56
118
  /**
@@ -61,22 +123,11 @@ export function injectBridgeEvent<T>(type: BridgeEvent, hook: BridgeHook<T>) {
61
123
  */
62
124
  export const createBridgeHook = <T>(type: BridgeEvent) => (hook: BridgeHook<T>) => injectBridgeEvent<T>(type, hook)
63
125
 
64
- /**
65
- * Hook for when the core box input changes.
66
- * The hook receives the new input value as a string.
67
- * @param data The input change data (string).
68
- */
69
- export const onCoreBoxInputChange = createBridgeHook<{ query: { inputs: Array<any>, text: string } }>(BridgeEventForCoreBox.CORE_BOX_INPUT_CHANGE)
70
-
71
- export const onCoreBoxClipboardChange = createBridgeHook<{ item: any }>(BridgeEventForCoreBox.CORE_BOX_CLIPBOARD_CHANGE)
126
+ export interface CoreBoxInputData {
127
+ query: { inputs: Array<any>, text: string }
128
+ }
72
129
 
73
- /**
74
- * Hook for when a keyboard event is forwarded from CoreBox.
75
- * This is triggered when the plugin's UI view is attached and the user
76
- * presses certain keys (Enter, Arrow keys, Meta+key combinations).
77
- * @param data The forwarded keyboard event data.
78
- */
79
- export const onCoreBoxKeyEvent = createBridgeHook<{
130
+ export interface CoreBoxKeyEventData {
80
131
  key: string
81
132
  code: string
82
133
  metaKey: boolean
@@ -84,4 +135,17 @@ export const onCoreBoxKeyEvent = createBridgeHook<{
84
135
  altKey: boolean
85
136
  shiftKey: boolean
86
137
  repeat: boolean
87
- }>(BridgeEventForCoreBox.CORE_BOX_KEY_EVENT)
138
+ }
139
+
140
+ export interface CoreBoxClipboardData {
141
+ item: any
142
+ }
143
+
144
+ /** Hook for CoreBox input changes. Payload includes `data` and `meta` (timestamp, fromCache). */
145
+ export const onCoreBoxInputChange = createBridgeHook<CoreBoxInputData>(BridgeEventForCoreBox.CORE_BOX_INPUT_CHANGE)
146
+
147
+ /** Hook for CoreBox clipboard changes. Payload includes `data` and `meta` (timestamp, fromCache). */
148
+ export const onCoreBoxClipboardChange = createBridgeHook<CoreBoxClipboardData>(BridgeEventForCoreBox.CORE_BOX_CLIPBOARD_CHANGE)
149
+
150
+ /** Hook for keyboard events forwarded from CoreBox. Payload includes `data` and `meta` (timestamp, fromCache). */
151
+ export const onCoreBoxKeyEvent = createBridgeHook<CoreBoxKeyEventData>(BridgeEventForCoreBox.CORE_BOX_KEY_EVENT)
@@ -1,4 +1,8 @@
1
+ import { getLogger } from '../../../common/logger'
1
2
  import { ensureRendererChannel } from '../channel'
3
+ import { useTouchSDK } from '../touch-sdk'
4
+
5
+ const sdkLog = getLogger('plugin-sdk')
2
6
 
3
7
  export enum LifecycleHooks {
4
8
  ENABLE = 'en',
@@ -9,27 +13,38 @@ export enum LifecycleHooks {
9
13
  CRASH = 'cr',
10
14
  }
11
15
 
12
- // @ts-ignore
13
- export function injectHook(type: LifecycleHooks, hook: Function, processFunc = ({ data, reply }) => {
14
- // @ts-ignore
15
- const hooks: Array<Function> = window.$touchSDK.__hooks[type]
16
- if (hooks) {
17
- hooks.forEach(hook => hook(data))
16
+ type LifecycleHook = (data: unknown) => void
17
+ interface HookContext { data: unknown, reply: (result: boolean) => void }
18
+ type HookProcessor = (context: HookContext) => void
19
+
20
+ export function injectHook(
21
+ type: LifecycleHooks,
22
+ hook: LifecycleHook,
23
+ processFunc: HookProcessor = ({ data, reply }) => {
24
+ const sdk = useTouchSDK('[Lifecycle Hook] TouchSDK not available. Make sure hooks run in plugin renderer context.')
25
+ const hooksMap = (sdk.__hooks ?? {}) as Record<LifecycleHooks, LifecycleHook[]>
26
+ const hooks = hooksMap[type]
27
+ if (hooks) {
28
+ hooks.forEach(hookItem => hookItem(data))
29
+ }
30
+ reply(true)
31
+ },
32
+ ) {
33
+ const sdk = useTouchSDK('[Lifecycle Hook] TouchSDK not available. Make sure hooks run in plugin renderer context.')
34
+ if (!sdk.__hooks || typeof sdk.__hooks !== 'object') {
35
+ sdk.__hooks = {}
18
36
  }
19
- reply(true)
20
- }) {
21
- // @ts-ignore
22
- const __hooks = window.$touchSDK.__hooks
23
- // @ts-ignore
24
- const hooks: Array<Function> = __hooks[type] || (__hooks[type] = [])
37
+ const hooksMap = sdk.__hooks as Record<LifecycleHooks, LifecycleHook[]>
38
+ const hooks = hooksMap[type] || (hooksMap[type] = [])
25
39
 
26
40
  if (hooks.length === 0) {
27
41
  const channel = ensureRendererChannel('[Lifecycle Hook] Channel not available. Make sure hooks run in plugin renderer context.')
28
42
  channel.regChannel(`@lifecycle:${type}`, (obj: any) => {
29
43
  processFunc(obj)
30
44
 
31
- // @ts-ignore
32
- delete window.$touchSDK.__hooks[type]
45
+ if (sdk?.__hooks) {
46
+ delete sdk.__hooks[type]
47
+ }
33
48
  })
34
49
  }
35
50
 
@@ -38,7 +53,7 @@ export function injectHook(type: LifecycleHooks, hook: Function, processFunc = (
38
53
  hook(data)
39
54
  }
40
55
  catch (e) {
41
- console.error(`[TouchSDK] ${type} hook error: `, e)
56
+ sdkLog.error(`[TouchSDK] ${type} hook error`, { error: e })
42
57
  }
43
58
  }
44
59
 
@@ -47,7 +62,11 @@ export function injectHook(type: LifecycleHooks, hook: Function, processFunc = (
47
62
  return wrappedHook
48
63
  }
49
64
 
50
- export const createHook = <T extends Function = (data: any) => any>(type: LifecycleHooks) => (hook: T) => injectHook(type, hook)
65
+ export function createHook<T extends LifecycleHook = (data: any) => void>(type: LifecycleHooks) {
66
+ return (
67
+ hook: T,
68
+ ) => injectHook(type, hook)
69
+ }
51
70
 
52
71
  /**
53
72
  * The plugin is enabled
@@ -2,24 +2,35 @@ import type * as HOOKS from './hooks/index'
2
2
 
3
3
  export interface ITouchSDK {
4
4
  hooks: typeof HOOKS
5
- __hooks: {}
5
+ __hooks: Record<string, unknown>
6
6
  }
7
7
 
8
8
  // Note: Window.$touchSDK is declared in ../preload.ts to avoid duplicate declarations
9
9
 
10
+ export * from './box-items'
10
11
  export * from './box-sdk'
11
12
  export * from './channel'
12
13
  export * from './clipboard'
14
+ export * from './cloud-sync'
13
15
  export * from './core-box'
14
16
  export * from './division-box'
15
17
  export * from './feature-sdk'
16
- export * from './flow'
17
18
  export { createFeaturesManager, useFeatures } from './features'
18
-
19
+ export * from './flow'
19
20
  export * from './hooks/index'
21
+ export * from './intelligence'
22
+
23
+ export * from './meta-sdk'
24
+ export * from './notification'
20
25
  export * from './performance'
26
+ export * from './power'
27
+ export * from './plugin-info'
28
+ export * from './recommend'
21
29
  export * from './service/index'
30
+ export * from './sqlite'
22
31
  export * from './storage'
23
32
  export * from './system'
33
+ export * from './temp-files'
34
+ export * from './touch-sdk'
24
35
  export * from './types'
25
36
  export * from './window/index'
@@ -0,0 +1,87 @@
1
+ import type {
2
+ IntelligenceInvokeOptions,
3
+ IntelligenceInvokeResult,
4
+ IntelligenceMessage,
5
+ } from '../../types/intelligence'
6
+ import { createIntelligenceClient } from '../../intelligence/client'
7
+ import { ensureRendererChannel } from './channel'
8
+ import { tryGetPluginSdkApi } from './plugin-info'
9
+
10
+ export interface IntelligenceChatOptions {
11
+ messages: IntelligenceMessage[]
12
+ providerId?: string
13
+ model?: string
14
+ promptTemplate?: string
15
+ promptVariables?: Record<string, any>
16
+ stream?: boolean
17
+ metadata?: Record<string, any>
18
+ }
19
+
20
+ export interface IntelligenceSDK {
21
+ invoke: <T = any>(
22
+ capabilityId: string,
23
+ payload: any,
24
+ options?: IntelligenceInvokeOptions,
25
+ ) => Promise<IntelligenceInvokeResult<T>>
26
+
27
+ /**
28
+ * @deprecated 请优先使用 invoke('text.chat', ...) 或 intelligence client 的 chatLangChain()。
29
+ */
30
+ chat: (options: IntelligenceChatOptions) => Promise<IntelligenceInvokeResult<string>>
31
+ }
32
+
33
+ function resolveSdkApi(): number | undefined {
34
+ return tryGetPluginSdkApi()
35
+ }
36
+
37
+ function createPluginIntelligenceClient() {
38
+ return createIntelligenceClient({
39
+ send: (eventName, payload) => {
40
+ const channel = ensureRendererChannel()
41
+ if (payload && typeof payload === 'object') {
42
+ return channel.send(eventName, {
43
+ ...(payload as Record<string, unknown>),
44
+ _sdkapi: resolveSdkApi(),
45
+ })
46
+ }
47
+ return channel.send(eventName, payload)
48
+ },
49
+ })
50
+ }
51
+
52
+ let cachedClient: ReturnType<typeof createPluginIntelligenceClient> | null = null
53
+
54
+ function getClient() {
55
+ if (!cachedClient) {
56
+ cachedClient = createPluginIntelligenceClient()
57
+ }
58
+ return cachedClient
59
+ }
60
+
61
+ async function invokeCapability<T = any>(
62
+ capabilityId: string,
63
+ payload: any,
64
+ options?: IntelligenceInvokeOptions,
65
+ ): Promise<IntelligenceInvokeResult<T>> {
66
+ return getClient().invoke<T>(capabilityId, payload, options)
67
+ }
68
+
69
+ /**
70
+ * @deprecated 请优先使用 invoke('text.chat', ...) 或 intelligence client 的 chatLangChain()。
71
+ */
72
+
73
+ async function chat(options: IntelligenceChatOptions): Promise<IntelligenceInvokeResult<string>> {
74
+ return getClient().chatLangChain({
75
+ messages: options.messages,
76
+ providerId: options.providerId,
77
+ model: options.model,
78
+ promptTemplate: options.promptTemplate,
79
+ promptVariables: options.promptVariables,
80
+ metadata: options.metadata,
81
+ })
82
+ }
83
+
84
+ export const intelligence: IntelligenceSDK = {
85
+ invoke: invokeCapability,
86
+ chat,
87
+ }
@@ -0,0 +1,179 @@
1
+ # MetaSDK 使用文档
2
+
3
+ MetaSDK 允许插件在 MetaOverlay 中注册全局操作,这些操作会出现在所有 item 的操作面板中。
4
+
5
+ ## 快速开始
6
+
7
+ ```typescript
8
+ export default {
9
+ onInit(context) {
10
+ const { meta } = context.utils
11
+
12
+ // 注册一个全局操作
13
+ const unregister = meta.registerAction({
14
+ id: 'my-plugin-action',
15
+ render: {
16
+ basic: {
17
+ title: '我的操作',
18
+ subtitle: '执行我的插件功能',
19
+ icon: { type: 'class', value: 'i-ri-star-line' }
20
+ },
21
+ shortcut: '⌘M',
22
+ group: '插件操作'
23
+ },
24
+ priority: 100
25
+ })
26
+
27
+ // 监听操作执行
28
+ meta.onActionExecute((data) => {
29
+ if (data.actionId === 'my-plugin-action') {
30
+ console.log('操作被执行,item:', data.item.id)
31
+ // 处理操作
32
+ }
33
+ })
34
+
35
+ // 插件卸载时清理
36
+ return () => {
37
+ unregister()
38
+ meta.unregisterAll()
39
+ }
40
+ }
41
+ }
42
+ ```
43
+
44
+ ## API 参考
45
+
46
+ ### `registerAction(action: MetaAction): () => void`
47
+
48
+ 注册一个全局操作。
49
+
50
+ **参数**:
51
+ - `action`: 操作定义
52
+
53
+ **返回**: 清理函数,调用后取消注册
54
+
55
+ **示例**:
56
+ ```typescript
57
+ const unregister = plugin.meta.registerAction({
58
+ id: 'custom-action',
59
+ render: {
60
+ basic: {
61
+ title: '自定义操作',
62
+ subtitle: '操作描述',
63
+ icon: { type: 'emoji', value: '🚀' }
64
+ },
65
+ shortcut: '⌘K',
66
+ group: '自定义'
67
+ },
68
+ priority: 100
69
+ })
70
+ ```
71
+
72
+ ### `unregisterAll(): void`
73
+
74
+ 取消注册该插件的所有操作。
75
+
76
+ **示例**:
77
+ ```typescript
78
+ // 插件卸载时
79
+ plugin.meta.unregisterAll()
80
+ ```
81
+
82
+ ### `onActionExecute(handler: ActionExecuteHandler): () => void`
83
+
84
+ 注册操作执行监听器。
85
+
86
+ **参数**:
87
+ - `handler`: 处理函数,接收 `{ actionId: string, item: TuffItem }`
88
+
89
+ **返回**: 清理函数
90
+
91
+ **示例**:
92
+ ```typescript
93
+ const unsubscribe = plugin.meta.onActionExecute((data) => {
94
+ console.log(`操作 ${data.actionId} 被执行`)
95
+ console.log('目标 item:', data.item.id)
96
+ })
97
+ ```
98
+
99
+ ## MetaAction 类型
100
+
101
+ ```typescript
102
+ interface MetaAction {
103
+ id: string // 唯一标识
104
+ render: {
105
+ basic: {
106
+ title: string // 操作标题
107
+ subtitle?: string // 操作描述
108
+ icon?: ITuffIcon // 图标
109
+ }
110
+ shortcut?: string // 快捷键,如 '⌘C'
111
+ group?: string // 分组标题
112
+ disabled?: boolean // 是否禁用
113
+ danger?: boolean // 危险操作(红色)
114
+ }
115
+ priority?: number // 优先级(默认 100)
116
+ }
117
+ ```
118
+
119
+ ## 完整示例
120
+
121
+ ```typescript
122
+ export default {
123
+ onInit(context) {
124
+ const { meta } = context.utils
125
+
126
+ // 注册多个操作
127
+ meta.registerAction({
128
+ id: 'analyze-item',
129
+ render: {
130
+ basic: {
131
+ title: '分析项目',
132
+ subtitle: '使用 AI 分析当前项目',
133
+ icon: { type: 'class', value: 'i-ri-brain-line' }
134
+ },
135
+ shortcut: '⌘A',
136
+ group: 'AI 操作'
137
+ }
138
+ })
139
+
140
+ meta.registerAction({
141
+ id: 'share-item',
142
+ render: {
143
+ basic: {
144
+ title: '分享项目',
145
+ subtitle: '分享到其他应用',
146
+ icon: { type: 'class', value: 'i-ri-share-line' }
147
+ },
148
+ shortcut: '⌘S',
149
+ group: '分享'
150
+ }
151
+ })
152
+
153
+ // 监听所有操作
154
+ meta.onActionExecute((data) => {
155
+ switch (data.actionId) {
156
+ case 'analyze-item':
157
+ // 处理分析
158
+ break
159
+ case 'share-item':
160
+ // 处理分享
161
+ break
162
+ }
163
+ })
164
+ },
165
+
166
+ onDestroy() {
167
+ // 清理所有操作
168
+ this.context.utils.meta.unregisterAll()
169
+ }
170
+ }
171
+ ```
172
+
173
+ ## 注意事项
174
+
175
+ 1. **优先级**: 插件操作的默认优先级是 100,高于内置操作(0)和 item 操作(50)
176
+ 2. **唯一性**: 操作 ID 必须在插件内唯一
177
+ 3. **清理**: 插件卸载时应该调用 `unregisterAll()` 清理所有操作
178
+ 4. **快捷键**: 快捷键仅在 MetaOverlay 打开时有效
179
+