@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
package/plugin/sdk/storage.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { FileDetails, StorageStats, StorageTreeNode } from '../../types/storage'
|
|
2
2
|
import { ensureRendererChannel } from './channel'
|
|
3
|
+
import { usePluginName } from './plugin-info'
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Get the storage for the current plugin.
|
|
@@ -9,12 +10,7 @@ import { ensureRendererChannel } from './channel'
|
|
|
9
10
|
* @returns An object with methods to interact with the storage.
|
|
10
11
|
*/
|
|
11
12
|
export function usePluginStorage() {
|
|
12
|
-
|
|
13
|
-
const pluginName = window.$plugin.name as string
|
|
14
|
-
|
|
15
|
-
if (!pluginName) {
|
|
16
|
-
throw new Error('[Plugin SDK] Cannot determine plugin name. Make sure this is called in a plugin context.')
|
|
17
|
-
}
|
|
13
|
+
const pluginName = usePluginName('[Plugin SDK] Cannot determine plugin name. Make sure this is called in a plugin context.')
|
|
18
14
|
|
|
19
15
|
const channel = ensureRendererChannel('[Plugin Storage] Channel not available. Make sure this is called in a plugin context.')
|
|
20
16
|
|
package/plugin/sdk/system.ts
CHANGED
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
import type { ActiveAppSnapshot } from './types'
|
|
2
|
-
|
|
3
|
-
function ensurePluginChannel() {
|
|
4
|
-
const channel = (window as any)?.$channel
|
|
5
|
-
if (!channel) {
|
|
6
|
-
throw new Error('[Plugin SDK] System channel requires plugin renderer context with $channel available.')
|
|
7
|
-
}
|
|
8
|
-
return channel
|
|
9
|
-
}
|
|
2
|
+
import { useChannel } from './channel'
|
|
10
3
|
|
|
11
4
|
export async function getActiveAppSnapshot(options: { forceRefresh?: boolean } = {}): Promise<ActiveAppSnapshot | null> {
|
|
12
|
-
const channel =
|
|
5
|
+
const channel = useChannel('[Plugin SDK] System channel requires plugin renderer context with $channel available.')
|
|
13
6
|
return channel.send('system:get-active-app', options)
|
|
14
7
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { useChannel } from './channel'
|
|
2
|
+
|
|
3
|
+
export interface TempPluginFileCreateOptions {
|
|
4
|
+
ext?: string
|
|
5
|
+
text?: string
|
|
6
|
+
base64?: string
|
|
7
|
+
prefix?: string
|
|
8
|
+
/**
|
|
9
|
+
* Optional retention in milliseconds.
|
|
10
|
+
* If omitted, the host will apply a default plugin temp retention policy.
|
|
11
|
+
*/
|
|
12
|
+
retentionMs?: number
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface TempPluginFileResult {
|
|
16
|
+
url: string
|
|
17
|
+
sizeBytes: number
|
|
18
|
+
createdAt: number
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function useTempPluginFiles() {
|
|
22
|
+
const channel = useChannel('[Plugin SDK] Temp files require plugin renderer context with $channel available.')
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
async create(options: TempPluginFileCreateOptions): Promise<TempPluginFileResult> {
|
|
26
|
+
const res = await channel.send('temp-file:create', options ?? {})
|
|
27
|
+
if (!res || typeof res !== 'object') {
|
|
28
|
+
throw new Error('[Plugin SDK] temp-file:create returned invalid response')
|
|
29
|
+
}
|
|
30
|
+
return res as TempPluginFileResult
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
async delete(url: string): Promise<boolean> {
|
|
34
|
+
const res = await channel.send('temp-file:delete', { url })
|
|
35
|
+
if (res && typeof res === 'object' && 'success' in res) {
|
|
36
|
+
return Boolean((res as any).success)
|
|
37
|
+
}
|
|
38
|
+
return Boolean(res)
|
|
39
|
+
},
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ITouchSDK } from './index'
|
|
2
|
+
import { hasWindow } from '../../env'
|
|
3
|
+
|
|
4
|
+
const DEFAULT_TOUCH_SDK_ERROR
|
|
5
|
+
= '[TouchSDK] Touch SDK not available. Make sure this is called in a plugin context.'
|
|
6
|
+
|
|
7
|
+
let cachedTouchSDK: ITouchSDK | null = null
|
|
8
|
+
|
|
9
|
+
export function useTouchSDK(errorMessage: string = DEFAULT_TOUCH_SDK_ERROR): ITouchSDK {
|
|
10
|
+
const globalWindow = hasWindow() ? window : undefined
|
|
11
|
+
const windowSdk = (globalWindow as any)?.$touchSDK as ITouchSDK | undefined
|
|
12
|
+
const sdk = windowSdk ?? cachedTouchSDK
|
|
13
|
+
if (!sdk) {
|
|
14
|
+
throw new Error(errorMessage)
|
|
15
|
+
}
|
|
16
|
+
cachedTouchSDK = sdk
|
|
17
|
+
return sdk
|
|
18
|
+
}
|
package/plugin/sdk/types.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import type { ITouchChannel, ITouchClientChannel, StandardChannelData } from '@talex-touch/utils/channel'
|
|
8
8
|
import type { IPluginFeature } from '../index'
|
|
9
|
+
import path from 'node:path'
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Handler signature for plugin channel events.
|
|
@@ -90,6 +91,15 @@ export interface IPluginRendererChannel {
|
|
|
90
91
|
export interface PluginClipboardItem {
|
|
91
92
|
id?: number
|
|
92
93
|
type: 'text' | 'image' | 'files'
|
|
94
|
+
/**
|
|
95
|
+
* Clipboard content:
|
|
96
|
+
* - text: plain string
|
|
97
|
+
* - files: JSON string array
|
|
98
|
+
* - image: defaults to a small preview data URL to keep IPC payload light
|
|
99
|
+
*
|
|
100
|
+
* For images, the original asset URL (tfile://...) may be available at:
|
|
101
|
+
* - `meta.image_original_url`
|
|
102
|
+
*/
|
|
93
103
|
content: string
|
|
94
104
|
thumbnail?: string | null
|
|
95
105
|
rawContent?: string | null
|
|
@@ -144,7 +154,6 @@ export interface PluginClipboardSearchResponse {
|
|
|
144
154
|
pageSize: number
|
|
145
155
|
}
|
|
146
156
|
|
|
147
|
-
|
|
148
157
|
export interface ActiveAppSnapshot {
|
|
149
158
|
identifier: string | null
|
|
150
159
|
displayName: string | null
|
|
@@ -230,6 +239,24 @@ export interface IPluginUtils {
|
|
|
230
239
|
*/
|
|
231
240
|
feature: import('./feature-sdk').FeatureSDK
|
|
232
241
|
|
|
242
|
+
/**
|
|
243
|
+
* MetaOverlay SDK for registering global actions
|
|
244
|
+
* @see {@link MetaSDK}
|
|
245
|
+
*/
|
|
246
|
+
meta: import('./meta-sdk').MetaSDK
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Power SDK for low power status
|
|
250
|
+
* @see {@link PowerSDK}
|
|
251
|
+
*/
|
|
252
|
+
power: import('./power').PowerSDK
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Recommend SDK for registering custom recommendation providers
|
|
256
|
+
* @see {@link RecommendSDK}
|
|
257
|
+
*/
|
|
258
|
+
recommend: import('./recommend').RecommendSDK
|
|
259
|
+
|
|
233
260
|
/**
|
|
234
261
|
* Opens a URL in the default browser
|
|
235
262
|
* @param url - The URL to open
|
|
@@ -496,14 +523,14 @@ export interface IEventManager {
|
|
|
496
523
|
* @param event - The event name to listen for
|
|
497
524
|
* @param callback - The callback function to execute when event is emitted
|
|
498
525
|
*/
|
|
499
|
-
on: (event: string, callback:
|
|
526
|
+
on: (event: string, callback: PluginEventHandler) => void
|
|
500
527
|
|
|
501
528
|
/**
|
|
502
529
|
* Removes an event listener
|
|
503
530
|
* @param event - The event name to stop listening for
|
|
504
531
|
* @param callback - The callback function to remove
|
|
505
532
|
*/
|
|
506
|
-
off: (event: string, callback:
|
|
533
|
+
off: (event: string, callback: PluginEventHandler) => void
|
|
507
534
|
|
|
508
535
|
/**
|
|
509
536
|
* Emits an event with optional arguments
|
|
@@ -513,6 +540,8 @@ export interface IEventManager {
|
|
|
513
540
|
emit: (event: string, ...args: any[]) => void
|
|
514
541
|
}
|
|
515
542
|
|
|
543
|
+
export type PluginEventHandler = (...args: any[]) => void
|
|
544
|
+
|
|
516
545
|
/**
|
|
517
546
|
* Plugin configuration interface
|
|
518
547
|
*
|
|
@@ -644,7 +673,6 @@ export function createStorageManager(
|
|
|
644
673
|
pluginPath: string,
|
|
645
674
|
fse: any,
|
|
646
675
|
): IStorageManager {
|
|
647
|
-
const path = require('node:path')
|
|
648
676
|
const dataPath = path.join(pluginPath, 'data')
|
|
649
677
|
|
|
650
678
|
/**
|
|
@@ -954,6 +982,18 @@ export interface TriggerFeatureRequest {
|
|
|
954
982
|
query?: string
|
|
955
983
|
}
|
|
956
984
|
|
|
985
|
+
/**
|
|
986
|
+
* Register a widget for preview or rendering
|
|
987
|
+
*/
|
|
988
|
+
export interface RegisterWidgetRequest {
|
|
989
|
+
/** Plugin name */
|
|
990
|
+
plugin: string
|
|
991
|
+
/** Feature ID */
|
|
992
|
+
feature: string
|
|
993
|
+
/** Emit update event even if cached */
|
|
994
|
+
emitAsUpdate?: boolean
|
|
995
|
+
}
|
|
996
|
+
|
|
957
997
|
/**
|
|
958
998
|
* Input changed event payload
|
|
959
999
|
*/
|
|
@@ -3,28 +3,31 @@ import type {
|
|
|
3
3
|
BrowserWindowConstructorOptions,
|
|
4
4
|
WebContents,
|
|
5
5
|
} from 'electron'
|
|
6
|
-
import {
|
|
6
|
+
import { useChannel } from '../channel'
|
|
7
7
|
|
|
8
|
-
export function createWindow(
|
|
9
|
-
|
|
8
|
+
export async function createWindow(
|
|
9
|
+
options: BrowserWindowConstructorOptions & { file?: string } & { url?: string },
|
|
10
|
+
): Promise<number> {
|
|
11
|
+
const channel = useChannel('[Plugin SDK] Window creation requires renderer channel.')
|
|
12
|
+
const res = await channel.send('window:new', options)
|
|
10
13
|
if (res.error)
|
|
11
14
|
throw new Error(res.error)
|
|
12
15
|
|
|
13
16
|
return res.id
|
|
14
17
|
}
|
|
15
18
|
|
|
16
|
-
export function toggleWinVisible(id: number, visible?: boolean): boolean {
|
|
17
|
-
const
|
|
19
|
+
export async function toggleWinVisible(id: number, visible?: boolean): Promise<boolean> {
|
|
20
|
+
const channel = useChannel('[Plugin SDK] Window visibility requires renderer channel.')
|
|
21
|
+
const res = await channel.send('window:visible', visible !== undefined ? { id, visible } : { id })
|
|
18
22
|
if (res.error)
|
|
19
23
|
throw new Error(res.error)
|
|
20
24
|
|
|
21
25
|
return res.visible
|
|
22
26
|
}
|
|
23
27
|
|
|
24
|
-
export function setWindowProperty(id: number, property: {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const res = genChannel().sendSync('window:property', { id, property })
|
|
28
|
+
export async function setWindowProperty(id: number, property: WindowProperties): Promise<boolean> {
|
|
29
|
+
const channel = useChannel('[Plugin SDK] Window property requires renderer channel.')
|
|
30
|
+
const res = await channel.send('window:property', { id, property })
|
|
28
31
|
if (res.error)
|
|
29
32
|
throw new Error(res.error)
|
|
30
33
|
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import type { SdkApiVersion } from './index'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Known SDK API versions (format: YYMMDD).
|
|
5
|
+
*
|
|
6
|
+
* Ranges (rough):
|
|
7
|
+
* - < 251212: legacy mode (no permission enforcement, no category requirement)
|
|
8
|
+
* - 251212 ~ 260113: permission enforcement + new input model baseline
|
|
9
|
+
* - >= 260114: `manifest.json.category` is required for plugin grouping
|
|
10
|
+
* - >= 260121: `tfileScope` is required when requesting tfile access
|
|
11
|
+
* - >= 260215: plugin sqlite sdk is available
|
|
12
|
+
*/
|
|
13
|
+
export enum SdkApi {
|
|
14
|
+
/**
|
|
15
|
+
* 2025-12-12: permissions + input model baseline.
|
|
16
|
+
*/
|
|
17
|
+
V251212 = 251212,
|
|
18
|
+
/**
|
|
19
|
+
* 2026-01-14: require `manifest.json.category` for plugins.
|
|
20
|
+
*/
|
|
21
|
+
V260114 = 260114,
|
|
22
|
+
/**
|
|
23
|
+
* 2026-01-21: add tfile permission + scope enforcement.
|
|
24
|
+
*/
|
|
25
|
+
V260121 = 260121,
|
|
26
|
+
/**
|
|
27
|
+
* 2026-02-15: add plugin sqlite sdk support.
|
|
28
|
+
*/
|
|
29
|
+
V260215 = 260215,
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Supported SDK versions in descending order.
|
|
34
|
+
* Used to gracefully fallback for unknown/invalid sdkapi values.
|
|
35
|
+
*/
|
|
36
|
+
export const SUPPORTED_SDK_VERSIONS: readonly SdkApiVersion[] = [
|
|
37
|
+
SdkApi.V260215,
|
|
38
|
+
SdkApi.V260121,
|
|
39
|
+
SdkApi.V260114,
|
|
40
|
+
SdkApi.V251212,
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Current SDK API version.
|
|
45
|
+
* Updated when breaking changes are introduced to plugin APIs.
|
|
46
|
+
*/
|
|
47
|
+
export const CURRENT_SDK_VERSION: SdkApiVersion = SdkApi.V260215
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Minimum SDK version required for permission enforcement.
|
|
51
|
+
* Plugins below this version will bypass permission checks with a warning.
|
|
52
|
+
*/
|
|
53
|
+
export const PERMISSION_ENFORCEMENT_MIN_VERSION: SdkApiVersion = SdkApi.V251212
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Minimum SDK version required for `manifest.json.category`.
|
|
57
|
+
*/
|
|
58
|
+
export const CATEGORY_REQUIRED_MIN_VERSION: SdkApiVersion = SdkApi.V260114
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Minimum SDK version required for `tfileScope` enforcement.
|
|
62
|
+
*/
|
|
63
|
+
export const TFILE_SCOPE_REQUIRED_MIN_VERSION: SdkApiVersion = SdkApi.V260121
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* SDK version compatibility result
|
|
67
|
+
*/
|
|
68
|
+
export interface SdkCompatibilityResult {
|
|
69
|
+
/** Whether the plugin SDK version is compatible */
|
|
70
|
+
compatible: boolean
|
|
71
|
+
/** Whether permission enforcement should be applied */
|
|
72
|
+
enforcePermissions: boolean
|
|
73
|
+
/** Warning message if compatibility issues exist */
|
|
74
|
+
warning?: string
|
|
75
|
+
/** Suggestion for fixing compatibility issues */
|
|
76
|
+
suggestion?: string
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Check SDK version compatibility for a plugin.
|
|
81
|
+
* @param pluginSdkVersion - The sdkapi value from plugin manifest (undefined if not declared)
|
|
82
|
+
* @param pluginName - Plugin name for error messages
|
|
83
|
+
* @returns Compatibility check result
|
|
84
|
+
*/
|
|
85
|
+
export function checkSdkCompatibility(
|
|
86
|
+
pluginSdkVersion: SdkApiVersion | undefined,
|
|
87
|
+
pluginName: string,
|
|
88
|
+
): SdkCompatibilityResult {
|
|
89
|
+
// No sdkapi declared - legacy plugin
|
|
90
|
+
if (pluginSdkVersion === undefined) {
|
|
91
|
+
return {
|
|
92
|
+
compatible: true,
|
|
93
|
+
enforcePermissions: false,
|
|
94
|
+
warning: `Plugin "${pluginName}" does not declare sdkapi version. Permission enforcement is disabled for compatibility.`,
|
|
95
|
+
suggestion: `Add "sdkapi": ${CURRENT_SDK_VERSION} to manifest.json to enable permission enforcement.`,
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const resolved = resolveSdkApiVersion(pluginSdkVersion)
|
|
100
|
+
const warningParts: string[] = []
|
|
101
|
+
const suggestionParts: string[] = []
|
|
102
|
+
|
|
103
|
+
// Validate + normalize to a supported SDK version (graceful fallback)
|
|
104
|
+
if (resolved === undefined) {
|
|
105
|
+
return {
|
|
106
|
+
compatible: true,
|
|
107
|
+
enforcePermissions: false,
|
|
108
|
+
warning: `Plugin "${pluginName}" has invalid sdkapi value: ${pluginSdkVersion}. Falling back to legacy mode.`,
|
|
109
|
+
suggestion: `Use format YYMMDD (e.g., "sdkapi": ${CURRENT_SDK_VERSION}).`,
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (resolved !== pluginSdkVersion) {
|
|
114
|
+
warningParts.push(
|
|
115
|
+
`Plugin "${pluginName}" declares sdkapi ${pluginSdkVersion}, but it is not a supported SDK marker. Falling back to ${resolved}.`,
|
|
116
|
+
)
|
|
117
|
+
suggestionParts.push(`Use a supported sdkapi marker, e.g., ${CURRENT_SDK_VERSION}.`)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Version too old - bypass permissions with warning
|
|
121
|
+
if (resolved < PERMISSION_ENFORCEMENT_MIN_VERSION) {
|
|
122
|
+
return {
|
|
123
|
+
compatible: true,
|
|
124
|
+
enforcePermissions: false,
|
|
125
|
+
warning: [
|
|
126
|
+
...warningParts,
|
|
127
|
+
`Plugin "${pluginName}" uses legacy SDK version ${resolved}. Permission enforcement is disabled.`,
|
|
128
|
+
].join(' '),
|
|
129
|
+
suggestion: [
|
|
130
|
+
...suggestionParts,
|
|
131
|
+
`Update to sdkapi: ${CURRENT_SDK_VERSION} for full permission support.`,
|
|
132
|
+
].join(' '),
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Version newer than current - might use unsupported features
|
|
137
|
+
if (pluginSdkVersion > CURRENT_SDK_VERSION) {
|
|
138
|
+
return {
|
|
139
|
+
compatible: true,
|
|
140
|
+
enforcePermissions: true,
|
|
141
|
+
warning: [
|
|
142
|
+
...warningParts,
|
|
143
|
+
`Plugin "${pluginName}" requires SDK version ${pluginSdkVersion}, but current version is ${CURRENT_SDK_VERSION}. Some features may not work.`,
|
|
144
|
+
].join(' '),
|
|
145
|
+
suggestion: [
|
|
146
|
+
...suggestionParts,
|
|
147
|
+
`Update Tuff to the latest version for full compatibility.`,
|
|
148
|
+
].join(' '),
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Perfect match or compatible older version
|
|
153
|
+
return {
|
|
154
|
+
compatible: true,
|
|
155
|
+
enforcePermissions: true,
|
|
156
|
+
warning: warningParts.length ? warningParts.join(' ') : undefined,
|
|
157
|
+
suggestion: suggestionParts.length ? suggestionParts.join(' ') : undefined,
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Resolve a plugin-declared sdkapi to the nearest supported SDK marker.
|
|
163
|
+
*
|
|
164
|
+
* Rules:
|
|
165
|
+
* - Invalid values => undefined (legacy)
|
|
166
|
+
* - Unknown future versions => fallback to the latest supported <= declared
|
|
167
|
+
* - Known versions => keep as-is
|
|
168
|
+
*/
|
|
169
|
+
export function resolveSdkApiVersion(raw: unknown): SdkApiVersion | undefined {
|
|
170
|
+
const num
|
|
171
|
+
= typeof raw === 'number'
|
|
172
|
+
? raw
|
|
173
|
+
: typeof raw === 'string'
|
|
174
|
+
? parseSdkVersion(raw)
|
|
175
|
+
: undefined
|
|
176
|
+
|
|
177
|
+
if (num === undefined || !isValidSdkVersion(num)) {
|
|
178
|
+
return undefined
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
for (const v of SUPPORTED_SDK_VERSIONS) {
|
|
182
|
+
if (num >= v) {
|
|
183
|
+
return v
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return undefined
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Validate SDK version format (YYMMDD)
|
|
192
|
+
*/
|
|
193
|
+
export function isValidSdkVersion(version: number): boolean {
|
|
194
|
+
if (!Number.isInteger(version) || version < 100000 || version > 999999) {
|
|
195
|
+
return false
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const str = version.toString()
|
|
199
|
+
const year = Number.parseInt(str.substring(0, 2), 10)
|
|
200
|
+
const month = Number.parseInt(str.substring(2, 4), 10)
|
|
201
|
+
const day = Number.parseInt(str.substring(4, 6), 10)
|
|
202
|
+
|
|
203
|
+
// Basic validation: year 20-99, month 01-12, day 01-31
|
|
204
|
+
return year >= 20 && year <= 99 && month >= 1 && month <= 12 && day >= 1 && day <= 31
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Format SDK version for display
|
|
209
|
+
* @param version - SDK version number (YYMMDD)
|
|
210
|
+
* @returns Formatted string like "25.12.12"
|
|
211
|
+
*/
|
|
212
|
+
export function formatSdkVersion(version: SdkApiVersion): string {
|
|
213
|
+
const str = version.toString().padStart(6, '0')
|
|
214
|
+
return `${str.substring(0, 2)}.${str.substring(2, 4)}.${str.substring(4, 6)}`
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Parse SDK version from string
|
|
219
|
+
* @param str - Version string like "251212" or "25.12.12"
|
|
220
|
+
* @returns SDK version number or undefined if invalid
|
|
221
|
+
*/
|
|
222
|
+
export function parseSdkVersion(str: string): SdkApiVersion | undefined {
|
|
223
|
+
// Remove dots if present
|
|
224
|
+
const cleaned = str.replace(/\./g, '')
|
|
225
|
+
const num = Number.parseInt(cleaned, 10)
|
|
226
|
+
|
|
227
|
+
if (isValidSdkVersion(num)) {
|
|
228
|
+
return num
|
|
229
|
+
}
|
|
230
|
+
return undefined
|
|
231
|
+
}
|
package/preload/renderer.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { LoadingEvent, LoadingMode, LoadingState, PreloadAPI } from './loading'
|
|
2
|
+
import { hasWindow } from '../env'
|
|
2
3
|
|
|
3
4
|
function getPreloadApi(): PreloadAPI | null {
|
|
4
|
-
if (
|
|
5
|
+
if (!hasWindow())
|
|
5
6
|
return null
|
|
6
7
|
return (window as any).api ?? null
|
|
7
8
|
}
|
|
@@ -37,7 +38,7 @@ export function preloadDebugStep(message: string, delta = 0.08): void {
|
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
export function preloadRemoveOverlay(): void {
|
|
40
|
-
if (
|
|
41
|
+
if (!hasWindow())
|
|
41
42
|
return
|
|
42
43
|
window.postMessage({ payload: 'removeLoading' }, '*')
|
|
43
44
|
}
|
|
@@ -5,6 +5,10 @@
|
|
|
5
5
|
export interface IArgMapperOptions {
|
|
6
6
|
/** The type of touch window - either main window or core-box popup */
|
|
7
7
|
touchType?: 'main' | 'core-box'
|
|
8
|
+
/** The sub-type for core-box windows (e.g., division-box) */
|
|
9
|
+
coreType?: 'division-box'
|
|
10
|
+
/** Whether this is a meta-overlay WebContentsView */
|
|
11
|
+
metaOverlay?: 'true' | 'false'
|
|
8
12
|
/** User data directory path */
|
|
9
13
|
userDataDir?: string
|
|
10
14
|
/** Application path */
|
|
@@ -31,23 +35,21 @@ declare global {
|
|
|
31
35
|
* @param args - Array of command line arguments (defaults to process.argv)
|
|
32
36
|
* @returns Mapped command line arguments as key-value pairs
|
|
33
37
|
*/
|
|
34
|
-
export function useArgMapper(args: string[] = process
|
|
35
|
-
if (window.$argMapper)
|
|
38
|
+
export function useArgMapper(args: string[] = (globalThis as any)?.process?.argv ?? []): IArgMapperOptions {
|
|
39
|
+
if (window.$argMapper)
|
|
36
40
|
return window.$argMapper
|
|
37
|
-
}
|
|
38
41
|
|
|
39
42
|
const mapper: IArgMapperOptions = {}
|
|
40
|
-
|
|
41
43
|
for (const arg of args) {
|
|
42
44
|
if (arg.startsWith('--') && arg.includes('=')) {
|
|
43
45
|
const [key, ...valueParts] = arg.slice(2).split('=')
|
|
44
46
|
const value = valueParts.join('=')
|
|
45
|
-
|
|
47
|
+
if (!key)
|
|
48
|
+
continue
|
|
46
49
|
const camelCaseKey = key.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase())
|
|
47
50
|
mapper[camelCaseKey] = value
|
|
48
51
|
}
|
|
49
52
|
}
|
|
50
|
-
|
|
51
53
|
return window.$argMapper = mapper
|
|
52
54
|
}
|
|
53
55
|
|
|
@@ -76,3 +78,29 @@ export function isMainWindow() {
|
|
|
76
78
|
export function isCoreBox() {
|
|
77
79
|
return useTouchType() === 'core-box'
|
|
78
80
|
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Gets the core-box sub-type from command line arguments
|
|
84
|
+
* @returns The core type ('division-box') or undefined
|
|
85
|
+
*/
|
|
86
|
+
export function useCoreType() {
|
|
87
|
+
const argMapper = useArgMapper()
|
|
88
|
+
return argMapper.coreType
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Checks if the current window is a division-box window
|
|
93
|
+
* @returns True if the current window is a division-box
|
|
94
|
+
*/
|
|
95
|
+
export function isDivisionBox() {
|
|
96
|
+
return isCoreBox() && useCoreType() === 'division-box'
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Checks if the current window is a meta-overlay WebContentsView
|
|
101
|
+
* @returns True if the current window is a meta-overlay
|
|
102
|
+
*/
|
|
103
|
+
export function isMetaOverlay() {
|
|
104
|
+
const argMapper = useArgMapper()
|
|
105
|
+
return argMapper.metaOverlay === 'true'
|
|
106
|
+
}
|
package/renderer/hooks/index.ts
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
export * from './arg-mapper'
|
|
2
2
|
export * from './initialize'
|
|
3
3
|
export * from './performance'
|
|
4
|
+
export * from './use-agent-market-sdk'
|
|
5
|
+
export * from './use-agents-sdk'
|
|
6
|
+
export * from './use-app-sdk'
|
|
4
7
|
export * from './use-channel'
|
|
8
|
+
export * from './use-download-sdk'
|
|
5
9
|
export * from './use-intelligence'
|
|
10
|
+
export * from './use-intelligence-sdk'
|
|
11
|
+
export * from './use-intelligence-stats'
|
|
12
|
+
export * from './use-market-sdk'
|
|
13
|
+
export * from './use-notification-sdk'
|
|
14
|
+
export * from './use-permission-sdk'
|
|
15
|
+
export * from './use-platform-sdk'
|
|
16
|
+
export * from './use-plugin-sdk'
|
|
17
|
+
export * from './use-settings-sdk'
|
|
18
|
+
export * from './use-update-sdk'
|
|
@@ -102,12 +102,13 @@ export function useInitialize(): IInitializationInfo {
|
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
const now = Date.now()
|
|
105
|
+
const runtimePlatform = (globalThis as any)?.process?.platform ?? navigator.platform
|
|
105
106
|
const initInfo: IInitializationInfo = {
|
|
106
107
|
initTimestamp: now,
|
|
107
108
|
initTime: new Date(now).toISOString(),
|
|
108
109
|
userAgent: navigator.userAgent,
|
|
109
110
|
currentUrl: window.location.href,
|
|
110
|
-
platform:
|
|
111
|
+
platform: runtimePlatform,
|
|
111
112
|
screenResolution: {
|
|
112
113
|
width: screen.width,
|
|
113
114
|
height: screen.height,
|