@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.
Files changed (235) 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 +97 -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 +21 -3
  72. package/market/index.ts +1 -1
  73. package/market/types.ts +20 -5
  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 +82 -8
  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 -0
  87. package/plugin/providers/market-client.ts +218 -0
  88. package/plugin/providers/npm-provider.ts +228 -0
  89. package/plugin/providers/tpex-provider.ts +297 -0
  90. package/plugin/providers/tpex-types.ts +34 -0
  91. package/plugin/sdk/box-items.ts +14 -0
  92. package/plugin/sdk/box-sdk.ts +64 -0
  93. package/plugin/sdk/channel.ts +119 -4
  94. package/plugin/sdk/clipboard.ts +26 -12
  95. package/plugin/sdk/cloud-sync.ts +113 -0
  96. package/plugin/sdk/common.ts +19 -11
  97. package/plugin/sdk/core-box.ts +6 -15
  98. package/plugin/sdk/division-box.ts +160 -65
  99. package/plugin/sdk/examples/storage-onDidChange-example.js +5 -2
  100. package/plugin/sdk/feature-sdk.ts +111 -76
  101. package/plugin/sdk/flow.ts +146 -45
  102. package/plugin/sdk/hooks/bridge.ts +113 -49
  103. package/plugin/sdk/hooks/life-cycle.ts +35 -16
  104. package/plugin/sdk/index.ts +14 -3
  105. package/plugin/sdk/intelligence.ts +87 -0
  106. package/plugin/sdk/meta/README.md +179 -0
  107. package/plugin/sdk/meta-sdk.ts +244 -0
  108. package/plugin/sdk/notification.ts +9 -0
  109. package/plugin/sdk/performance.ts +1 -16
  110. package/plugin/sdk/plugin-info.ts +64 -0
  111. package/plugin/sdk/power.ts +155 -0
  112. package/plugin/sdk/recommend.ts +21 -0
  113. package/plugin/sdk/service/index.ts +12 -8
  114. package/plugin/sdk/sqlite.ts +141 -0
  115. package/plugin/sdk/storage.ts +2 -6
  116. package/plugin/sdk/system.ts +2 -9
  117. package/plugin/sdk/temp-files.ts +41 -0
  118. package/plugin/sdk/touch-sdk.ts +18 -0
  119. package/plugin/sdk/types.ts +44 -4
  120. package/plugin/sdk/window/index.ts +12 -9
  121. package/plugin/sdk-version.ts +231 -0
  122. package/preload/renderer.ts +3 -2
  123. package/renderer/hooks/arg-mapper.ts +34 -6
  124. package/renderer/hooks/index.ts +13 -0
  125. package/renderer/hooks/initialize.ts +2 -1
  126. package/renderer/hooks/use-agent-market-sdk.ts +7 -0
  127. package/renderer/hooks/use-agent-market.ts +106 -0
  128. package/renderer/hooks/use-agents-sdk.ts +7 -0
  129. package/renderer/hooks/use-app-sdk.ts +7 -0
  130. package/renderer/hooks/use-channel.ts +33 -4
  131. package/renderer/hooks/use-download-sdk.ts +21 -0
  132. package/renderer/hooks/use-intelligence-sdk.ts +7 -0
  133. package/renderer/hooks/use-intelligence-stats.ts +290 -0
  134. package/renderer/hooks/use-intelligence.ts +202 -104
  135. package/renderer/hooks/use-market-sdk.ts +16 -0
  136. package/renderer/hooks/use-notification-sdk.ts +7 -0
  137. package/renderer/hooks/use-permission-sdk.ts +7 -0
  138. package/renderer/hooks/use-permission.ts +325 -0
  139. package/renderer/hooks/use-platform-sdk.ts +7 -0
  140. package/renderer/hooks/use-plugin-sdk.ts +16 -0
  141. package/renderer/hooks/use-settings-sdk.ts +7 -0
  142. package/renderer/hooks/use-update-sdk.ts +21 -0
  143. package/renderer/index.ts +1 -0
  144. package/renderer/ref.ts +19 -10
  145. package/renderer/shared/components/SharedPluginDetailContent.vue +84 -0
  146. package/renderer/shared/components/SharedPluginDetailHeader.vue +116 -0
  147. package/renderer/shared/components/SharedPluginDetailMetaList.vue +39 -0
  148. package/renderer/shared/components/SharedPluginDetailReadme.vue +45 -0
  149. package/renderer/shared/components/SharedPluginDetailVersions.vue +98 -0
  150. package/renderer/shared/components/index.ts +5 -0
  151. package/renderer/shared/components/shims-vue.d.ts +5 -0
  152. package/renderer/shared/index.ts +2 -0
  153. package/renderer/shared/plugin-detail.ts +62 -0
  154. package/renderer/storage/app-settings.ts +3 -1
  155. package/renderer/storage/base-storage.ts +508 -82
  156. package/renderer/storage/intelligence-storage.ts +37 -46
  157. package/renderer/storage/openers.ts +3 -1
  158. package/renderer/storage/storage-subscription.ts +126 -42
  159. package/renderer/touch-sdk/env.ts +10 -10
  160. package/renderer/touch-sdk/index.ts +114 -18
  161. package/renderer/touch-sdk/terminal.ts +24 -13
  162. package/search/feature-matcher.ts +279 -0
  163. package/search/fuzzy-match.ts +64 -34
  164. package/search/index.ts +10 -0
  165. package/search/levenshtein-utils.ts +17 -11
  166. package/transport/errors.ts +310 -0
  167. package/transport/event/builder.ts +378 -0
  168. package/transport/event/index.ts +7 -0
  169. package/transport/event/types.ts +292 -0
  170. package/transport/events/index.ts +2670 -0
  171. package/transport/events/meta-overlay.ts +79 -0
  172. package/transport/events/types/agents.ts +177 -0
  173. package/transport/events/types/app-index.ts +9 -0
  174. package/transport/events/types/app.ts +475 -0
  175. package/transport/events/types/box-item.ts +222 -0
  176. package/transport/events/types/clipboard.ts +80 -0
  177. package/transport/events/types/core-box.ts +534 -0
  178. package/transport/events/types/device-idle.ts +7 -0
  179. package/transport/events/types/division-box.ts +99 -0
  180. package/transport/events/types/download.ts +115 -0
  181. package/transport/events/types/file-index.ts +73 -0
  182. package/transport/events/types/flow.ts +149 -0
  183. package/transport/events/types/index.ts +70 -0
  184. package/transport/events/types/market.ts +39 -0
  185. package/transport/events/types/meta-overlay.ts +184 -0
  186. package/transport/events/types/notification.ts +140 -0
  187. package/transport/events/types/permission.ts +90 -0
  188. package/transport/events/types/platform.ts +8 -0
  189. package/transport/events/types/plugin.ts +620 -0
  190. package/transport/events/types/sentry.ts +20 -0
  191. package/transport/events/types/storage.ts +208 -0
  192. package/transport/events/types/transport.ts +60 -0
  193. package/transport/events/types/tray.ts +16 -0
  194. package/transport/events/types/update.ts +78 -0
  195. package/transport/index.ts +139 -0
  196. package/transport/main.ts +2 -0
  197. package/transport/sdk/constants.ts +29 -0
  198. package/transport/sdk/domains/agents-market.ts +47 -0
  199. package/transport/sdk/domains/agents.ts +62 -0
  200. package/transport/sdk/domains/app.ts +48 -0
  201. package/transport/sdk/domains/disposable.ts +35 -0
  202. package/transport/sdk/domains/download.ts +139 -0
  203. package/transport/sdk/domains/index.ts +13 -0
  204. package/transport/sdk/domains/intelligence.ts +616 -0
  205. package/transport/sdk/domains/market.ts +35 -0
  206. package/transport/sdk/domains/notification.ts +62 -0
  207. package/transport/sdk/domains/permission.ts +85 -0
  208. package/transport/sdk/domains/platform.ts +19 -0
  209. package/transport/sdk/domains/plugin.ts +144 -0
  210. package/transport/sdk/domains/settings.ts +92 -0
  211. package/transport/sdk/domains/update.ts +64 -0
  212. package/transport/sdk/index.ts +60 -0
  213. package/transport/sdk/main-transport.ts +710 -0
  214. package/transport/sdk/main.ts +9 -0
  215. package/transport/sdk/plugin-transport.ts +654 -0
  216. package/transport/sdk/port-policy.ts +38 -0
  217. package/transport/sdk/renderer-transport.ts +1165 -0
  218. package/transport/types.ts +605 -0
  219. package/types/agent.ts +399 -0
  220. package/types/cloud-sync.ts +157 -0
  221. package/types/division-box.ts +47 -27
  222. package/types/download.ts +1 -0
  223. package/types/flow.ts +63 -12
  224. package/types/icon.ts +2 -1
  225. package/types/index.ts +5 -0
  226. package/types/intelligence.ts +1492 -81
  227. package/types/modules/base.ts +2 -0
  228. package/types/path-browserify.d.ts +5 -0
  229. package/types/platform.ts +12 -0
  230. package/types/startup-info.ts +32 -0
  231. package/types/touch-app-core.ts +8 -8
  232. package/types/update.ts +94 -1
  233. package/vitest.config.ts +25 -0
  234. package/auth/useClerkConfig.ts +0 -40
  235. package/auth/useClerkProvider.ts +0 -52
