@talex-touch/utils 1.0.42 → 1.0.45

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 (234) 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 +32 -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 +9 -5
  72. package/market/index.ts +1 -1
  73. package/market/types.ts +19 -4
  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 +80 -7
  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 -4
  87. package/plugin/providers/market-client.ts +6 -3
  88. package/plugin/providers/npm-provider.ts +22 -7
  89. package/plugin/providers/tpex-provider.ts +22 -8
  90. package/plugin/sdk/box-items.ts +14 -0
  91. package/plugin/sdk/box-sdk.ts +64 -0
  92. package/plugin/sdk/channel.ts +119 -4
  93. package/plugin/sdk/clipboard.ts +26 -12
  94. package/plugin/sdk/cloud-sync.ts +113 -0
  95. package/plugin/sdk/common.ts +19 -11
  96. package/plugin/sdk/core-box.ts +6 -15
  97. package/plugin/sdk/division-box.ts +160 -65
  98. package/plugin/sdk/examples/storage-onDidChange-example.js +5 -2
  99. package/plugin/sdk/feature-sdk.ts +111 -76
  100. package/plugin/sdk/flow.ts +146 -45
  101. package/plugin/sdk/hooks/bridge.ts +13 -6
  102. package/plugin/sdk/hooks/life-cycle.ts +35 -16
  103. package/plugin/sdk/index.ts +14 -3
  104. package/plugin/sdk/intelligence.ts +87 -0
  105. package/plugin/sdk/meta/README.md +179 -0
  106. package/plugin/sdk/meta-sdk.ts +244 -0
  107. package/plugin/sdk/notification.ts +9 -0
  108. package/plugin/sdk/plugin-info.ts +64 -0
  109. package/plugin/sdk/power.ts +155 -0
  110. package/plugin/sdk/recommend.ts +21 -0
  111. package/plugin/sdk/service/index.ts +12 -8
  112. package/plugin/sdk/sqlite.ts +141 -0
  113. package/plugin/sdk/storage.ts +2 -6
  114. package/plugin/sdk/system.ts +2 -9
  115. package/plugin/sdk/temp-files.ts +41 -0
  116. package/plugin/sdk/touch-sdk.ts +18 -0
  117. package/plugin/sdk/types.ts +44 -4
  118. package/plugin/sdk/window/index.ts +12 -9
  119. package/plugin/sdk-version.ts +231 -0
  120. package/preload/renderer.ts +3 -2
  121. package/renderer/hooks/arg-mapper.ts +16 -2
  122. package/renderer/hooks/index.ts +13 -0
  123. package/renderer/hooks/initialize.ts +2 -1
  124. package/renderer/hooks/use-agent-market-sdk.ts +7 -0
  125. package/renderer/hooks/use-agent-market.ts +106 -0
  126. package/renderer/hooks/use-agents-sdk.ts +7 -0
  127. package/renderer/hooks/use-app-sdk.ts +7 -0
  128. package/renderer/hooks/use-channel.ts +33 -4
  129. package/renderer/hooks/use-download-sdk.ts +21 -0
  130. package/renderer/hooks/use-intelligence-sdk.ts +7 -0
  131. package/renderer/hooks/use-intelligence-stats.ts +290 -0
  132. package/renderer/hooks/use-intelligence.ts +55 -214
  133. package/renderer/hooks/use-market-sdk.ts +16 -0
  134. package/renderer/hooks/use-notification-sdk.ts +7 -0
  135. package/renderer/hooks/use-permission-sdk.ts +7 -0
  136. package/renderer/hooks/use-permission.ts +325 -0
  137. package/renderer/hooks/use-platform-sdk.ts +7 -0
  138. package/renderer/hooks/use-plugin-sdk.ts +16 -0
  139. package/renderer/hooks/use-settings-sdk.ts +7 -0
  140. package/renderer/hooks/use-update-sdk.ts +21 -0
  141. package/renderer/index.ts +1 -0
  142. package/renderer/ref.ts +19 -10
  143. package/renderer/shared/components/SharedPluginDetailContent.vue +84 -0
  144. package/renderer/shared/components/SharedPluginDetailHeader.vue +116 -0
  145. package/renderer/shared/components/SharedPluginDetailMetaList.vue +39 -0
  146. package/renderer/shared/components/SharedPluginDetailReadme.vue +45 -0
  147. package/renderer/shared/components/SharedPluginDetailVersions.vue +98 -0
  148. package/renderer/shared/components/index.ts +5 -0
  149. package/renderer/shared/components/shims-vue.d.ts +5 -0
  150. package/renderer/shared/index.ts +2 -0
  151. package/renderer/shared/plugin-detail.ts +62 -0
  152. package/renderer/storage/app-settings.ts +3 -1
  153. package/renderer/storage/base-storage.ts +508 -82
  154. package/renderer/storage/intelligence-storage.ts +31 -40
  155. package/renderer/storage/openers.ts +3 -1
  156. package/renderer/storage/storage-subscription.ts +126 -42
  157. package/renderer/touch-sdk/env.ts +10 -10
  158. package/renderer/touch-sdk/index.ts +114 -18
  159. package/renderer/touch-sdk/terminal.ts +24 -13
  160. package/search/feature-matcher.ts +279 -0
  161. package/search/fuzzy-match.ts +64 -34
  162. package/search/index.ts +10 -0
  163. package/search/levenshtein-utils.ts +17 -11
  164. package/transport/errors.ts +310 -0
  165. package/transport/event/builder.ts +378 -0
  166. package/transport/event/index.ts +7 -0
  167. package/transport/event/types.ts +292 -0
  168. package/transport/events/index.ts +2690 -0
  169. package/transport/events/meta-overlay.ts +79 -0
  170. package/transport/events/types/agents.ts +177 -0
  171. package/transport/events/types/app-index.ts +20 -0
  172. package/transport/events/types/app.ts +475 -0
  173. package/transport/events/types/box-item.ts +222 -0
  174. package/transport/events/types/clipboard.ts +80 -0
  175. package/transport/events/types/core-box.ts +534 -0
  176. package/transport/events/types/device-idle.ts +7 -0
  177. package/transport/events/types/division-box.ts +99 -0
  178. package/transport/events/types/download.ts +115 -0
  179. package/transport/events/types/file-index.ts +84 -0
  180. package/transport/events/types/flow.ts +149 -0
  181. package/transport/events/types/index.ts +70 -0
  182. package/transport/events/types/market.ts +39 -0
  183. package/transport/events/types/meta-overlay.ts +184 -0
  184. package/transport/events/types/notification.ts +140 -0
  185. package/transport/events/types/permission.ts +90 -0
  186. package/transport/events/types/platform.ts +8 -0
  187. package/transport/events/types/plugin.ts +631 -0
  188. package/transport/events/types/sentry.ts +20 -0
  189. package/transport/events/types/storage.ts +208 -0
  190. package/transport/events/types/transport.ts +60 -0
  191. package/transport/events/types/tray.ts +16 -0
  192. package/transport/events/types/update.ts +78 -0
  193. package/transport/index.ts +141 -0
  194. package/transport/main.ts +2 -0
  195. package/transport/prelude.ts +208 -0
  196. package/transport/sdk/constants.ts +29 -0
  197. package/transport/sdk/domains/agents-market.ts +47 -0
  198. package/transport/sdk/domains/agents.ts +62 -0
  199. package/transport/sdk/domains/app.ts +48 -0
  200. package/transport/sdk/domains/disposable.ts +35 -0
  201. package/transport/sdk/domains/download.ts +139 -0
  202. package/transport/sdk/domains/index.ts +13 -0
  203. package/transport/sdk/domains/intelligence.ts +616 -0
  204. package/transport/sdk/domains/market.ts +35 -0
  205. package/transport/sdk/domains/notification.ts +62 -0
  206. package/transport/sdk/domains/permission.ts +85 -0
  207. package/transport/sdk/domains/platform.ts +19 -0
  208. package/transport/sdk/domains/plugin.ts +144 -0
  209. package/transport/sdk/domains/settings.ts +102 -0
  210. package/transport/sdk/domains/update.ts +64 -0
  211. package/transport/sdk/index.ts +60 -0
  212. package/transport/sdk/main-transport.ts +710 -0
  213. package/transport/sdk/main.ts +9 -0
  214. package/transport/sdk/plugin-transport.ts +654 -0
  215. package/transport/sdk/port-policy.ts +38 -0
  216. package/transport/sdk/renderer-transport.ts +1165 -0
  217. package/transport/types.ts +605 -0
  218. package/types/agent.ts +399 -0
  219. package/types/cloud-sync.ts +157 -0
  220. package/types/division-box.ts +31 -31
  221. package/types/download.ts +1 -0
  222. package/types/flow.ts +63 -12
  223. package/types/icon.ts +2 -1
  224. package/types/index.ts +5 -0
  225. package/types/intelligence.ts +166 -173
  226. package/types/modules/base.ts +2 -0
  227. package/types/path-browserify.d.ts +5 -0
  228. package/types/platform.ts +12 -0
  229. package/types/startup-info.ts +32 -0
  230. package/types/touch-app-core.ts +8 -8
  231. package/types/update.ts +94 -1
  232. package/vitest.config.ts +25 -0
  233. package/auth/useClerkConfig.ts +0 -40
  234. package/auth/useClerkProvider.ts +0 -52
