@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.
- 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 +32 -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 +9 -5
- package/market/index.ts +1 -1
- package/market/types.ts +19 -4
- 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 +80 -7
- 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 -4
- package/plugin/providers/market-client.ts +6 -3
- package/plugin/providers/npm-provider.ts +22 -7
- package/plugin/providers/tpex-provider.ts +22 -8
- 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 +13 -6
- 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/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 +16 -2
- 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 +55 -214
- 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 +31 -40
- 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 +2690 -0
- package/transport/events/meta-overlay.ts +79 -0
- package/transport/events/types/agents.ts +177 -0
- package/transport/events/types/app-index.ts +20 -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 +84 -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 +631 -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 +141 -0
- package/transport/main.ts +2 -0
- package/transport/prelude.ts +208 -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 +102 -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 +31 -31
- 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 +166 -173
- 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,5 +1,6 @@
|
|
|
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
|
|
|
@@ -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
|
-
|
|
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))
|
|
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))
|
|
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
|
-
|
|
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
|
-
/**
|
|
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
|
-
|
|
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
|
+
|
|
@@ -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
|
+
}
|