@talex-touch/utils 1.0.42 → 1.0.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (233) hide show
  1. package/.eslintcache +1 -0
  2. package/__tests__/cloud-sync-sdk.test.ts +442 -0
  3. package/__tests__/icons/icons.test.ts +84 -0
  4. package/__tests__/plugin-sdk-lifecycle.test.ts +130 -0
  5. package/__tests__/power-sdk.test.ts +143 -0
  6. package/__tests__/preset-export-types.test.ts +108 -0
  7. package/__tests__/search/fuzzy-match.test.ts +137 -0
  8. package/__tests__/transport/port-policy.test.ts +44 -0
  9. package/__tests__/transport-domain-sdks.test.ts +152 -0
  10. package/__tests__/types/update.test.ts +67 -0
  11. package/account/account-sdk.ts +915 -0
  12. package/account/index.ts +2 -0
  13. package/account/types.ts +321 -0
  14. package/analytics/client.ts +136 -0
  15. package/analytics/index.ts +2 -0
  16. package/analytics/types.ts +156 -0
  17. package/animation/auto-resize.ts +322 -0
  18. package/animation/window-node.ts +26 -19
  19. package/auth/clerk-types.ts +12 -30
  20. package/auth/index.ts +0 -2
  21. package/auth/useAuthState.ts +6 -14
  22. package/base/index.ts +2 -0
  23. package/base/log-level.ts +105 -0
  24. package/channel/index.ts +170 -69
  25. package/cloud-sync/cloud-sync-sdk.ts +450 -0
  26. package/cloud-sync/index.ts +1 -0
  27. package/common/file-scan-utils.ts +17 -9
  28. package/common/index.ts +4 -0
  29. package/common/logger/index.ts +46 -0
  30. package/common/logger/logger-manager.ts +303 -0
  31. package/common/logger/module-logger.ts +270 -0
  32. package/common/logger/transport-logger.ts +234 -0
  33. package/common/logger/types.ts +93 -0
  34. package/common/search/gather.ts +48 -6
  35. package/common/search/index.ts +8 -0
  36. package/common/storage/constants.ts +13 -0
  37. package/common/storage/entity/app-settings.ts +245 -0
  38. package/common/storage/entity/index.ts +3 -0
  39. package/common/storage/entity/layout-atom-types.ts +147 -0
  40. package/common/storage/entity/openers.ts +1 -0
  41. package/common/storage/entity/preset-cloud-api.ts +132 -0
  42. package/common/storage/entity/preset-export-types.ts +256 -0
  43. package/common/storage/entity/shortcut-settings.ts +1 -0
  44. package/common/storage/shortcut-storage.ts +11 -0
  45. package/common/utils/clone-diagnostics.ts +105 -0
  46. package/common/utils/file.ts +16 -8
  47. package/common/utils/index.ts +6 -2
  48. package/common/utils/payload-preview.ts +173 -0
  49. package/common/utils/polling.ts +167 -13
  50. package/common/utils/safe-path.ts +103 -0
  51. package/common/utils/safe-shell.ts +115 -0
  52. package/common/utils/task-queue.ts +4 -1
  53. package/core-box/builder/tuff-builder.ts +0 -1
  54. package/core-box/index.ts +1 -1
  55. package/core-box/recommendation.ts +38 -1
  56. package/core-box/tuff/tuff-dsl.ts +32 -0
  57. package/electron/download-manager.ts +10 -7
  58. package/electron/env-tool.ts +42 -40
  59. package/electron/index.ts +0 -1
  60. package/env/index.ts +156 -0
  61. package/eslint.config.js +55 -0
  62. package/i18n/index.ts +62 -0
  63. package/i18n/locales/en.json +226 -0
  64. package/i18n/locales/zh.json +226 -0
  65. package/i18n/message-keys.ts +236 -0
  66. package/i18n/resolver.ts +181 -0
  67. package/icons/index.ts +257 -0
  68. package/icons/svg.ts +69 -0
  69. package/index.ts +9 -1
  70. package/intelligence/client.ts +72 -42
  71. package/market/constants.ts +9 -5
  72. package/market/index.ts +1 -1
  73. package/market/types.ts +19 -4
  74. package/package.json +15 -5
  75. package/permission/index.ts +143 -46
  76. package/permission/legacy.ts +26 -0
  77. package/permission/registry.ts +304 -0
  78. package/permission/types.ts +164 -0
  79. package/plugin/channel.ts +68 -39
  80. package/plugin/index.ts +80 -7
  81. package/plugin/install.ts +3 -0
  82. package/plugin/log/types.ts +22 -5
  83. package/plugin/node/logger-manager.ts +11 -3
  84. package/plugin/node/logger.ts +24 -17
  85. package/plugin/preload.ts +25 -2
  86. package/plugin/providers/index.ts +4 -4
  87. package/plugin/providers/market-client.ts +6 -3
  88. package/plugin/providers/npm-provider.ts +22 -7
  89. package/plugin/providers/tpex-provider.ts +22 -8
  90. package/plugin/sdk/box-items.ts +14 -0
  91. package/plugin/sdk/box-sdk.ts +64 -0
  92. package/plugin/sdk/channel.ts +119 -4
  93. package/plugin/sdk/clipboard.ts +26 -12
  94. package/plugin/sdk/cloud-sync.ts +113 -0
  95. package/plugin/sdk/common.ts +19 -11
  96. package/plugin/sdk/core-box.ts +6 -15
  97. package/plugin/sdk/division-box.ts +160 -65
  98. package/plugin/sdk/examples/storage-onDidChange-example.js +5 -2
  99. package/plugin/sdk/feature-sdk.ts +111 -76
  100. package/plugin/sdk/flow.ts +146 -45
  101. package/plugin/sdk/hooks/bridge.ts +13 -6
  102. package/plugin/sdk/hooks/life-cycle.ts +35 -16
  103. package/plugin/sdk/index.ts +14 -3
  104. package/plugin/sdk/intelligence.ts +87 -0
  105. package/plugin/sdk/meta/README.md +179 -0
  106. package/plugin/sdk/meta-sdk.ts +244 -0
  107. package/plugin/sdk/notification.ts +9 -0
  108. package/plugin/sdk/plugin-info.ts +64 -0
  109. package/plugin/sdk/power.ts +155 -0
  110. package/plugin/sdk/recommend.ts +21 -0
  111. package/plugin/sdk/service/index.ts +12 -8
  112. package/plugin/sdk/sqlite.ts +141 -0
  113. package/plugin/sdk/storage.ts +2 -6
  114. package/plugin/sdk/system.ts +2 -9
  115. package/plugin/sdk/temp-files.ts +41 -0
  116. package/plugin/sdk/touch-sdk.ts +18 -0
  117. package/plugin/sdk/types.ts +44 -4
  118. package/plugin/sdk/window/index.ts +12 -9
  119. package/plugin/sdk-version.ts +231 -0
  120. package/preload/renderer.ts +3 -2
  121. package/renderer/hooks/arg-mapper.ts +16 -2
  122. package/renderer/hooks/index.ts +13 -0
  123. package/renderer/hooks/initialize.ts +2 -1
  124. package/renderer/hooks/use-agent-market-sdk.ts +7 -0
  125. package/renderer/hooks/use-agent-market.ts +106 -0
  126. package/renderer/hooks/use-agents-sdk.ts +7 -0
  127. package/renderer/hooks/use-app-sdk.ts +7 -0
  128. package/renderer/hooks/use-channel.ts +33 -4
  129. package/renderer/hooks/use-download-sdk.ts +21 -0
  130. package/renderer/hooks/use-intelligence-sdk.ts +7 -0
  131. package/renderer/hooks/use-intelligence-stats.ts +290 -0
  132. package/renderer/hooks/use-intelligence.ts +55 -214
  133. package/renderer/hooks/use-market-sdk.ts +16 -0
  134. package/renderer/hooks/use-notification-sdk.ts +7 -0
  135. package/renderer/hooks/use-permission-sdk.ts +7 -0
  136. package/renderer/hooks/use-permission.ts +325 -0
  137. package/renderer/hooks/use-platform-sdk.ts +7 -0
  138. package/renderer/hooks/use-plugin-sdk.ts +16 -0
  139. package/renderer/hooks/use-settings-sdk.ts +7 -0
  140. package/renderer/hooks/use-update-sdk.ts +21 -0
  141. package/renderer/index.ts +1 -0
  142. package/renderer/ref.ts +19 -10
  143. package/renderer/shared/components/SharedPluginDetailContent.vue +84 -0
  144. package/renderer/shared/components/SharedPluginDetailHeader.vue +116 -0
  145. package/renderer/shared/components/SharedPluginDetailMetaList.vue +39 -0
  146. package/renderer/shared/components/SharedPluginDetailReadme.vue +45 -0
  147. package/renderer/shared/components/SharedPluginDetailVersions.vue +98 -0
  148. package/renderer/shared/components/index.ts +5 -0
  149. package/renderer/shared/components/shims-vue.d.ts +5 -0
  150. package/renderer/shared/index.ts +2 -0
  151. package/renderer/shared/plugin-detail.ts +62 -0
  152. package/renderer/storage/app-settings.ts +3 -1
  153. package/renderer/storage/base-storage.ts +508 -82
  154. package/renderer/storage/intelligence-storage.ts +31 -40
  155. package/renderer/storage/openers.ts +3 -1
  156. package/renderer/storage/storage-subscription.ts +126 -42
  157. package/renderer/touch-sdk/env.ts +10 -10
  158. package/renderer/touch-sdk/index.ts +114 -18
  159. package/renderer/touch-sdk/terminal.ts +24 -13
  160. package/search/feature-matcher.ts +279 -0
  161. package/search/fuzzy-match.ts +64 -34
  162. package/search/index.ts +10 -0
  163. package/search/levenshtein-utils.ts +17 -11
  164. package/transport/errors.ts +310 -0
  165. package/transport/event/builder.ts +378 -0
  166. package/transport/event/index.ts +7 -0
  167. package/transport/event/types.ts +292 -0
  168. package/transport/events/index.ts +2670 -0
  169. package/transport/events/meta-overlay.ts +79 -0
  170. package/transport/events/types/agents.ts +177 -0
  171. package/transport/events/types/app-index.ts +9 -0
  172. package/transport/events/types/app.ts +475 -0
  173. package/transport/events/types/box-item.ts +222 -0
  174. package/transport/events/types/clipboard.ts +80 -0
  175. package/transport/events/types/core-box.ts +534 -0
  176. package/transport/events/types/device-idle.ts +7 -0
  177. package/transport/events/types/division-box.ts +99 -0
  178. package/transport/events/types/download.ts +115 -0
  179. package/transport/events/types/file-index.ts +73 -0
  180. package/transport/events/types/flow.ts +149 -0
  181. package/transport/events/types/index.ts +70 -0
  182. package/transport/events/types/market.ts +39 -0
  183. package/transport/events/types/meta-overlay.ts +184 -0
  184. package/transport/events/types/notification.ts +140 -0
  185. package/transport/events/types/permission.ts +90 -0
  186. package/transport/events/types/platform.ts +8 -0
  187. package/transport/events/types/plugin.ts +620 -0
  188. package/transport/events/types/sentry.ts +20 -0
  189. package/transport/events/types/storage.ts +208 -0
  190. package/transport/events/types/transport.ts +60 -0
  191. package/transport/events/types/tray.ts +16 -0
  192. package/transport/events/types/update.ts +78 -0
  193. package/transport/index.ts +139 -0
  194. package/transport/main.ts +2 -0
  195. package/transport/sdk/constants.ts +29 -0
  196. package/transport/sdk/domains/agents-market.ts +47 -0
  197. package/transport/sdk/domains/agents.ts +62 -0
  198. package/transport/sdk/domains/app.ts +48 -0
  199. package/transport/sdk/domains/disposable.ts +35 -0
  200. package/transport/sdk/domains/download.ts +139 -0
  201. package/transport/sdk/domains/index.ts +13 -0
  202. package/transport/sdk/domains/intelligence.ts +616 -0
  203. package/transport/sdk/domains/market.ts +35 -0
  204. package/transport/sdk/domains/notification.ts +62 -0
  205. package/transport/sdk/domains/permission.ts +85 -0
  206. package/transport/sdk/domains/platform.ts +19 -0
  207. package/transport/sdk/domains/plugin.ts +144 -0
  208. package/transport/sdk/domains/settings.ts +92 -0
  209. package/transport/sdk/domains/update.ts +64 -0
  210. package/transport/sdk/index.ts +60 -0
  211. package/transport/sdk/main-transport.ts +710 -0
  212. package/transport/sdk/main.ts +9 -0
  213. package/transport/sdk/plugin-transport.ts +654 -0
  214. package/transport/sdk/port-policy.ts +38 -0
  215. package/transport/sdk/renderer-transport.ts +1165 -0
  216. package/transport/types.ts +605 -0
  217. package/types/agent.ts +399 -0
  218. package/types/cloud-sync.ts +157 -0
  219. package/types/division-box.ts +31 -31
  220. package/types/download.ts +1 -0
  221. package/types/flow.ts +63 -12
  222. package/types/icon.ts +2 -1
  223. package/types/index.ts +5 -0
  224. package/types/intelligence.ts +166 -173
  225. package/types/modules/base.ts +2 -0
  226. package/types/path-browserify.d.ts +5 -0
  227. package/types/platform.ts +12 -0
  228. package/types/startup-info.ts +32 -0
  229. package/types/touch-app-core.ts +8 -8
  230. package/types/update.ts +94 -1
  231. package/vitest.config.ts +25 -0
  232. package/auth/useClerkConfig.ts +0 -40
  233. package/auth/useClerkProvider.ts +0 -52