@@ -1,5 +1,6 @@
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
 
@@ -36,17 +37,20 @@ const CACHE_MAX_SIZE: Record<BridgeEvent, number> = {
36
37
  [BridgeEventForCoreBox.CORE_BOX_KEY_EVENT]: 10,
37
38
  }
38
39
 
40
+ const bridgeLog = getLogger('plugin-sdk')
41
+
39
42
  function invokeHook<T>(hook: BridgeHook<T>, data: T, fromCache: boolean, timestamp: number): void {
40
43
  try {
41
44
  hook({ data, meta: { timestamp, fromCache } })
42
45
  }
43
46
  catch (e) {
44
- console.error('[TouchSDK] Bridge hook error:', e)
47
+ bridgeLog.error('[TouchSDK] Bridge hook error', { error: e })
45
48
  }
46
49
  }
47
50
 
48
51
  function registerEarlyListener(type: BridgeEvent): void {
49
- if (__channelRegistered.has(type)) return
52
+ if (__channelRegistered.has(type))
53
+ return
50
54
 
51
55
  try {
52
56
  const channel = ensureRendererChannel()
@@ -58,12 +62,13 @@ function registerEarlyListener(type: BridgeEvent): void {
58
62
  hooks.forEach(h => invokeHook(h, data, false, timestamp))
59
63
  }
60
64
  else {
61
- if (!__eventCache.has(type)) __eventCache.set(type, [])
65
+ if (!__eventCache.has(type))
66
+ __eventCache.set(type, [])
62
67
  const cache = __eventCache.get(type)!
63
68
  const maxSize = CACHE_MAX_SIZE[type] ?? 1
64
69
  cache.push({ data, timestamp })
65
70
  while (cache.length > maxSize) cache.shift()
66
- console.debug(`[TouchSDK] ${type} cached, size: ${cache.length}`)
71
+ bridgeLog.debug(`[TouchSDK] ${type} cached, size: ${cache.length}`)
67
72
  }
68
73
  })