@@ -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
+ }
@@ -0,0 +1,290 @@
1
+ import type { Ref } from 'vue'
2
+ import { ref } from 'vue'
3
+ import { useIntelligenceSdk } from './use-intelligence-sdk'
4
+
5
+ /**
6
+ * Usage summary for a specific period
7
+ */
8
+ interface IntelligenceUsageSummary {
9
+ period: string
10
+ periodType: 'minute' | 'day' | 'month'
11
+ requestCount: number
12
+ successCount: number
13
+ failureCount: number
14
+ totalTokens: number
15
+ promptTokens: number
16
+ completionTokens: number
17
+ totalCost: number
18
+ avgLatency: number
19
+ }
20
+
21
+ /**
22
+ * Audit log entry
23
+ */
24
+ interface IntelligenceAuditLogEntry {
25
+ traceId: string
26
+ timestamp: number
27
+ capabilityId: string
28
+ provider: string
29
+ model: string
30
+ promptHash?: string
31
+ caller?: string
32
+ userId?: string
33
+ usage: {
34
+ promptTokens: number
35
+ completionTokens: number
36
+ totalTokens: number
37
+ }
38
+ latency: number
39
+ success: boolean
40
+ error?: string
41
+ estimatedCost?: number
42
+ }
43
+
44
+ /**
45
+ * Current usage for a caller
46
+ */
47
+ interface CurrentUsage {
48
+ requestsThisMinute: number
49
+ requestsToday: number
50
+ requestsThisMonth: number
51
+ tokensThisMinute: number
52
+ tokensToday: number
53
+ tokensThisMonth: number
54
+ costToday: number
55
+ costThisMonth: number
56
+ }
57
+
58
+ /**
59
+ * Quota configuration
60
+ */
61
+ interface QuotaConfig {
62
+ callerId: string
63
+ callerType: 'plugin' | 'user' | 'system'
64
+ requestsPerMinute?: number
65
+ requestsPerDay?: number
66
+ requestsPerMonth?: number
67
+ tokensPerMinute?: number
68
+ tokensPerDay?: number
69
+ tokensPerMonth?: number
70
+ costLimitPerDay?: number
71
+ costLimitPerMonth?: number
72
+ enabled?: boolean
73
+ }
74
+
75
+ /**
76
+ * Quota check result
77
+ */
78
+ interface QuotaCheckResult {
79
+ allowed: boolean
80
+ reason?: string
81
+ remainingRequests?: number
82
+ remainingTokens?: number
83
+ remainingCost?: number
84
+ }
85
+
86
+ /**
87
+ * Query options for audit logs
88
+ */
89
+ interface AuditLogQueryOptions {
90
+ caller?: string
91
+ capabilityId?: string
92
+ provider?: string
93
+ startTime?: number
94
+ endTime?: number
95
+ success?: boolean
96
+ limit?: number
97
+ offset?: number
98
+ }
99
+
100
+ interface IntelligenceStatsComposable {
101
+ // Audit logs
102
+ getAuditLogs: (options?: AuditLogQueryOptions) => Promise<IntelligenceAuditLogEntry[]>
103
+
104
+ // Usage statistics
105
+ getTodayStats: (callerId?: string) => Promise<IntelligenceUsageSummary | null>
106
+ getMonthStats: (callerId?: string) => Promise<IntelligenceUsageSummary | null>
107
+ getUsageStats: (
108
+ callerId: string,
109
+ periodType: 'day' | 'month',
110
+ startPeriod?: string,
111
+ endPeriod?: string,
112
+ ) => Promise<IntelligenceUsageSummary[]>
113
+
114
+ // Quota management
115
+ getQuota: (callerId: string, callerType?: 'plugin' | 'user' | 'system') => Promise<QuotaConfig | null>
116
+ setQuota: (config: QuotaConfig) => Promise<void>
117
+ deleteQuota: (callerId: string, callerType?: 'plugin' | 'user' | 'system') => Promise<void>
118
+ getAllQuotas: () => Promise<QuotaConfig[]>
119
+ checkQuota: (callerId: string, callerType?: 'plugin' | 'user' | 'system', estimatedTokens?: number) => Promise<QuotaCheckResult>
120
+ getCurrentUsage: (callerId: string, callerType?: 'plugin' | 'user' | 'system') => Promise<CurrentUsage>
121
+
122
+ // Export utilities
123
+ exportToCSV: (logs: IntelligenceAuditLogEntry[]) => string
124
+ exportToJSON: (logs: IntelligenceAuditLogEntry[]) => string
125
+ downloadAsFile: (content: string, filename: string, mimeType: string) => void
126
+
127
+ // Loading state
128
+ isLoading: Ref<boolean>
129
+ lastError: Ref<string | null>
130
+ }
131
+
132
+ /**
133
+ * Intelligence Statistics Composable for Vue components
134
+ *
135
+ * Provides access to audit logs, usage statistics, and quota management
136
+ *
137
+ * @example
138
+ * ```ts
139
+ * const { getTodayStats, getAuditLogs, exportToCSV } = useIntelligenceStats()
140
+ *
141
+ * // Get today's usage
142
+ * const stats = await getTodayStats()
143
+ * console.log(`Today: ${stats.requestCount} requests, $${stats.totalCost.toFixed(4)} cost`)
144
+ *
145
+ * // Get audit logs
146
+ * const logs = await getAuditLogs({ limit: 100 })
147
+ *
148
+ * // Export to CSV
149
+ * const csv = exportToCSV(logs)
150
+ * downloadAsFile(csv, 'audit-logs.csv', 'text/csv')
151
+ * ```
152
+ */
153
+ /**
154
+ * @deprecated 请优先使用 useIntelligenceSdk() 直接调用统计相关能力。
155
+ */
156
+ export function useIntelligenceStats(): IntelligenceStatsComposable {
157
+ const isLoading = ref(false)
158
+ const lastError = ref<string | null>(null)
159
+ const intelligenceSdk = useIntelligenceSdk()
160
+
161
+ async function withLoadingState<T>(operation: () => Promise<T>): Promise<T> {
162
+ isLoading.value = true
163
+ lastError.value = null
164
+
165
+ try {
166
+ return await operation()
167
+ }
168
+ catch (error) {
169
+ const errorMessage = error instanceof Error ? error.message : String(error)
170
+ lastError.value = errorMessage
171
+ throw error
172
+ }
173
+ finally {
174
+ isLoading.value = false
175
+ }
176
+ }
177
+
178
+ // Export to CSV
179
+ function exportToCSV(logs: IntelligenceAuditLogEntry[]): string {
180
+ const headers = [
181
+ 'Trace ID',
182
+ 'Timestamp',
183
+ 'Capability',
184
+ 'Provider',
185
+ 'Model',
186
+ 'Caller',
187
+ 'Prompt Tokens',
188
+ 'Completion Tokens',
189
+ 'Total Tokens',
190
+ 'Estimated Cost',
191
+ 'Latency (ms)',
192
+ 'Success',
193
+ 'Error',
194
+ ]
195
+
196
+ const rows = logs.map(log => [
197
+ log.traceId,
198
+ new Date(log.timestamp).toISOString(),
199
+ log.capabilityId,
200
+ log.provider,
201
+ log.model,
202
+ log.caller || '',
203
+ log.usage.promptTokens,
204
+ log.usage.completionTokens,
205
+ log.usage.totalTokens,
206
+ log.estimatedCost?.toFixed(6) || '',
207
+ log.latency,
208
+ log.success ? 'Yes' : 'No',
209
+ log.error || '',
210
+ ])
211
+
212
+ const csvContent = [
213
+ headers.join(','),
214
+ ...rows.map(row => row.map(cell => `"${String(cell).replace(/"/g, '""')}"`).join(',')),
215
+ ].join('\n')
216
+
217
+ return csvContent
218
+ }
219
+
220
+ // Export to JSON
221
+ function exportToJSON(logs: IntelligenceAuditLogEntry[]): string {
222
+ return JSON.stringify(logs, null, 2)
223
+ }
224
+
225
+ // Download as file
226
+ function downloadAsFile(content: string, filename: string, mimeType: string): void {
227
+ const blob = new Blob([content], { type: mimeType })
228
+ const url = URL.createObjectURL(blob)
229
+ const link = document.createElement('a')
230
+ link.href = url
231
+ link.download = filename
232
+ document.body.appendChild(link)
233
+ link.click()
234
+ document.body.removeChild(link)
235
+ URL.revokeObjectURL(url)
236
+ }
237
+
238
+ return {
239
+ // Audit logs
240
+ getAuditLogs: (options?: AuditLogQueryOptions) =>
241
+ withLoadingState(() => intelligenceSdk.getAuditLogs(options)),
242
+
243
+ // Usage statistics
244
+ getTodayStats: (callerId?: string) =>
245
+ withLoadingState(() => intelligenceSdk.getTodayStats(callerId)),
246
+
247
+ getMonthStats: (callerId?: string) =>
248
+ withLoadingState(() => intelligenceSdk.getMonthStats(callerId)),
249
+
250
+ getUsageStats: (callerId: string, periodType: 'day' | 'month', startPeriod?: string, endPeriod?: string) =>
251
+ withLoadingState(() =>
252
+ intelligenceSdk.getUsageStats({
253
+ callerId,
254
+ periodType,
255
+ startPeriod,
256
+ endPeriod,
257
+ }),
258
+ ),
259
+
260
+ // Quota management
261
+ getQuota: (callerId: string, callerType: 'plugin' | 'user' | 'system' = 'plugin') =>
262
+ withLoadingState(() => intelligenceSdk.getQuota({ callerId, callerType })),
263
+
264
+ setQuota: (config: QuotaConfig) =>
265
+ withLoadingState(() => intelligenceSdk.setQuota(config)),
266
+
267
+ deleteQuota: (callerId: string, callerType: 'plugin' | 'user' | 'system' = 'plugin') =>
268
+ withLoadingState(() => intelligenceSdk.deleteQuota({ callerId, callerType })),
269
+
270
+ getAllQuotas: () =>
271
+ withLoadingState(() => intelligenceSdk.getAllQuotas()),
272
+
273
+ checkQuota: (callerId: string, callerType: 'plugin' | 'user' | 'system' = 'plugin', estimatedTokens: number = 0) =>
274
+ withLoadingState(() =>
275
+ intelligenceSdk.checkQuota({ callerId, callerType, estimatedTokens }),
276
+ ),
277
+
278
+ getCurrentUsage: (callerId: string, callerType: 'plugin' | 'user' | 'system' = 'plugin') =>
279
+ withLoadingState(() => intelligenceSdk.getCurrentUsage({ callerId, callerType })),
280
+
281
+ // Export utilities
282
+ exportToCSV,
283
+ exportToJSON,
284
+ downloadAsFile,
285
+
286
+ // Loading state
287
+ isLoading,
288
+ lastError,
289
+ }
290
+ }