@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
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Permission Registry
|
|
3
|
+
*
|
|
4
|
+
* Defines all available permissions in the system.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { PermissionDefinition } from './types'
|
|
8
|
+
import { PermissionCategory, PermissionRiskLevel } from './types'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* All permission definitions
|
|
12
|
+
*/
|
|
13
|
+
export const PERMISSIONS: PermissionDefinition[] = [
|
|
14
|
+
// Filesystem permissions
|
|
15
|
+
{
|
|
16
|
+
id: 'fs.read',
|
|
17
|
+
category: PermissionCategory.FILESYSTEM,
|
|
18
|
+
risk: PermissionRiskLevel.MEDIUM,
|
|
19
|
+
nameKey: 'permission.fs.read.name',
|
|
20
|
+
descKey: 'permission.fs.read.desc',
|
|
21
|
+
icon: 'FileText',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
id: 'fs.write',
|
|
25
|
+
category: PermissionCategory.FILESYSTEM,
|
|
26
|
+
risk: PermissionRiskLevel.HIGH,
|
|
27
|
+
nameKey: 'permission.fs.write.name',
|
|
28
|
+
descKey: 'permission.fs.write.desc',
|
|
29
|
+
icon: 'FilePen',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
id: 'fs.execute',
|
|
33
|
+
category: PermissionCategory.FILESYSTEM,
|
|
34
|
+
risk: PermissionRiskLevel.HIGH,
|
|
35
|
+
nameKey: 'permission.fs.execute.name',
|
|
36
|
+
descKey: 'permission.fs.execute.desc',
|
|
37
|
+
icon: 'Terminal',
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
id: 'fs.tfile',
|
|
41
|
+
category: PermissionCategory.FILESYSTEM,
|
|
42
|
+
risk: PermissionRiskLevel.MEDIUM,
|
|
43
|
+
nameKey: 'permission.fs.tfile.name',
|
|
44
|
+
descKey: 'permission.fs.tfile.desc',
|
|
45
|
+
icon: 'FileText',
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
// Clipboard permissions
|
|
49
|
+
{
|
|
50
|
+
id: 'clipboard.read',
|
|
51
|
+
category: PermissionCategory.CLIPBOARD,
|
|
52
|
+
risk: PermissionRiskLevel.MEDIUM,
|
|
53
|
+
nameKey: 'permission.clipboard.read.name',
|
|
54
|
+
descKey: 'permission.clipboard.read.desc',
|
|
55
|
+
icon: 'ClipboardCopy',
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
id: 'clipboard.write',
|
|
59
|
+
category: PermissionCategory.CLIPBOARD,
|
|
60
|
+
risk: PermissionRiskLevel.LOW,
|
|
61
|
+
nameKey: 'permission.clipboard.write.name',
|
|
62
|
+
descKey: 'permission.clipboard.write.desc',
|
|
63
|
+
icon: 'ClipboardPaste',
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
// Network permissions
|
|
67
|
+
{
|
|
68
|
+
id: 'network.local',
|
|
69
|
+
category: PermissionCategory.NETWORK,
|
|
70
|
+
risk: PermissionRiskLevel.LOW,
|
|
71
|
+
nameKey: 'permission.network.local.name',
|
|
72
|
+
descKey: 'permission.network.local.desc',
|
|
73
|
+
icon: 'Wifi',
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
id: 'network.internet',
|
|
77
|
+
category: PermissionCategory.NETWORK,
|
|
78
|
+
risk: PermissionRiskLevel.MEDIUM,
|
|
79
|
+
nameKey: 'permission.network.internet.name',
|
|
80
|
+
descKey: 'permission.network.internet.desc',
|
|
81
|
+
icon: 'Globe',
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
id: 'network.download',
|
|
85
|
+
category: PermissionCategory.NETWORK,
|
|
86
|
+
risk: PermissionRiskLevel.MEDIUM,
|
|
87
|
+
nameKey: 'permission.network.download.name',
|
|
88
|
+
descKey: 'permission.network.download.desc',
|
|
89
|
+
icon: 'Download',
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
// System permissions
|
|
93
|
+
{
|
|
94
|
+
id: 'system.shell',
|
|
95
|
+
category: PermissionCategory.SYSTEM,
|
|
96
|
+
risk: PermissionRiskLevel.HIGH,
|
|
97
|
+
nameKey: 'permission.system.shell.name',
|
|
98
|
+
descKey: 'permission.system.shell.desc',
|
|
99
|
+
icon: 'Terminal',
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
id: 'system.notification',
|
|
103
|
+
category: PermissionCategory.SYSTEM,
|
|
104
|
+
risk: PermissionRiskLevel.LOW,
|
|
105
|
+
nameKey: 'permission.system.notification.name',
|
|
106
|
+
descKey: 'permission.system.notification.desc',
|
|
107
|
+
icon: 'Bell',
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
id: 'system.tray',
|
|
111
|
+
category: PermissionCategory.SYSTEM,
|
|
112
|
+
risk: PermissionRiskLevel.MEDIUM,
|
|
113
|
+
nameKey: 'permission.system.tray.name',
|
|
114
|
+
descKey: 'permission.system.tray.desc',
|
|
115
|
+
icon: 'PanelTop',
|
|
116
|
+
},
|
|
117
|
+
|
|
118
|
+
// Intelligence permissions
|
|
119
|
+
{
|
|
120
|
+
id: 'intelligence.basic',
|
|
121
|
+
category: PermissionCategory.INTELLIGENCE,
|
|
122
|
+
risk: PermissionRiskLevel.LOW,
|
|
123
|
+
nameKey: 'permission.intelligence.basic.name',
|
|
124
|
+
descKey: 'permission.intelligence.basic.desc',
|
|
125
|
+
icon: 'Bot',
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
id: 'intelligence.admin',
|
|
129
|
+
category: PermissionCategory.INTELLIGENCE,
|
|
130
|
+
risk: PermissionRiskLevel.HIGH,
|
|
131
|
+
nameKey: 'permission.intelligence.admin.name',
|
|
132
|
+
descKey: 'permission.intelligence.admin.desc',
|
|
133
|
+
icon: 'Shield',
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
id: 'intelligence.agents',
|
|
137
|
+
category: PermissionCategory.INTELLIGENCE,
|
|
138
|
+
risk: PermissionRiskLevel.HIGH,
|
|
139
|
+
nameKey: 'permission.intelligence.agents.name',
|
|
140
|
+
descKey: 'permission.intelligence.agents.desc',
|
|
141
|
+
icon: 'Users',
|
|
142
|
+
},
|
|
143
|
+
|
|
144
|
+
// Storage permissions
|
|
145
|
+
{
|
|
146
|
+
id: 'storage.plugin',
|
|
147
|
+
category: PermissionCategory.STORAGE,
|
|
148
|
+
risk: PermissionRiskLevel.LOW,
|
|
149
|
+
nameKey: 'permission.storage.plugin.name',
|
|
150
|
+
descKey: 'permission.storage.plugin.desc',
|
|
151
|
+
icon: 'Database',
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
id: 'storage.shared',
|
|
155
|
+
category: PermissionCategory.STORAGE,
|
|
156
|
+
risk: PermissionRiskLevel.MEDIUM,
|
|
157
|
+
nameKey: 'permission.storage.shared.name',
|
|
158
|
+
descKey: 'permission.storage.shared.desc',
|
|
159
|
+
icon: 'Share2',
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
id: 'storage.sqlite',
|
|
163
|
+
category: PermissionCategory.STORAGE,
|
|
164
|
+
risk: PermissionRiskLevel.MEDIUM,
|
|
165
|
+
nameKey: 'permission.storage.sqlite.name',
|
|
166
|
+
descKey: 'permission.storage.sqlite.desc',
|
|
167
|
+
icon: 'Database',
|
|
168
|
+
},
|
|
169
|
+
|
|
170
|
+
// Window permissions
|
|
171
|
+
{
|
|
172
|
+
id: 'window.create',
|
|
173
|
+
category: PermissionCategory.WINDOW,
|
|
174
|
+
risk: PermissionRiskLevel.LOW,
|
|
175
|
+
nameKey: 'permission.window.create.name',
|
|
176
|
+
descKey: 'permission.window.create.desc',
|
|
177
|
+
icon: 'AppWindow',
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
id: 'window.capture',
|
|
181
|
+
category: PermissionCategory.WINDOW,
|
|
182
|
+
risk: PermissionRiskLevel.HIGH,
|
|
183
|
+
nameKey: 'permission.window.capture.name',
|
|
184
|
+
descKey: 'permission.window.capture.desc',
|
|
185
|
+
icon: 'Camera',
|
|
186
|
+
},
|
|
187
|
+
]
|
|
188
|
+
|
|
189
|
+
export function normalizePermissionId(id: string): string {
|
|
190
|
+
return id
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export function getPermissionIdCandidates(id: string): string[] {
|
|
194
|
+
return [normalizePermissionId(id)]
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Permission registry class
|
|
199
|
+
*/
|
|
200
|
+
export class PermissionRegistry {
|
|
201
|
+
private permissions: Map<string, PermissionDefinition> = new Map()
|
|
202
|
+
|
|
203
|
+
constructor() {
|
|
204
|
+
// Register all built-in permissions
|
|
205
|
+
PERMISSIONS.forEach((p) => this.permissions.set(normalizePermissionId(p.id), p))
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Get permission definition by ID
|
|
210
|
+
*/
|
|
211
|
+
get(id: string): PermissionDefinition | undefined {
|
|
212
|
+
return this.permissions.get(normalizePermissionId(id))
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Get all permissions
|
|
217
|
+
*/
|
|
218
|
+
all(): PermissionDefinition[] {
|
|
219
|
+
return Array.from(this.permissions.values())
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Get permissions by category
|
|
224
|
+
*/
|
|
225
|
+
byCategory(category: PermissionCategory): PermissionDefinition[] {
|
|
226
|
+
return this.all().filter(p => p.category === category)
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Get permissions by risk level
|
|
231
|
+
*/
|
|
232
|
+
byRisk(risk: PermissionRiskLevel): PermissionDefinition[] {
|
|
233
|
+
return this.all().filter(p => p.risk === risk)
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Check if permission exists
|
|
238
|
+
*/
|
|
239
|
+
has(id: string): boolean {
|
|
240
|
+
return this.permissions.has(normalizePermissionId(id))
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Register custom permission
|
|
245
|
+
*/
|
|
246
|
+
register(permission: PermissionDefinition): void {
|
|
247
|
+
this.permissions.set(normalizePermissionId(permission.id), permission)
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Singleton permission registry
|
|
253
|
+
*/
|
|
254
|
+
export const permissionRegistry = new PermissionRegistry()
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Permission ID constants for type safety
|
|
258
|
+
*/
|
|
259
|
+
export const PermissionIds = {
|
|
260
|
+
// Filesystem
|
|
261
|
+
FS_READ: 'fs.read',
|
|
262
|
+
FS_WRITE: 'fs.write',
|
|
263
|
+
FS_EXECUTE: 'fs.execute',
|
|
264
|
+
FS_TFILE: 'fs.tfile',
|
|
265
|
+
|
|
266
|
+
// Clipboard
|
|
267
|
+
CLIPBOARD_READ: 'clipboard.read',
|
|
268
|
+
CLIPBOARD_WRITE: 'clipboard.write',
|
|
269
|
+
|
|
270
|
+
// Network
|
|
271
|
+
NETWORK_LOCAL: 'network.local',
|
|
272
|
+
NETWORK_INTERNET: 'network.internet',
|
|
273
|
+
NETWORK_DOWNLOAD: 'network.download',
|
|
274
|
+
|
|
275
|
+
// System
|
|
276
|
+
SYSTEM_SHELL: 'system.shell',
|
|
277
|
+
SYSTEM_NOTIFICATION: 'system.notification',
|
|
278
|
+
SYSTEM_TRAY: 'system.tray',
|
|
279
|
+
|
|
280
|
+
// Intelligence
|
|
281
|
+
INTELLIGENCE_BASIC: 'intelligence.basic',
|
|
282
|
+
INTELLIGENCE_ADMIN: 'intelligence.admin',
|
|
283
|
+
INTELLIGENCE_AGENTS: 'intelligence.agents',
|
|
284
|
+
|
|
285
|
+
// Storage
|
|
286
|
+
STORAGE_PLUGIN: 'storage.plugin',
|
|
287
|
+
STORAGE_SHARED: 'storage.shared',
|
|
288
|
+
STORAGE_SQLITE: 'storage.sqlite',
|
|
289
|
+
|
|
290
|
+
// Window
|
|
291
|
+
WINDOW_CREATE: 'window.create',
|
|
292
|
+
WINDOW_CAPTURE: 'window.capture',
|
|
293
|
+
} as const
|
|
294
|
+
|
|
295
|
+
export type PermissionId = (typeof PermissionIds)[keyof typeof PermissionIds]
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Default permissions that are auto-granted
|
|
299
|
+
*/
|
|
300
|
+
export const DEFAULT_PERMISSIONS: string[] = [
|
|
301
|
+
PermissionIds.STORAGE_PLUGIN,
|
|
302
|
+
PermissionIds.CLIPBOARD_WRITE,
|
|
303
|
+
PermissionIds.WINDOW_CREATE,
|
|
304
|
+
]
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Permission System Types
|
|
3
|
+
*
|
|
4
|
+
* Defines the permission model for plugin security.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Permission category
|
|
9
|
+
*/
|
|
10
|
+
export enum PermissionCategory {
|
|
11
|
+
FILESYSTEM = 'fs',
|
|
12
|
+
CLIPBOARD = 'clipboard',
|
|
13
|
+
NETWORK = 'network',
|
|
14
|
+
SYSTEM = 'system',
|
|
15
|
+
INTELLIGENCE = 'intelligence',
|
|
16
|
+
STORAGE = 'storage',
|
|
17
|
+
WINDOW = 'window',
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Risk level for permissions
|
|
22
|
+
*/
|
|
23
|
+
export enum PermissionRiskLevel {
|
|
24
|
+
LOW = 'low',
|
|
25
|
+
MEDIUM = 'medium',
|
|
26
|
+
HIGH = 'high',
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Permission definition
|
|
31
|
+
*/
|
|
32
|
+
export interface PermissionDefinition {
|
|
33
|
+
/** Permission ID (e.g., 'fs.read') */
|
|
34
|
+
id: string
|
|
35
|
+
/** Category */
|
|
36
|
+
category: PermissionCategory
|
|
37
|
+
/** Risk level */
|
|
38
|
+
risk: PermissionRiskLevel
|
|
39
|
+
/** i18n key for display name */
|
|
40
|
+
nameKey: string
|
|
41
|
+
/** i18n key for description */
|
|
42
|
+
descKey: string
|
|
43
|
+
/** Icon name (lucide icon) */
|
|
44
|
+
icon?: string
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Permission grant record
|
|
49
|
+
*/
|
|
50
|
+
export interface PermissionGrant {
|
|
51
|
+
/** Plugin ID */
|
|
52
|
+
pluginId: string
|
|
53
|
+
/** Permission ID */
|
|
54
|
+
permissionId: string
|
|
55
|
+
/** Grant timestamp */
|
|
56
|
+
grantedAt: number
|
|
57
|
+
/** How it was granted */
|
|
58
|
+
grantedBy: 'user' | 'auto' | 'trust'
|
|
59
|
+
/** Expiration timestamp (optional) */
|
|
60
|
+
expiresAt?: number
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Permission denial record
|
|
65
|
+
*/
|
|
66
|
+
export interface PermissionDenial {
|
|
67
|
+
/** Plugin ID */
|
|
68
|
+
pluginId: string
|
|
69
|
+
/** Permission ID */
|
|
70
|
+
permissionId: string
|
|
71
|
+
/** Denial timestamp */
|
|
72
|
+
deniedAt: number
|
|
73
|
+
/** Reason for denial */
|
|
74
|
+
reason?: string
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Permission check result
|
|
79
|
+
*/
|
|
80
|
+
export interface PermissionCheckResult {
|
|
81
|
+
/** Permission ID */
|
|
82
|
+
permissionId: string
|
|
83
|
+
/** Whether permission is granted */
|
|
84
|
+
granted: boolean
|
|
85
|
+
/** Grant details if granted */
|
|
86
|
+
grant?: PermissionGrant
|
|
87
|
+
/** Whether enforcement is active (sdkapi check) */
|
|
88
|
+
enforced: boolean
|
|
89
|
+
/** Warning message if any */
|
|
90
|
+
warning?: string
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Plugin permission status
|
|
95
|
+
*/
|
|
96
|
+
export interface PluginPermissionStatus {
|
|
97
|
+
/** Plugin ID */
|
|
98
|
+
pluginId: string
|
|
99
|
+
/** SDK API version */
|
|
100
|
+
sdkapi?: number
|
|
101
|
+
/** Whether permission enforcement is active */
|
|
102
|
+
enforcePermissions: boolean
|
|
103
|
+
/** Required permissions from manifest */
|
|
104
|
+
required: string[]
|
|
105
|
+
/** Optional permissions from manifest */
|
|
106
|
+
optional: string[]
|
|
107
|
+
/** Granted permissions */
|
|
108
|
+
granted: string[]
|
|
109
|
+
/** Denied permissions */
|
|
110
|
+
denied: string[]
|
|
111
|
+
/** Missing required permissions */
|
|
112
|
+
missingRequired: string[]
|
|
113
|
+
/** Compatibility warning */
|
|
114
|
+
warning?: string
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Permission request for UI prompt
|
|
119
|
+
*/
|
|
120
|
+
export interface PermissionRequest {
|
|
121
|
+
/** Plugin ID */
|
|
122
|
+
pluginId: string
|
|
123
|
+
/** Plugin display name */
|
|
124
|
+
pluginName: string
|
|
125
|
+
/** Permission ID */
|
|
126
|
+
permissionId: string
|
|
127
|
+
/** Reason from manifest */
|
|
128
|
+
reason?: string
|
|
129
|
+
/** Context of the request */
|
|
130
|
+
context?: Record<string, unknown>
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Audit log entry
|
|
135
|
+
*/
|
|
136
|
+
export interface PermissionAuditLog {
|
|
137
|
+
/** Log ID */
|
|
138
|
+
id: string
|
|
139
|
+
/** Timestamp */
|
|
140
|
+
timestamp: number
|
|
141
|
+
/** Plugin ID */
|
|
142
|
+
pluginId: string
|
|
143
|
+
/** Permission ID */
|
|
144
|
+
permissionId: string
|
|
145
|
+
/** Action type */
|
|
146
|
+
action: 'granted' | 'denied' | 'revoked' | 'used' | 'blocked'
|
|
147
|
+
/** Additional context */
|
|
148
|
+
context?: Record<string, unknown>
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Manifest permission declaration
|
|
153
|
+
*/
|
|
154
|
+
export interface ManifestPermissions {
|
|
155
|
+
/** Required permissions - plugin won't work without these */
|
|
156
|
+
required?: string[]
|
|
157
|
+
/** Optional permissions - can be granted later */
|
|
158
|
+
optional?: string[]
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Permission reasons in manifest
|
|
163
|
+
*/
|
|
164
|
+
export type ManifestPermissionReasons = Record<string, string>
|
package/plugin/channel.ts
CHANGED
|
@@ -9,25 +9,45 @@ import {
|
|
|
9
9
|
ChannelType,
|
|
10
10
|
DataCode,
|
|
11
11
|
} from '../channel'
|
|
12
|
+
import { getLogger } from '../common/logger'
|
|
13
|
+
import { findCloneIssue, isCloneError, summarizeClonePayload } from '../common/utils/clone-diagnostics'
|
|
14
|
+
import { formatPayloadPreview } from '../common/utils/payload-preview'
|
|
15
|
+
import { hasWindow } from '../env'
|
|
12
16
|
|
|
13
|
-
const CHANNEL_DEFAULT_TIMEOUT =
|
|
17
|
+
const CHANNEL_DEFAULT_TIMEOUT = 60_000
|
|
14
18
|
|
|
15
19
|
let cachedIpcRenderer: IpcRenderer | null = null
|
|
20
|
+
const channelLog = getLogger('plugin-channel')
|
|
21
|
+
|
|
22
|
+
type PluginWindow = Window & {
|
|
23
|
+
$plugin?: { name?: string }
|
|
24
|
+
$channel?: ITouchClientChannel
|
|
25
|
+
electron?: { ipcRenderer?: IpcRenderer }
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function getPluginWindow(): PluginWindow | undefined {
|
|
29
|
+
return hasWindow() ? (window as unknown as PluginWindow) : undefined
|
|
30
|
+
}
|
|
16
31
|
|
|
17
32
|
// 使用惰性解析避免在打包阶段静态引入 electron
|
|
18
33
|
function resolveIpcRenderer(): IpcRenderer | null {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
return bridge.ipcRenderer as IpcRenderer
|
|
23
|
-
}
|
|
34
|
+
const globalWindow = getPluginWindow()
|
|
35
|
+
if (globalWindow?.electron?.ipcRenderer)
|
|
36
|
+
return globalWindow.electron.ipcRenderer as IpcRenderer
|
|
24
37
|
|
|
25
38
|
try {
|
|
26
|
-
const
|
|
27
|
-
if (
|
|
28
|
-
return
|
|
39
|
+
const electronFromGlobal = (globalThis as any)?.electron
|
|
40
|
+
if (electronFromGlobal?.ipcRenderer)
|
|
41
|
+
return electronFromGlobal.ipcRenderer as IpcRenderer
|
|
42
|
+
|
|
43
|
+
const requireFromGlobal = (globalThis as any)?.require
|
|
44
|
+
if (typeof requireFromGlobal === 'function') {
|
|
45
|
+
const electron = requireFromGlobal('electron')
|
|
46
|
+
if (electron?.ipcRenderer)
|
|
47
|
+
return electron.ipcRenderer as IpcRenderer
|
|
48
|
+
}
|
|
29
49
|
}
|
|
30
|
-
catch
|
|
50
|
+
catch {
|
|
31
51
|
// ignore – will throw below if no ipcRenderer is resolved
|
|
32
52
|
}
|
|
33
53
|
|
|
@@ -46,14 +66,17 @@ function ensureIpcRenderer(): IpcRenderer {
|
|
|
46
66
|
return cachedIpcRenderer
|
|
47
67
|
}
|
|
48
68
|
|
|
69
|
+
type ChannelListener = (data: StandardChannelData) => unknown
|
|
70
|
+
type PendingCallback = (data: RawStandardChannelData) => void
|
|
71
|
+
|
|
49
72
|
/**
|
|
50
73
|
* @deprecated This class is deprecated and will be removed in the future.
|
|
51
74
|
* Due to the new secret system, ipc message transmission should unique Key, and will inject when ui view attached.
|
|
52
75
|
*/
|
|
53
76
|
class TouchChannel implements ITouchClientChannel {
|
|
54
|
-
channelMap: Map<string,
|
|
77
|
+
channelMap: Map<string, ChannelListener[]> = new Map()
|
|
55
78
|
|
|
56
|
-
pendingMap: Map<string,
|
|
79
|
+
pendingMap: Map<string, PendingCallback> = new Map()
|
|
57
80
|
|
|
58
81
|
plugin: string
|
|
59
82
|
|
|
@@ -66,7 +89,7 @@ class TouchChannel implements ITouchClientChannel {
|
|
|
66
89
|
}
|
|
67
90
|
|
|
68
91
|
__parse_raw_data(e: IpcRendererEvent | undefined, arg: any): RawStandardChannelData | null {
|
|
69
|
-
|
|
92
|
+
channelLog.debug('Raw data', { meta: { payload: formatPayloadPreview(arg) } })
|
|
70
93
|
if (arg) {
|
|
71
94
|
const { name, header, code, data, sync } = arg
|
|
72
95
|
|
|
@@ -86,7 +109,7 @@ class TouchChannel implements ITouchClientChannel {
|
|
|
86
109
|
}
|
|
87
110
|
}
|
|
88
111
|
|
|
89
|
-
|
|
112
|
+
channelLog.error('Invalid message payload', { error: { event: e, payload: arg } })
|
|
90
113
|
return null
|
|
91
114
|
// throw new Error("Invalid message!");
|
|
92
115
|
}
|
|
@@ -154,7 +177,7 @@ class TouchChannel implements ITouchClientChannel {
|
|
|
154
177
|
|
|
155
178
|
regChannel(
|
|
156
179
|
eventName: string,
|
|
157
|
-
callback:
|
|
180
|
+
callback: ChannelListener,
|
|
158
181
|
): () => void {
|
|
159
182
|
const listeners = this.channelMap.get(eventName) || []
|
|
160
183
|
|
|
@@ -176,7 +199,7 @@ class TouchChannel implements ITouchClientChannel {
|
|
|
176
199
|
}
|
|
177
200
|
}
|
|
178
201
|
|
|
179
|
-
unRegChannel(eventName: string, callback:
|
|
202
|
+
unRegChannel(eventName: string, callback: ChannelListener): boolean {
|
|
180
203
|
const listeners = this.channelMap.get(eventName)
|
|
181
204
|
|
|
182
205
|
if (!listeners) {
|
|
@@ -200,16 +223,7 @@ class TouchChannel implements ITouchClientChannel {
|
|
|
200
223
|
}
|
|
201
224
|
|
|
202
225
|
private formatPayloadPreview(payload: unknown): string {
|
|
203
|
-
|
|
204
|
-
return String(payload)
|
|
205
|
-
if (typeof payload === 'string')
|
|
206
|
-
return payload.length > 200 ? `${payload.slice(0, 200)}…` : payload
|
|
207
|
-
try {
|
|
208
|
-
return JSON.stringify(payload)
|
|
209
|
-
}
|
|
210
|
-
catch {
|
|
211
|
-
return '[unserializable]'
|
|
212
|
-
}
|
|
226
|
+
return formatPayloadPreview(payload)
|
|
213
227
|
}
|
|
214
228
|
|
|
215
229
|
send(eventName: string, arg: any): Promise<any> {
|
|
@@ -239,13 +253,20 @@ class TouchChannel implements ITouchClientChannel {
|
|
|
239
253
|
}
|
|
240
254
|
catch (error) {
|
|
241
255
|
const errorMessage = error instanceof Error ? error.message : String(error)
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
)
|
|
256
|
+
const meta: Record<string, unknown> = {
|
|
257
|
+
payloadPreview: this.formatPayloadPreview(arg)
|
|
258
|
+
}
|
|
259
|
+
if (isCloneError(error)) {
|
|
260
|
+
meta.cloneIssue = findCloneIssue(arg)
|
|
261
|
+
meta.payloadSummary = summarizeClonePayload(arg)
|
|
262
|
+
}
|
|
263
|
+
channelLog.error(`Failed to send \"${eventName}\": ${errorMessage}`, {
|
|
264
|
+
meta,
|
|
265
|
+
error,
|
|
266
|
+
})
|
|
246
267
|
reject(
|
|
247
268
|
Object.assign(
|
|
248
|
-
new Error(`Failed to send plugin channel message "${eventName}": ${errorMessage}`),
|
|
269
|
+
new Error(`Failed to send plugin channel message \"${eventName}\": ${errorMessage}`),
|
|
249
270
|
{ code: 'plugin_channel_send_failed' },
|
|
250
271
|
),
|
|
251
272
|
)
|
|
@@ -258,10 +279,10 @@ class TouchChannel implements ITouchClientChannel {
|
|
|
258
279
|
return
|
|
259
280
|
this.pendingMap.delete(uniqueId)
|
|
260
281
|
const timeoutError = Object.assign(
|
|
261
|
-
new Error(`Plugin channel request "${eventName}" timed out after ${timeoutMs}ms`),
|
|
282
|
+
new Error(`Plugin channel request \"${eventName}\" timed out after ${timeoutMs}ms`),
|
|
262
283
|
{ code: 'plugin_channel_timeout' },
|
|
263
284
|
)
|
|
264
|
-
|
|
285
|
+
channelLog.warn(timeoutError.message)
|
|
265
286
|
reject(timeoutError)
|
|
266
287
|
}, timeoutMs)
|
|
267
288
|
|
|
@@ -299,12 +320,19 @@ class TouchChannel implements ITouchClientChannel {
|
|
|
299
320
|
}
|
|
300
321
|
catch (error) {
|
|
301
322
|
const errorMessage = error instanceof Error ? error.message : String(error)
|
|
302
|
-
|
|
323
|
+
const meta: Record<string, unknown> = {
|
|
303
324
|
eventName,
|
|
304
|
-
error: errorMessage,
|
|
305
325
|
payloadPreview: this.formatPayloadPreview(arg),
|
|
326
|
+
}
|
|
327
|
+
if (isCloneError(error)) {
|
|
328
|
+
meta.cloneIssue = findCloneIssue(arg)
|
|
329
|
+
meta.payloadSummary = summarizeClonePayload(arg)
|
|
330
|
+
}
|
|
331
|
+
channelLog.error('Failed to sendSync message', {
|
|
332
|
+
meta,
|
|
333
|
+
error,
|
|
306
334
|
})
|
|
307
|
-
throw new Error(`Failed to sendSync plugin channel message "${eventName}": ${errorMessage}`)
|
|
335
|
+
throw new Error(`Failed to sendSync plugin channel message \"${eventName}\": ${errorMessage}`)
|
|
308
336
|
}
|
|
309
337
|
}
|
|
310
338
|
}
|
|
@@ -313,13 +341,14 @@ let touchChannel: ITouchClientChannel | null = null
|
|
|
313
341
|
|
|
314
342
|
export function genChannel(): ITouchClientChannel {
|
|
315
343
|
if (!touchChannel) {
|
|
316
|
-
|
|
344
|
+
const globalWindow = getPluginWindow()
|
|
345
|
+
const pluginName = globalWindow?.$plugin?.name
|
|
346
|
+
if (!globalWindow || !pluginName) {
|
|
317
347
|
throw new Error('TouchChannel cannot be initialized outside plugin renderer context')
|
|
318
348
|
}
|
|
319
349
|
|
|
320
|
-
const pluginName = (window as any).$plugin.name as string
|
|
321
350
|
touchChannel = new TouchChannel(pluginName)
|
|
322
|
-
|
|
351
|
+
globalWindow.$channel = touchChannel
|
|
323
352
|
}
|
|
324
353
|
|
|
325
354
|
return touchChannel
|