69
74
  __channelRegistered.add(type)
@@ -90,7 +95,9 @@ export function clearBridgeEventCache(type?: BridgeEvent): void {
90
95
  }, 0)
91
96
  })()
92
97
 
93
- /** @internal Injects a hook for a given bridge event with cache replay. */
98
+ /**
99
+ * @internal
100
+ */
94
101
  export function injectBridgeEvent<T>(type: BridgeEvent, hook: BridgeHook<T>) {
95
102
  const hooks: Array<BridgeHook<T>> = __hooks[type] || (__hooks[type] = [])
96
103
 
@@ -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
+
@@ -0,0 +1,244 @@
1
+ /**
2
+ * MetaOverlay SDK for Plugin Development
3
+ *
4
+ * Provides API for plugins to register global actions in MetaOverlay.
5
+ * MetaOverlay is a floating action panel that appears above plugin UI.
6
+ */
7
+
8
+ import type { TuffItem } from '../../core-box/tuff/tuff-dsl'
9
+ import type { MetaAction } from '../../transport/events/types/meta-overlay'
10
+ import { createPluginTuffTransport } from '../../transport'
11
+ import { defineRawEvent } from '../../transport/event/builder'
12
+ import { MetaOverlayEvents } from '../../transport/events/meta-overlay'
13
+ import { createDisposableBag } from '../../transport/sdk'
14
+
15
+ /**
16
+ * Action execution handler
17
+ */
18
+ export type ActionExecuteHandler = (data: {
19
+ actionId: string
20
+ item: TuffItem
21
+ }) => void
22
+
23
+ const metaOverlayActionExecutedEvent = defineRawEvent<{ pluginId: string, actionId: string, item: TuffItem }, void>('meta-overlay:action-executed')
24
+
25
+ /**
26
+ * MetaOverlay SDK interface for plugins
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * // Register a global action
31
+ * const unregister = plugin.meta.registerAction({
32
+ * id: 'my-plugin-action',
33
+ * render: {
34
+ * basic: {
35
+ * title: 'My Action',
36
+ * subtitle: 'Execute my plugin action',
37
+ * icon: { type: 'class', value: 'i-ri-star-line' }
38
+ * },
39
+ * shortcut: '⌘M',
40
+ * group: '插件操作'
41
+ * },
42
+ * priority: 100
43
+ * })
44
+ *
45
+ * // Listen for action execution
46
+ * plugin.meta.onActionExecute((data) => {
47
+ * if (data.actionId === 'my-plugin-action') {
48
+ * // Handle action
49
+ * }
50
+ * })
51
+ *
52
+ * // Unregister all actions
53
+ * plugin.meta.unregisterAll()
54
+ * ```
55
+ */
56
+ export interface MetaSDK {
57
+ /**
58
+ * Registers a global action that will appear in MetaOverlay
59
+ *
60
+ * @param action - Action definition
61
+ * @returns Cleanup function to unregister this action
62
+ *
63
+ * @example
64
+ * ```typescript
65
+ * const unregister = plugin.meta.registerAction({
66
+ * id: 'custom-action',
67
+ * render: {
68
+ * basic: {
69
+ * title: 'Custom Action',
70
+ * subtitle: 'Description',
71
+ * icon: { type: 'emoji', value: '🚀' }
72
+ * },
73
+ * shortcut: '⌘K',
74
+ * group: 'Custom'
75
+ * },
76
+ * priority: 100
77
+ * })
78
+ *
79
+ * // Later: unregister
80
+ * unregister()
81
+ * ```
82
+ */
83
+ registerAction: (action: MetaAction) => () => void
84
+
85
+ /**
86
+ * Unregisters all actions registered by this plugin
87
+ *
88
+ * @example
89
+ * ```typescript
90
+ * // Cleanup on plugin unload
91
+ * plugin.meta.unregisterAll()
92
+ * ```
93
+ */
94
+ unregisterAll: () => void
95
+
96
+ /**
97
+ * Registers a listener for when actions registered by this plugin are executed
98
+ *
99
+ * @param handler - Handler function
100
+ * @returns Cleanup function to remove listener
101
+ *
102
+ * @example
103
+ * ```typescript
104
+ * const unsubscribe = plugin.meta.onActionExecute((data) => {
105
+ * console.log(`Action ${data.actionId} executed for item ${data.item.id}`)
106
+ * // Handle the action
107
+ * })
108
+ *
109
+ * // Later: unsubscribe
110
+ * unsubscribe()
111
+ * ```
112
+ */
113
+ onActionExecute: (handler: ActionExecuteHandler) => () => void
114
+
115
+ /**
116
+ * 释放 SDK 内部监听器
117
+ */
118
+ dispose: () => void
119
+ }
120
+
121
+ /**
122
+ * Creates a MetaSDK instance for plugin use
123
+ *
124
+ * @param channel - The plugin channel bridge for IPC communication
125
+ * @param pluginId - Plugin identifier
126
+ * @returns Configured MetaSDK instance
127
+ *
128
+ * @internal
129
+ */
130
+ export function createMetaSDK(channel: any, pluginId: string): MetaSDK {
131
+ const actionExecuteHandlers: Set<ActionExecuteHandler> = new Set()
132
+ const registeredActionIds: Set<string> = new Set()
133
+ const transport = createPluginTuffTransport(channel)
134
+ const disposables = createDisposableBag()
135
+ let disposed = false
136
+
137
+ const emitActionExecute = (data: { pluginId: string, actionId: string, item: TuffItem }) => {
138
+ if (data.pluginId !== pluginId || !registeredActionIds.has(data.actionId)) {
139
+ return
140
+ }
141
+
142
+ for (const handler of actionExecuteHandlers) {
143
+ try {
144
+ handler({
145
+ actionId: data.actionId,
146
+ item: data.item,
147
+ })
148
+ }
149
+ catch (error) {
150
+ console.error('[MetaSDK] onActionExecute handler error', error)
151
+ }
152
+ }
153
+ }
154
+
155
+ const dispose = () => {
156
+ if (disposed) {
157
+ return
158
+ }
159
+
160
+ disposed = true
161
+ actionExecuteHandlers.clear()
162
+
163
+ if (registeredActionIds.size > 0) {
164
+ void transport.send(MetaOverlayEvents.action.unregister, { pluginId }).catch((error) => {
165
+ console.error('[MetaSDK] Failed to unregister all actions during dispose', error)
166
+ })
167
+ }
168
+
169
+ registeredActionIds.clear()
170
+ disposables.dispose()
171
+ transport.destroy()
172
+ }
173
+
174
+ const ensureActive = (method: string) => {
175
+ if (disposed) {
176
+ throw new Error(`[MetaSDK] Cannot call ${method} after dispose`)
177
+ }
178
+ }
179
+
180
+ disposables.add(
181
+ transport.on(metaOverlayActionExecutedEvent, (payload) => {
182
+ emitActionExecute(payload)
183
+ }),
184
+ )
185
+
186
+ if (typeof window !== 'undefined' && typeof window.addEventListener === 'function') {
187
+ const onBeforeUnload = () => dispose()
188
+ window.addEventListener('beforeunload', onBeforeUnload, { once: true })
189
+ disposables.add(() => window.removeEventListener('beforeunload', onBeforeUnload))
190
+ }
191
+
192
+ return {
193
+ registerAction(action: MetaAction): () => void {
194
+ ensureActive('registerAction')
195
+ registeredActionIds.add(action.id)
196
+
197
+ void transport.send(MetaOverlayEvents.action.register, {
198
+ pluginId,
199
+ action: {
200
+ ...action,
201
+ handler: pluginId,
202
+ priority: action.priority ?? 100,
203
+ },
204
+ }).catch((error) => {
205
+ console.error('[MetaSDK] Failed to register action', error)
206
+ })
207
+
208
+ return () => {
209
+ if (!registeredActionIds.has(action.id)) {
210
+ return
211
+ }
212
+
213
+ registeredActionIds.delete(action.id)
214
+ void transport.send(MetaOverlayEvents.action.unregister, {
215
+ pluginId,
216
+ actionId: action.id,
217
+ } as any).catch((error) => {
218
+ console.error('[MetaSDK] Failed to unregister action', error)
219
+ })
220
+ }
221
+ },
222
+
223
+ unregisterAll(): void {
224
+ ensureActive('unregisterAll')
225
+ registeredActionIds.clear()
226
+
227
+ void transport.send(MetaOverlayEvents.action.unregister, {
228
+ pluginId,
229
+ }).catch((error) => {
230
+ console.error('[MetaSDK] Failed to unregister all actions', error)
231
+ })
232
+ },
233
+
234
+ onActionExecute(handler: ActionExecuteHandler): () => void {
235
+ ensureActive('onActionExecute')
236
+ actionExecuteHandlers.add(handler)
237
+ return () => {
238
+ actionExecuteHandlers.delete(handler)
239
+ }
240
+ },
241
+
242
+ dispose,
243
+ }
244
+ }
@@ -0,0 +1,9 @@
1
+ import { createNotificationSdk } from '../../transport/sdk/domains/notification'
2
+ import { createPluginTuffTransport } from '../../transport/sdk/plugin-transport'
3
+ import { useChannel } from './channel'
4
+
5
+ export function useNotificationSdk() {
6
+ const channel = useChannel()
7
+ const transport = createPluginTuffTransport(channel)
8
+ return createNotificationSdk(transport)
9
+ }