@vetta-org/plugin-sdk 0.1.1 → 0.3.0
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/dist/activity-tab.d.ts +2 -0
- package/dist/activity-tab.d.ts.map +1 -1
- package/dist/activity-tab.js +1 -1
- package/dist/activity-tab.js.map +1 -1
- package/dist/agent.d.ts +148 -4
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +14 -1
- package/dist/agent.js.map +1 -1
- package/dist/ai.d.ts +106 -0
- package/dist/ai.d.ts.map +1 -0
- package/dist/ai.js +2 -0
- package/dist/ai.js.map +1 -0
- package/dist/app-actions.d.ts +9 -1
- package/dist/app-actions.d.ts.map +1 -1
- package/dist/app-actions.js.map +1 -1
- package/dist/artifacts.d.ts +31 -0
- package/dist/artifacts.d.ts.map +1 -0
- package/dist/artifacts.js +2 -0
- package/dist/artifacts.js.map +1 -0
- package/dist/browser.d.ts +119 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +2 -0
- package/dist/browser.js.map +1 -0
- package/dist/capture.d.ts +64 -0
- package/dist/capture.d.ts.map +1 -0
- package/dist/capture.js +2 -0
- package/dist/capture.js.map +1 -0
- package/dist/cli-provider.d.ts +18 -0
- package/dist/cli-provider.d.ts.map +1 -0
- package/dist/cli-provider.js +2 -0
- package/dist/cli-provider.js.map +1 -0
- package/dist/context.d.ts +59 -7
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js.map +1 -1
- package/dist/conversation.d.ts +66 -2
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js.map +1 -1
- package/dist/gateway.d.ts +37 -0
- package/dist/gateway.d.ts.map +1 -0
- package/dist/gateway.js +14 -0
- package/dist/gateway.js.map +1 -0
- package/dist/index.d.ts +26 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/jobs.d.ts +34 -0
- package/dist/jobs.d.ts.map +1 -0
- package/dist/jobs.js +2 -0
- package/dist/jobs.js.map +1 -0
- package/dist/manifest-schema.d.ts +637 -0
- package/dist/manifest-schema.d.ts.map +1 -0
- package/dist/manifest-schema.js +251 -0
- package/dist/manifest-schema.js.map +1 -0
- package/dist/manifest.d.ts +21 -55
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js +468 -1
- package/dist/manifest.js.map +1 -1
- package/dist/media.d.ts +193 -0
- package/dist/media.d.ts.map +1 -0
- package/dist/media.js +11 -0
- package/dist/media.js.map +1 -0
- package/dist/models.d.ts +35 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.js +2 -0
- package/dist/models.js.map +1 -0
- package/dist/network.d.ts +2 -1
- package/dist/network.d.ts.map +1 -1
- package/dist/network.js.map +1 -1
- package/dist/npm-package.d.ts +17 -0
- package/dist/npm-package.d.ts.map +1 -0
- package/dist/npm-package.js +38 -0
- package/dist/npm-package.js.map +1 -0
- package/dist/ocr.d.ts +78 -0
- package/dist/ocr.d.ts.map +1 -0
- package/dist/ocr.js +2 -0
- package/dist/ocr.js.map +1 -0
- package/dist/official.d.ts +219 -10
- package/dist/official.d.ts.map +1 -1
- package/dist/official.js.map +1 -1
- package/dist/permissions.d.ts +2 -1
- package/dist/permissions.d.ts.map +1 -1
- package/dist/permissions.js +62 -1
- package/dist/permissions.js.map +1 -1
- package/dist/prompt-attachment.d.ts +30 -6
- package/dist/prompt-attachment.d.ts.map +1 -1
- package/dist/prompt-attachment.js +35 -1
- package/dist/prompt-attachment.js.map +1 -1
- package/dist/quickjs.d.ts +147 -0
- package/dist/quickjs.d.ts.map +1 -0
- package/dist/quickjs.js +2 -0
- package/dist/quickjs.js.map +1 -0
- package/dist/secrets.d.ts +27 -0
- package/dist/secrets.d.ts.map +1 -0
- package/dist/secrets.js +2 -0
- package/dist/secrets.js.map +1 -0
- package/dist/service-provider.d.ts +62 -0
- package/dist/service-provider.d.ts.map +1 -0
- package/dist/service-provider.js +2 -0
- package/dist/service-provider.js.map +1 -0
- package/dist/storage.d.ts +46 -6
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +8 -1
- package/dist/storage.js.map +1 -1
- package/dist/ui.d.ts +341 -22
- package/dist/ui.d.ts.map +1 -1
- package/dist/ui.js.map +1 -1
- package/package.json +22 -2
- package/src/tailwind-theme.css +30 -0
- package/dist/settings.d.ts +0 -13
- package/dist/settings.d.ts.map +0 -1
- package/dist/settings.js +0 -2
- package/dist/settings.js.map +0 -1
package/dist/manifest.js
CHANGED
|
@@ -1,2 +1,469 @@
|
|
|
1
|
-
|
|
1
|
+
import { Value } from "@sinclair/typebox/value";
|
|
2
|
+
import { PluginCommandNamesSchema, PluginIdSchema, PluginManifestSchema, PluginMcpServerConfigSchema, PluginVersionSchema, } from "./manifest-schema.js";
|
|
3
|
+
import "./permissions.js";
|
|
4
|
+
export { PluginAgentManifestSchema, PluginAgentProfileManifestSchema, PluginAgentTeamManifestSchema, PluginAgentTeamMemberManifestSchema, PluginBrowserManifestSchema, PluginCommandNameSchema, PluginCommandNamesSchema, PluginCliProviderManifestSchema, PluginServiceArtifactSchema, PluginServicePlatformSchema, PluginServiceProviderManifestSchema, PluginIdSchema, PluginManifestSchema, PluginMcpHttpServerConfigSchema, PluginMcpServerConfigSchema, PluginMcpStdioServerConfigSchema, PluginMcpServiceServerConfigSchema, PluginSkillPresentationRuleSchema, PluginSkillPresentationSchema, PluginModuleFederationManifestSchema, PluginNetworkManifestSchema, PluginProvidersManifestSchema, PluginPermissionSchema, PluginVersionSchema, } from "./manifest-schema.js";
|
|
5
|
+
export { PLUGIN_PERMISSIONS } from "./permissions.js";
|
|
6
|
+
function schemaErrorPath(path) {
|
|
7
|
+
if (!path)
|
|
8
|
+
return "";
|
|
9
|
+
return path
|
|
10
|
+
.split("/")
|
|
11
|
+
.slice(1)
|
|
12
|
+
.map((segment) => segment.replace(/~1/g, "/").replace(/~0/g, "~"))
|
|
13
|
+
.map((segment) => {
|
|
14
|
+
if (segment === "")
|
|
15
|
+
return '[""]';
|
|
16
|
+
return /^\d+$/.test(segment) ? `[${segment}]` : `.${segment}`;
|
|
17
|
+
})
|
|
18
|
+
.join("");
|
|
19
|
+
}
|
|
20
|
+
function mostSpecificSchemaError(issue) {
|
|
21
|
+
const nested = issue.errors.flatMap((iterator) => [...iterator].map((child) => mostSpecificSchemaError(child)));
|
|
22
|
+
const deeper = nested.filter((child) => child.path.length > issue.path.length);
|
|
23
|
+
if (deeper.length === 0)
|
|
24
|
+
return issue;
|
|
25
|
+
return deeper.reduce((best, child) => (child.path.length > best.path.length ? child : best));
|
|
26
|
+
}
|
|
27
|
+
function assertSchema(schema, value, fieldName) {
|
|
28
|
+
if (Value.Check(schema, value))
|
|
29
|
+
return;
|
|
30
|
+
const firstIssue = Value.Errors(schema, value).First();
|
|
31
|
+
const issue = firstIssue ? mostSpecificSchemaError(firstIssue) : undefined;
|
|
32
|
+
const location = `${fieldName}${schemaErrorPath(issue?.path ?? "")}`;
|
|
33
|
+
throw new Error(`Invalid plugin ${location}: ${issue?.message ?? "schema validation failed"}`);
|
|
34
|
+
}
|
|
35
|
+
function trimString(value) {
|
|
36
|
+
return value.trim();
|
|
37
|
+
}
|
|
38
|
+
function normalizeStringArray(values) {
|
|
39
|
+
return (values ?? []).map(trimString);
|
|
40
|
+
}
|
|
41
|
+
function normalizeOptionalAgentModes(value) {
|
|
42
|
+
if (value === undefined)
|
|
43
|
+
return undefined;
|
|
44
|
+
return Array.isArray(value) ? normalizeStringArray(value) : trimString(value);
|
|
45
|
+
}
|
|
46
|
+
function normalizePermissions(permissions) {
|
|
47
|
+
return Array.from(new Set(permissions ?? []));
|
|
48
|
+
}
|
|
49
|
+
function normalizeAllowedHost(value, fieldName) {
|
|
50
|
+
const raw = trimString(value).toLowerCase();
|
|
51
|
+
if (raw === "*")
|
|
52
|
+
return raw;
|
|
53
|
+
const wildcard = raw.startsWith("*.");
|
|
54
|
+
const candidate = wildcard ? raw.slice(2) : raw;
|
|
55
|
+
if (!candidate || candidate.includes("*") || /[\\/?#@]/.test(candidate)) {
|
|
56
|
+
throw new Error(`Invalid plugin ${fieldName}.allowedHosts entry: ${value}`);
|
|
57
|
+
}
|
|
58
|
+
const unwrapped = candidate.startsWith("[") && candidate.endsWith("]") ? candidate.slice(1, -1) : candidate;
|
|
59
|
+
if (wildcard && unwrapped.includes(":")) {
|
|
60
|
+
throw new Error(`Invalid plugin ${fieldName}.allowedHosts entry: ${value}`);
|
|
61
|
+
}
|
|
62
|
+
try {
|
|
63
|
+
const parsed = new URL(`http://${unwrapped.includes(":") ? `[${unwrapped}]` : unwrapped}`);
|
|
64
|
+
const hostname = parsed.hostname.replace(/^\[|\]$/g, "").replace(/\.$/, "").toLowerCase();
|
|
65
|
+
if (!hostname || parsed.port || parsed.username || parsed.password)
|
|
66
|
+
throw new Error("invalid host");
|
|
67
|
+
return wildcard ? `*.${hostname}` : hostname;
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
throw new Error(`Invalid plugin ${fieldName}.allowedHosts entry: ${value}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function normalizeNetworkManifest(network) {
|
|
74
|
+
if (!network)
|
|
75
|
+
return undefined;
|
|
76
|
+
return { allowedHosts: Array.from(new Set(network.allowedHosts.map((host) => normalizeAllowedHost(host, "network")))) };
|
|
77
|
+
}
|
|
78
|
+
function normalizeBrowserManifest(browser) {
|
|
79
|
+
if (!browser)
|
|
80
|
+
return undefined;
|
|
81
|
+
return { allowedHosts: Array.from(new Set(browser.allowedHosts.map((host) => normalizeAllowedHost(host, "browser")))) };
|
|
82
|
+
}
|
|
83
|
+
function normalizeModuleFederation(moduleFederation) {
|
|
84
|
+
return {
|
|
85
|
+
remoteName: trimString(moduleFederation.remoteName),
|
|
86
|
+
expose: trimString(moduleFederation.expose),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
function normalizeToolPolicy(toolPolicy) {
|
|
90
|
+
if (!toolPolicy)
|
|
91
|
+
return undefined;
|
|
92
|
+
return {
|
|
93
|
+
allow: normalizeStringArray(toolPolicy.allow),
|
|
94
|
+
deny: normalizeStringArray(toolPolicy.deny),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
function normalizeMcpServers(mcpServers) {
|
|
98
|
+
if (mcpServers === undefined)
|
|
99
|
+
return undefined;
|
|
100
|
+
if (typeof mcpServers === "string") {
|
|
101
|
+
return validatePluginRelativePath(trimString(mcpServers), "agent.mcpServers");
|
|
102
|
+
}
|
|
103
|
+
const result = {};
|
|
104
|
+
for (const [name, config] of Object.entries(mcpServers)) {
|
|
105
|
+
result[trimString(name)] = normalizePluginMcpServerConfig(config);
|
|
106
|
+
}
|
|
107
|
+
return result;
|
|
108
|
+
}
|
|
109
|
+
function normalizeAgentManifest(agent) {
|
|
110
|
+
if (!agent)
|
|
111
|
+
return undefined;
|
|
112
|
+
return {
|
|
113
|
+
systemPrompt: agent.systemPrompt
|
|
114
|
+
? {
|
|
115
|
+
promptPaths: normalizeStringArray(agent.systemPrompt.promptPaths).map((path) => validatePluginRelativePath(path, "agent.systemPrompt.promptPaths")),
|
|
116
|
+
}
|
|
117
|
+
: undefined,
|
|
118
|
+
skillPaths: normalizeStringArray(agent.skillPaths).map((path) => validatePluginRelativePath(path, "agent.skillPaths")),
|
|
119
|
+
skillPresentation: normalizeSkillPresentation(agent.skillPresentation),
|
|
120
|
+
mcpServers: normalizeMcpServers(agent.mcpServers),
|
|
121
|
+
toolPolicy: normalizeToolPolicy(agent.toolPolicy),
|
|
122
|
+
agents: agent.agents?.map((profile) => ({
|
|
123
|
+
...profile,
|
|
124
|
+
// 路径都要过越界校验:manifest 里写 `../` 不该能读到插件目录之外。
|
|
125
|
+
avatar: profile.avatar ? validatePluginRelativePath(profile.avatar, "agent.agents.avatar") : undefined,
|
|
126
|
+
systemPromptPath: profile.systemPromptPath
|
|
127
|
+
? validatePluginRelativePath(profile.systemPromptPath, "agent.agents.systemPromptPath")
|
|
128
|
+
: undefined,
|
|
129
|
+
})),
|
|
130
|
+
teams: agent.teams?.map((team) => ({
|
|
131
|
+
...team,
|
|
132
|
+
workflowPath: team.workflowPath
|
|
133
|
+
? validatePluginRelativePath(team.workflowPath, "agent.teams.workflowPath")
|
|
134
|
+
: undefined,
|
|
135
|
+
})),
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
function normalizeSkillPresentation(presentation) {
|
|
139
|
+
if (!presentation)
|
|
140
|
+
return undefined;
|
|
141
|
+
const normalizeRule = (rule) => ({
|
|
142
|
+
defaultVisibility: rule.defaultVisibility,
|
|
143
|
+
surfaces: rule.surfaces ? { ...rule.surfaces } : undefined,
|
|
144
|
+
displayName: rule.displayName?.trim(),
|
|
145
|
+
displayDescription: rule.displayDescription?.trim(),
|
|
146
|
+
});
|
|
147
|
+
return {
|
|
148
|
+
defaultVisibility: presentation.defaultVisibility,
|
|
149
|
+
surfaces: presentation.surfaces ? { ...presentation.surfaces } : undefined,
|
|
150
|
+
skills: presentation.skills
|
|
151
|
+
? Object.fromEntries(Object.entries(presentation.skills).map(([name, rule]) => [name.trim(), normalizeRule(rule)]))
|
|
152
|
+
: undefined,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
function normalizeCliProviders(providers) {
|
|
156
|
+
if (!providers || providers.length === 0)
|
|
157
|
+
return undefined;
|
|
158
|
+
const ids = new Set();
|
|
159
|
+
return providers.map((provider) => {
|
|
160
|
+
if (ids.has(provider.id))
|
|
161
|
+
throw new Error(`Duplicate CLI provider id: ${provider.id}`);
|
|
162
|
+
ids.add(provider.id);
|
|
163
|
+
return {
|
|
164
|
+
id: provider.id,
|
|
165
|
+
command: provider.command,
|
|
166
|
+
probe: provider.probe
|
|
167
|
+
? { args: provider.probe.args ? [...provider.probe.args] : undefined, timeoutMs: provider.probe.timeoutMs }
|
|
168
|
+
: undefined,
|
|
169
|
+
install: {
|
|
170
|
+
command: provider.install.command,
|
|
171
|
+
args: provider.install.args ? [...provider.install.args] : undefined,
|
|
172
|
+
timeoutMs: provider.install.timeoutMs,
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
function normalizeServiceProviders(providers) {
|
|
178
|
+
if (!providers || providers.length === 0)
|
|
179
|
+
return undefined;
|
|
180
|
+
const ids = new Set();
|
|
181
|
+
return providers.map((provider) => {
|
|
182
|
+
if (ids.has(provider.id))
|
|
183
|
+
throw new Error(`Duplicate service provider id: ${provider.id}`);
|
|
184
|
+
ids.add(provider.id);
|
|
185
|
+
const runtimeKind = provider.runtime.kind ?? "managed-binary";
|
|
186
|
+
const entry = provider.runtime.entry
|
|
187
|
+
? validatePluginRelativePath(provider.runtime.entry, `providers.services.${provider.id}.runtime.entry`)
|
|
188
|
+
: undefined;
|
|
189
|
+
if (runtimeKind === "host-node" && !entry) {
|
|
190
|
+
throw new Error(`Host-node service must declare runtime.entry: ${provider.id}`);
|
|
191
|
+
}
|
|
192
|
+
const platforms = {};
|
|
193
|
+
for (const [platformTag, platform] of Object.entries(provider.runtime.platforms)) {
|
|
194
|
+
const destinations = new Set();
|
|
195
|
+
platforms[platformTag] = {
|
|
196
|
+
executable: validatePluginRelativePath(platform.executable, `providers.services.${provider.id}.executable`),
|
|
197
|
+
artifacts: platform.artifacts.map((artifact) => {
|
|
198
|
+
const destination = validatePluginRelativePath(artifact.destination, `providers.services.${provider.id}.artifacts.destination`);
|
|
199
|
+
if (destinations.has(destination)) {
|
|
200
|
+
throw new Error(`Duplicate service artifact destination: ${provider.id}/${platformTag}/${destination}`);
|
|
201
|
+
}
|
|
202
|
+
destinations.add(destination);
|
|
203
|
+
return { ...artifact, destination };
|
|
204
|
+
}),
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
if (Object.keys(platforms).length === 0) {
|
|
208
|
+
throw new Error(`Service provider must declare at least one platform: ${provider.id}`);
|
|
209
|
+
}
|
|
210
|
+
const credentialIds = new Set();
|
|
211
|
+
const credentials = provider.credentials?.map((credential) => {
|
|
212
|
+
if (credentialIds.has(credential.id))
|
|
213
|
+
throw new Error(`Duplicate service credential id: ${provider.id}/${credential.id}`);
|
|
214
|
+
credentialIds.add(credential.id);
|
|
215
|
+
return { id: credential.id, bytes: credential.bytes };
|
|
216
|
+
});
|
|
217
|
+
if (provider.health.credentialId && !credentialIds.has(provider.health.credentialId)) {
|
|
218
|
+
throw new Error(`Unknown service health credential: ${provider.id}/${provider.health.credentialId}`);
|
|
219
|
+
}
|
|
220
|
+
const templateDestinations = new Set();
|
|
221
|
+
const templates = provider.templates?.map((template) => {
|
|
222
|
+
const source = validatePluginRelativePath(template.source, `providers.services.${provider.id}.templates.source`);
|
|
223
|
+
const destination = validatePluginRelativePath(template.destination, `providers.services.${provider.id}.templates.destination`);
|
|
224
|
+
if (templateDestinations.has(destination))
|
|
225
|
+
throw new Error(`Duplicate service template destination: ${provider.id}/${destination}`);
|
|
226
|
+
templateDestinations.add(destination);
|
|
227
|
+
return { source, destination, mode: template.mode };
|
|
228
|
+
});
|
|
229
|
+
const normalizedRuntime = {
|
|
230
|
+
version: provider.runtime.version,
|
|
231
|
+
platforms,
|
|
232
|
+
...(runtimeKind === "host-node" ? { kind: runtimeKind, entry } : provider.runtime.kind ? { kind: runtimeKind } : {}),
|
|
233
|
+
};
|
|
234
|
+
return {
|
|
235
|
+
id: provider.id,
|
|
236
|
+
runtime: normalizedRuntime,
|
|
237
|
+
credentials,
|
|
238
|
+
templates,
|
|
239
|
+
process: {
|
|
240
|
+
args: provider.process.args ? [...provider.process.args] : undefined,
|
|
241
|
+
env: provider.process.env ? { ...provider.process.env } : undefined,
|
|
242
|
+
},
|
|
243
|
+
health: { ...provider.health },
|
|
244
|
+
};
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
function normalizePluginMcpServerConfig(config) {
|
|
248
|
+
const common = {
|
|
249
|
+
disabled: config.disabled,
|
|
250
|
+
autoApprove: config.autoApprove?.map(trimString),
|
|
251
|
+
startupTimeout: config.startupTimeout,
|
|
252
|
+
debug: config.debug,
|
|
253
|
+
displayName: config.displayName,
|
|
254
|
+
description: config.description,
|
|
255
|
+
agent_mode: normalizeOptionalAgentModes(config.agent_mode),
|
|
256
|
+
};
|
|
257
|
+
if (config.type === "service") {
|
|
258
|
+
return {
|
|
259
|
+
type: "service",
|
|
260
|
+
serviceId: trimString(config.serviceId),
|
|
261
|
+
path: trimString(config.path),
|
|
262
|
+
...common,
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
if (config.type === "http") {
|
|
266
|
+
return {
|
|
267
|
+
type: "http",
|
|
268
|
+
url: trimString(config.url),
|
|
269
|
+
headers: config.headers ? { ...config.headers } : undefined,
|
|
270
|
+
oauthClientId: config.oauthClientId,
|
|
271
|
+
oauthDeviceFlow: config.oauthDeviceFlow,
|
|
272
|
+
oauthScopes: config.oauthScopes,
|
|
273
|
+
...common,
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
return {
|
|
277
|
+
type: config.type,
|
|
278
|
+
command: trimString(config.command),
|
|
279
|
+
args: config.args ? [...config.args] : undefined,
|
|
280
|
+
env: config.env ? { ...config.env } : undefined,
|
|
281
|
+
cwd: config.cwd,
|
|
282
|
+
...common,
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
export function validatePluginId(id) {
|
|
286
|
+
if (!Value.Check(PluginIdSchema, id)) {
|
|
287
|
+
throw new Error("Plugin id must be 1-64 chars: lowercase letters, numbers, dot, underscore, or dash");
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
export function validatePluginVersion(version) {
|
|
291
|
+
if (!Value.Check(PluginVersionSchema, version)) {
|
|
292
|
+
throw new Error("Plugin version must be 1-64 chars and cannot contain path separators");
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
export function validatePluginRelativePath(value, fieldName) {
|
|
296
|
+
if (value.startsWith("/") || /^[a-zA-Z]:/.test(value)) {
|
|
297
|
+
throw new Error(`Invalid plugin ${fieldName}`);
|
|
298
|
+
}
|
|
299
|
+
const parts = [];
|
|
300
|
+
for (const part of value.replace(/\\/g, "/").split("/")) {
|
|
301
|
+
if (part === "" || part === ".")
|
|
302
|
+
continue;
|
|
303
|
+
if (part === "..") {
|
|
304
|
+
if (parts.length === 0)
|
|
305
|
+
throw new Error(`Invalid plugin ${fieldName}`);
|
|
306
|
+
parts.pop();
|
|
307
|
+
continue;
|
|
308
|
+
}
|
|
309
|
+
parts.push(part);
|
|
310
|
+
}
|
|
311
|
+
const normalized = parts.join("/");
|
|
312
|
+
if (!normalized)
|
|
313
|
+
throw new Error(`Invalid plugin ${fieldName}`);
|
|
314
|
+
return normalized;
|
|
315
|
+
}
|
|
316
|
+
export function parsePluginCommandNames(value) {
|
|
317
|
+
if (value === undefined)
|
|
318
|
+
return [];
|
|
319
|
+
assertSchema(PluginCommandNamesSchema, value, "commands");
|
|
320
|
+
return Array.from(new Set(value));
|
|
321
|
+
}
|
|
322
|
+
/** @deprecated agent_mode 已无任何运行时语义(ADR-0071),保留仅为容忍既有 manifest。 */
|
|
323
|
+
export function normalizePluginAgentModes(value) {
|
|
324
|
+
if (value === undefined || value === null)
|
|
325
|
+
return undefined;
|
|
326
|
+
const values = Array.isArray(value) ? value : [value];
|
|
327
|
+
const modes = values.map((item) => String(item).trim()).filter(Boolean);
|
|
328
|
+
return modes.length > 0 ? modes : undefined;
|
|
329
|
+
}
|
|
330
|
+
export function parsePluginMcpServerConfig(name, raw) {
|
|
331
|
+
assertSchema(PluginMcpServerConfigSchema, raw, `MCP server '${name}'`);
|
|
332
|
+
return normalizePluginMcpServerConfig(raw);
|
|
333
|
+
}
|
|
334
|
+
export function isPluginPassthroughIconRef(icon) {
|
|
335
|
+
return (icon.startsWith("http://") ||
|
|
336
|
+
icon.startsWith("https://") ||
|
|
337
|
+
/^[a-z0-9]+(?:-[a-z0-9]+)*:[a-z0-9]+(?:-[a-z0-9]+)*$/.test(icon));
|
|
338
|
+
}
|
|
339
|
+
export function isPluginPackagedIconPath(icon) {
|
|
340
|
+
return !isPluginPassthroughIconRef(icon);
|
|
341
|
+
}
|
|
342
|
+
export function parsePluginManifest(raw) {
|
|
343
|
+
if (typeof raw === "object" && raw !== null && "runtime" in raw) {
|
|
344
|
+
throw new Error('Invalid plugin manifest.runtime: runtime selection is unsupported; plugins use Module Federation.');
|
|
345
|
+
}
|
|
346
|
+
assertSchema(PluginManifestSchema, raw, "manifest");
|
|
347
|
+
const commands = parsePluginCommandNames(raw.commands);
|
|
348
|
+
const icon = raw.icon === undefined ? undefined : trimString(raw.icon);
|
|
349
|
+
const permissions = normalizePermissions(raw.permissions);
|
|
350
|
+
const network = normalizeNetworkManifest(raw.network);
|
|
351
|
+
const browser = normalizeBrowserManifest(raw.browser);
|
|
352
|
+
if (permissions.includes("network.fetch") && !network) {
|
|
353
|
+
throw new Error("Plugin network.allowedHosts is required with network.fetch");
|
|
354
|
+
}
|
|
355
|
+
const browserPermissions = permissions.filter((permission) => permission.startsWith("browser."));
|
|
356
|
+
if (browserPermissions.length > 0 && !browser) {
|
|
357
|
+
throw new Error("Plugin browser.allowedHosts is required with browser permissions");
|
|
358
|
+
}
|
|
359
|
+
if (permissions.includes("browser.interact") && !permissions.includes("browser.read")) {
|
|
360
|
+
throw new Error("Plugin browser.interact requires browser.read");
|
|
361
|
+
}
|
|
362
|
+
const normalizedServices = raw.providers ? normalizeServiceProviders(raw.providers.services) : undefined;
|
|
363
|
+
for (const [name, server] of Object.entries(raw.agent?.mcpServers && typeof raw.agent.mcpServers !== "string" ? raw.agent.mcpServers : {})) {
|
|
364
|
+
if (server.type === "service" && !normalizedServices?.some((service) => service.id === server.serviceId)) {
|
|
365
|
+
throw new Error(`Plugin MCP server '${name}' references unknown service '${server.serviceId}'`);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
return {
|
|
369
|
+
id: raw.id,
|
|
370
|
+
name: trimString(raw.name),
|
|
371
|
+
version: raw.version,
|
|
372
|
+
pluginApiVersion: trimString(raw.pluginApiVersion),
|
|
373
|
+
entry: validatePluginRelativePath(trimString(raw.entry), "entry"),
|
|
374
|
+
moduleFederation: normalizeModuleFederation(raw.moduleFederation),
|
|
375
|
+
agent: normalizeAgentManifest(raw.agent),
|
|
376
|
+
providers: raw.providers
|
|
377
|
+
? {
|
|
378
|
+
cli: normalizeCliProviders(raw.providers.cli),
|
|
379
|
+
services: normalizedServices,
|
|
380
|
+
}
|
|
381
|
+
: undefined,
|
|
382
|
+
styles: normalizeStringArray(raw.styles).map((style) => validatePluginRelativePath(style, "styles")),
|
|
383
|
+
permissions,
|
|
384
|
+
network,
|
|
385
|
+
browser,
|
|
386
|
+
commands: commands.length > 0 ? commands : undefined,
|
|
387
|
+
description: raw.description,
|
|
388
|
+
author: raw.author,
|
|
389
|
+
icon: icon === undefined || isPluginPassthroughIconRef(icon)
|
|
390
|
+
? icon
|
|
391
|
+
: validatePluginRelativePath(icon, "icon"),
|
|
392
|
+
guidingWords: raw.guidingWords?.map(trimString),
|
|
393
|
+
defaultLocale: raw.defaultLocale ?? "zh",
|
|
394
|
+
contributionMode: raw.contributionMode
|
|
395
|
+
? { hardIsolation: raw.contributionMode.hardIsolation === true }
|
|
396
|
+
: undefined,
|
|
397
|
+
agent_mode: normalizePluginAgentModes(raw.agent_mode),
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
export function listPluginManifestResources(manifest) {
|
|
401
|
+
const resources = [
|
|
402
|
+
{ field: "entry", path: manifest.entry, kind: "file" },
|
|
403
|
+
];
|
|
404
|
+
for (const stylePath of manifest.styles ?? []) {
|
|
405
|
+
resources.push({ field: "styles", path: stylePath, kind: "file" });
|
|
406
|
+
}
|
|
407
|
+
if (manifest.icon && isPluginPackagedIconPath(manifest.icon)) {
|
|
408
|
+
resources.push({ field: "icon", path: manifest.icon, kind: "file" });
|
|
409
|
+
}
|
|
410
|
+
for (const promptPath of manifest.agent?.systemPrompt?.promptPaths ?? []) {
|
|
411
|
+
resources.push({ field: "agent.systemPrompt.promptPaths", path: promptPath, kind: "file-or-directory" });
|
|
412
|
+
}
|
|
413
|
+
for (const skillPath of manifest.agent?.skillPaths ?? []) {
|
|
414
|
+
resources.push({ field: "agent.skillPaths", path: skillPath, kind: "file-or-directory" });
|
|
415
|
+
}
|
|
416
|
+
for (const agent of manifest.agent?.agents ?? []) {
|
|
417
|
+
// 人设与头像是插件包里的真实文件:不登记就不会被打进包,装到用户机器上时这个
|
|
418
|
+
// 智能体会因为「提示词读不出来」被整个跳过。
|
|
419
|
+
if (agent.avatar)
|
|
420
|
+
resources.push({ field: "agent.agents.avatar", path: agent.avatar, kind: "file" });
|
|
421
|
+
if (agent.systemPromptPath) {
|
|
422
|
+
resources.push({ field: "agent.agents.systemPromptPath", path: agent.systemPromptPath, kind: "file" });
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
for (const team of manifest.agent?.teams ?? []) {
|
|
426
|
+
if (team.workflowPath) {
|
|
427
|
+
resources.push({ field: "agent.teams.workflowPath", path: team.workflowPath, kind: "file" });
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
if (typeof manifest.agent?.mcpServers === "string") {
|
|
431
|
+
resources.push({ field: "agent.mcpServers", path: manifest.agent.mcpServers, kind: "file" });
|
|
432
|
+
}
|
|
433
|
+
for (const service of manifest.providers?.services ?? []) {
|
|
434
|
+
for (const template of service.templates ?? []) {
|
|
435
|
+
resources.push({ field: `providers.services.${service.id}.templates.source`, path: template.source, kind: "file" });
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
return resources;
|
|
439
|
+
}
|
|
440
|
+
function parseApiVersion(value) {
|
|
441
|
+
const match = /^(\d+)\.(\d+)\.(\d+)$/.exec(value);
|
|
442
|
+
if (!match)
|
|
443
|
+
return undefined;
|
|
444
|
+
return [Number(match[1]), Number(match[2]), Number(match[3])];
|
|
445
|
+
}
|
|
446
|
+
function compareApiVersions(left, right) {
|
|
447
|
+
for (let index = 0; index < left.length; index += 1) {
|
|
448
|
+
if (left[index] !== right[index])
|
|
449
|
+
return left[index] - right[index];
|
|
450
|
+
}
|
|
451
|
+
return 0;
|
|
452
|
+
}
|
|
453
|
+
export function isPluginApiCompatible(hostVersion, range) {
|
|
454
|
+
const host = parseApiVersion(hostVersion);
|
|
455
|
+
if (!host)
|
|
456
|
+
return false;
|
|
457
|
+
const normalized = range.trim();
|
|
458
|
+
const exact = parseApiVersion(normalized);
|
|
459
|
+
if (exact)
|
|
460
|
+
return exact[0] === host[0] && compareApiVersions(host, exact) >= 0;
|
|
461
|
+
const caret = normalized.startsWith("^") ? parseApiVersion(normalized.slice(1)) : undefined;
|
|
462
|
+
if (caret)
|
|
463
|
+
return caret[0] === host[0] && compareApiVersions(host, caret) >= 0;
|
|
464
|
+
if (normalized === `^${host[0]}` || normalized === `${host[0]}.x`)
|
|
465
|
+
return true;
|
|
466
|
+
const minimum = normalized.startsWith(">=") ? parseApiVersion(normalized.slice(2)) : undefined;
|
|
467
|
+
return minimum !== undefined && compareApiVersions(host, minimum) >= 0;
|
|
468
|
+
}
|
|
2
469
|
//# sourceMappingURL=manifest.js.map
|
package/dist/manifest.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * MCP server config declared inside a plugin (stdio or http). Relative paths in\n * stdio `command`/`args`/`cwd` are resolved against the plugin root at contribute time.\n */\nexport type PluginMcpServerConfig =\n\t| {\n\t\t\ttype?: \"stdio\";\n\t\t\tcommand: string;\n\t\t\targs?: string[];\n\t\t\tenv?: Record<string, string>;\n\t\t\tcwd?: string;\n\t\t\tdisabled?: boolean;\n\t\t\tautoApprove?: string[];\n\t\t\tstartupTimeout?: number;\n\t\t\tdebug?: boolean;\n\t\t\tdisplayName?: string;\n\t\t\tdescription?: string;\n\t\t\t/** 该 server 的工具允许出现的工作模式 slug(agent_mode 轴,缺省/空 = 通用)。见 ADR-0046。 */\n\t\t\tagent_mode?: string | string[];\n\t }\n\t| {\n\t\t\ttype: \"http\";\n\t\t\turl: string;\n\t\t\theaders?: Record<string, string>;\n\t\t\toauthClientId?: string;\n\t\t\toauthDeviceFlow?: boolean;\n\t\t\toauthScopes?: string;\n\t\t\tdisabled?: boolean;\n\t\t\tautoApprove?: string[];\n\t\t\tstartupTimeout?: number;\n\t\t\tdebug?: boolean;\n\t\t\tdisplayName?: string;\n\t\t\tdescription?: string;\n\t\t\t/** 该 server 的工具允许出现的工作模式 slug(agent_mode 轴,缺省/空 = 通用)。见 ADR-0046。 */\n\t\t\tagent_mode?: string | string[];\n\t };\n\nexport interface PluginAgentManifest {\n\tsystemPrompt?: {\n\t\t/**\n\t\t * Plugin-packaged prompt contribution file paths. Main-process aggregation\n\t\t * resolves these relative to the installed plugin root.\n\t\t */\n\t\tpromptPaths?: string[];\n\t};\n\t/** Plugin-packaged skill files or directories to add to the agent resource graph. */\n\tskillPaths?: string[];\n\t/**\n\t * Plugin-scoped MCP servers. Either a relative path to `.mcp.json`\n\t * (shape `{ mcpServers: { ... } }`) or an inline map of server configs.\n\t * Requires permission `agent.mcp.control`. Never written into user mcp.json.\n\t */\n\tmcpServers?: string | Record<string, PluginMcpServerConfig>;\n\t/** Declarative tool visibility policy. Names are tool ids after registration. */\n\ttoolPolicy?: {\n\t\tallow?: string[];\n\t\tdeny?: string[];\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Static, type TSchema } from \"@sinclair/typebox\";\nimport type { ValueError } from \"@sinclair/typebox/errors\";\nimport { Value } from \"@sinclair/typebox/value\";\nimport {\n\tPluginCommandNameSchema,\n\tPluginCommandNamesSchema,\n\tPluginCliProviderManifestSchema,\n\tPluginServiceProviderManifestSchema,\n\tPluginIdSchema,\n\tPluginManifestSchema,\n\tPluginMcpServerConfigSchema,\n\tPluginMcpServiceServerConfigSchema,\n\tPluginSkillPresentationRuleSchema,\n\tPluginSkillPresentationSchema,\n\tPluginVersionSchema,\n\ttype PluginAgentManifest,\n\ttype PluginAgentProfileManifest,\n\ttype PluginAgentTeamManifest,\n\ttype PluginAgentTeamMemberManifest,\n\ttype PluginBrowserManifest,\n\ttype PluginCliProviderManifest,\n\ttype PluginServiceProviderManifest,\n\ttype PluginServiceRuntimeKind,\n\ttype PluginManifest,\n\ttype PluginManifestInput,\n\ttype PluginMcpServerConfig,\n\ttype PluginSkillPresentation,\n\ttype PluginSkillPresentationRule,\n\ttype PluginNetworkManifest,\n} from \"./manifest-schema.js\";\nimport { PLUGIN_PERMISSIONS, type PluginPermission } from \"./permissions.js\";\n\nexport {\n\tPluginAgentManifestSchema,\n\tPluginAgentProfileManifestSchema,\n\tPluginAgentTeamManifestSchema,\n\tPluginAgentTeamMemberManifestSchema,\n\tPluginBrowserManifestSchema,\n\tPluginCommandNameSchema,\n\tPluginCommandNamesSchema,\n\tPluginCliProviderManifestSchema,\n\tPluginServiceArtifactSchema,\n\tPluginServicePlatformSchema,\n\tPluginServiceProviderManifestSchema,\n\tPluginIdSchema,\n\tPluginManifestSchema,\n\tPluginMcpHttpServerConfigSchema,\n\tPluginMcpServerConfigSchema,\n\tPluginMcpStdioServerConfigSchema,\n\tPluginMcpServiceServerConfigSchema,\n\tPluginSkillPresentationRuleSchema,\n\tPluginSkillPresentationSchema,\n\tPluginModuleFederationManifestSchema,\n\tPluginNetworkManifestSchema,\n\tPluginProvidersManifestSchema,\n\tPluginPermissionSchema,\n\tPluginVersionSchema,\n} from \"./manifest-schema.js\";\nexport type {\n\tPluginAgentManifest,\n\tPluginAgentProfileManifest,\n\tPluginAgentTeamManifest,\n\tPluginAgentTeamMemberManifest,\n\tPluginBrowserManifest,\n\tPluginCliProviderManifest,\n\tPluginServiceArtifact,\n\tPluginServicePlatform,\n\tPluginServiceProviderManifest,\n\tPluginServiceRuntimeKind,\n\tPluginManifest,\n\tPluginManifestInput,\n\tPluginMcpServerConfig,\n\tPluginSkillPresentation,\n\tPluginSkillPresentationRule,\n\tPluginNetworkManifest,\n} from \"./manifest-schema.js\";\nexport { PLUGIN_PERMISSIONS } from \"./permissions.js\";\nexport type { PluginPermission } from \"./permissions.js\";\n\nexport interface PluginManifestResourceReference {\n\tfield: string;\n\tpath: string;\n\tkind: \"file\" | \"file-or-directory\";\n}\n\nfunction schemaErrorPath(path: string): string {\n\tif (!path) return \"\";\n\treturn path\n\t\t.split(\"/\")\n\t\t.slice(1)\n\t\t.map((segment) => segment.replace(/~1/g, \"/\").replace(/~0/g, \"~\"))\n\t\t.map((segment) => {\n\t\t\tif (segment === \"\") return '[\"\"]';\n\t\t\treturn /^\\d+$/.test(segment) ? `[${segment}]` : `.${segment}`;\n\t\t})\n\t\t.join(\"\");\n}\n\nfunction mostSpecificSchemaError(issue: ValueError): ValueError {\n\tconst nested = issue.errors.flatMap((iterator) =>\n\t\t[...iterator].map((child) => mostSpecificSchemaError(child)),\n\t);\n\tconst deeper = nested.filter((child) => child.path.length > issue.path.length);\n\tif (deeper.length === 0) return issue;\n\treturn deeper.reduce((best, child) => (child.path.length > best.path.length ? child : best));\n}\n\nfunction assertSchema<Schema extends TSchema>(\n\tschema: Schema,\n\tvalue: unknown,\n\tfieldName: string,\n): asserts value is Static<Schema> {\n\tif (Value.Check(schema, value)) return;\n\tconst firstIssue = Value.Errors(schema, value).First();\n\tconst issue = firstIssue ? mostSpecificSchemaError(firstIssue) : undefined;\n\tconst location = `${fieldName}${schemaErrorPath(issue?.path ?? \"\")}`;\n\tthrow new Error(`Invalid plugin ${location}: ${issue?.message ?? \"schema validation failed\"}`);\n}\n\nfunction trimString(value: string): string {\n\treturn value.trim();\n}\n\nfunction normalizeStringArray(values: string[] | undefined): string[] {\n\treturn (values ?? []).map(trimString);\n}\n\nfunction normalizeOptionalAgentModes(value: string | string[] | undefined): string | string[] | undefined {\n\tif (value === undefined) return undefined;\n\treturn Array.isArray(value) ? normalizeStringArray(value) : trimString(value);\n}\n\nfunction normalizePermissions(permissions: PluginPermission[] | undefined): PluginPermission[] {\n\treturn Array.from(new Set(permissions ?? []));\n}\n\nfunction normalizeAllowedHost(value: string, fieldName: \"network\" | \"browser\"): string {\n\tconst raw = trimString(value).toLowerCase();\n\tif (raw === \"*\") return raw;\n\tconst wildcard = raw.startsWith(\"*.\");\n\tconst candidate = wildcard ? raw.slice(2) : raw;\n\tif (!candidate || candidate.includes(\"*\") || /[\\\\/?#@]/.test(candidate)) {\n\t\tthrow new Error(`Invalid plugin ${fieldName}.allowedHosts entry: ${value}`);\n\t}\n\tconst unwrapped = candidate.startsWith(\"[\") && candidate.endsWith(\"]\") ? candidate.slice(1, -1) : candidate;\n\tif (wildcard && unwrapped.includes(\":\")) {\n\t\tthrow new Error(`Invalid plugin ${fieldName}.allowedHosts entry: ${value}`);\n\t}\n\ttry {\n\t\tconst parsed = new URL(`http://${unwrapped.includes(\":\") ? `[${unwrapped}]` : unwrapped}`);\n\t\tconst hostname = parsed.hostname.replace(/^\\[|\\]$/g, \"\").replace(/\\.$/, \"\").toLowerCase();\n\t\tif (!hostname || parsed.port || parsed.username || parsed.password) throw new Error(\"invalid host\");\n\t\treturn wildcard ? `*.${hostname}` : hostname;\n\t} catch {\n\t\tthrow new Error(`Invalid plugin ${fieldName}.allowedHosts entry: ${value}`);\n\t}\n}\n\nfunction normalizeNetworkManifest(network: PluginNetworkManifest | undefined): PluginNetworkManifest | undefined {\n\tif (!network) return undefined;\n\treturn { allowedHosts: Array.from(new Set(network.allowedHosts.map((host) => normalizeAllowedHost(host, \"network\")))) };\n}\n\nfunction normalizeBrowserManifest(browser: PluginBrowserManifest | undefined): PluginBrowserManifest | undefined {\n\tif (!browser) return undefined;\n\treturn { allowedHosts: Array.from(new Set(browser.allowedHosts.map((host) => normalizeAllowedHost(host, \"browser\")))) };\n}\n\nfunction normalizeModuleFederation(\n\tmoduleFederation: PluginManifestInput[\"moduleFederation\"],\n): PluginManifest[\"moduleFederation\"] {\n\treturn {\n\t\tremoteName: trimString(moduleFederation.remoteName),\n\t\texpose: trimString(moduleFederation.expose),\n\t};\n}\n\nfunction normalizeToolPolicy(\n\ttoolPolicy: PluginAgentManifest[\"toolPolicy\"],\n): PluginAgentManifest[\"toolPolicy\"] {\n\tif (!toolPolicy) return undefined;\n\treturn {\n\t\tallow: normalizeStringArray(toolPolicy.allow),\n\t\tdeny: normalizeStringArray(toolPolicy.deny),\n\t};\n}\n\nfunction normalizeMcpServers(\n\tmcpServers: PluginAgentManifest[\"mcpServers\"],\n): PluginAgentManifest[\"mcpServers\"] {\n\tif (mcpServers === undefined) return undefined;\n\tif (typeof mcpServers === \"string\") {\n\t\treturn validatePluginRelativePath(trimString(mcpServers), \"agent.mcpServers\");\n\t}\n\tconst result: Record<string, PluginMcpServerConfig> = {};\n\tfor (const [name, config] of Object.entries(mcpServers)) {\n\t\tresult[trimString(name)] = normalizePluginMcpServerConfig(config);\n\t}\n\treturn result;\n}\n\nfunction normalizeAgentManifest(agent: PluginAgentManifest | undefined): PluginAgentManifest | undefined {\n\tif (!agent) return undefined;\n\treturn {\n\t\tsystemPrompt: agent.systemPrompt\n\t\t\t? {\n\t\t\t\t\tpromptPaths: normalizeStringArray(agent.systemPrompt.promptPaths).map((path) =>\n\t\t\t\t\t\tvalidatePluginRelativePath(path, \"agent.systemPrompt.promptPaths\"),\n\t\t\t\t\t),\n\t\t\t\t}\n\t\t\t: undefined,\n\t\tskillPaths: normalizeStringArray(agent.skillPaths).map((path) =>\n\t\t\tvalidatePluginRelativePath(path, \"agent.skillPaths\"),\n\t\t),\n\t\tskillPresentation: normalizeSkillPresentation(agent.skillPresentation),\n\t\tmcpServers: normalizeMcpServers(agent.mcpServers),\n\t\ttoolPolicy: normalizeToolPolicy(agent.toolPolicy),\n\t\tagents: agent.agents?.map((profile) => ({\n\t\t\t...profile,\n\t\t\t// 路径都要过越界校验:manifest 里写 `../` 不该能读到插件目录之外。\n\t\t\tavatar: profile.avatar ? validatePluginRelativePath(profile.avatar, \"agent.agents.avatar\") : undefined,\n\t\t\tsystemPromptPath: profile.systemPromptPath\n\t\t\t\t? validatePluginRelativePath(profile.systemPromptPath, \"agent.agents.systemPromptPath\")\n\t\t\t\t: undefined,\n\t\t})),\n\t\tteams: agent.teams?.map((team) => ({\n\t\t\t...team,\n\t\t\tworkflowPath: team.workflowPath\n\t\t\t\t? validatePluginRelativePath(team.workflowPath, \"agent.teams.workflowPath\")\n\t\t\t\t: undefined,\n\t\t})),\n\t};\n}\n\nfunction normalizeSkillPresentation(\n\tpresentation: PluginSkillPresentation | undefined,\n): PluginSkillPresentation | undefined {\n\tif (!presentation) return undefined;\n\tconst normalizeRule = (rule: PluginSkillPresentationRule): PluginSkillPresentationRule => ({\n\t\tdefaultVisibility: rule.defaultVisibility,\n\t\tsurfaces: rule.surfaces ? { ...rule.surfaces } : undefined,\n\t\tdisplayName: rule.displayName?.trim(),\n\t\tdisplayDescription: rule.displayDescription?.trim(),\n\t});\n\treturn {\n\t\tdefaultVisibility: presentation.defaultVisibility,\n\t\tsurfaces: presentation.surfaces ? { ...presentation.surfaces } : undefined,\n\t\tskills: presentation.skills\n\t\t\t? Object.fromEntries(\n\t\t\t\t\tObject.entries(presentation.skills).map(([name, rule]) => [name.trim(), normalizeRule(rule)]),\n\t\t\t\t)\n\t\t\t: undefined,\n\t};\n}\n\nfunction normalizeCliProviders(providers: PluginCliProviderManifest[] | undefined): PluginCliProviderManifest[] | undefined {\n\tif (!providers || providers.length === 0) return undefined;\n\tconst ids = new Set<string>();\n\treturn providers.map((provider) => {\n\t\tif (ids.has(provider.id)) throw new Error(`Duplicate CLI provider id: ${provider.id}`);\n\t\tids.add(provider.id);\n\t\treturn {\n\t\t\tid: provider.id,\n\t\t\tcommand: provider.command,\n\t\t\tprobe: provider.probe\n\t\t\t\t? { args: provider.probe.args ? [...provider.probe.args] : undefined, timeoutMs: provider.probe.timeoutMs }\n\t\t\t\t: undefined,\n\t\t\tinstall: {\n\t\t\t\tcommand: provider.install.command,\n\t\t\t\targs: provider.install.args ? [...provider.install.args] : undefined,\n\t\t\t\ttimeoutMs: provider.install.timeoutMs,\n\t\t\t},\n\t\t};\n\t});\n}\n\nfunction normalizeServiceProviders(\n\tproviders: PluginServiceProviderManifest[] | undefined,\n): PluginServiceProviderManifest[] | undefined {\n\tif (!providers || providers.length === 0) return undefined;\n\tconst ids = new Set<string>();\n\treturn providers.map((provider) => {\n\t\tif (ids.has(provider.id)) throw new Error(`Duplicate service provider id: ${provider.id}`);\n\t\tids.add(provider.id);\n\t\tconst runtimeKind: PluginServiceRuntimeKind = provider.runtime.kind ?? \"managed-binary\";\n\t\tconst entry = provider.runtime.entry\n\t\t\t? validatePluginRelativePath(provider.runtime.entry, `providers.services.${provider.id}.runtime.entry`)\n\t\t\t: undefined;\n\t\tif (runtimeKind === \"host-node\" && !entry) {\n\t\t\tthrow new Error(`Host-node service must declare runtime.entry: ${provider.id}`);\n\t\t}\n\t\tconst platforms: PluginServiceProviderManifest[\"runtime\"][\"platforms\"] = {};\n\t\tfor (const [platformTag, platform] of Object.entries(provider.runtime.platforms)) {\n\t\t\tconst destinations = new Set<string>();\n\t\t\tplatforms[platformTag] = {\n\t\t\t\texecutable: validatePluginRelativePath(platform.executable, `providers.services.${provider.id}.executable`),\n\t\t\t\tartifacts: platform.artifacts.map((artifact) => {\n\t\t\t\t\tconst destination = validatePluginRelativePath(\n\t\t\t\t\t\tartifact.destination,\n\t\t\t\t\t\t`providers.services.${provider.id}.artifacts.destination`,\n\t\t\t\t\t);\n\t\t\t\t\tif (destinations.has(destination)) {\n\t\t\t\t\t\tthrow new Error(`Duplicate service artifact destination: ${provider.id}/${platformTag}/${destination}`);\n\t\t\t\t\t}\n\t\t\t\t\tdestinations.add(destination);\n\t\t\t\t\treturn { ...artifact, destination };\n\t\t\t\t}),\n\t\t\t};\n\t\t}\n\t\tif (Object.keys(platforms).length === 0) {\n\t\t\tthrow new Error(`Service provider must declare at least one platform: ${provider.id}`);\n\t\t}\n\t\tconst credentialIds = new Set<string>();\n\t\tconst credentials = provider.credentials?.map((credential) => {\n\t\t\tif (credentialIds.has(credential.id)) throw new Error(`Duplicate service credential id: ${provider.id}/${credential.id}`);\n\t\t\tcredentialIds.add(credential.id);\n\t\t\treturn { id: credential.id, bytes: credential.bytes };\n\t\t});\n\t\tif (provider.health.credentialId && !credentialIds.has(provider.health.credentialId)) {\n\t\t\tthrow new Error(`Unknown service health credential: ${provider.id}/${provider.health.credentialId}`);\n\t\t}\n\t\tconst templateDestinations = new Set<string>();\n\t\tconst templates = provider.templates?.map((template) => {\n\t\t\tconst source = validatePluginRelativePath(template.source, `providers.services.${provider.id}.templates.source`);\n\t\t\tconst destination = validatePluginRelativePath(\n\t\t\t\ttemplate.destination,\n\t\t\t\t`providers.services.${provider.id}.templates.destination`,\n\t\t\t);\n\t\t\tif (templateDestinations.has(destination)) throw new Error(`Duplicate service template destination: ${provider.id}/${destination}`);\n\t\t\ttemplateDestinations.add(destination);\n\t\t\treturn { source, destination, mode: template.mode };\n\t\t});\n\t\tconst normalizedRuntime: PluginServiceProviderManifest[\"runtime\"] = {\n\t\t\tversion: provider.runtime.version,\n\t\t\tplatforms,\n\t\t\t...(runtimeKind === \"host-node\" ? { kind: runtimeKind, entry } : provider.runtime.kind ? { kind: runtimeKind } : {}),\n\t\t};\n\t\treturn {\n\t\t\tid: provider.id,\n\t\t\truntime: normalizedRuntime,\n\t\t\tcredentials,\n\t\t\ttemplates,\n\t\t\tprocess: {\n\t\t\t\targs: provider.process.args ? [...provider.process.args] : undefined,\n\t\t\t\tenv: provider.process.env ? { ...provider.process.env } : undefined,\n\t\t\t},\n\t\t\thealth: { ...provider.health },\n\t\t};\n\t});\n}\n\nfunction normalizePluginMcpServerConfig(config: PluginMcpServerConfig): PluginMcpServerConfig {\n\tconst common = {\n\t\tdisabled: config.disabled,\n\t\tautoApprove: config.autoApprove?.map(trimString),\n\t\tstartupTimeout: config.startupTimeout,\n\t\tdebug: config.debug,\n\t\tdisplayName: config.displayName,\n\t\tdescription: config.description,\n\t\tagent_mode: normalizeOptionalAgentModes(config.agent_mode),\n\t};\n\tif (config.type === \"service\") {\n\t\treturn {\n\t\t\ttype: \"service\",\n\t\t\tserviceId: trimString(config.serviceId),\n\t\t\tpath: trimString(config.path),\n\t\t\t...common,\n\t\t};\n\t}\n\tif (config.type === \"http\") {\n\t\treturn {\n\t\t\ttype: \"http\",\n\t\t\turl: trimString(config.url),\n\t\t\theaders: config.headers ? { ...config.headers } : undefined,\n\t\t\toauthClientId: config.oauthClientId,\n\t\t\toauthDeviceFlow: config.oauthDeviceFlow,\n\t\t\toauthScopes: config.oauthScopes,\n\t\t\t...common,\n\t\t};\n\t}\n\treturn {\n\t\ttype: config.type,\n\t\tcommand: trimString(config.command),\n\t\targs: config.args ? [...config.args] : undefined,\n\t\tenv: config.env ? { ...config.env } : undefined,\n\t\tcwd: config.cwd,\n\t\t...common,\n\t};\n}\n\nexport function validatePluginId(id: string): void {\n\tif (!Value.Check(PluginIdSchema, id)) {\n\t\tthrow new Error(\"Plugin id must be 1-64 chars: lowercase letters, numbers, dot, underscore, or dash\");\n\t}\n}\n\nexport function validatePluginVersion(version: string): void {\n\tif (!Value.Check(PluginVersionSchema, version)) {\n\t\tthrow new Error(\"Plugin version must be 1-64 chars and cannot contain path separators\");\n\t}\n}\n\nexport function validatePluginRelativePath(value: string, fieldName: string): string {\n\tif (value.startsWith(\"/\") || /^[a-zA-Z]:/.test(value)) {\n\t\tthrow new Error(`Invalid plugin ${fieldName}`);\n\t}\n\tconst parts: string[] = [];\n\tfor (const part of value.replace(/\\\\/g, \"/\").split(\"/\")) {\n\t\tif (part === \"\" || part === \".\") continue;\n\t\tif (part === \"..\") {\n\t\t\tif (parts.length === 0) throw new Error(`Invalid plugin ${fieldName}`);\n\t\t\tparts.pop();\n\t\t\tcontinue;\n\t\t}\n\t\tparts.push(part);\n\t}\n\tconst normalized = parts.join(\"/\");\n\tif (!normalized) throw new Error(`Invalid plugin ${fieldName}`);\n\treturn normalized;\n}\n\nexport function parsePluginCommandNames(value: unknown): string[] {\n\tif (value === undefined) return [];\n\tassertSchema(PluginCommandNamesSchema, value, \"commands\");\n\treturn Array.from(new Set(value));\n}\n\n/** @deprecated agent_mode 已无任何运行时语义(ADR-0071),保留仅为容忍既有 manifest。 */\nexport function normalizePluginAgentModes(value: unknown): string[] | undefined {\n\tif (value === undefined || value === null) return undefined;\n\tconst values = Array.isArray(value) ? value : [value];\n\tconst modes = values.map((item) => String(item).trim()).filter(Boolean);\n\treturn modes.length > 0 ? modes : undefined;\n}\n\nexport function parsePluginMcpServerConfig(name: string, raw: unknown): PluginMcpServerConfig {\n\tassertSchema(PluginMcpServerConfigSchema, raw, `MCP server '${name}'`);\n\treturn normalizePluginMcpServerConfig(raw);\n}\n\nexport function isPluginPassthroughIconRef(icon: string): boolean {\n\treturn (\n\t\ticon.startsWith(\"http://\") ||\n\t\ticon.startsWith(\"https://\") ||\n\t\t/^[a-z0-9]+(?:-[a-z0-9]+)*:[a-z0-9]+(?:-[a-z0-9]+)*$/.test(icon)\n\t);\n}\n\nexport function isPluginPackagedIconPath(icon: string): boolean {\n\treturn !isPluginPassthroughIconRef(icon);\n}\n\nexport function parsePluginManifest(raw: unknown): PluginManifest {\n\tif (typeof raw === \"object\" && raw !== null && \"runtime\" in raw) {\n\t\tthrow new Error(\n\t\t\t'Invalid plugin manifest.runtime: runtime selection is unsupported; plugins use Module Federation.',\n\t\t);\n\t}\n\tassertSchema(PluginManifestSchema, raw, \"manifest\");\n\tconst commands = parsePluginCommandNames(raw.commands);\n\tconst icon = raw.icon === undefined ? undefined : trimString(raw.icon);\n\tconst permissions = normalizePermissions(raw.permissions);\n\tconst network = normalizeNetworkManifest(raw.network);\n\tconst browser = normalizeBrowserManifest(raw.browser);\n\tif (permissions.includes(\"network.fetch\") && !network) {\n\t\tthrow new Error(\"Plugin network.allowedHosts is required with network.fetch\");\n\t}\n\tconst browserPermissions = permissions.filter((permission) => permission.startsWith(\"browser.\"));\n\tif (browserPermissions.length > 0 && !browser) {\n\t\tthrow new Error(\"Plugin browser.allowedHosts is required with browser permissions\");\n\t}\n\tif (permissions.includes(\"browser.interact\") && !permissions.includes(\"browser.read\")) {\n\t\tthrow new Error(\"Plugin browser.interact requires browser.read\");\n\t}\n\tconst normalizedServices = raw.providers ? normalizeServiceProviders(raw.providers.services) : undefined;\n\tfor (const [name, server] of Object.entries(raw.agent?.mcpServers && typeof raw.agent.mcpServers !== \"string\" ? raw.agent.mcpServers : {})) {\n\t\tif (server.type === \"service\" && !normalizedServices?.some((service) => service.id === server.serviceId)) {\n\t\t\tthrow new Error(`Plugin MCP server '${name}' references unknown service '${server.serviceId}'`);\n\t\t}\n\t}\n\treturn {\n\t\tid: raw.id,\n\t\tname: trimString(raw.name),\n\t\tversion: raw.version,\n\t\tpluginApiVersion: trimString(raw.pluginApiVersion),\n\t\tentry: validatePluginRelativePath(trimString(raw.entry), \"entry\"),\n\t\tmoduleFederation: normalizeModuleFederation(raw.moduleFederation),\n\t\tagent: normalizeAgentManifest(raw.agent),\n\t\tproviders: raw.providers\n\t\t\t? {\n\t\t\t\t\tcli: normalizeCliProviders(raw.providers.cli),\n\t\t\t\t\tservices: normalizedServices,\n\t\t\t\t}\n\t\t\t: undefined,\n\t\tstyles: normalizeStringArray(raw.styles).map((style) => validatePluginRelativePath(style, \"styles\")),\n\t\tpermissions,\n\t\tnetwork,\n\t\tbrowser,\n\t\tcommands: commands.length > 0 ? commands : undefined,\n\t\tdescription: raw.description,\n\t\tauthor: raw.author,\n\t\ticon:\n\t\t\ticon === undefined || isPluginPassthroughIconRef(icon)\n\t\t\t\t? icon\n\t\t\t\t: validatePluginRelativePath(icon, \"icon\"),\n\t\tguidingWords: raw.guidingWords?.map(trimString),\n\t\tdefaultLocale: raw.defaultLocale ?? \"zh\",\n\t\tcontributionMode: raw.contributionMode\n\t\t\t? { hardIsolation: raw.contributionMode.hardIsolation === true }\n\t\t\t: undefined,\n\t\tagent_mode: normalizePluginAgentModes(raw.agent_mode),\n\t};\n}\n\nexport function listPluginManifestResources(\n\tmanifest: PluginManifest,\n): PluginManifestResourceReference[] {\n\tconst resources: PluginManifestResourceReference[] = [\n\t\t{ field: \"entry\", path: manifest.entry, kind: \"file\" },\n\t];\n\tfor (const stylePath of manifest.styles ?? []) {\n\t\tresources.push({ field: \"styles\", path: stylePath, kind: \"file\" });\n\t}\n\tif (manifest.icon && isPluginPackagedIconPath(manifest.icon)) {\n\t\tresources.push({ field: \"icon\", path: manifest.icon, kind: \"file\" });\n\t}\n\tfor (const promptPath of manifest.agent?.systemPrompt?.promptPaths ?? []) {\n\t\tresources.push({ field: \"agent.systemPrompt.promptPaths\", path: promptPath, kind: \"file-or-directory\" });\n\t}\n\tfor (const skillPath of manifest.agent?.skillPaths ?? []) {\n\t\tresources.push({ field: \"agent.skillPaths\", path: skillPath, kind: \"file-or-directory\" });\n\t}\n\tfor (const agent of manifest.agent?.agents ?? []) {\n\t\t// 人设与头像是插件包里的真实文件:不登记就不会被打进包,装到用户机器上时这个\n\t\t// 智能体会因为「提示词读不出来」被整个跳过。\n\t\tif (agent.avatar) resources.push({ field: \"agent.agents.avatar\", path: agent.avatar, kind: \"file\" });\n\t\tif (agent.systemPromptPath) {\n\t\t\tresources.push({ field: \"agent.agents.systemPromptPath\", path: agent.systemPromptPath, kind: \"file\" });\n\t\t}\n\t}\n\tfor (const team of manifest.agent?.teams ?? []) {\n\t\tif (team.workflowPath) {\n\t\t\tresources.push({ field: \"agent.teams.workflowPath\", path: team.workflowPath, kind: \"file\" });\n\t\t}\n\t}\n\tif (typeof manifest.agent?.mcpServers === \"string\") {\n\t\tresources.push({ field: \"agent.mcpServers\", path: manifest.agent.mcpServers, kind: \"file\" });\n\t}\n\tfor (const service of manifest.providers?.services ?? []) {\n\t\tfor (const template of service.templates ?? []) {\n\t\t\tresources.push({ field: `providers.services.${service.id}.templates.source`, path: template.source, kind: \"file\" });\n\t\t}\n\t}\n\treturn resources;\n}\n\nfunction parseApiVersion(value: string): readonly [number, number, number] | undefined {\n\tconst match = /^(\\d+)\\.(\\d+)\\.(\\d+)$/.exec(value);\n\tif (!match) return undefined;\n\treturn [Number(match[1]), Number(match[2]), Number(match[3])];\n}\n\nfunction compareApiVersions(\n\tleft: readonly [number, number, number],\n\tright: readonly [number, number, number],\n): number {\n\tfor (let index = 0; index < left.length; index += 1) {\n\t\tif (left[index] !== right[index]) return left[index] - right[index];\n\t}\n\treturn 0;\n}\n\nexport function isPluginApiCompatible(hostVersion: string, range: string): boolean {\n\tconst host = parseApiVersion(hostVersion);\n\tif (!host) return false;\n\tconst normalized = range.trim();\n\tconst exact = parseApiVersion(normalized);\n\tif (exact) return exact[0] === host[0] && compareApiVersions(host, exact) >= 0;\n\tconst caret = normalized.startsWith(\"^\") ? parseApiVersion(normalized.slice(1)) : undefined;\n\tif (caret) return caret[0] === host[0] && compareApiVersions(host, caret) >= 0;\n\tif (normalized === `^${host[0]}` || normalized === `${host[0]}.x`) return true;\n\tconst minimum = normalized.startsWith(\">=\") ? parseApiVersion(normalized.slice(2)) : undefined;\n\treturn minimum !== undefined && compareApiVersions(host, minimum) >= 0;\n}\n"]}
|