@get-bb/plugin-sdk 0.4.88 → 0.4.97
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/bundled-types/bb-plugin-sdk-app.d.ts +94 -33
- package/bundled-types/bb-plugin-sdk-host.d.ts +9 -0
- package/bundled-types/bb-plugin-sdk-internal-host-policy.d.ts +66 -2
- package/bundled-types/bb-plugin-sdk-internal-plugin-app-collector.d.ts +16 -3
- package/bundled-types/bb-plugin-sdk-machine-provider.d.ts +2 -0
- package/bundled-types/bb-plugin-sdk-provider-bridge-testing.d.ts +8 -0
- package/bundled-types/bb-plugin-sdk-provider-bridge.d.ts +10 -0
- package/bundled-types/bb-plugin-sdk-testing-app.d.ts +3 -4
- package/bundled-types/bb-plugin-sdk-testing.d.ts +42 -6
- package/bundled-types/bb-plugin-sdk.d.ts +222 -44
- package/dist/internal/host-policy.js +175 -91
- package/dist/internal/plugin-app-collector.js +13834 -22
- package/dist/provider-bridge-acp.js +2207 -1578
- package/dist/provider-bridge-testing.js +1232 -1224
- package/dist/provider-bridge.js +1821 -1305
- package/dist/testing/app.js +13987 -175
- package/dist/testing/index.js +182 -93
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/internal/host-policy.ts
|
|
2
2
|
import { createHash } from "node:crypto";
|
|
3
|
-
import { z as
|
|
3
|
+
import { z as z5 } from "zod";
|
|
4
4
|
|
|
5
5
|
// ../domain/src/plugin-icon.ts
|
|
6
6
|
function isPluginOwnedIconPath(icon) {
|
|
@@ -54,6 +54,12 @@ import { z } from "zod";
|
|
|
54
54
|
var PROVIDER_FORK_VALUES = ["none", "tip", "checkpoint"];
|
|
55
55
|
var providerForkSchema = z.enum(PROVIDER_FORK_VALUES);
|
|
56
56
|
|
|
57
|
+
// ../domain/src/completed-turn-display.ts
|
|
58
|
+
import { z as z2 } from "zod";
|
|
59
|
+
var COMPLETED_TURN_DISPLAY_VALUES = ["collapse", "flat"];
|
|
60
|
+
var completedTurnDisplaySchema = z2.enum(COMPLETED_TURN_DISPLAY_VALUES);
|
|
61
|
+
var DEFAULT_COMPLETED_TURN_DISPLAY = "collapse";
|
|
62
|
+
|
|
57
63
|
// ../domain/src/provider-skill-roots.ts
|
|
58
64
|
function isAbsoluteProviderSkillRootPath(value) {
|
|
59
65
|
if (value.length === 0) {
|
|
@@ -76,53 +82,53 @@ function isRelativeProviderSkillRootPath(value) {
|
|
|
76
82
|
}
|
|
77
83
|
|
|
78
84
|
// ../domain/src/json-value.ts
|
|
79
|
-
import { z as
|
|
80
|
-
var jsonValueSchema =
|
|
81
|
-
() =>
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
import { z as z3 } from "zod";
|
|
86
|
+
var jsonValueSchema = z3.lazy(
|
|
87
|
+
() => z3.union([
|
|
88
|
+
z3.string(),
|
|
89
|
+
z3.number(),
|
|
90
|
+
z3.boolean(),
|
|
91
|
+
z3.null(),
|
|
92
|
+
z3.array(jsonValueSchema),
|
|
93
|
+
z3.record(z3.string(), jsonValueSchema)
|
|
88
94
|
])
|
|
89
95
|
);
|
|
90
|
-
var jsonObjectSchema =
|
|
91
|
-
|
|
96
|
+
var jsonObjectSchema = z3.record(
|
|
97
|
+
z3.string(),
|
|
92
98
|
jsonValueSchema
|
|
93
99
|
);
|
|
94
100
|
|
|
95
101
|
// ../domain/src/native-roots.ts
|
|
96
|
-
import { z as
|
|
102
|
+
import { z as z4 } from "zod";
|
|
97
103
|
var PROVIDER_NATIVE_ROOTS_MAX = 32;
|
|
98
104
|
var PROVIDER_NATIVE_ROOT_NAME_PREFIX_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,62}:$/u;
|
|
99
|
-
var nativeRootNamePrefixSchema =
|
|
105
|
+
var nativeRootNamePrefixSchema = z4.string().refine(
|
|
100
106
|
(value) => value === "" || PROVIDER_NATIVE_ROOT_NAME_PREFIX_PATTERN.test(value),
|
|
101
107
|
"A root name prefix is a plugin-name-like token ending in ':'"
|
|
102
108
|
);
|
|
103
|
-
var nativeRootManifestPathSchema =
|
|
109
|
+
var nativeRootManifestPathSchema = z4.string().min(1).refine(
|
|
104
110
|
isRelativeProviderSkillRootPath,
|
|
105
111
|
"A manifest marker is a relative path without dot segments"
|
|
106
112
|
);
|
|
107
|
-
var relativeNativeRootPathSchema =
|
|
113
|
+
var relativeNativeRootPathSchema = z4.string().min(1).refine(
|
|
108
114
|
isRelativeProviderSkillRootPath,
|
|
109
115
|
"Roots must be relative paths without dot segments"
|
|
110
116
|
);
|
|
111
|
-
var absoluteNativeRootPathSchema =
|
|
117
|
+
var absoluteNativeRootPathSchema = z4.string().min(1).refine(
|
|
112
118
|
isAbsoluteProviderSkillRootPath,
|
|
113
119
|
"Absolute roots must be absolute paths without dot segments"
|
|
114
120
|
);
|
|
115
|
-
var providerNativeRootInputSchema =
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
path:
|
|
121
|
+
var providerNativeRootInputSchema = z4.union([
|
|
122
|
+
z4.string().min(1),
|
|
123
|
+
z4.object({
|
|
124
|
+
path: z4.string().min(1),
|
|
119
125
|
/** Skills nest in subdirectories (the agent scans recursively). */
|
|
120
|
-
recursive:
|
|
126
|
+
recursive: z4.boolean().optional(),
|
|
121
127
|
/**
|
|
122
128
|
* Scan the same relative directory in every ancestor of the workspace
|
|
123
129
|
* up to the repository root (`project` roots only).
|
|
124
130
|
*/
|
|
125
|
-
ancestors:
|
|
131
|
+
ancestors: z4.boolean().optional(),
|
|
126
132
|
/**
|
|
127
133
|
* Prepended to every name under the root, a vendor plugin's
|
|
128
134
|
* `plugin-name:`; a prefixed root is listed as a plugin root.
|
|
@@ -137,14 +143,14 @@ var providerNativeRootInputSchema = z3.union([
|
|
|
137
143
|
skipIfManifest: nativeRootManifestPathSchema.optional()
|
|
138
144
|
}).strict()
|
|
139
145
|
]);
|
|
140
|
-
var providerNativeRootsInputSchema =
|
|
141
|
-
user:
|
|
142
|
-
project:
|
|
146
|
+
var providerNativeRootsInputSchema = z4.object({
|
|
147
|
+
user: z4.array(providerNativeRootInputSchema).optional(),
|
|
148
|
+
project: z4.array(providerNativeRootInputSchema).optional()
|
|
143
149
|
}).strict();
|
|
144
|
-
var providerNativeRootSchema =
|
|
145
|
-
path:
|
|
146
|
-
recursive:
|
|
147
|
-
ancestors:
|
|
150
|
+
var providerNativeRootSchema = z4.object({
|
|
151
|
+
path: z4.string().min(1),
|
|
152
|
+
recursive: z4.boolean(),
|
|
153
|
+
ancestors: z4.boolean(),
|
|
148
154
|
namePrefix: nativeRootNamePrefixSchema,
|
|
149
155
|
/** Absent: every skill-shaped directory under the root is a skill. */
|
|
150
156
|
skipIfManifest: nativeRootManifestPathSchema.optional()
|
|
@@ -153,7 +159,7 @@ function uniqueByPath(roots) {
|
|
|
153
159
|
return new Set(roots.map((root) => root.path)).size === roots.length;
|
|
154
160
|
}
|
|
155
161
|
function nativeRootSideSchema(side) {
|
|
156
|
-
return
|
|
162
|
+
return z4.array(
|
|
157
163
|
providerNativeRootSchema.extend({ path: relativeNativeRootPathSchema }).superRefine((root, context) => {
|
|
158
164
|
if (root.ancestors && side !== "project") {
|
|
159
165
|
context.addIssue({
|
|
@@ -164,7 +170,7 @@ function nativeRootSideSchema(side) {
|
|
|
164
170
|
})
|
|
165
171
|
).max(PROVIDER_NATIVE_ROOTS_MAX).refine(uniqueByPath, "Roots must not repeat a path");
|
|
166
172
|
}
|
|
167
|
-
var providerNativeRootsSchema =
|
|
173
|
+
var providerNativeRootsSchema = z4.object({
|
|
168
174
|
user: nativeRootSideSchema("user"),
|
|
169
175
|
project: nativeRootSideSchema("project")
|
|
170
176
|
}).strict();
|
|
@@ -190,19 +196,19 @@ function normalizeProviderNativeRoots(roots) {
|
|
|
190
196
|
project: (roots?.project ?? []).map(normalizeProviderNativeRoot)
|
|
191
197
|
};
|
|
192
198
|
}
|
|
193
|
-
var providerResolvedNativeRootShapeSchema =
|
|
199
|
+
var providerResolvedNativeRootShapeSchema = z4.enum([
|
|
194
200
|
"skills",
|
|
195
201
|
"skill",
|
|
196
202
|
"skill-file",
|
|
197
203
|
"commands",
|
|
198
204
|
"command-file"
|
|
199
205
|
]);
|
|
200
|
-
var resolvedNativeRootFieldsSchema =
|
|
206
|
+
var resolvedNativeRootFieldsSchema = z4.object({
|
|
201
207
|
path: absoluteNativeRootPathSchema,
|
|
202
|
-
origin:
|
|
203
|
-
recursive:
|
|
208
|
+
origin: z4.enum(["user", "project"]),
|
|
209
|
+
recursive: z4.boolean(),
|
|
204
210
|
/** Only with origin `project`, for a path inside the workspace. */
|
|
205
|
-
ancestors:
|
|
211
|
+
ancestors: z4.boolean(),
|
|
206
212
|
namePrefix: nativeRootNamePrefixSchema,
|
|
207
213
|
shape: providerResolvedNativeRootShapeSchema,
|
|
208
214
|
/**
|
|
@@ -210,7 +216,7 @@ var resolvedNativeRootFieldsSchema = z3.object({
|
|
|
210
216
|
* none. A vendor plugin's root SKILL.md takes the plugin's name; absent
|
|
211
217
|
* means the parent directory's name.
|
|
212
218
|
*/
|
|
213
|
-
fallbackName:
|
|
219
|
+
fallbackName: z4.string().min(1).optional(),
|
|
214
220
|
/**
|
|
215
221
|
* `skills` only: a file, relative to a skill directory under this root,
|
|
216
222
|
* that marks the directory as a vendor plugin rather than a skill; the
|
|
@@ -254,14 +260,14 @@ var resolvedCommandShapes = /* @__PURE__ */ new Set([
|
|
|
254
260
|
"command-file"
|
|
255
261
|
]);
|
|
256
262
|
var PROVIDER_RESOLVED_NATIVE_ROOTS_MAX = 256;
|
|
257
|
-
var providerResolvedNativeRootsSchema =
|
|
258
|
-
skills:
|
|
263
|
+
var providerResolvedNativeRootsSchema = z4.object({
|
|
264
|
+
skills: z4.array(
|
|
259
265
|
providerResolvedNativeRootSchema.refine(
|
|
260
266
|
(root) => resolvedSkillShapes.has(root.shape),
|
|
261
267
|
"A skills root needs a skill shape"
|
|
262
268
|
)
|
|
263
269
|
).max(PROVIDER_RESOLVED_NATIVE_ROOTS_MAX),
|
|
264
|
-
commands:
|
|
270
|
+
commands: z4.array(
|
|
265
271
|
providerResolvedNativeRootSchema.refine(
|
|
266
272
|
(root) => resolvedCommandShapes.has(root.shape),
|
|
267
273
|
"A commands root needs a command shape"
|
|
@@ -272,7 +278,7 @@ var EMPTY_PROVIDER_RESOLVED_NATIVE_ROOTS = Object.freeze({
|
|
|
272
278
|
skills: Object.freeze([]),
|
|
273
279
|
commands: Object.freeze([])
|
|
274
280
|
});
|
|
275
|
-
var providerNativeRootSetSchema =
|
|
281
|
+
var providerNativeRootSetSchema = z4.object({
|
|
276
282
|
skills: providerNativeRootsSchema,
|
|
277
283
|
commands: providerNativeRootsSchema,
|
|
278
284
|
resolved: providerResolvedNativeRootsSchema
|
|
@@ -305,15 +311,15 @@ var CLI_COMMAND_NAME_PATTERN = /^[a-z0-9-]+$/;
|
|
|
305
311
|
var AGENT_TOOL_NAME_PATTERN = /^[a-zA-Z0-9_-]+$/;
|
|
306
312
|
var PLUGIN_PROVIDER_ENV_NAME_PATTERN = /^[A-Z_][A-Z0-9_]*$/;
|
|
307
313
|
var PLUGIN_PROVIDER_ENV_MAX_ENTRIES = 32;
|
|
308
|
-
var pluginProviderEnvEntrySchema =
|
|
309
|
-
name:
|
|
310
|
-
value:
|
|
311
|
-
|
|
312
|
-
|
|
314
|
+
var pluginProviderEnvEntrySchema = z5.object({
|
|
315
|
+
name: z5.string().regex(PLUGIN_PROVIDER_ENV_NAME_PATTERN),
|
|
316
|
+
value: z5.union([
|
|
317
|
+
z5.string(),
|
|
318
|
+
z5.object({ serverPath: z5.string().startsWith("/") }).strict()
|
|
313
319
|
]),
|
|
314
|
-
reason:
|
|
320
|
+
reason: z5.string()
|
|
315
321
|
}).strict();
|
|
316
|
-
var pluginProviderEnvEntriesSchema =
|
|
322
|
+
var pluginProviderEnvEntriesSchema = z5.array(pluginProviderEnvEntrySchema).max(PLUGIN_PROVIDER_ENV_MAX_ENTRIES).superRefine((entries, context) => {
|
|
317
323
|
const names = /* @__PURE__ */ new Set();
|
|
318
324
|
for (let index = 0; index < entries.length; index += 1) {
|
|
319
325
|
const name = entries[index]?.name;
|
|
@@ -348,26 +354,26 @@ var PROVIDER_ID_PATTERN = /^[a-z0-9][a-z0-9-]{1,63}$/;
|
|
|
348
354
|
var PLUGIN_PROVIDER_BRIDGE_OPTIONS_MAX_BYTES = 64 * 1024;
|
|
349
355
|
var SETTING_KEY_PATTERN = /^[a-zA-Z0-9_-]+$/;
|
|
350
356
|
var settingsBaseFields = {
|
|
351
|
-
label:
|
|
352
|
-
description:
|
|
357
|
+
label: z5.string().min(1),
|
|
358
|
+
description: z5.string().min(1).optional()
|
|
353
359
|
};
|
|
354
|
-
var stringSettingSchemaSchema =
|
|
360
|
+
var stringSettingSchemaSchema = z5.custom(
|
|
355
361
|
(value) => isStandardSchema(value)
|
|
356
362
|
);
|
|
357
|
-
var booleanSettingSchemaSchema =
|
|
363
|
+
var booleanSettingSchemaSchema = z5.custom(
|
|
358
364
|
(value) => isStandardSchema(value)
|
|
359
365
|
);
|
|
360
|
-
var numberSettingSchemaSchema =
|
|
366
|
+
var numberSettingSchemaSchema = z5.custom(
|
|
361
367
|
(value) => isStandardSchema(value)
|
|
362
368
|
);
|
|
363
|
-
var settingDescriptorSchema =
|
|
364
|
-
|
|
365
|
-
type:
|
|
369
|
+
var settingDescriptorSchema = z5.discriminatedUnion("type", [
|
|
370
|
+
z5.object({
|
|
371
|
+
type: z5.literal("string"),
|
|
366
372
|
...settingsBaseFields,
|
|
367
|
-
secret:
|
|
368
|
-
experimental_multiline:
|
|
373
|
+
secret: z5.literal(true).optional(),
|
|
374
|
+
experimental_multiline: z5.boolean().optional(),
|
|
369
375
|
experimental_schema: stringSettingSchemaSchema.optional(),
|
|
370
|
-
default:
|
|
376
|
+
default: z5.string().optional()
|
|
371
377
|
}).strict().refine(
|
|
372
378
|
(descriptor) => !(descriptor.secret === true && descriptor.experimental_multiline === true),
|
|
373
379
|
{
|
|
@@ -375,30 +381,30 @@ var settingDescriptorSchema = z4.discriminatedUnion("type", [
|
|
|
375
381
|
path: ["experimental_multiline"]
|
|
376
382
|
}
|
|
377
383
|
),
|
|
378
|
-
|
|
379
|
-
type:
|
|
384
|
+
z5.object({
|
|
385
|
+
type: z5.literal("boolean"),
|
|
380
386
|
...settingsBaseFields,
|
|
381
387
|
experimental_schema: booleanSettingSchemaSchema.optional(),
|
|
382
|
-
default:
|
|
388
|
+
default: z5.boolean().optional()
|
|
383
389
|
}).strict(),
|
|
384
|
-
|
|
385
|
-
type:
|
|
390
|
+
z5.object({
|
|
391
|
+
type: z5.literal("number"),
|
|
386
392
|
...settingsBaseFields,
|
|
387
393
|
experimental_schema: numberSettingSchemaSchema.optional(),
|
|
388
|
-
default:
|
|
394
|
+
default: z5.number().finite().optional()
|
|
389
395
|
}).strict(),
|
|
390
|
-
|
|
391
|
-
type:
|
|
396
|
+
z5.object({
|
|
397
|
+
type: z5.literal("select"),
|
|
392
398
|
...settingsBaseFields,
|
|
393
|
-
options:
|
|
399
|
+
options: z5.array(z5.string().min(1)).min(1),
|
|
394
400
|
experimental_schema: stringSettingSchemaSchema.optional(),
|
|
395
|
-
default:
|
|
401
|
+
default: z5.string().optional()
|
|
396
402
|
}).strict(),
|
|
397
|
-
|
|
398
|
-
type:
|
|
403
|
+
z5.object({
|
|
404
|
+
type: z5.literal("project"),
|
|
399
405
|
...settingsBaseFields,
|
|
400
406
|
experimental_schema: stringSettingSchemaSchema.optional(),
|
|
401
|
-
default:
|
|
407
|
+
default: z5.string().optional()
|
|
402
408
|
}).strict()
|
|
403
409
|
]);
|
|
404
410
|
function registerSettingDescriptors(target, added) {
|
|
@@ -946,6 +952,18 @@ function validateProviderModelCatalogScope(providerId, value) {
|
|
|
946
952
|
}
|
|
947
953
|
return value;
|
|
948
954
|
}
|
|
955
|
+
var PROVIDER_COMPLETED_TURN_DISPLAYS = COMPLETED_TURN_DISPLAY_VALUES;
|
|
956
|
+
function validateProviderCompletedTurnDisplay(providerId, value) {
|
|
957
|
+
if (value === void 0) {
|
|
958
|
+
return DEFAULT_COMPLETED_TURN_DISPLAY;
|
|
959
|
+
}
|
|
960
|
+
if (typeof value !== "string" || !PROVIDER_COMPLETED_TURN_DISPLAYS.includes(value)) {
|
|
961
|
+
throw new Error(
|
|
962
|
+
`provider "${providerId}" completedTurnDisplay must be one of ${PROVIDER_COMPLETED_TURN_DISPLAYS.join(", ")}`
|
|
963
|
+
);
|
|
964
|
+
}
|
|
965
|
+
return value;
|
|
966
|
+
}
|
|
949
967
|
function validateProviderFallbackModels(providerId, value) {
|
|
950
968
|
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
951
969
|
throw new Error(`provider "${providerId}" models must be an object`);
|
|
@@ -1326,6 +1344,10 @@ function validatePluginProviderDeclaration(declaration) {
|
|
|
1326
1344
|
allowed: PLUGIN_PROVIDER_COMPOSER_ACTION_VALUES,
|
|
1327
1345
|
requireNonEmpty: false
|
|
1328
1346
|
});
|
|
1347
|
+
const completedTurnDisplay = validateProviderCompletedTurnDisplay(
|
|
1348
|
+
id,
|
|
1349
|
+
declaration.completedTurnDisplay
|
|
1350
|
+
);
|
|
1329
1351
|
const bridgeOptions = declaration.experimental_bridgeOptions === void 0 ? void 0 : normalizeProviderBridgeOptions(
|
|
1330
1352
|
id,
|
|
1331
1353
|
declaration.experimental_bridgeOptions
|
|
@@ -1391,6 +1413,7 @@ function validatePluginProviderDeclaration(declaration) {
|
|
|
1391
1413
|
maintenance: normalizedMaintenance,
|
|
1392
1414
|
capabilities: normalizedCapabilities,
|
|
1393
1415
|
composerActions,
|
|
1416
|
+
completedTurnDisplay,
|
|
1394
1417
|
...strings === void 0 ? {} : { strings },
|
|
1395
1418
|
...serviceTiers === void 0 ? {} : { serviceTiers },
|
|
1396
1419
|
...reasoningLevels === void 0 ? {} : { reasoningLevels },
|
|
@@ -1421,6 +1444,11 @@ function isStandardSchema(value) {
|
|
|
1421
1444
|
const standard = Reflect.get(value, "~standard");
|
|
1422
1445
|
return typeof standard === "object" && standard !== null && Reflect.get(standard, "version") === 1 && typeof Reflect.get(standard, "vendor") === "string" && typeof Reflect.get(standard, "validate") === "function";
|
|
1423
1446
|
}
|
|
1447
|
+
var rpcDescriptionSchema = z5.string().trim().min(1).max(4096).optional().transform((value) => value ?? null);
|
|
1448
|
+
var rpcPublicationOptionsSchema = z5.object({
|
|
1449
|
+
experimental_discoverable: z5.boolean().default(false),
|
|
1450
|
+
experimental_description: rpcDescriptionSchema
|
|
1451
|
+
}).strict();
|
|
1424
1452
|
function readRpcMethodContract(method, value) {
|
|
1425
1453
|
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
1426
1454
|
throw new Error(
|
|
@@ -1439,7 +1467,59 @@ function readRpcMethodContract(method, value) {
|
|
|
1439
1467
|
`rpc method "${method}" output must be a Standard Schema v1 validator`
|
|
1440
1468
|
);
|
|
1441
1469
|
}
|
|
1442
|
-
|
|
1470
|
+
const description = rpcDescriptionSchema.parse(
|
|
1471
|
+
Reflect.get(value, "experimental_description")
|
|
1472
|
+
);
|
|
1473
|
+
return description === null ? { input, output } : { input, output, experimental_description: description };
|
|
1474
|
+
}
|
|
1475
|
+
function readRpcPublicationOptions(value) {
|
|
1476
|
+
return rpcPublicationOptionsSchema.parse(value ?? {});
|
|
1477
|
+
}
|
|
1478
|
+
function publishedRpcSchema(schema, direction) {
|
|
1479
|
+
const converter = schema["~standard"].jsonSchema;
|
|
1480
|
+
if (converter === void 0 || typeof converter[direction] !== "function") {
|
|
1481
|
+
throw new Error(
|
|
1482
|
+
"discoverable RPC requires Standard JSON Schema export support"
|
|
1483
|
+
);
|
|
1484
|
+
}
|
|
1485
|
+
const serialized = JSON.stringify(
|
|
1486
|
+
converter[direction]({ target: "draft-2020-12" })
|
|
1487
|
+
);
|
|
1488
|
+
if (serialized === void 0 || new TextEncoder().encode(serialized).byteLength > 128 * 1024) {
|
|
1489
|
+
throw new Error("published RPC schema must be JSON and at most 128 KiB");
|
|
1490
|
+
}
|
|
1491
|
+
const result = z5.record(z5.string(), jsonValueSchema).parse(JSON.parse(serialized));
|
|
1492
|
+
const inspect = (value) => {
|
|
1493
|
+
if (value === null || typeof value !== "object") return;
|
|
1494
|
+
if (Array.isArray(value)) {
|
|
1495
|
+
for (const item of value) inspect(item);
|
|
1496
|
+
return;
|
|
1497
|
+
}
|
|
1498
|
+
for (const [key, item] of Object.entries(value)) {
|
|
1499
|
+
if ((key === "$ref" || key === "$dynamicRef") && typeof item === "string" && !item.startsWith("#")) {
|
|
1500
|
+
throw new Error("published RPC schemas must use local references");
|
|
1501
|
+
}
|
|
1502
|
+
inspect(item);
|
|
1503
|
+
}
|
|
1504
|
+
};
|
|
1505
|
+
inspect(result);
|
|
1506
|
+
return result;
|
|
1507
|
+
}
|
|
1508
|
+
function publishRpcMethod(method, contract, options) {
|
|
1509
|
+
if (!options.experimental_discoverable) return null;
|
|
1510
|
+
try {
|
|
1511
|
+
return {
|
|
1512
|
+
method,
|
|
1513
|
+
registrationDescription: options.experimental_description,
|
|
1514
|
+
methodDescription: contract.experimental_description ?? null,
|
|
1515
|
+
inputSchema: publishedRpcSchema(contract.input, "input"),
|
|
1516
|
+
outputSchema: publishedRpcSchema(contract.output, "output")
|
|
1517
|
+
};
|
|
1518
|
+
} catch (error) {
|
|
1519
|
+
throw new Error(
|
|
1520
|
+
`rpc method "${method}" cannot be published: ${error instanceof Error ? error.message : String(error)}`
|
|
1521
|
+
);
|
|
1522
|
+
}
|
|
1443
1523
|
}
|
|
1444
1524
|
function isZodSchemaLike(value) {
|
|
1445
1525
|
return typeof value === "object" && value !== null && typeof value.safeParse === "function";
|
|
@@ -1458,7 +1538,7 @@ function zodSchemaToJsonSchema(schema) {
|
|
|
1458
1538
|
if (typeof schema.toJSONSchema === "function") {
|
|
1459
1539
|
return schema.toJSONSchema({ io: "input" });
|
|
1460
1540
|
}
|
|
1461
|
-
return
|
|
1541
|
+
return z5.toJSONSchema(schema, { io: "input" });
|
|
1462
1542
|
}
|
|
1463
1543
|
var SINGLE_SCHEMA_KEYWORDS = [
|
|
1464
1544
|
"additionalItems",
|
|
@@ -1803,15 +1883,15 @@ var ENVIRONMENT_PROVIDER_REQUIREMENT_NAMES = [
|
|
|
1803
1883
|
"gitRemote",
|
|
1804
1884
|
"projectless"
|
|
1805
1885
|
];
|
|
1806
|
-
var environmentCompositionSchema =
|
|
1807
|
-
id:
|
|
1808
|
-
displayName:
|
|
1809
|
-
description:
|
|
1810
|
-
icon:
|
|
1886
|
+
var environmentCompositionSchema = z5.object({
|
|
1887
|
+
id: z5.string().regex(ENVIRONMENT_PROVIDER_ID_PATTERN),
|
|
1888
|
+
displayName: z5.string().trim().min(1).max(ENVIRONMENT_PROVIDER_DISPLAY_NAME_MAX_CHARS),
|
|
1889
|
+
description: z5.string().trim().min(1).max(ENVIRONMENT_PROVIDER_DESCRIPTION_MAX_CHARS).optional().transform((value) => value ?? null),
|
|
1890
|
+
icon: z5.string().trim().min(1).transform(
|
|
1811
1891
|
(icon) => isPluginOwnedIconPath(icon) ? validateProviderRelativePath(icon, "Composition icon") : icon
|
|
1812
1892
|
).optional().transform((value) => value ?? null),
|
|
1813
|
-
machineProviderId:
|
|
1814
|
-
environmentProviderId:
|
|
1893
|
+
machineProviderId: z5.string().regex(ENVIRONMENT_PROVIDER_ID_PATTERN),
|
|
1894
|
+
environmentProviderId: z5.string().regex(ENVIRONMENT_PROVIDER_ID_PATTERN)
|
|
1815
1895
|
}).strict();
|
|
1816
1896
|
function requireProviderIdAndDisplayName(noun, declaration) {
|
|
1817
1897
|
if (typeof declaration !== "object" || declaration === null) {
|
|
@@ -1877,8 +1957,8 @@ function validatePluginEnvironmentProviderDeclaration(declaration) {
|
|
|
1877
1957
|
"environment provider",
|
|
1878
1958
|
declaration
|
|
1879
1959
|
);
|
|
1880
|
-
const description =
|
|
1881
|
-
const icon =
|
|
1960
|
+
const description = z5.string().trim().min(1).max(ENVIRONMENT_PROVIDER_DESCRIPTION_MAX_CHARS).optional().transform((value) => value ?? null).parse(declaration.description);
|
|
1961
|
+
const icon = z5.string().trim().min(1).optional().transform((value) => value ?? null).parse(declaration.icon);
|
|
1882
1962
|
if (icon !== null) {
|
|
1883
1963
|
assertProviderIconShape("environment provider", id, icon);
|
|
1884
1964
|
}
|
|
@@ -1947,9 +2027,9 @@ function normalizeEnvironmentProviderRequirements(id, declaration) {
|
|
|
1947
2027
|
}
|
|
1948
2028
|
return normalized;
|
|
1949
2029
|
}
|
|
1950
|
-
var environmentProviderPolicySchema =
|
|
1951
|
-
retireGraceMs:
|
|
1952
|
-
pathKeys:
|
|
2030
|
+
var environmentProviderPolicySchema = z5.object({
|
|
2031
|
+
retireGraceMs: z5.number().int().nonnegative().nullable().default(3e5),
|
|
2032
|
+
pathKeys: z5.enum(["per-thread", "per-attempt"]).default("per-thread")
|
|
1953
2033
|
}).strict();
|
|
1954
2034
|
var MACHINE_PROVIDER_DESCRIPTION_MAX_CHARS = 200;
|
|
1955
2035
|
function validatePluginMachineProviderDeclaration(declaration) {
|
|
@@ -1957,10 +2037,10 @@ function validatePluginMachineProviderDeclaration(declaration) {
|
|
|
1957
2037
|
"machine provider",
|
|
1958
2038
|
declaration
|
|
1959
2039
|
);
|
|
1960
|
-
const description =
|
|
1961
|
-
const icon =
|
|
2040
|
+
const description = z5.string().trim().min(1).max(MACHINE_PROVIDER_DESCRIPTION_MAX_CHARS).parse(declaration.description);
|
|
2041
|
+
const icon = z5.string().trim().min(1).parse(declaration.icon);
|
|
1962
2042
|
assertProviderIconShape("machine provider", id, icon);
|
|
1963
|
-
const ephemeral =
|
|
2043
|
+
const ephemeral = z5.boolean().default(false).parse(declaration.ephemeral);
|
|
1964
2044
|
const inputs = normalizeProviderInputs(
|
|
1965
2045
|
"machine provider",
|
|
1966
2046
|
id,
|
|
@@ -2115,13 +2195,14 @@ function normalizeWebSocketRouteRegistration(path, handler, opts, existingRoutes
|
|
|
2115
2195
|
}
|
|
2116
2196
|
return { path, auth };
|
|
2117
2197
|
}
|
|
2118
|
-
function normalizeRpcRegistration(contract, handlers, registered) {
|
|
2198
|
+
function normalizeRpcRegistration(contract, handlers, registered, options) {
|
|
2119
2199
|
if (typeof contract !== "object" || contract === null || Array.isArray(contract)) {
|
|
2120
2200
|
throw new Error("rpc.register contract must be an object");
|
|
2121
2201
|
}
|
|
2122
2202
|
if (typeof handlers !== "object" || handlers === null || Array.isArray(handlers)) {
|
|
2123
2203
|
throw new Error("rpc.register handlers must be an object");
|
|
2124
2204
|
}
|
|
2205
|
+
const publicationOptions = readRpcPublicationOptions(options);
|
|
2125
2206
|
const pending = [];
|
|
2126
2207
|
const contractEntries = Object.entries(contract);
|
|
2127
2208
|
const contractNames = new Set(contractEntries.map(([name]) => name));
|
|
@@ -2149,6 +2230,7 @@ function normalizeRpcRegistration(contract, handlers, registered) {
|
|
|
2149
2230
|
pending.push([
|
|
2150
2231
|
name,
|
|
2151
2232
|
{
|
|
2233
|
+
publication: publishRpcMethod(name, methodContract, publicationOptions),
|
|
2152
2234
|
inputSchema: methodContract.input,
|
|
2153
2235
|
outputSchema: methodContract.output,
|
|
2154
2236
|
handler
|
|
@@ -2730,6 +2812,8 @@ export {
|
|
|
2730
2812
|
providerAlreadyRegisteredMessage,
|
|
2731
2813
|
providerIconRefusalMessage,
|
|
2732
2814
|
providerWithoutBridgeMessage,
|
|
2815
|
+
publishRpcMethod,
|
|
2816
|
+
readRpcPublicationOptions,
|
|
2733
2817
|
registerSettingDescriptors,
|
|
2734
2818
|
runPluginStorageMigrations,
|
|
2735
2819
|
storePluginHook,
|