@@ -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
+ }
@@ -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 (typeof window === 'undefined')
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 (typeof window === 'undefined')
41
+ if (!hasWindow())
41
42
  return
42
43
  window.postMessage({ payload: 'removeLoading' }, '*')
43
44
  }
@@ -7,6 +7,8 @@ export interface IArgMapperOptions {
7
7
  touchType?: 'main' | 'core-box'
8
8
  /** The sub-type for core-box windows (e.g., division-box) */
9
9
  coreType?: 'division-box'
10
+ /** Whether this is a meta-overlay WebContentsView */
11
+ metaOverlay?: 'true' | 'false'
10
12
  /** User data directory path */
11
13
  userDataDir?: string
12
14
  /** Application path */
@@ -33,14 +35,17 @@ declare global {
33
35
  * @param args - Array of command line arguments (defaults to process.argv)
34
36
  * @returns Mapped command line arguments as key-value pairs
35
37
  */
36
- export function useArgMapper(args: string[] = process.argv): IArgMapperOptions {
37
- if (window.$argMapper) return window.$argMapper
38
+ export function useArgMapper(args: string[] = (globalThis as any)?.process?.argv ?? []): IArgMapperOptions {
39
+ if (window.$argMapper)
40
+ return window.$argMapper
38
41
 
39
42
  const mapper: IArgMapperOptions = {}
40
43
  for (const arg of args) {
41
44
  if (arg.startsWith('--') && arg.includes('=')) {
42
45
  const [key, ...valueParts] = arg.slice(2).split('=')
43
46
  const value = valueParts.join('=')
47
+ if (!key)
48
+ continue
44
49
  const camelCaseKey = key.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase())
45
50
  mapper[camelCaseKey] = value
46
51
  }
@@ -90,3 +95,12 @@ export function useCoreType() {
90
95
  export function isDivisionBox() {
91
96
  return isCoreBox() && useCoreType() === 'division-box'
92
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
+ }
@@ -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: process.platform,
111
+ platform: runtimePlatform,
111
112
  screenResolution: {
112
113
  width: screen.width,
113
114
  height: screen.height,
@@ -0,0 +1,7 @@
1
+ import { useTuffTransport } from '../../transport'
2
+ import { createAgentMarketSdk } from '../../transport/sdk/domains/agents-market'
3
+
4
+ export function useAgentMarketSdk() {
5
+ const transport = useTuffTransport()
6
+ return createAgentMarketSdk(transport)
7
+ }
@@ -0,0 +1,106 @@
1
+ import type { Ref } from 'vue'
2
+ import type {
3
+ AgentCategory,
4
+ AgentInstallResult,
5
+ AgentSearchOptions,
6
+ AgentSearchResult,
7
+ MarketAgentInfo,
8
+ } from '../../transport/sdk/domains/agents-market'
9
+ import { ref } from 'vue'
10
+ import { useAgentMarketSdk } from './use-agent-market-sdk'
11
+
12
+ export type {
13
+ AgentCategory,
14
+ AgentInstallResult,
15
+ AgentSearchOptions,
16
+ AgentSearchResult,
17
+ MarketAgentInfo,
18
+ }
19
+
20
+ interface AgentMarketComposable {
21
+ // Search and browse
22
+ searchAgents: (options?: AgentSearchOptions) => Promise<AgentSearchResult>
23
+ getAgentDetails: (agentId: string) => Promise<MarketAgentInfo | null>
24
+ getFeaturedAgents: () => Promise<MarketAgentInfo[]>
25
+ getInstalledAgents: () => Promise<MarketAgentInfo[]>
26
+ getCategories: () => Promise<AgentCategory[]>
27
+
28
+ // Install/Uninstall
29
+ installAgent: (agentId: string, version?: string) => Promise<AgentInstallResult>
30
+ uninstallAgent: (agentId: string) => Promise<AgentInstallResult>
31
+ checkUpdates: () => Promise<MarketAgentInfo[]>
32
+
33
+ // State
34
+ isLoading: Ref<boolean>
35
+ lastError: Ref<string | null>
36
+ }
37
+
38
+ /**
39
+ * Agent Market Composable
40
+ *
41
+ * Provides access to the agent marketplace for browsing, searching,
42
+ * and installing agents.
43
+ *
44
+ * @example
45
+ * ```ts
46
+ * const { searchAgents, installAgent, isLoading } = useAgentMarket()
47
+ *
48
+ * // Search agents
49
+ * const result = await searchAgents({ keyword: 'file', category: 'productivity' })
50
+ *
51
+ * // Install an agent
52
+ * const installResult = await installAgent('community.workflow-agent')
53
+ * ```
54
+ */
55
+ /**
56
+ * @deprecated 请优先使用 useAgentMarketSdk() 直接调用 typed domain SDK,该 hook 仅保留兼容壳。
57
+ */
58
+ export function useAgentMarket(): AgentMarketComposable {
59
+ const isLoading = ref(false)
60
+ const lastError = ref<string | null>(null)
61
+ const agentMarketSdk = useAgentMarketSdk()
62
+
63
+ async function withLoading<T>(fn: () => Promise<T>): Promise<T> {
64
+ isLoading.value = true
65
+ lastError.value = null
66
+ try {
67
+ return await fn()
68
+ }
69
+ catch (error) {
70
+ lastError.value = error instanceof Error ? error.message : String(error)
71
+ throw error
72
+ }
73
+ finally {
74
+ isLoading.value = false
75
+ }
76
+ }
77
+
78
+ return {
79
+ searchAgents: (options?: AgentSearchOptions) =>
80
+ withLoading(() => agentMarketSdk.searchAgents(options)),
81
+
82
+ getAgentDetails: (agentId: string) =>
83
+ withLoading(() => agentMarketSdk.getAgentDetails(agentId)),
84
+
85
+ getFeaturedAgents: () =>
86
+ withLoading(() => agentMarketSdk.getFeaturedAgents()),
87
+
88
+ getInstalledAgents: () =>
89
+ withLoading(() => agentMarketSdk.getInstalledAgents()),
90
+
91
+ getCategories: () =>
92
+ withLoading(() => agentMarketSdk.getCategories()),
93
+
94
+ installAgent: (agentId: string, version?: string) =>
95
+ withLoading(() => agentMarketSdk.installAgent(agentId, version)),
96
+
97
+ uninstallAgent: (agentId: string) =>
98
+ withLoading(() => agentMarketSdk.uninstallAgent(agentId)),
99
+
100
+ checkUpdates: () =>
101
+ withLoading(() => agentMarketSdk.checkUpdates()),
102
+
103
+ isLoading,
104
+ lastError,
105
+ }
106
+ }
@@ -0,0 +1,7 @@
1
+ import { useTuffTransport } from '../../transport'
2
+ import { createAgentsSdk } from '../../transport/sdk/domains/agents'
3
+
4
+ export function useAgentsSdk() {
5
+ const transport = useTuffTransport()
6
+ return createAgentsSdk(transport)
7
+ }
@@ -0,0 +1,7 @@
1
+ import { useTuffTransport } from '../../transport'
2
+ import { createAppSdk } from '../../transport/sdk/domains/app'
3
+
4
+ export function useAppSdk() {
5
+ const transport = useTuffTransport()
6
+ return createAppSdk(transport)
7
+ }
@@ -1,5 +1,6 @@
1
1
  import type { InjectionKey } from 'vue'
2
2
  import { inject } from 'vue'
3
+ import { hasWindow } from '../../env'
3
4
 
4
5
  export interface TouchChannel {
5
6
  send: <TRequest = any, TResponse = any>(
@@ -11,6 +12,16 @@ export interface TouchChannel {
11
12
  eventName: string,
12
13
  handler: (data: TRequest) => Promise<any> | any,
13
14
  ) => () => void
15
+
16
+ unRegChannel?: <TRequest = any>(
17
+ eventName: string,
18
+ handler: (data: TRequest) => Promise<any> | any,
19
+ ) => boolean
20
+
21
+ sendSync?: <TRequest = any, TResponse = any>(
22
+ eventName: string,
23
+ data?: TRequest,
24
+ ) => TResponse
14
25
  }
15
26
 
16
27
  // Injection key for the TouchChannel
@@ -26,8 +37,8 @@ declare global {
26
37
  $touchChannel?: TouchChannel
27
38
  }
28
39
 
29
- var touchChannel: TouchChannel | undefined
30
- var $touchChannel: TouchChannel | undefined
40
+ let touchChannel: TouchChannel | undefined
41
+ let $touchChannel: TouchChannel | undefined
31
42
  }
32
43
 
33
44
  /**
@@ -49,16 +60,18 @@ function resolveTouchChannel(): TouchChannel | null {
49
60
  const channel
50
61
  = (globalThis as any).touchChannel
51
62
  || (globalThis as any).$touchChannel
63
+ || (globalThis as any).$channel
52
64
  || (globalThis as any).window?.touchChannel
53
65
  || (globalThis as any).window?.$touchChannel
66
+ || (globalThis as any).window?.$channel
54
67
 
55
68
  if (channel)
56
69
  return channel
57
70
  }
58
71
 
59
72
  // Try window object (browser environment)
60
- if (typeof window !== 'undefined') {
61
- const channel = window.touchChannel || window.$touchChannel
73
+ if (hasWindow()) {
74
+ const channel = window.touchChannel || window.$touchChannel || (window as any).$channel
62
75
  if (channel)
63
76
  return channel
64
77
  }
@@ -107,6 +120,22 @@ export function useChannel(): TouchChannel {
107
120
  return channel
108
121
  }
109
122
 
123
+ /**
124
+ * Safe version of useChannel that returns null instead of throwing
125
+ * when TouchChannel is not available. Useful for optional features.
126
+ *
127
+ * @example
128
+ * ```ts
129
+ * const channel = tryUseChannel()
130
+ * if (channel) {
131
+ * const result = await channel.send('get-app-config')
132
+ * }
133
+ * ```
134
+ */
135
+ export function tryUseChannel(): TouchChannel | null {
136
+ return resolveTouchChannel()
137
+ }
138
+
110
139
  /**
111
140
  * Helper composable that creates a typed channel wrapper
112
141
  * for specific communication patterns
@@ -0,0 +1,21 @@
1
+ import { onUnmounted } from 'vue'
2
+ import { useTuffTransport } from '../../transport'
3
+ import { createDisposableBag } from '../../transport/sdk'
4
+ import { createDownloadSdk } from '../../transport/sdk/domains/download'
5
+
6
+ export function useDownloadSdk() {
7
+ const transport = useTuffTransport()
8
+ return createDownloadSdk(transport)
9
+ }
10
+
11
+ export function useDownloadSdkScope() {
12
+ const sdk = useDownloadSdk()
13
+ const disposables = createDisposableBag()
14
+ const register = (dispose: () => void) => {
15
+ disposables.add(dispose)
16
+ return dispose
17
+ }
18
+
19
+ onUnmounted(() => disposables.dispose())
20
+ return { sdk, disposables, register }
21
+ }
@@ -0,0 +1,7 @@
1
+ import { useTuffTransport } from '../../transport'
2
+ import { createIntelligenceSdk } from '../../transport/sdk/domains/intelligence'
3
+
4
+ export function useIntelligenceSdk() {
5
+ const transport = useTuffTransport()
6
+ return createIntelligenceSdk(transport)
7
+ }