@get-bb/plugin-sdk 0.4.9 → 0.4.11

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.
@@ -54,6 +54,7 @@ var PLUGIN_AGENT_DYNAMIC_INSTRUCTIONS_MAX_CHARS = 4096;
54
54
  var PLUGIN_AGENT_TOOL_PARAMETERS_MAX_BYTES = 128 * 1024;
55
55
  var MENTION_PROVIDER_ID_PATTERN = /^[a-zA-Z0-9_-]+$/;
56
56
  var PROVIDER_ID_PATTERN = /^[a-z0-9][a-z0-9-]{1,63}$/;
57
+ var PLUGIN_PROVIDER_BRIDGE_OPTIONS_MAX_BYTES = 64 * 1024;
57
58
  var SETTING_KEY_PATTERN = /^[a-zA-Z0-9_-]+$/;
58
59
  var settingsBaseFields = {
59
60
  label: z2.string().min(1),
@@ -255,6 +256,383 @@ function validateProviderLiteralArray(args) {
255
256
  }
256
257
  return Object.freeze(normalized);
257
258
  }
259
+ function normalizeProviderBridgeOptions(providerId, value, label = "experimental_bridgeOptions") {
260
+ const active = /* @__PURE__ */ new Set();
261
+ function visit(current, path) {
262
+ if (current === null || typeof current === "string" || typeof current === "boolean") {
263
+ return current;
264
+ }
265
+ if (typeof current === "number") {
266
+ if (!Number.isFinite(current)) {
267
+ throw new Error(
268
+ `provider "${providerId}" ${label}${path} must be finite JSON`
269
+ );
270
+ }
271
+ return current;
272
+ }
273
+ if (typeof current !== "object") {
274
+ throw new Error(
275
+ `provider "${providerId}" ${label}${path} must be JSON`
276
+ );
277
+ }
278
+ if (active.has(current)) {
279
+ throw new Error(
280
+ `provider "${providerId}" experimental_bridgeOptions must not contain cycles`
281
+ );
282
+ }
283
+ active.add(current);
284
+ try {
285
+ if (Array.isArray(current)) {
286
+ const normalized3 = current.map(
287
+ (entry, index) => visit(entry, `${path}[${index}]`)
288
+ );
289
+ Object.freeze(normalized3);
290
+ return normalized3;
291
+ }
292
+ const prototype = Object.getPrototypeOf(current);
293
+ if (prototype !== Object.prototype && prototype !== null) {
294
+ throw new Error(
295
+ `provider "${providerId}" ${label}${path} must contain only plain JSON objects`
296
+ );
297
+ }
298
+ const normalized2 = Object.fromEntries(
299
+ Object.entries(current).map(([key, entry]) => [
300
+ key,
301
+ visit(entry, `${path}.${key}`)
302
+ ])
303
+ );
304
+ Object.freeze(normalized2);
305
+ return normalized2;
306
+ } finally {
307
+ active.delete(current);
308
+ }
309
+ }
310
+ const normalized = visit(value, "");
311
+ if (normalized === null || Array.isArray(normalized) || typeof normalized !== "object") {
312
+ throw new Error(
313
+ `provider "${providerId}" ${label} must be an object`
314
+ );
315
+ }
316
+ if (Buffer.byteLength(JSON.stringify(normalized), "utf8") > PLUGIN_PROVIDER_BRIDGE_OPTIONS_MAX_BYTES) {
317
+ throw new Error(
318
+ `provider "${providerId}" ${label} exceeds ${PLUGIN_PROVIDER_BRIDGE_OPTIONS_MAX_BYTES} bytes`
319
+ );
320
+ }
321
+ return normalized;
322
+ }
323
+ var PROVIDER_STRING_MAX_CHARS = 512;
324
+ var PROVIDER_EXTENSION_KIND_NAME_PATTERN = /^[a-z0-9-]+$/u;
325
+ var PROVIDER_EXTENSION_KINDS_MAX = 32;
326
+ function requireNonBlankString(args) {
327
+ const { providerId, field, value } = args;
328
+ if (typeof value !== "string" || value.trim().length === 0 || value.length > PROVIDER_STRING_MAX_CHARS) {
329
+ throw new Error(
330
+ `provider "${providerId}" ${field} must be a non-blank string of at most ${PROVIDER_STRING_MAX_CHARS} characters`
331
+ );
332
+ }
333
+ return value;
334
+ }
335
+ function validateProviderStrings(providerId, value) {
336
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
337
+ throw new Error(
338
+ `provider "${providerId}" experimental_strings must be an object`
339
+ );
340
+ }
341
+ const record = Object.fromEntries(
342
+ Object.entries(value)
343
+ );
344
+ const required = (field) => requireNonBlankString({
345
+ providerId,
346
+ field: `experimental_strings.${field}`,
347
+ value: record[field]
348
+ });
349
+ const optional = (field) => record[field] === void 0 ? void 0 : requireNonBlankString({
350
+ providerId,
351
+ field: `experimental_strings.${field}`,
352
+ value: record[field]
353
+ });
354
+ let iconTint;
355
+ if (record.iconTint !== void 0) {
356
+ const tint = record.iconTint;
357
+ if (typeof tint !== "object" || tint === null || Array.isArray(tint)) {
358
+ throw new Error(
359
+ `provider "${providerId}" experimental_strings.iconTint must be { light, dark }`
360
+ );
361
+ }
362
+ const tintRecord = Object.fromEntries(
363
+ Object.entries(tint)
364
+ );
365
+ iconTint = Object.freeze({
366
+ light: requireNonBlankString({
367
+ providerId,
368
+ field: "experimental_strings.iconTint.light",
369
+ value: tintRecord.light
370
+ }),
371
+ dark: requireNonBlankString({
372
+ providerId,
373
+ field: "experimental_strings.iconTint.dark",
374
+ value: tintRecord.dark
375
+ })
376
+ });
377
+ }
378
+ const brandPrefix = optional("brandPrefix");
379
+ const planModeCopy = optional("planModeCopy");
380
+ return Object.freeze({
381
+ signInHint: required("signInHint"),
382
+ expiredHint: required("expiredHint"),
383
+ installUrl: required("installUrl"),
384
+ ...brandPrefix === void 0 ? {} : { brandPrefix },
385
+ ...planModeCopy === void 0 ? {} : { planModeCopy },
386
+ ...iconTint === void 0 ? {} : { iconTint }
387
+ });
388
+ }
389
+ function validateProviderOptionDescriptors(args) {
390
+ const { providerId, field, value } = args;
391
+ if (!Array.isArray(value) || value.length === 0) {
392
+ throw new Error(
393
+ `provider "${providerId}" ${field} must be a non-empty array of { id, label, description? }`
394
+ );
395
+ }
396
+ const seen = /* @__PURE__ */ new Set();
397
+ const normalized = value.map(
398
+ (entry, index) => {
399
+ if (typeof entry !== "object" || entry === null || Array.isArray(entry)) {
400
+ throw new Error(
401
+ `provider "${providerId}" ${field}[${index}] must be { id, label, description? }`
402
+ );
403
+ }
404
+ const record = Object.fromEntries(
405
+ Object.entries(entry)
406
+ );
407
+ const id = requireNonBlankString({
408
+ providerId,
409
+ field: `${field}[${index}].id`,
410
+ value: record.id
411
+ });
412
+ if (seen.has(id)) {
413
+ throw new Error(
414
+ `provider "${providerId}" ${field} id ${JSON.stringify(id)} is duplicated`
415
+ );
416
+ }
417
+ seen.add(id);
418
+ const label = requireNonBlankString({
419
+ providerId,
420
+ field: `${field}[${index}].label`,
421
+ value: record.label
422
+ });
423
+ const description = record.description === void 0 ? void 0 : requireNonBlankString({
424
+ providerId,
425
+ field: `${field}[${index}].description`,
426
+ value: record.description
427
+ });
428
+ return Object.freeze({
429
+ id,
430
+ label,
431
+ ...description === void 0 ? {} : { description }
432
+ });
433
+ }
434
+ );
435
+ return Object.freeze(normalized);
436
+ }
437
+ function validateProviderExtensionKinds(providerId, value) {
438
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
439
+ throw new Error(
440
+ `provider "${providerId}" experimental_extensionKinds must be an object keyed by kind name`
441
+ );
442
+ }
443
+ const entries = Object.entries(value);
444
+ if (entries.length > PROVIDER_EXTENSION_KINDS_MAX) {
445
+ throw new Error(
446
+ `provider "${providerId}" experimental_extensionKinds declares more than ${PROVIDER_EXTENSION_KINDS_MAX} kinds`
447
+ );
448
+ }
449
+ const normalized = {};
450
+ for (const [name, declaration] of entries) {
451
+ if (!PROVIDER_EXTENSION_KIND_NAME_PATTERN.test(name)) {
452
+ throw new Error(
453
+ `provider "${providerId}" experimental_extensionKinds name ${JSON.stringify(name)} must match ${PROVIDER_EXTENSION_KIND_NAME_PATTERN}`
454
+ );
455
+ }
456
+ if (typeof declaration !== "object" || declaration === null || Array.isArray(declaration)) {
457
+ throw new Error(
458
+ `provider "${providerId}" experimental_extensionKinds.${name} must be { item?, state? }`
459
+ );
460
+ }
461
+ const item = Reflect.get(declaration, "item");
462
+ const state = Reflect.get(declaration, "state");
463
+ if (item === void 0 && state === void 0) {
464
+ throw new Error(
465
+ `provider "${providerId}" experimental_extensionKinds.${name} must declare an item schema, a state schema, or both`
466
+ );
467
+ }
468
+ if (item !== void 0 && !isStandardSchema(item)) {
469
+ throw new Error(
470
+ `provider "${providerId}" experimental_extensionKinds.${name}.item must be a Standard Schema v1 validator`
471
+ );
472
+ }
473
+ if (state !== void 0 && !isStandardSchema(state)) {
474
+ throw new Error(
475
+ `provider "${providerId}" experimental_extensionKinds.${name}.state must be a Standard Schema v1 validator`
476
+ );
477
+ }
478
+ normalized[name] = Object.freeze({
479
+ ...item === void 0 ? {} : { item },
480
+ ...state === void 0 ? {} : { state }
481
+ });
482
+ }
483
+ return Object.freeze(normalized);
484
+ }
485
+ var PROVIDER_FALLBACK_MODELS_MAX = 64;
486
+ var PROVIDER_ENV_PASSTHROUGH_MAX = 32;
487
+ var PROVIDER_ENV_NAME_PATTERN = /^[A-Z_][A-Z0-9_]*$/u;
488
+ function validateProviderEnvPassthrough(providerId, value) {
489
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
490
+ throw new Error(
491
+ `provider "${providerId}" experimental_env must be { passthrough: [...] }`
492
+ );
493
+ }
494
+ const passthrough = Reflect.get(value, "passthrough");
495
+ if (!Array.isArray(passthrough)) {
496
+ throw new Error(
497
+ `provider "${providerId}" experimental_env.passthrough must be an array of variable names`
498
+ );
499
+ }
500
+ if (passthrough.length > PROVIDER_ENV_PASSTHROUGH_MAX) {
501
+ throw new Error(
502
+ `provider "${providerId}" experimental_env.passthrough names more than ${PROVIDER_ENV_PASSTHROUGH_MAX} variables`
503
+ );
504
+ }
505
+ const seen = /* @__PURE__ */ new Set();
506
+ for (const name of passthrough) {
507
+ if (typeof name !== "string" || !PROVIDER_ENV_NAME_PATTERN.test(name)) {
508
+ throw new Error(
509
+ `provider "${providerId}" experimental_env.passthrough entries must match ${PROVIDER_ENV_NAME_PATTERN}`
510
+ );
511
+ }
512
+ if (seen.has(name)) {
513
+ throw new Error(
514
+ `provider "${providerId}" experimental_env.passthrough repeats ${JSON.stringify(name)}`
515
+ );
516
+ }
517
+ seen.add(name);
518
+ }
519
+ return Object.freeze([...seen]);
520
+ }
521
+ function validateProviderFallbackModels(providerId, value) {
522
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
523
+ throw new Error(
524
+ `provider "${providerId}" experimental_models must be { fallback: [...] }`
525
+ );
526
+ }
527
+ const fallback = Reflect.get(value, "fallback");
528
+ if (!Array.isArray(fallback)) {
529
+ throw new Error(
530
+ `provider "${providerId}" experimental_models.fallback must be an array`
531
+ );
532
+ }
533
+ if (fallback.length > PROVIDER_FALLBACK_MODELS_MAX) {
534
+ throw new Error(
535
+ `provider "${providerId}" experimental_models.fallback lists more than ${PROVIDER_FALLBACK_MODELS_MAX} models`
536
+ );
537
+ }
538
+ const seen = /* @__PURE__ */ new Set();
539
+ let defaults = 0;
540
+ const normalized = fallback.map((entry, index) => {
541
+ const field = `experimental_models.fallback[${index}]`;
542
+ if (typeof entry !== "object" || entry === null || Array.isArray(entry)) {
543
+ throw new Error(`provider "${providerId}" ${field} must be an object`);
544
+ }
545
+ const record = Object.fromEntries(
546
+ Object.entries(entry)
547
+ );
548
+ const id = requireNonBlankString({
549
+ providerId,
550
+ field: `${field}.id`,
551
+ value: record.id
552
+ });
553
+ if (seen.has(id)) {
554
+ throw new Error(
555
+ `provider "${providerId}" experimental_models.fallback id ${JSON.stringify(id)} is duplicated`
556
+ );
557
+ }
558
+ seen.add(id);
559
+ const displayName = requireNonBlankString({
560
+ providerId,
561
+ field: `${field}.displayName`,
562
+ value: record.displayName
563
+ });
564
+ const description = requireNonBlankString({
565
+ providerId,
566
+ field: `${field}.description`,
567
+ value: record.description
568
+ });
569
+ const efforts = record.supportedReasoningEfforts;
570
+ if (!Array.isArray(efforts) || efforts.length === 0) {
571
+ throw new Error(
572
+ `provider "${providerId}" ${field}.supportedReasoningEfforts must be a non-empty array`
573
+ );
574
+ }
575
+ const levels = /* @__PURE__ */ new Set();
576
+ const supportedReasoningEfforts = efforts.map(
577
+ (effort, effortIndex) => {
578
+ if (typeof effort !== "object" || effort === null || Array.isArray(effort)) {
579
+ throw new Error(
580
+ `provider "${providerId}" ${field}.supportedReasoningEfforts[${effortIndex}] must be { reasoningEffort, description }`
581
+ );
582
+ }
583
+ const reasoningEffort = Reflect.get(effort, "reasoningEffort");
584
+ if (typeof reasoningEffort !== "string" || !PLUGIN_PROVIDER_REASONING_LEVEL_VALUES.includes(
585
+ reasoningEffort
586
+ )) {
587
+ throw new Error(
588
+ `provider "${providerId}" ${field}.supportedReasoningEfforts[${effortIndex}].reasoningEffort must be one of ${PLUGIN_PROVIDER_REASONING_LEVEL_VALUES.join(", ")}`
589
+ );
590
+ }
591
+ const level = reasoningEffort;
592
+ if (levels.has(level)) {
593
+ throw new Error(
594
+ `provider "${providerId}" ${field}.supportedReasoningEfforts repeats ${JSON.stringify(level)}`
595
+ );
596
+ }
597
+ levels.add(level);
598
+ return Object.freeze({
599
+ reasoningEffort: level,
600
+ description: requireNonBlankString({
601
+ providerId,
602
+ field: `${field}.supportedReasoningEfforts[${effortIndex}].description`,
603
+ value: Reflect.get(effort, "description")
604
+ })
605
+ });
606
+ }
607
+ );
608
+ const defaultReasoningEffort = record.defaultReasoningEffort;
609
+ if (typeof defaultReasoningEffort !== "string" || !levels.has(defaultReasoningEffort)) {
610
+ throw new Error(
611
+ `provider "${providerId}" ${field}.defaultReasoningEffort must be one of its supportedReasoningEfforts`
612
+ );
613
+ }
614
+ if (typeof record.isDefault !== "boolean") {
615
+ throw new Error(
616
+ `provider "${providerId}" ${field}.isDefault must be a boolean`
617
+ );
618
+ }
619
+ if (record.isDefault) defaults += 1;
620
+ return Object.freeze({
621
+ id,
622
+ displayName,
623
+ description,
624
+ supportedReasoningEfforts: Object.freeze(supportedReasoningEfforts),
625
+ defaultReasoningEffort,
626
+ isDefault: record.isDefault
627
+ });
628
+ });
629
+ if (normalized.length > 0 && defaults !== 1) {
630
+ throw new Error(
631
+ `provider "${providerId}" experimental_models.fallback must mark exactly one model isDefault (found ${defaults})`
632
+ );
633
+ }
634
+ return Object.freeze(normalized);
635
+ }
258
636
  function validatePluginProviderDeclaration(declaration) {
259
637
  if (typeof declaration !== "object" || declaration === null) {
260
638
  throw new Error("provider declaration must be an object");
@@ -265,6 +643,12 @@ function validatePluginProviderDeclaration(declaration) {
265
643
  `invalid provider id ${JSON.stringify(id)} \u2014 use 2-64 lowercase letters, digits, and "-", starting with a letter or digit`
266
644
  );
267
645
  }
646
+ const family = declaration.experimental_family;
647
+ if (family !== void 0 && (typeof family !== "string" || !PROVIDER_ID_PATTERN.test(family))) {
648
+ throw new Error(
649
+ `provider "${id}" experimental_family must use the provider id grammar (2-64 lowercase letters, digits, and "-")`
650
+ );
651
+ }
268
652
  const displayName = typeof declaration.displayName === "string" ? declaration.displayName.trim() : "";
269
653
  if (displayName.length === 0 || displayName.length > PLUGIN_PROVIDER_DISPLAY_NAME_MAX_CHARS) {
270
654
  throw new Error(
@@ -292,13 +676,30 @@ function validatePluginProviderDeclaration(declaration) {
292
676
  if (typeof capabilities !== "object" || capabilities === null) {
293
677
  throw new Error(`provider "${id}" capabilities must be an object`);
294
678
  }
679
+ const experimentalProviderHealth = capabilities.experimental_providerHealth ?? false;
680
+ const experimentalProviderUsage = capabilities.experimental_providerUsage ?? false;
681
+ const experimentalProviderInstallation = capabilities.experimental_providerInstallation ?? false;
682
+ if (typeof experimentalProviderHealth !== "boolean") {
683
+ throw new Error(
684
+ `provider "${id}" capabilities.experimental_providerHealth must be a boolean`
685
+ );
686
+ }
687
+ if (typeof experimentalProviderUsage !== "boolean") {
688
+ throw new Error(
689
+ `provider "${id}" capabilities.experimental_providerUsage must be a boolean`
690
+ );
691
+ }
692
+ if (typeof experimentalProviderInstallation !== "boolean") {
693
+ throw new Error(
694
+ `provider "${id}" capabilities.experimental_providerInstallation must be a boolean`
695
+ );
696
+ }
295
697
  const booleanCapabilityFields = [
296
698
  "supportsServiceTier",
297
699
  "supportsNativeUserQuestion",
298
700
  "supportsManualCompaction",
299
701
  "supportsThreadArchive",
300
- "supportsThreadRename",
301
- "supportsWorkflows"
702
+ "supportsThreadRename"
302
703
  ];
303
704
  for (const field of booleanCapabilityFields) {
304
705
  if (typeof capabilities[field] !== "boolean") {
@@ -313,13 +714,15 @@ function validatePluginProviderDeclaration(declaration) {
313
714
  );
314
715
  }
315
716
  const normalizedCapabilities = Object.freeze({
717
+ experimental_providerHealth: experimentalProviderHealth,
718
+ experimental_providerUsage: experimentalProviderUsage,
719
+ experimental_providerInstallation: experimentalProviderInstallation,
316
720
  supportsServiceTier: capabilities.supportsServiceTier,
317
721
  supportsNativeUserQuestion: capabilities.supportsNativeUserQuestion,
318
722
  fork: capabilities.fork,
319
723
  supportsManualCompaction: capabilities.supportsManualCompaction,
320
724
  supportsThreadArchive: capabilities.supportsThreadArchive,
321
725
  supportsThreadRename: capabilities.supportsThreadRename,
322
- supportsWorkflows: capabilities.supportsWorkflows,
323
726
  permissionModes: validateProviderLiteralArray({
324
727
  providerId: id,
325
728
  field: "capabilities.permissionModes",
@@ -342,14 +745,72 @@ function validatePluginProviderDeclaration(declaration) {
342
745
  allowed: PLUGIN_PROVIDER_COMPOSER_ACTION_VALUES,
343
746
  requireNonEmpty: false
344
747
  });
748
+ const bridgeOptions = declaration.experimental_bridgeOptions === void 0 ? void 0 : normalizeProviderBridgeOptions(
749
+ id,
750
+ declaration.experimental_bridgeOptions
751
+ );
752
+ const visibility = declaration.experimental_visibility ?? "always";
753
+ if (visibility !== "always" && visibility !== "installed") {
754
+ throw new Error(
755
+ `provider "${id}" experimental_visibility must be "always" or "installed"`
756
+ );
757
+ }
758
+ if (visibility === "installed" && !normalizedCapabilities.experimental_providerHealth) {
759
+ throw new Error(
760
+ `provider "${id}" experimental_visibility "installed" requires experimental_providerHealth`
761
+ );
762
+ }
763
+ const strings = declaration.experimental_strings === void 0 ? void 0 : validateProviderStrings(id, declaration.experimental_strings);
764
+ const serviceTiers = declaration.experimental_serviceTiers === void 0 ? void 0 : validateProviderOptionDescriptors({
765
+ providerId: id,
766
+ field: "experimental_serviceTiers",
767
+ value: declaration.experimental_serviceTiers
768
+ });
769
+ const reasoningLevels = declaration.experimental_reasoningLevels === void 0 ? void 0 : validateProviderOptionDescriptors({
770
+ providerId: id,
771
+ field: "experimental_reasoningLevels",
772
+ value: declaration.experimental_reasoningLevels
773
+ });
774
+ const extensionKinds = declaration.experimental_extensionKinds === void 0 ? void 0 : validateProviderExtensionKinds(
775
+ id,
776
+ declaration.experimental_extensionKinds
777
+ );
778
+ const fallbackModels = declaration.experimental_models === void 0 ? void 0 : validateProviderFallbackModels(id, declaration.experimental_models);
779
+ const envPassthrough = declaration.experimental_env === void 0 ? void 0 : validateProviderEnvPassthrough(id, declaration.experimental_env);
780
+ const deriveProviderOptions = declaration.experimental_deriveProviderOptions;
781
+ if (deriveProviderOptions !== void 0 && typeof deriveProviderOptions !== "function") {
782
+ throw new Error(
783
+ `provider "${id}" experimental_deriveProviderOptions must be a function (context) => providerOptions`
784
+ );
785
+ }
345
786
  return Object.freeze({
346
787
  id,
347
788
  displayName,
789
+ ...family === void 0 ? {} : { experimental_family: family },
348
790
  ...icon === void 0 ? {} : { icon },
791
+ ...bridgeOptions === void 0 ? {} : { experimental_bridgeOptions: bridgeOptions },
792
+ experimental_visibility: visibility,
349
793
  capabilities: normalizedCapabilities,
350
- composerActions
794
+ composerActions,
795
+ ...strings === void 0 ? {} : { experimental_strings: strings },
796
+ ...serviceTiers === void 0 ? {} : { experimental_serviceTiers: serviceTiers },
797
+ ...reasoningLevels === void 0 ? {} : { experimental_reasoningLevels: reasoningLevels },
798
+ ...extensionKinds === void 0 ? {} : { experimental_extensionKinds: extensionKinds },
799
+ ...fallbackModels === void 0 ? {} : { experimental_models: Object.freeze({ fallback: fallbackModels }) },
800
+ ...envPassthrough === void 0 ? {} : { experimental_env: Object.freeze({ passthrough: envPassthrough }) },
801
+ ...deriveProviderOptions === void 0 ? {} : { experimental_deriveProviderOptions: deriveProviderOptions }
351
802
  });
352
803
  }
804
+ function deriveValidatedProviderOptions(args) {
805
+ const hook = args.declaration.experimental_deriveProviderOptions;
806
+ if (hook === void 0) return Object.freeze({});
807
+ const result = hook(args.context);
808
+ return normalizeProviderBridgeOptions(
809
+ args.declaration.id,
810
+ result,
811
+ "experimental_deriveProviderOptions result"
812
+ );
813
+ }
353
814
  function isStandardSchema(value) {
354
815
  if (typeof value !== "object" || value === null) return false;
355
816
  const standard = Reflect.get(value, "~standard");
@@ -608,6 +1069,7 @@ export {
608
1069
  PLUGIN_AGENT_TOOL_PARAMETERS_MAX_BYTES,
609
1070
  PLUGIN_HTTP_METHODS,
610
1071
  PLUGIN_MENTION_TRIGGER_VALUES,
1072
+ PLUGIN_PROVIDER_BRIDGE_OPTIONS_MAX_BYTES,
611
1073
  PLUGIN_PROVIDER_COMPOSER_ACTION_VALUES,
612
1074
  PLUGIN_PROVIDER_DISPLAY_NAME_MAX_CHARS,
613
1075
  PLUGIN_PROVIDER_PERMISSION_MODE_VALUES,
@@ -619,6 +1081,7 @@ export {
619
1081
  SETTING_KEY_PATTERN,
620
1082
  adoptHttpRouteResponse,
621
1083
  assertNoRecursiveJsonSchemaReferences,
1084
+ deriveValidatedProviderOptions,
622
1085
  enforcePluginCliOutputLimit,
623
1086
  isPluginMentionTrigger,
624
1087
  isStandardSchema,
@@ -276,6 +276,7 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
276
276
  const kind = "slots.navPanel";
277
277
  const id = requireSlotId(kind, registration?.id);
278
278
  requireUniqueId(kind, seenIds.navPanel, id);
279
+ const panelId = id;
279
280
  const path = requireNonEmptyString(kind, "path", registration.path);
280
281
  if (!PLUGIN_SLOT_ID_PATTERN.test(path)) {
281
282
  throw new Error(
@@ -311,8 +312,25 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
311
312
  `${fixedTabKind}: "layout" must be "padded" or "flush" when set`
312
313
  );
313
314
  }
315
+ const fixedTabPanelId = requireNonEmptyString(
316
+ fixedTabKind,
317
+ "panelId",
318
+ fixedTab?.panelId
319
+ );
320
+ if (fixedTabPanelId !== panelId) {
321
+ throw new Error(
322
+ `${fixedTabKind}: "panelId" must match its containing navPanel id ${JSON.stringify(panelId)}`
323
+ );
324
+ }
325
+ const experimentalTarget = fixedTab?.experimental_target;
326
+ if (experimentalTarget !== void 0 && (typeof experimentalTarget !== "object" || experimentalTarget === null || typeof Reflect.get(experimentalTarget, "validate") !== "function")) {
327
+ throw new Error(
328
+ `${fixedTabKind}: "experimental_target.validate" must be a function when set`
329
+ );
330
+ }
314
331
  return {
315
332
  id: id2,
333
+ panelId: fixedTabPanelId,
316
334
  title: requireNonEmptyString(
317
335
  fixedTabKind,
318
336
  "title",
@@ -324,7 +342,10 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
324
342
  fixedTab?.icon
325
343
  ),
326
344
  component: requireComponent(fixedTabKind, fixedTab?.component),
327
- ...layout === void 0 ? {} : { layout }
345
+ ...layout === void 0 ? {} : { layout },
346
+ ...experimentalTarget === void 0 ? {} : {
347
+ experimental_target: experimentalTarget
348
+ }
328
349
  };
329
350
  });
330
351
  })();