@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.
- package/.eslintcache +1 -0
- package/__tests__/cloud-sync-sdk.test.ts +442 -0
- package/__tests__/icons/icons.test.ts +84 -0
- package/__tests__/plugin-sdk-lifecycle.test.ts +130 -0
- package/__tests__/power-sdk.test.ts +143 -0
- package/__tests__/preset-export-types.test.ts +108 -0
- package/__tests__/search/fuzzy-match.test.ts +137 -0
- package/__tests__/transport/port-policy.test.ts +44 -0
- package/__tests__/transport-domain-sdks.test.ts +152 -0
- package/__tests__/types/update.test.ts +67 -0
- package/account/account-sdk.ts +915 -0
- package/account/index.ts +2 -0
- package/account/types.ts +321 -0
- package/analytics/client.ts +136 -0
- package/analytics/index.ts +2 -0
- package/analytics/types.ts +156 -0
- package/animation/auto-resize.ts +322 -0
- package/animation/window-node.ts +26 -19
- package/auth/clerk-types.ts +12 -30
- package/auth/index.ts +0 -2
- package/auth/useAuthState.ts +6 -14
- package/base/index.ts +2 -0
- package/base/log-level.ts +105 -0
- package/channel/index.ts +170 -69
- package/cloud-sync/cloud-sync-sdk.ts +450 -0
- package/cloud-sync/index.ts +1 -0
- package/common/file-scan-utils.ts +17 -9
- package/common/index.ts +4 -0
- package/common/logger/index.ts +46 -0
- package/common/logger/logger-manager.ts +303 -0
- package/common/logger/module-logger.ts +270 -0
- package/common/logger/transport-logger.ts +234 -0
- package/common/logger/types.ts +93 -0
- package/common/search/gather.ts +48 -6
- package/common/search/index.ts +8 -0
- package/common/storage/constants.ts +13 -0
- package/common/storage/entity/app-settings.ts +245 -0
- package/common/storage/entity/index.ts +3 -0
- package/common/storage/entity/layout-atom-types.ts +147 -0
- package/common/storage/entity/openers.ts +1 -0
- package/common/storage/entity/preset-cloud-api.ts +132 -0
- package/common/storage/entity/preset-export-types.ts +256 -0
- package/common/storage/entity/shortcut-settings.ts +1 -0
- package/common/storage/shortcut-storage.ts +11 -0
- package/common/utils/clone-diagnostics.ts +105 -0
- package/common/utils/file.ts +16 -8
- package/common/utils/index.ts +6 -2
- package/common/utils/payload-preview.ts +173 -0
- package/common/utils/polling.ts +167 -13
- package/common/utils/safe-path.ts +103 -0
- package/common/utils/safe-shell.ts +115 -0
- package/common/utils/task-queue.ts +4 -1
- package/core-box/builder/tuff-builder.ts +0 -1
- package/core-box/index.ts +1 -1
- package/core-box/recommendation.ts +38 -1
- package/core-box/tuff/tuff-dsl.ts +97 -0
- package/electron/download-manager.ts +10 -7
- package/electron/env-tool.ts +42 -40
- package/electron/index.ts +0 -1
- package/env/index.ts +156 -0
- package/eslint.config.js +55 -0
- package/i18n/index.ts +62 -0
- package/i18n/locales/en.json +226 -0
- package/i18n/locales/zh.json +226 -0
- package/i18n/message-keys.ts +236 -0
- package/i18n/resolver.ts +181 -0
- package/icons/index.ts +257 -0
- package/icons/svg.ts +69 -0
- package/index.ts +9 -1
- package/intelligence/client.ts +72 -42
- package/market/constants.ts +21 -3
- package/market/index.ts +1 -1
- package/market/types.ts +20 -5
- package/package.json +15 -5
- package/permission/index.ts +143 -46
- package/permission/legacy.ts +26 -0
- package/permission/registry.ts +304 -0
- package/permission/types.ts +164 -0
- package/plugin/channel.ts +68 -39
- package/plugin/index.ts +82 -8
- package/plugin/install.ts +3 -0
- package/plugin/log/types.ts +22 -5
- package/plugin/node/logger-manager.ts +11 -3
- package/plugin/node/logger.ts +24 -17
- package/plugin/preload.ts +25 -2
- package/plugin/providers/index.ts +4 -0
- package/plugin/providers/market-client.ts +218 -0
- package/plugin/providers/npm-provider.ts +228 -0
- package/plugin/providers/tpex-provider.ts +297 -0
- package/plugin/providers/tpex-types.ts +34 -0
- package/plugin/sdk/box-items.ts +14 -0
- package/plugin/sdk/box-sdk.ts +64 -0
- package/plugin/sdk/channel.ts +119 -4
- package/plugin/sdk/clipboard.ts +26 -12
- package/plugin/sdk/cloud-sync.ts +113 -0
- package/plugin/sdk/common.ts +19 -11
- package/plugin/sdk/core-box.ts +6 -15
- package/plugin/sdk/division-box.ts +160 -65
- package/plugin/sdk/examples/storage-onDidChange-example.js +5 -2
- package/plugin/sdk/feature-sdk.ts +111 -76
- package/plugin/sdk/flow.ts +146 -45
- package/plugin/sdk/hooks/bridge.ts +113 -49
- package/plugin/sdk/hooks/life-cycle.ts +35 -16
- package/plugin/sdk/index.ts +14 -3
- package/plugin/sdk/intelligence.ts +87 -0
- package/plugin/sdk/meta/README.md +179 -0
- package/plugin/sdk/meta-sdk.ts +244 -0
- package/plugin/sdk/notification.ts +9 -0
- package/plugin/sdk/performance.ts +1 -16
- package/plugin/sdk/plugin-info.ts +64 -0
- package/plugin/sdk/power.ts +155 -0
- package/plugin/sdk/recommend.ts +21 -0
- package/plugin/sdk/service/index.ts +12 -8
- package/plugin/sdk/sqlite.ts +141 -0
- package/plugin/sdk/storage.ts +2 -6
- package/plugin/sdk/system.ts +2 -9
- package/plugin/sdk/temp-files.ts +41 -0
- package/plugin/sdk/touch-sdk.ts +18 -0
- package/plugin/sdk/types.ts +44 -4
- package/plugin/sdk/window/index.ts +12 -9
- package/plugin/sdk-version.ts +231 -0
- package/preload/renderer.ts +3 -2
- package/renderer/hooks/arg-mapper.ts +34 -6
- package/renderer/hooks/index.ts +13 -0
- package/renderer/hooks/initialize.ts +2 -1
- package/renderer/hooks/use-agent-market-sdk.ts +7 -0
- package/renderer/hooks/use-agent-market.ts +106 -0
- package/renderer/hooks/use-agents-sdk.ts +7 -0
- package/renderer/hooks/use-app-sdk.ts +7 -0
- package/renderer/hooks/use-channel.ts +33 -4
- package/renderer/hooks/use-download-sdk.ts +21 -0
- package/renderer/hooks/use-intelligence-sdk.ts +7 -0
- package/renderer/hooks/use-intelligence-stats.ts +290 -0
- package/renderer/hooks/use-intelligence.ts +202 -104
- package/renderer/hooks/use-market-sdk.ts +16 -0
- package/renderer/hooks/use-notification-sdk.ts +7 -0
- package/renderer/hooks/use-permission-sdk.ts +7 -0
- package/renderer/hooks/use-permission.ts +325 -0
- package/renderer/hooks/use-platform-sdk.ts +7 -0
- package/renderer/hooks/use-plugin-sdk.ts +16 -0
- package/renderer/hooks/use-settings-sdk.ts +7 -0
- package/renderer/hooks/use-update-sdk.ts +21 -0
- package/renderer/index.ts +1 -0
- package/renderer/ref.ts +19 -10
- package/renderer/shared/components/SharedPluginDetailContent.vue +84 -0
- package/renderer/shared/components/SharedPluginDetailHeader.vue +116 -0
- package/renderer/shared/components/SharedPluginDetailMetaList.vue +39 -0
- package/renderer/shared/components/SharedPluginDetailReadme.vue +45 -0
- package/renderer/shared/components/SharedPluginDetailVersions.vue +98 -0
- package/renderer/shared/components/index.ts +5 -0
- package/renderer/shared/components/shims-vue.d.ts +5 -0
- package/renderer/shared/index.ts +2 -0
- package/renderer/shared/plugin-detail.ts +62 -0
- package/renderer/storage/app-settings.ts +3 -1
- package/renderer/storage/base-storage.ts +508 -82
- package/renderer/storage/intelligence-storage.ts +37 -46
- package/renderer/storage/openers.ts +3 -1
- package/renderer/storage/storage-subscription.ts +126 -42
- package/renderer/touch-sdk/env.ts +10 -10
- package/renderer/touch-sdk/index.ts +114 -18
- package/renderer/touch-sdk/terminal.ts +24 -13
- package/search/feature-matcher.ts +279 -0
- package/search/fuzzy-match.ts +64 -34
- package/search/index.ts +10 -0
- package/search/levenshtein-utils.ts +17 -11
- package/transport/errors.ts +310 -0
- package/transport/event/builder.ts +378 -0
- package/transport/event/index.ts +7 -0
- package/transport/event/types.ts +292 -0
- package/transport/events/index.ts +2670 -0
- package/transport/events/meta-overlay.ts +79 -0
- package/transport/events/types/agents.ts +177 -0
- package/transport/events/types/app-index.ts +9 -0
- package/transport/events/types/app.ts +475 -0
- package/transport/events/types/box-item.ts +222 -0
- package/transport/events/types/clipboard.ts +80 -0
- package/transport/events/types/core-box.ts +534 -0
- package/transport/events/types/device-idle.ts +7 -0
- package/transport/events/types/division-box.ts +99 -0
- package/transport/events/types/download.ts +115 -0
- package/transport/events/types/file-index.ts +73 -0
- package/transport/events/types/flow.ts +149 -0
- package/transport/events/types/index.ts +70 -0
- package/transport/events/types/market.ts +39 -0
- package/transport/events/types/meta-overlay.ts +184 -0
- package/transport/events/types/notification.ts +140 -0
- package/transport/events/types/permission.ts +90 -0
- package/transport/events/types/platform.ts +8 -0
- package/transport/events/types/plugin.ts +620 -0
- package/transport/events/types/sentry.ts +20 -0
- package/transport/events/types/storage.ts +208 -0
- package/transport/events/types/transport.ts +60 -0
- package/transport/events/types/tray.ts +16 -0
- package/transport/events/types/update.ts +78 -0
- package/transport/index.ts +139 -0
- package/transport/main.ts +2 -0
- package/transport/sdk/constants.ts +29 -0
- package/transport/sdk/domains/agents-market.ts +47 -0
- package/transport/sdk/domains/agents.ts +62 -0
- package/transport/sdk/domains/app.ts +48 -0
- package/transport/sdk/domains/disposable.ts +35 -0
- package/transport/sdk/domains/download.ts +139 -0
- package/transport/sdk/domains/index.ts +13 -0
- package/transport/sdk/domains/intelligence.ts +616 -0
- package/transport/sdk/domains/market.ts +35 -0
- package/transport/sdk/domains/notification.ts +62 -0
- package/transport/sdk/domains/permission.ts +85 -0
- package/transport/sdk/domains/platform.ts +19 -0
- package/transport/sdk/domains/plugin.ts +144 -0
- package/transport/sdk/domains/settings.ts +92 -0
- package/transport/sdk/domains/update.ts +64 -0
- package/transport/sdk/index.ts +60 -0
- package/transport/sdk/main-transport.ts +710 -0
- package/transport/sdk/main.ts +9 -0
- package/transport/sdk/plugin-transport.ts +654 -0
- package/transport/sdk/port-policy.ts +38 -0
- package/transport/sdk/renderer-transport.ts +1165 -0
- package/transport/types.ts +605 -0
- package/types/agent.ts +399 -0
- package/types/cloud-sync.ts +157 -0
- package/types/division-box.ts +47 -27
- package/types/download.ts +1 -0
- package/types/flow.ts +63 -12
- package/types/icon.ts +2 -1
- package/types/index.ts +5 -0
- package/types/intelligence.ts +1492 -81
- package/types/modules/base.ts +2 -0
- package/types/path-browserify.d.ts +5 -0
- package/types/platform.ts +12 -0
- package/types/startup-info.ts +32 -0
- package/types/touch-app-core.ts +8 -8
- package/types/update.ts +94 -1
- package/vitest.config.ts +25 -0
- package/auth/useClerkConfig.ts +0 -40
- package/auth/useClerkProvider.ts +0 -52
|
@@ -1,13 +1,26 @@
|
|
|
1
|
-
import {
|
|
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
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
if (
|
|
37
|
-
|
|
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
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
66
|
-
|
|
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
|
-
}
|
|
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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
|
|
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
|
-
|
|
32
|
-
|
|
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
|
-
|
|
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
|
|
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
|
package/plugin/sdk/index.ts
CHANGED
|
@@ -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
|
+
|