@get-bb/plugin-sdk 0.4.48 → 0.4.53

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.
@@ -40,6 +40,14 @@ function requireSlotId(kind, value) {
40
40
  }
41
41
  return value;
42
42
  }
43
+ function requireEnvironmentProviderId(kind, value) {
44
+ if (typeof value !== "string" || !PLUGIN_SLOT_ID_PATTERN.test(value)) {
45
+ throw new Error(
46
+ `${kind}: "environmentProviderId" must match ${String(PLUGIN_SLOT_ID_PATTERN)}, got ${JSON.stringify(value)}`
47
+ );
48
+ }
49
+ return value;
50
+ }
43
51
  function requireProviderId(kind, value) {
44
52
  if (typeof value !== "string" || !PLUGIN_SLOT_ID_PATTERN.test(value)) {
45
53
  throw new Error(
@@ -248,6 +256,7 @@ export {
248
256
  collectComposerCustomization,
249
257
  normalizePluginThreadRowStatus,
250
258
  requireComponent,
259
+ requireEnvironmentProviderId,
251
260
  requireMessageDirectiveId,
252
261
  requireNonEmptyString,
253
262
  requireOptionalString,
@@ -1,5 +1,5 @@
1
1
  // src/internal/host-policy.ts
2
- import { z as z3 } from "zod";
2
+ import { z as z4 } from "zod";
3
3
 
4
4
  // ../domain/src/plugin-icon.ts
5
5
  function isPluginOwnedIconPath(icon) {
@@ -70,37 +70,54 @@ function isRelativeProviderSkillRootPath(value) {
70
70
  return !normalized.startsWith("/") && !/^[a-zA-Z]:\//u.test(normalized) && normalized.split("/").every((segment) => segment !== "" && segment !== "." && segment !== "..");
71
71
  }
72
72
 
73
- // ../domain/src/native-roots.ts
73
+ // ../domain/src/json-value.ts
74
74
  import { z as z2 } from "zod";
75
+ var jsonValueSchema = z2.lazy(
76
+ () => z2.union([
77
+ z2.string(),
78
+ z2.number(),
79
+ z2.boolean(),
80
+ z2.null(),
81
+ z2.array(jsonValueSchema),
82
+ z2.record(z2.string(), jsonValueSchema)
83
+ ])
84
+ );
85
+ var jsonObjectSchema = z2.record(
86
+ z2.string(),
87
+ jsonValueSchema
88
+ );
89
+
90
+ // ../domain/src/native-roots.ts
91
+ import { z as z3 } from "zod";
75
92
  var PROVIDER_NATIVE_ROOTS_MAX = 32;
76
93
  var PROVIDER_NATIVE_ROOT_NAME_PREFIX_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,62}:$/u;
77
- var nativeRootNamePrefixSchema = z2.string().refine(
94
+ var nativeRootNamePrefixSchema = z3.string().refine(
78
95
  (value) => value === "" || PROVIDER_NATIVE_ROOT_NAME_PREFIX_PATTERN.test(value),
79
96
  "A root name prefix is a plugin-name-like token ending in ':'"
80
97
  );
81
- var nativeRootManifestPathSchema = z2.string().min(1).refine(
98
+ var nativeRootManifestPathSchema = z3.string().min(1).refine(
82
99
  isRelativeProviderSkillRootPath,
83
100
  "A manifest marker is a relative path without dot segments"
84
101
  );
85
- var relativeNativeRootPathSchema = z2.string().min(1).refine(
102
+ var relativeNativeRootPathSchema = z3.string().min(1).refine(
86
103
  isRelativeProviderSkillRootPath,
87
104
  "Roots must be relative paths without dot segments"
88
105
  );
89
- var absoluteNativeRootPathSchema = z2.string().min(1).refine(
106
+ var absoluteNativeRootPathSchema = z3.string().min(1).refine(
90
107
  isAbsoluteProviderSkillRootPath,
91
108
  "Absolute roots must be absolute paths without dot segments"
92
109
  );
93
- var providerNativeRootInputSchema = z2.union([
94
- z2.string().min(1),
95
- z2.object({
96
- path: z2.string().min(1),
110
+ var providerNativeRootInputSchema = z3.union([
111
+ z3.string().min(1),
112
+ z3.object({
113
+ path: z3.string().min(1),
97
114
  /** Skills nest in subdirectories (the agent scans recursively). */
98
- recursive: z2.boolean().optional(),
115
+ recursive: z3.boolean().optional(),
99
116
  /**
100
117
  * Scan the same relative directory in every ancestor of the workspace
101
118
  * up to the repository root (`project` roots only).
102
119
  */
103
- ancestors: z2.boolean().optional(),
120
+ ancestors: z3.boolean().optional(),
104
121
  /**
105
122
  * Prepended to every name under the root, a vendor plugin's
106
123
  * `plugin-name:`; a prefixed root is listed as a plugin root.
@@ -115,14 +132,14 @@ var providerNativeRootInputSchema = z2.union([
115
132
  skipIfManifest: nativeRootManifestPathSchema.optional()
116
133
  }).strict()
117
134
  ]);
118
- var providerNativeRootsInputSchema = z2.object({
119
- user: z2.array(providerNativeRootInputSchema).optional(),
120
- project: z2.array(providerNativeRootInputSchema).optional()
135
+ var providerNativeRootsInputSchema = z3.object({
136
+ user: z3.array(providerNativeRootInputSchema).optional(),
137
+ project: z3.array(providerNativeRootInputSchema).optional()
121
138
  }).strict();
122
- var providerNativeRootSchema = z2.object({
123
- path: z2.string().min(1),
124
- recursive: z2.boolean(),
125
- ancestors: z2.boolean(),
139
+ var providerNativeRootSchema = z3.object({
140
+ path: z3.string().min(1),
141
+ recursive: z3.boolean(),
142
+ ancestors: z3.boolean(),
126
143
  namePrefix: nativeRootNamePrefixSchema,
127
144
  /** Absent: every skill-shaped directory under the root is a skill. */
128
145
  skipIfManifest: nativeRootManifestPathSchema.optional()
@@ -131,7 +148,7 @@ function uniqueByPath(roots) {
131
148
  return new Set(roots.map((root) => root.path)).size === roots.length;
132
149
  }
133
150
  function nativeRootSideSchema(side) {
134
- return z2.array(
151
+ return z3.array(
135
152
  providerNativeRootSchema.extend({ path: relativeNativeRootPathSchema }).superRefine((root, context) => {
136
153
  if (root.ancestors && side !== "project") {
137
154
  context.addIssue({
@@ -142,7 +159,7 @@ function nativeRootSideSchema(side) {
142
159
  })
143
160
  ).max(PROVIDER_NATIVE_ROOTS_MAX).refine(uniqueByPath, "Roots must not repeat a path");
144
161
  }
145
- var providerNativeRootsSchema = z2.object({
162
+ var providerNativeRootsSchema = z3.object({
146
163
  user: nativeRootSideSchema("user"),
147
164
  project: nativeRootSideSchema("project")
148
165
  }).strict();
@@ -168,19 +185,19 @@ function normalizeProviderNativeRoots(roots) {
168
185
  project: (roots?.project ?? []).map(normalizeProviderNativeRoot)
169
186
  };
170
187
  }
171
- var providerResolvedNativeRootShapeSchema = z2.enum([
188
+ var providerResolvedNativeRootShapeSchema = z3.enum([
172
189
  "skills",
173
190
  "skill",
174
191
  "skill-file",
175
192
  "commands",
176
193
  "command-file"
177
194
  ]);
178
- var resolvedNativeRootFieldsSchema = z2.object({
195
+ var resolvedNativeRootFieldsSchema = z3.object({
179
196
  path: absoluteNativeRootPathSchema,
180
- origin: z2.enum(["user", "project"]),
181
- recursive: z2.boolean(),
197
+ origin: z3.enum(["user", "project"]),
198
+ recursive: z3.boolean(),
182
199
  /** Only with origin `project`, for a path inside the workspace. */
183
- ancestors: z2.boolean(),
200
+ ancestors: z3.boolean(),
184
201
  namePrefix: nativeRootNamePrefixSchema,
185
202
  shape: providerResolvedNativeRootShapeSchema,
186
203
  /**
@@ -188,7 +205,7 @@ var resolvedNativeRootFieldsSchema = z2.object({
188
205
  * none. A vendor plugin's root SKILL.md takes the plugin's name; absent
189
206
  * means the parent directory's name.
190
207
  */
191
- fallbackName: z2.string().min(1).optional(),
208
+ fallbackName: z3.string().min(1).optional(),
192
209
  /**
193
210
  * `skills` only: a file, relative to a skill directory under this root,
194
211
  * that marks the directory as a vendor plugin rather than a skill; the
@@ -232,14 +249,14 @@ var resolvedCommandShapes = /* @__PURE__ */ new Set([
232
249
  "command-file"
233
250
  ]);
234
251
  var PROVIDER_RESOLVED_NATIVE_ROOTS_MAX = 256;
235
- var providerResolvedNativeRootsSchema = z2.object({
236
- skills: z2.array(
252
+ var providerResolvedNativeRootsSchema = z3.object({
253
+ skills: z3.array(
237
254
  providerResolvedNativeRootSchema.refine(
238
255
  (root) => resolvedSkillShapes.has(root.shape),
239
256
  "A skills root needs a skill shape"
240
257
  )
241
258
  ).max(PROVIDER_RESOLVED_NATIVE_ROOTS_MAX),
242
- commands: z2.array(
259
+ commands: z3.array(
243
260
  providerResolvedNativeRootSchema.refine(
244
261
  (root) => resolvedCommandShapes.has(root.shape),
245
262
  "A commands root needs a command shape"
@@ -250,7 +267,7 @@ var EMPTY_PROVIDER_RESOLVED_NATIVE_ROOTS = Object.freeze({
250
267
  skills: Object.freeze([]),
251
268
  commands: Object.freeze([])
252
269
  });
253
- var providerNativeRootSetSchema = z2.object({
270
+ var providerNativeRootSetSchema = z3.object({
254
271
  skills: providerNativeRootsSchema,
255
272
  commands: providerNativeRootsSchema,
256
273
  resolved: providerResolvedNativeRootsSchema
@@ -283,16 +300,16 @@ var CLI_COMMAND_NAME_PATTERN = /^[a-z0-9-]+$/;
283
300
  var AGENT_TOOL_NAME_PATTERN = /^[a-zA-Z0-9_-]+$/;
284
301
  var PLUGIN_PROVIDER_ENV_NAME_PATTERN = /^[A-Z_][A-Z0-9_]*$/;
285
302
  var PLUGIN_PROVIDER_ENV_MAX_ENTRIES = 32;
286
- var pluginProviderEnvEntrySchema = z3.object({
287
- name: z3.string().regex(PLUGIN_PROVIDER_ENV_NAME_PATTERN),
288
- value: z3.union([
289
- z3.string(),
290
- z3.object({ serverPath: z3.string().startsWith("/") }).strict()
303
+ var pluginProviderEnvEntrySchema = z4.object({
304
+ name: z4.string().regex(PLUGIN_PROVIDER_ENV_NAME_PATTERN),
305
+ value: z4.union([
306
+ z4.string(),
307
+ z4.object({ serverPath: z4.string().startsWith("/") }).strict()
291
308
  ]),
292
- reason: z3.string(),
293
- secret: z3.boolean()
309
+ reason: z4.string(),
310
+ secret: z4.boolean()
294
311
  }).strict();
295
- var pluginProviderEnvEntriesSchema = z3.array(pluginProviderEnvEntrySchema).max(PLUGIN_PROVIDER_ENV_MAX_ENTRIES).superRefine((entries, context) => {
312
+ var pluginProviderEnvEntriesSchema = z4.array(pluginProviderEnvEntrySchema).max(PLUGIN_PROVIDER_ENV_MAX_ENTRIES).superRefine((entries, context) => {
296
313
  const names = /* @__PURE__ */ new Set();
297
314
  for (let index = 0; index < entries.length; index += 1) {
298
315
  const name = entries[index]?.name;
@@ -327,26 +344,26 @@ var PROVIDER_ID_PATTERN = /^[a-z0-9][a-z0-9-]{1,63}$/;
327
344
  var PLUGIN_PROVIDER_BRIDGE_OPTIONS_MAX_BYTES = 64 * 1024;
328
345
  var SETTING_KEY_PATTERN = /^[a-zA-Z0-9_-]+$/;
329
346
  var settingsBaseFields = {
330
- label: z3.string().min(1),
331
- description: z3.string().min(1).optional()
347
+ label: z4.string().min(1),
348
+ description: z4.string().min(1).optional()
332
349
  };
333
- var stringSettingSchemaSchema = z3.custom(
350
+ var stringSettingSchemaSchema = z4.custom(
334
351
  (value) => isStandardSchema(value)
335
352
  );
336
- var booleanSettingSchemaSchema = z3.custom(
353
+ var booleanSettingSchemaSchema = z4.custom(
337
354
  (value) => isStandardSchema(value)
338
355
  );
339
- var numberSettingSchemaSchema = z3.custom(
356
+ var numberSettingSchemaSchema = z4.custom(
340
357
  (value) => isStandardSchema(value)
341
358
  );
342
- var settingDescriptorSchema = z3.discriminatedUnion("type", [
343
- z3.object({
344
- type: z3.literal("string"),
359
+ var settingDescriptorSchema = z4.discriminatedUnion("type", [
360
+ z4.object({
361
+ type: z4.literal("string"),
345
362
  ...settingsBaseFields,
346
- secret: z3.literal(true).optional(),
347
- experimental_multiline: z3.boolean().optional(),
363
+ secret: z4.literal(true).optional(),
364
+ experimental_multiline: z4.boolean().optional(),
348
365
  experimental_schema: stringSettingSchemaSchema.optional(),
349
- default: z3.string().optional()
366
+ default: z4.string().optional()
350
367
  }).strict().refine(
351
368
  (descriptor) => !(descriptor.secret === true && descriptor.experimental_multiline === true),
352
369
  {
@@ -354,30 +371,30 @@ var settingDescriptorSchema = z3.discriminatedUnion("type", [
354
371
  path: ["experimental_multiline"]
355
372
  }
356
373
  ),
357
- z3.object({
358
- type: z3.literal("boolean"),
374
+ z4.object({
375
+ type: z4.literal("boolean"),
359
376
  ...settingsBaseFields,
360
377
  experimental_schema: booleanSettingSchemaSchema.optional(),
361
- default: z3.boolean().optional()
378
+ default: z4.boolean().optional()
362
379
  }).strict(),
363
- z3.object({
364
- type: z3.literal("number"),
380
+ z4.object({
381
+ type: z4.literal("number"),
365
382
  ...settingsBaseFields,
366
383
  experimental_schema: numberSettingSchemaSchema.optional(),
367
- default: z3.number().finite().optional()
384
+ default: z4.number().finite().optional()
368
385
  }).strict(),
369
- z3.object({
370
- type: z3.literal("select"),
386
+ z4.object({
387
+ type: z4.literal("select"),
371
388
  ...settingsBaseFields,
372
- options: z3.array(z3.string().min(1)).min(1),
389
+ options: z4.array(z4.string().min(1)).min(1),
373
390
  experimental_schema: stringSettingSchemaSchema.optional(),
374
- default: z3.string().optional()
391
+ default: z4.string().optional()
375
392
  }).strict(),
376
- z3.object({
377
- type: z3.literal("project"),
393
+ z4.object({
394
+ type: z4.literal("project"),
378
395
  ...settingsBaseFields,
379
396
  experimental_schema: stringSettingSchemaSchema.optional(),
380
- default: z3.string().optional()
397
+ default: z4.string().optional()
381
398
  }).strict()
382
399
  ]);
383
400
  function registerSettingDescriptors(target, added) {
@@ -1407,11 +1424,21 @@ function readRpcMethodContract(method, value) {
1407
1424
  function isZodSchemaLike(value) {
1408
1425
  return typeof value === "object" && value !== null && typeof value.safeParse === "function";
1409
1426
  }
1427
+ function standardSchemaToJsonSchema(schema) {
1428
+ if (isZodSchemaLike(schema)) {
1429
+ return zodSchemaToJsonSchema(schema);
1430
+ }
1431
+ const convertible = schema;
1432
+ if (typeof convertible.toJSONSchema === "function") {
1433
+ return convertible.toJSONSchema();
1434
+ }
1435
+ throw new Error("the validator exposes no JSON Schema conversion");
1436
+ }
1410
1437
  function zodSchemaToJsonSchema(schema) {
1411
1438
  if (typeof schema.toJSONSchema === "function") {
1412
1439
  return schema.toJSONSchema({ io: "input" });
1413
1440
  }
1414
- return z3.toJSONSchema(schema, { io: "input" });
1441
+ return z4.toJSONSchema(schema, { io: "input" });
1415
1442
  }
1416
1443
  var SINGLE_SCHEMA_KEYWORDS = [
1417
1444
  "additionalItems",
@@ -1632,6 +1659,16 @@ function parsePluginAgentToolPresentation(toolName, value) {
1632
1659
  }
1633
1660
  return presentation;
1634
1661
  }
1662
+ function summarizeStandardIssues(issues) {
1663
+ if (issues.length === 0) return "invalid";
1664
+ return issues.map((issue) => {
1665
+ const segments = issue.path === void 0 ? [] : Array.isArray(issue.path) ? issue.path.map(
1666
+ (segment) => typeof segment === "object" && segment !== null ? String(segment.key) : String(segment)
1667
+ ) : [String(issue.path)];
1668
+ const path = segments.length > 0 ? segments.join(".") : "(input)";
1669
+ return `${path}: ${issue.message}`;
1670
+ }).join("; ");
1671
+ }
1635
1672
  function summarizeParseIssues(error) {
1636
1673
  const issues = error?.issues;
1637
1674
  if (Array.isArray(issues) && issues.length > 0) {
@@ -1737,11 +1774,140 @@ function storePluginHook(records, hook, handler) {
1737
1774
  function pluginHookAlreadyRegisteredMessage(hook) {
1738
1775
  return `a "${hook}" hook handler is already registered by this plugin`;
1739
1776
  }
1777
+ var ENVIRONMENT_PROVIDER_ID_PATTERN = /^[a-z0-9][a-z0-9-]{1,63}$/;
1778
+ var ENVIRONMENT_PROVIDER_DISPLAY_NAME_MAX_CHARS = 80;
1779
+ var ENVIRONMENT_PROVIDER_REQUIREMENT_NAMES = [
1780
+ "projectCheckout",
1781
+ "gitCheckout",
1782
+ "gitRemote",
1783
+ "projectless"
1784
+ ];
1785
+ function validatePluginEnvironmentProviderDeclaration(declaration) {
1786
+ if (typeof declaration !== "object" || declaration === null) {
1787
+ throw new Error("environment provider declaration must be an object");
1788
+ }
1789
+ const id = declaration.id;
1790
+ if (typeof id !== "string" || !ENVIRONMENT_PROVIDER_ID_PATTERN.test(id)) {
1791
+ throw new Error(
1792
+ `invalid environment provider id ${JSON.stringify(id)} \u2014 use 2-64 lowercase letters, digits, or "-", starting with a letter or digit`
1793
+ );
1794
+ }
1795
+ const displayName = typeof declaration.displayName === "string" ? declaration.displayName.trim() : "";
1796
+ if (displayName.length === 0 || displayName.length > ENVIRONMENT_PROVIDER_DISPLAY_NAME_MAX_CHARS) {
1797
+ throw new Error(
1798
+ `environment provider "${id}" needs a displayName of 1-${ENVIRONMENT_PROVIDER_DISPLAY_NAME_MAX_CHARS} characters`
1799
+ );
1800
+ }
1801
+ const icon = declaration.icon === void 0 ? null : z4.string().min(1).parse(declaration.icon).trim();
1802
+ if (icon !== null) {
1803
+ if (isPluginOwnedIconPath(icon))
1804
+ validateProviderRelativePath(icon, `"${id}" icon`);
1805
+ else if (!isNamespacedGlyph(icon) && /[/\\]/u.test(icon))
1806
+ throw new Error(
1807
+ `environment provider "${id}" icon must be a glyph, declared icon, or plugin-relative path`
1808
+ );
1809
+ }
1810
+ if (icon !== null && icon.length === 0) {
1811
+ throw new Error(`environment provider "${id}" declares an empty icon`);
1812
+ }
1813
+ const requires = normalizeEnvironmentProviderRequirements(id, declaration);
1814
+ const inputs = normalizeEnvironmentProviderInputs(id, declaration);
1815
+ if (typeof declaration.create !== "function" || typeof declaration.remove !== "function") {
1816
+ throw new Error(
1817
+ `environment provider "${id}" must declare create and remove functions`
1818
+ );
1819
+ }
1820
+ if (declaration.validate !== void 0 && typeof declaration.validate !== "function") {
1821
+ throw new Error(
1822
+ `environment provider "${id}" declares a validate that is not a function`
1823
+ );
1824
+ }
1825
+ if (declaration.availability !== void 0 && typeof declaration.availability !== "function") {
1826
+ throw new Error(
1827
+ `environment provider "${id}" declares availability that is not a function`
1828
+ );
1829
+ }
1830
+ return {
1831
+ id,
1832
+ displayName,
1833
+ icon,
1834
+ requires,
1835
+ inputs: inputs === null ? null : inputs.schema,
1836
+ inputsJsonSchema: inputs === null ? null : inputs.jsonSchema,
1837
+ availability: declaration.availability ?? null,
1838
+ validate: declaration.validate ?? null,
1839
+ create: declaration.create,
1840
+ remove: declaration.remove,
1841
+ policy: environmentProviderPolicySchema.parse(declaration.policy ?? {})
1842
+ };
1843
+ }
1844
+ function normalizeEnvironmentProviderInputs(id, declaration) {
1845
+ const inputs = declaration.inputs;
1846
+ if (inputs === void 0) {
1847
+ return null;
1848
+ }
1849
+ if (!isStandardSchema(inputs)) {
1850
+ throw new Error(
1851
+ `environment provider "${id}" declares an inputs that is not a Standard Schema v1 validator`
1852
+ );
1853
+ }
1854
+ let converted;
1855
+ try {
1856
+ converted = JSON.parse(JSON.stringify(standardSchemaToJsonSchema(inputs)));
1857
+ } catch (error) {
1858
+ throw new Error(
1859
+ `environment provider "${id}" declares an inputs validator that cannot be published as JSON Schema (${error instanceof Error ? error.message : String(error)}) \u2014 declare it with zod 4 or a validator exposing toJSONSchema()`
1860
+ );
1861
+ }
1862
+ const jsonSchema = jsonValueSchema.safeParse(converted);
1863
+ if (!jsonSchema.success) {
1864
+ throw new Error(
1865
+ `environment provider "${id}" declares an inputs schema whose JSON Schema is not JSON-serializable`
1866
+ );
1867
+ }
1868
+ return { schema: inputs, jsonSchema: jsonSchema.data };
1869
+ }
1870
+ function normalizeEnvironmentProviderRequirements(id, declaration) {
1871
+ const requires = declaration.requires ?? {};
1872
+ if (typeof requires !== "object" || requires === null || Array.isArray(requires)) {
1873
+ throw new Error(
1874
+ `environment provider "${id}" declares a requires that is not an object`
1875
+ );
1876
+ }
1877
+ const normalized = {};
1878
+ for (const name of ENVIRONMENT_PROVIDER_REQUIREMENT_NAMES) {
1879
+ const value = requires[name];
1880
+ if (value !== void 0 && typeof value !== "boolean") {
1881
+ throw new Error(
1882
+ `environment provider "${id}" declares a requires.${name} that is not a boolean`
1883
+ );
1884
+ }
1885
+ normalized[name] = value === true;
1886
+ }
1887
+ if (normalized.gitCheckout) {
1888
+ normalized.projectCheckout = true;
1889
+ }
1890
+ if (normalized.projectless && (normalized.projectCheckout || normalized.gitRemote)) {
1891
+ throw new Error(
1892
+ `environment provider "${id}" declares requires.projectless together with a project requirement \u2014 a projectless thread has no checkout or remote`
1893
+ );
1894
+ }
1895
+ return normalized;
1896
+ }
1897
+ var environmentProviderPolicySchema = z4.object({
1898
+ retireGraceMs: z4.number().int().nonnegative().nullable().default(3e5),
1899
+ pathKeys: z4.enum(["per-thread", "per-attempt"]).default("per-thread")
1900
+ }).strict();
1901
+ var MACHINE_PROVIDER_REQUIREMENT_NAMES = ["gitRemote"];
1740
1902
  export {
1741
1903
  AGENT_TOOL_NAME_PATTERN,
1742
1904
  BACKGROUND_NAME_PATTERN,
1743
1905
  CLI_COMMAND_NAME_PATTERN,
1906
+ ENVIRONMENT_PROVIDER_DISPLAY_NAME_MAX_CHARS,
1907
+ ENVIRONMENT_PROVIDER_ID_PATTERN,
1908
+ ENVIRONMENT_PROVIDER_REQUIREMENT_NAMES,
1744
1909
  KV_VALUE_MAX_BYTES,
1910
+ MACHINE_PROVIDER_REQUIREMENT_NAMES,
1745
1911
  MENTION_PROVIDER_ID_PATTERN,
1746
1912
  PLUGIN_AGENT_DYNAMIC_INSTRUCTIONS_MAX_CHARS,
1747
1913
  PLUGIN_AGENT_SELECTION_MAX_IDS,
@@ -1785,8 +1951,10 @@ export {
1785
1951
  rejectStaleAgentToolFields,
1786
1952
  storePluginHook,
1787
1953
  summarizeParseIssues,
1954
+ summarizeStandardIssues,
1788
1955
  undeclaredIconProblem,
1789
1956
  validatePluginAiServiceDeclaration,
1957
+ validatePluginEnvironmentProviderDeclaration,
1790
1958
  validatePluginProviderDeclaration,
1791
1959
  validatePluginProviderEnvEntries,
1792
1960
  validateSettingsUpdate,
@@ -9,6 +9,14 @@ function requireSlotId(kind, value) {
9
9
  }
10
10
  return value;
11
11
  }
12
+ function requireEnvironmentProviderId(kind, value) {
13
+ if (typeof value !== "string" || !PLUGIN_SLOT_ID_PATTERN.test(value)) {
14
+ throw new Error(
15
+ `${kind}: "environmentProviderId" must match ${String(PLUGIN_SLOT_ID_PATTERN)}, got ${JSON.stringify(value)}`
16
+ );
17
+ }
18
+ return value;
19
+ }
12
20
  function requireProviderId(kind, value) {
13
21
  if (typeof value !== "string" || !PLUGIN_SLOT_ID_PATTERN.test(value)) {
14
22
  throw new Error(
@@ -391,6 +399,7 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
391
399
  commandPaletteActions: [],
392
400
  providerIcons: [],
393
401
  timelineRenderers: [],
402
+ environmentProviderInputs: [],
394
403
  contentScripts: []
395
404
  };
396
405
  sidebarFooterItemsByRegistrationSet.set(collected, sidebarFooterItems);
@@ -415,6 +424,7 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
415
424
  commandPaletteAction: /* @__PURE__ */ new Set(),
416
425
  providerIcon: /* @__PURE__ */ new Set(),
417
426
  timelineRenderer: /* @__PURE__ */ new Set(),
427
+ environmentProviderInputs: /* @__PURE__ */ new Set(),
418
428
  contentScript: /* @__PURE__ */ new Set()
419
429
  };
420
430
  definition.setup({
@@ -765,6 +775,22 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
765
775
  kind: itemKind,
766
776
  component: requireComponent(kind, registration.component)
767
777
  });
778
+ },
779
+ experimental_environmentProviderInputs(registration) {
780
+ const kind = "slots.experimental_environmentProviderInputs";
781
+ const environmentProviderId = requireEnvironmentProviderId(
782
+ kind,
783
+ registration?.environmentProviderId
784
+ );
785
+ requireUniqueId(
786
+ kind,
787
+ seenIds.environmentProviderInputs,
788
+ environmentProviderId
789
+ );
790
+ collected.environmentProviderInputs.push({
791
+ environmentProviderId,
792
+ component: requireComponent(kind, registration.component)
793
+ });
768
794
  }
769
795
  },
770
796
  experimental_sidebarFooter: new SidebarFooterCollector(
@@ -1316,7 +1316,7 @@ var systemThreadProvisioningStatusSchema = z11.enum(
1316
1316
  var systemThreadProvisioningEventDataSchema = z11.object({
1317
1317
  provisioningId: z11.string(),
1318
1318
  status: systemThreadProvisioningStatusSchema,
1319
- environmentId: z11.string(),
1319
+ environmentId: z11.string().nullable(),
1320
1320
  entries: z11.array(provisioningTranscriptEntrySchema)
1321
1321
  });
1322
1322
  var systemLegacyUserMessageEventDataSchema = z11.object({
@@ -1717,6 +1717,19 @@ var threadEventItemTruncationSchema = z14.object({
1717
1717
  result: threadEventTextTruncationSchema.optional(),
1718
1718
  resultText: threadEventTextTruncationSchema.optional()
1719
1719
  });
1720
+ var threadEventImageGenerationItemSchema = z14.object({
1721
+ type: z14.literal("imageGeneration"),
1722
+ id: z14.string(),
1723
+ status: threadEventItemStatusSchema,
1724
+ prompt: z14.string().nullable(),
1725
+ path: z14.string().nullable(),
1726
+ result: z14.string().optional(),
1727
+ error: z14.string().nullable(),
1728
+ transparentBackground: z14.boolean(),
1729
+ truncation: threadEventItemTruncationSchema.optional(),
1730
+ ...itemPresentationField,
1731
+ parentToolCallId: z14.string().optional()
1732
+ });
1720
1733
  var threadEventUserContentSchema = z14.discriminatedUnion("type", [
1721
1734
  z14.object({ type: z14.literal("text"), text: z14.string() }),
1722
1735
  z14.object({ type: z14.literal("image"), url: z14.string() }),
@@ -1828,6 +1841,7 @@ var threadEventItemSchema = z14.discriminatedUnion("type", [
1828
1841
  threadEventWebSearchItemSchema,
1829
1842
  threadEventWebFetchItemSchema,
1830
1843
  threadEventImageViewItemSchema,
1844
+ threadEventImageGenerationItemSchema,
1831
1845
  threadEventFileReadItemSchema,
1832
1846
  threadEventSearchItemSchema,
1833
1847
  z14.object({
@@ -2896,6 +2910,14 @@ var deltaItemShapeSchema = z25.discriminatedUnion("type", [
2896
2910
  pattern: z25.string().nullable()
2897
2911
  }),
2898
2912
  z25.object({ type: z25.literal("imageView"), path: z25.string() }),
2913
+ z25.object({
2914
+ type: z25.literal("imageGeneration"),
2915
+ prompt: z25.string().nullable(),
2916
+ path: z25.string().nullable(),
2917
+ result: z25.string().optional(),
2918
+ error: z25.string().nullable(),
2919
+ transparentBackground: z25.boolean()
2920
+ }),
2899
2921
  deltaBackgroundTaskShapeSchema,
2900
2922
  deltaFileReadShapeSchema,
2901
2923
  deltaSearchShapeSchema,
@@ -3831,6 +3853,7 @@ import { promises as fs2, readFileSync } from "node:fs";
3831
3853
  import { createServer } from "node:net";
3832
3854
  import { dirname as dirname2, isAbsolute, basename as basename3, relative, resolve as resolve3 } from "node:path";
3833
3855
  import { fileURLToPath } from "node:url";
3856
+ import { isDeepStrictEqual } from "node:util";
3834
3857
  import { z as z40 } from "zod";
3835
3858
 
3836
3859
  // ../provider-bridge-acp/src/bridge-protocol.ts
@@ -8751,6 +8774,7 @@ async function startAgentSession(request) {
8751
8774
  });
8752
8775
  session = {
8753
8776
  bbThreadId,
8777
+ construction: params,
8754
8778
  providerThreadId: "",
8755
8779
  cwd: params.cwd,
8756
8780
  dialect,
@@ -9484,7 +9508,7 @@ async function handleRequest2(request) {
9484
9508
  }
9485
9509
  case "turn/start": {
9486
9510
  const params = request.params;
9487
- const session = liveSessionForThread(params.threadId);
9511
+ let session = liveSessionForThread(params.threadId);
9488
9512
  if (session === void 0) {
9489
9513
  sendError(request.id, -32e3, "No active ACP session");
9490
9514
  return;
@@ -9493,6 +9517,26 @@ async function handleRequest2(request) {
9493
9517
  sendError(request.id, -32e3, "A turn is already active");
9494
9518
  return;
9495
9519
  }
9520
+ if (Object.keys(params.options.envVars ?? {}).length > 0) {
9521
+ const envVars = {
9522
+ ...decodeLaunchSpec(params.options.providerOptions)?.env ?? {},
9523
+ ...params.options.envVars
9524
+ };
9525
+ if (!isDeepStrictEqual(envVars, session.construction.envVars ?? {})) {
9526
+ const previousProviderThreadId = session.providerThreadId;
9527
+ session = await startAgentSession({
9528
+ kind: "resume",
9529
+ params: { ...session.construction, envVars },
9530
+ resumeProviderThreadId: previousProviderThreadId
9531
+ });
9532
+ sendNotification(BRIDGE_NOTIFICATION_METHODS.sessionReplaced, {
9533
+ threadId: params.threadId,
9534
+ providerThreadId: session.providerThreadId,
9535
+ reason: "Execution settings changed; the ACP session was rebuilt to apply them.",
9536
+ contextLost: session.providerThreadId !== previousProviderThreadId
9537
+ });
9538
+ }
9539
+ }
9496
9540
  const pending = {
9497
9541
  clientRequestId: params.clientRequestId,
9498
9542
  input: params.input,