@get-bb/plugin-sdk 0.4.35 → 0.4.45

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.
@@ -276,10 +276,46 @@ var PLUGIN_HTTP_METHODS = /* @__PURE__ */ new Set([
276
276
  "HEAD",
277
277
  "OPTIONS"
278
278
  ]);
279
- var RPC_METHOD_PATTERN = /^[a-zA-Z0-9_-]+$/;
279
+ var RPC_METHOD_PATTERN = /^[a-zA-Z0-9_-]+(?:\.[a-zA-Z0-9_-]+)*$/;
280
280
  var BACKGROUND_NAME_PATTERN = /^[a-zA-Z0-9_-]+$/;
281
281
  var CLI_COMMAND_NAME_PATTERN = /^[a-z0-9-]+$/;
282
282
  var AGENT_TOOL_NAME_PATTERN = /^[a-zA-Z0-9_-]+$/;
283
+ var PLUGIN_PROVIDER_ENV_NAME_PATTERN = /^[A-Z_][A-Z0-9_]*$/;
284
+ var PLUGIN_PROVIDER_ENV_MAX_ENTRIES = 32;
285
+ var pluginProviderEnvEntrySchema = z3.object({
286
+ name: z3.string().regex(PLUGIN_PROVIDER_ENV_NAME_PATTERN),
287
+ value: z3.union([
288
+ z3.string(),
289
+ z3.object({ serverPath: z3.string().startsWith("/") }).strict()
290
+ ]),
291
+ reason: z3.string(),
292
+ secret: z3.boolean()
293
+ }).strict();
294
+ var pluginProviderEnvEntriesSchema = z3.array(pluginProviderEnvEntrySchema).max(PLUGIN_PROVIDER_ENV_MAX_ENTRIES).superRefine((entries, context) => {
295
+ const names = /* @__PURE__ */ new Set();
296
+ for (let index = 0; index < entries.length; index += 1) {
297
+ const name = entries[index]?.name;
298
+ if (name !== void 0 && names.has(name)) {
299
+ context.addIssue({
300
+ code: "custom",
301
+ path: [index, "name"],
302
+ message: "must be unique within one resolver"
303
+ });
304
+ }
305
+ if (name !== void 0) names.add(name);
306
+ }
307
+ });
308
+ function validatePluginProviderEnvEntries(value) {
309
+ const parsed = pluginProviderEnvEntriesSchema.safeParse(value);
310
+ if (!parsed.success) {
311
+ const issue = parsed.error.issues[0];
312
+ const path = issue?.path.length ? `[${issue.path.join(".")}] ` : "";
313
+ throw new Error(
314
+ `provider environment contribution ${path}${issue?.message ?? "is invalid"}`
315
+ );
316
+ }
317
+ return parsed.data;
318
+ }
283
319
  var PLUGIN_AGENT_STATIC_INSTRUCTIONS_MAX_CHARS = 4096;
284
320
  var PLUGIN_AGENT_STATUS_LABEL_MAX_CHARS = 80;
285
321
  var PLUGIN_AGENT_SELECTION_MAX_IDS = 256;
@@ -299,6 +335,9 @@ var stringSettingSchemaSchema = z3.custom(
299
335
  var booleanSettingSchemaSchema = z3.custom(
300
336
  (value) => isStandardSchema(value)
301
337
  );
338
+ var numberSettingSchemaSchema = z3.custom(
339
+ (value) => isStandardSchema(value)
340
+ );
302
341
  var settingDescriptorSchema = z3.discriminatedUnion("type", [
303
342
  z3.object({
304
343
  type: z3.literal("string"),
@@ -320,6 +359,12 @@ var settingDescriptorSchema = z3.discriminatedUnion("type", [
320
359
  experimental_schema: booleanSettingSchemaSchema.optional(),
321
360
  default: z3.boolean().optional()
322
361
  }).strict(),
362
+ z3.object({
363
+ type: z3.literal("number"),
364
+ ...settingsBaseFields,
365
+ experimental_schema: numberSettingSchemaSchema.optional(),
366
+ default: z3.number().finite().optional()
367
+ }).strict(),
323
368
  z3.object({
324
369
  type: z3.literal("select"),
325
370
  ...settingsBaseFields,
@@ -416,6 +461,21 @@ function validateSettingsUpdate(descriptors, values) {
416
461
  }
417
462
  continue;
418
463
  }
464
+ if (descriptor.type === "number") {
465
+ if (typeof value !== "number" || !Number.isFinite(value)) {
466
+ errors.push(`setting "${key}" expects a finite number`);
467
+ continue;
468
+ }
469
+ const validationError2 = settingSchemaError(
470
+ key,
471
+ descriptor.experimental_schema,
472
+ value
473
+ );
474
+ if (validationError2 !== null) {
475
+ errors.push(validationError2);
476
+ }
477
+ continue;
478
+ }
419
479
  if (typeof value !== "string") {
420
480
  errors.push(`setting "${key}" expects a string`);
421
481
  continue;
@@ -1692,6 +1752,8 @@ export {
1692
1752
  PLUGIN_PROVIDER_BRIDGE_OPTIONS_MAX_BYTES,
1693
1753
  PLUGIN_PROVIDER_COMPOSER_ACTION_VALUES,
1694
1754
  PLUGIN_PROVIDER_DISPLAY_NAME_MAX_CHARS,
1755
+ PLUGIN_PROVIDER_ENV_MAX_ENTRIES,
1756
+ PLUGIN_PROVIDER_ENV_NAME_PATTERN,
1695
1757
  PLUGIN_PROVIDER_PERMISSION_MODE_VALUES,
1696
1758
  PLUGIN_PROVIDER_REASONING_LEVEL_VALUES,
1697
1759
  PROVIDER_ID_PATTERN,
@@ -1725,6 +1787,7 @@ export {
1725
1787
  undeclaredIconProblem,
1726
1788
  validatePluginAiServiceDeclaration,
1727
1789
  validatePluginProviderDeclaration,
1790
+ validatePluginProviderEnvEntries,
1728
1791
  validateSettingsUpdate,
1729
1792
  zodSchemaToJsonSchema
1730
1793
  };
@@ -246,6 +246,7 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
246
246
  const collected = {
247
247
  homepageSections: [],
248
248
  settingsSections: [],
249
+ appOverlays: [],
249
250
  navPanels: [],
250
251
  threadPanelActions: [],
251
252
  newThreadPanelActions: [],
@@ -268,6 +269,7 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
268
269
  const seenIds = {
269
270
  homepageSection: /* @__PURE__ */ new Set(),
270
271
  settingsSection: /* @__PURE__ */ new Set(),
272
+ appOverlay: /* @__PURE__ */ new Set(),
271
273
  navPanel: /* @__PURE__ */ new Set(),
272
274
  threadPanelAction: /* @__PURE__ */ new Set(),
273
275
  newThreadPanelAction: /* @__PURE__ */ new Set(),
@@ -316,6 +318,15 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
316
318
  component: requireComponent(kind, registration.component)
317
319
  });
318
320
  },
321
+ experimental_appOverlay(registration) {
322
+ const kind = "slots.experimental_appOverlay";
323
+ const id = requireSlotId(kind, registration?.id);
324
+ requireUniqueId(kind, seenIds.appOverlay, id);
325
+ collected.appOverlays.push({
326
+ id,
327
+ component: requireComponent(kind, registration.component)
328
+ });
329
+ },
319
330
  navPanel(registration) {
320
331
  const kind = "slots.navPanel";
321
332
  const id = requireSlotId(kind, registration?.id);
@@ -684,13 +684,21 @@ var threadEventItemPresentationTintSchema = z6.object({
684
684
  light: z6.string().min(1),
685
685
  dark: z6.string().min(1)
686
686
  });
687
+ var THREAD_EVENT_ITEM_PRESENTATION_BADGE_LABEL_MAX_LENGTH = 80;
688
+ var threadEventItemPresentationBadgeSchema = z6.object({
689
+ glyph: z6.string().min(1),
690
+ label: z6.string().min(1).max(THREAD_EVENT_ITEM_PRESENTATION_BADGE_LABEL_MAX_LENGTH),
691
+ hint: z6.string().min(1).max(THREAD_EVENT_ITEM_PRESENTATION_BADGE_LABEL_MAX_LENGTH),
692
+ tone: z6.enum(["neutral", "destructive"])
693
+ });
687
694
  var threadEventItemPresentationSchema = z6.object({
688
695
  label: threadEventItemPresentationLabelSchema,
689
696
  icon: threadEventItemPresentationIconSchema,
690
697
  title: z6.string().optional(),
691
698
  detail: z6.string().max(THREAD_EVENT_ITEM_PRESENTATION_DETAIL_MAX_LENGTH).optional(),
692
699
  suppress: z6.boolean().optional(),
693
- tint: threadEventItemPresentationTintSchema.optional()
700
+ tint: threadEventItemPresentationTintSchema.optional(),
701
+ badge: threadEventItemPresentationBadgeSchema.optional()
694
702
  });
695
703
 
696
704
  // ../domain/src/provider-extension-kind.ts
@@ -1409,6 +1417,10 @@ var threadEventScopeDefinitionByType = {
1409
1417
  policy: "thread",
1410
1418
  rationale: "Subscription usage is account-scoped state that can affect multiple turns and threads."
1411
1419
  },
1420
+ "provider.env-resolved": {
1421
+ policy: "thread",
1422
+ rationale: "Resolved provider environment is session state and can change between turns."
1423
+ },
1412
1424
  "thread/extensionState/updated": {
1413
1425
  policy: "thread",
1414
1426
  rationale: "Plugin-declared thread state is current thread metadata (like goals), not part of a specific turn transcript; latest snapshot per kind wins."
@@ -2052,6 +2064,25 @@ var unscopedProviderEventSchema = z14.discriminatedUnion("type", [
2052
2064
  providerThreadId: z14.string(),
2053
2065
  rateLimits: providerRateLimitStateSchema
2054
2066
  }),
2067
+ z14.object({
2068
+ type: z14.literal("provider.env-resolved"),
2069
+ threadId: z14.string(),
2070
+ providerThreadId: z14.string(),
2071
+ entries: z14.array(
2072
+ z14.object({
2073
+ name: z14.string(),
2074
+ source: z14.union([
2075
+ z14.literal("shell"),
2076
+ z14.object({ plugin: z14.string() }).strict()
2077
+ ]),
2078
+ value: z14.union([
2079
+ z14.string(),
2080
+ z14.object({ masked: z14.literal(true) }).strict()
2081
+ ]),
2082
+ reason: z14.string().optional()
2083
+ }).strict()
2084
+ )
2085
+ }),
2055
2086
  z14.object({
2056
2087
  type: z14.literal("thread/extensionState/updated"),
2057
2088
  threadId: z14.string(),
@@ -2705,7 +2736,8 @@ var sessionReplacedNotificationSchema = z23.object({
2705
2736
  threadId: z23.string().min(1),
2706
2737
  providerThreadId: z23.string().min(1).nullable(),
2707
2738
  reason: z23.string().min(1),
2708
- contextLost: z23.boolean().default(false)
2739
+ contextLost: z23.boolean().default(false),
2740
+ showRuntimeNote: z23.boolean().default(false)
2709
2741
  }).passthrough();
2710
2742
  var providerRawNotificationSchema = z23.object({
2711
2743
  threadId: z23.string().min(1).optional(),
@@ -4189,6 +4221,11 @@ var acpCompactionCompletedNotificationParamsSchema = z34.discriminatedUnion("sta
4189
4221
  threadId: z34.string().min(1),
4190
4222
  status: z34.literal("interrupted")
4191
4223
  }).passthrough(),
4224
+ z34.object({
4225
+ threadId: z34.string().min(1),
4226
+ status: z34.literal("skipped"),
4227
+ detail: z34.string().min(1)
4228
+ }).passthrough(),
4192
4229
  z34.object({
4193
4230
  threadId: z34.string().min(1),
4194
4231
  status: z34.literal("failed"),
@@ -4820,6 +4857,18 @@ function ompCommandResult(event) {
4820
4857
  ...output.length === 0 ? {} : { output }
4821
4858
  };
4822
4859
  }
4860
+ var OMP_COMPACTION_FAILURE_PATTERN = /\bcompaction failed\b/i;
4861
+ var OMP_COMPACTION_NOOP_PATTERN = /\b(?:nothing to compact|already compacted)\b/i;
4862
+ function compactionOutcomeForEndTurn(dialect, agentMessage) {
4863
+ if (dialect.id !== "omp") {
4864
+ return { status: "completed" };
4865
+ }
4866
+ const text = agentMessage.trim();
4867
+ if (!OMP_COMPACTION_FAILURE_PATTERN.test(text)) {
4868
+ return { status: "completed" };
4869
+ }
4870
+ return OMP_COMPACTION_NOOP_PATTERN.test(text) ? { status: "skipped", detail: text } : { status: "failed", error: text };
4871
+ }
4823
4872
  var OMP_ACP_DIALECT = {
4824
4873
  id: "omp",
4825
4874
  commandResult: ompCommandResult
@@ -6022,12 +6071,22 @@ function createAcpDeltaTranslator(options = {}) {
6022
6071
  return [];
6023
6072
  }
6024
6073
  const status = params.data.status;
6074
+ const turnStatus = status === "skipped" ? "completed" : status;
6025
6075
  return [
6026
- ...flushOpenTurnWork(context, status),
6076
+ ...flushOpenTurnWork(context, itemStatusForTurnStatus(turnStatus)),
6027
6077
  ...status === "completed" ? [{ kind: "context.compacted" }] : [],
6078
+ ...status === "skipped" ? [
6079
+ {
6080
+ kind: "provider.warning",
6081
+ category: "compaction-skipped",
6082
+ summary: "Context compaction skipped",
6083
+ details: params.data.detail,
6084
+ vouchedTurn: true
6085
+ }
6086
+ ] : [],
6028
6087
  {
6029
6088
  kind: "turn.boundary",
6030
- status,
6089
+ status: turnStatus,
6031
6090
  ...status === "failed" ? { error: { message: params.data.error } } : {}
6032
6091
  }
6033
6092
  ];
@@ -6663,6 +6722,93 @@ function splitPrimaryModels(catalogModels, primaryModels) {
6663
6722
  };
6664
6723
  }
6665
6724
 
6725
+ // ../provider-bridge-acp/src/cursor-model-selection.ts
6726
+ var CURSOR_LEGACY_FAMILY_SELECTIONS = {
6727
+ "claude-4-sonnet": { modelId: "claude-sonnet-4" },
6728
+ "claude-4.5-opus": { modelId: "claude-opus-4-5" },
6729
+ "claude-4.5-sonnet": { modelId: "claude-sonnet-4-5" },
6730
+ "claude-4.6-opus": { modelId: "claude-opus-4-6" },
6731
+ "claude-4.6-sonnet": { modelId: "claude-sonnet-4-6" },
6732
+ "gemini-3.6-flash-minimal": {
6733
+ modelId: "gemini-3.6-flash",
6734
+ reasoningLevel: "low"
6735
+ },
6736
+ "gpt-5.1-codex-max": { modelId: "gpt-5.1" }
6737
+ };
6738
+ function bareCursorFamilyId(model) {
6739
+ const familyId = model === "auto" ? "default" : agentModelFamilyId(model);
6740
+ return familyId.startsWith("cursor-") ? familyId.slice("cursor-".length) : familyId;
6741
+ }
6742
+ function cursorParameterizedSelection(model, reasoningLevel) {
6743
+ const familyId = bareCursorFamilyId(model);
6744
+ const selection = CURSOR_LEGACY_FAMILY_SELECTIONS[familyId] ?? {
6745
+ modelId: familyId
6746
+ };
6747
+ return selection.reasoningLevel !== void 0 || reasoningLevel === void 0 ? selection : { ...selection, reasoningLevel };
6748
+ }
6749
+ function cursorCatalogModel(model) {
6750
+ const selection = cursorParameterizedSelection(
6751
+ model.id,
6752
+ model.defaultReasoningEffort
6753
+ );
6754
+ const efforts = /* @__PURE__ */ new Map();
6755
+ for (const effort of model.supportedReasoningEfforts) {
6756
+ const level = cursorParameterizedSelection(model.id, effort.reasoningEffort).reasoningLevel ?? effort.reasoningEffort;
6757
+ if (!efforts.has(level)) {
6758
+ efforts.set(level, { ...effort, reasoningEffort: level });
6759
+ }
6760
+ }
6761
+ return {
6762
+ model: {
6763
+ ...model,
6764
+ id: selection.modelId,
6765
+ model: selection.modelId,
6766
+ supportedReasoningEfforts: [...efforts.values()].sort(
6767
+ (a, b) => reasoningLevelValues.indexOf(a.reasoningEffort) - reasoningLevelValues.indexOf(b.reasoningEffort)
6768
+ ),
6769
+ defaultReasoningEffort: selection.reasoningLevel ?? model.defaultReasoningEffort
6770
+ },
6771
+ directFamily: bareCursorFamilyId(model.id) === selection.modelId
6772
+ };
6773
+ }
6774
+ function buildCursorParameterizedModelCatalog(models) {
6775
+ const normalized = /* @__PURE__ */ new Map();
6776
+ for (const model of models) {
6777
+ const candidate = cursorCatalogModel(model);
6778
+ const current = normalized.get(candidate.model.id);
6779
+ if (current === void 0) {
6780
+ normalized.set(candidate.model.id, candidate);
6781
+ continue;
6782
+ }
6783
+ const preferred = candidate.directFamily && !current.directFamily ? candidate : current;
6784
+ const efforts = new Map(
6785
+ preferred.model.supportedReasoningEfforts.map((effort) => [
6786
+ effort.reasoningEffort,
6787
+ effort
6788
+ ])
6789
+ );
6790
+ for (const effort of [
6791
+ ...current.model.supportedReasoningEfforts,
6792
+ ...candidate.model.supportedReasoningEfforts
6793
+ ]) {
6794
+ if (!efforts.has(effort.reasoningEffort)) {
6795
+ efforts.set(effort.reasoningEffort, effort);
6796
+ }
6797
+ }
6798
+ normalized.set(candidate.model.id, {
6799
+ model: {
6800
+ ...preferred.model,
6801
+ supportedReasoningEfforts: [...efforts.values()].sort(
6802
+ (a, b) => reasoningLevelValues.indexOf(a.reasoningEffort) - reasoningLevelValues.indexOf(b.reasoningEffort)
6803
+ ),
6804
+ isDefault: current.model.isDefault || candidate.model.isDefault
6805
+ },
6806
+ directFamily: preferred.directFamily
6807
+ });
6808
+ }
6809
+ return [...normalized.values()].map((entry) => entry.model);
6810
+ }
6811
+
6666
6812
  // ../provider-bridge-acp/src/session-params.ts
6667
6813
  function sanitizeAcpSkillDescription(description) {
6668
6814
  const sanitized = description.replace(/[\r\n]+/gu, " ").replace(/\s+/gu, " ").replace(/[<>]/gu, "").trim();
@@ -6751,26 +6897,6 @@ function buildAcpModelListParams(launchSpec, options) {
6751
6897
  ...launchSpec.nativeReasoning !== void 0 ? { nativeReasoning: launchSpec.nativeReasoning } : {}
6752
6898
  };
6753
6899
  }
6754
- var CURSOR_LEGACY_FAMILY_SELECTIONS = {
6755
- "claude-4-sonnet": { modelId: "claude-sonnet-4" },
6756
- "claude-4.5-opus": { modelId: "claude-opus-4-5" },
6757
- "claude-4.5-sonnet": { modelId: "claude-sonnet-4-5" },
6758
- "claude-4.6-opus": { modelId: "claude-opus-4-6" },
6759
- "claude-4.6-sonnet": { modelId: "claude-sonnet-4-6" },
6760
- "gemini-3.6-flash-minimal": {
6761
- modelId: "gemini-3.6-flash",
6762
- reasoningLevel: "low"
6763
- },
6764
- "gpt-5.1-codex-max": { modelId: "gpt-5.1" }
6765
- };
6766
- function cursorParameterizedSelection(model, reasoningLevel) {
6767
- const familyId = model === "auto" ? "default" : agentModelFamilyId(model);
6768
- const bareFamilyId = familyId.startsWith("cursor-") ? familyId.slice("cursor-".length) : familyId;
6769
- const selection = CURSOR_LEGACY_FAMILY_SELECTIONS[bareFamilyId] ?? {
6770
- modelId: bareFamilyId
6771
- };
6772
- return selection.reasoningLevel !== void 0 || reasoningLevel === void 0 ? selection : { ...selection, reasoningLevel };
6773
- }
6774
6900
  function buildAcpModelSelectionParam(launchSpec, options, parameterizedModelPicker, dialectId) {
6775
6901
  const model = options.model;
6776
6902
  const listCommand = buildAcpModelListCommand(launchSpec);
@@ -8636,6 +8762,7 @@ async function startAgentSession(request) {
8636
8762
  },
8637
8763
  pendingInstructions: params.instructions,
8638
8764
  activePromptKind: null,
8765
+ compactionAgentMessage: "",
8639
8766
  queuedInputs: [],
8640
8767
  promptRequestPending: false,
8641
8768
  cancelRequested: false,
@@ -8977,6 +9104,7 @@ function runTurn(session, firstInput) {
8977
9104
  }
8978
9105
  function startCompaction(session, pending) {
8979
9106
  session.activePromptKind = "compaction";
9107
+ session.compactionAgentMessage = "";
8980
9108
  emitForSession(session, ACP_COMPACTION_STARTED_METHOD, {
8981
9109
  threadId: session.bbThreadId
8982
9110
  });
@@ -8994,7 +9122,10 @@ function startCompaction(session, pending) {
8994
9122
  acceptTurnInput(session, pending);
8995
9123
  session.turnSettled = promptResult.then((result) => {
8996
9124
  finish(
8997
- result.stopReason === "end_turn" ? { status: "completed" } : result.stopReason === "cancelled" ? { status: "interrupted" } : {
9125
+ result.stopReason === "end_turn" ? compactionOutcomeForEndTurn(
9126
+ session.dialect,
9127
+ session.compactionAgentMessage
9128
+ ) : result.stopReason === "cancelled" ? { status: "interrupted" } : {
8998
9129
  status: "failed",
8999
9130
  error: `Agent stopped compaction: ${result.stopReason}`
9000
9131
  }
@@ -9080,6 +9211,14 @@ function handleAgentNotification(session, method, params) {
9080
9211
  if (parsed.data.sessionId !== session.providerThreadId) {
9081
9212
  return;
9082
9213
  }
9214
+ if (session.activePromptKind === "compaction") {
9215
+ const chunk = acpAgentMessageChunkUpdateSchema.safeParse(
9216
+ parsed.data.update
9217
+ );
9218
+ if (chunk.success) {
9219
+ session.compactionAgentMessage += extractAcpContentText(chunk.data.content) ?? "";
9220
+ }
9221
+ }
9083
9222
  emitForSession(session, ACP_UPDATE_METHOD, update);
9084
9223
  }
9085
9224
  function decodeAcpBridgeJsonRpcRequest(raw) {
@@ -9113,13 +9252,14 @@ function decodeAcpBridgeJsonRpcRequest(raw) {
9113
9252
  issues: command.error.issues.map((issue) => `${issue.path.join(".")}: ${issue.message}`).join("; ")
9114
9253
  };
9115
9254
  }
9116
- async function handleModelList(id, params) {
9255
+ async function handleModelList(id, params, dialectId) {
9117
9256
  const catalog = params.listCommand ? await loadAgentModelCatalog(params.listCommand) : null;
9118
9257
  if (catalog) {
9258
+ const catalogModels = params.parameterizedModelPicker && dialectId === "cursor" ? buildCursorParameterizedModelCatalog(catalog.models) : catalog.models;
9119
9259
  sendResult(
9120
9260
  id,
9121
9261
  splitPrimaryModels(
9122
- applyConfiguredReasoningToModels(catalog.models, {
9262
+ applyConfiguredReasoningToModels(catalogModels, {
9123
9263
  reasoningCli: params.reasoningCli,
9124
9264
  nativeReasoning: params.nativeReasoning
9125
9265
  }),
@@ -9221,7 +9361,8 @@ async function handleRequest2(request) {
9221
9361
  buildAcpModelListParams(
9222
9362
  decodeLaunchSpec(request.params.providerOptions),
9223
9363
  modelPicker
9224
- )
9364
+ ),
9365
+ decodeDialectId(request.params.providerOptions)
9225
9366
  );
9226
9367
  return;
9227
9368
  }
@@ -322,13 +322,21 @@ var threadEventItemPresentationTintSchema = z4.object({
322
322
  light: z4.string().min(1),
323
323
  dark: z4.string().min(1)
324
324
  });
325
+ var THREAD_EVENT_ITEM_PRESENTATION_BADGE_LABEL_MAX_LENGTH = 80;
326
+ var threadEventItemPresentationBadgeSchema = z4.object({
327
+ glyph: z4.string().min(1),
328
+ label: z4.string().min(1).max(THREAD_EVENT_ITEM_PRESENTATION_BADGE_LABEL_MAX_LENGTH),
329
+ hint: z4.string().min(1).max(THREAD_EVENT_ITEM_PRESENTATION_BADGE_LABEL_MAX_LENGTH),
330
+ tone: z4.enum(["neutral", "destructive"])
331
+ });
325
332
  var threadEventItemPresentationSchema = z4.object({
326
333
  label: threadEventItemPresentationLabelSchema,
327
334
  icon: threadEventItemPresentationIconSchema,
328
335
  title: z4.string().optional(),
329
336
  detail: z4.string().max(THREAD_EVENT_ITEM_PRESENTATION_DETAIL_MAX_LENGTH).optional(),
330
337
  suppress: z4.boolean().optional(),
331
- tint: threadEventItemPresentationTintSchema.optional()
338
+ tint: threadEventItemPresentationTintSchema.optional(),
339
+ badge: threadEventItemPresentationBadgeSchema.optional()
332
340
  });
333
341
 
334
342
  // ../domain/src/provider-extension-kind.ts
@@ -1041,6 +1049,10 @@ var threadEventScopeDefinitionByType = {
1041
1049
  policy: "thread",
1042
1050
  rationale: "Subscription usage is account-scoped state that can affect multiple turns and threads."
1043
1051
  },
1052
+ "provider.env-resolved": {
1053
+ policy: "thread",
1054
+ rationale: "Resolved provider environment is session state and can change between turns."
1055
+ },
1044
1056
  "thread/extensionState/updated": {
1045
1057
  policy: "thread",
1046
1058
  rationale: "Plugin-declared thread state is current thread metadata (like goals), not part of a specific turn transcript; latest snapshot per kind wins."
@@ -1693,6 +1705,25 @@ var unscopedProviderEventSchema = z12.discriminatedUnion("type", [
1693
1705
  providerThreadId: z12.string(),
1694
1706
  rateLimits: providerRateLimitStateSchema
1695
1707
  }),
1708
+ z12.object({
1709
+ type: z12.literal("provider.env-resolved"),
1710
+ threadId: z12.string(),
1711
+ providerThreadId: z12.string(),
1712
+ entries: z12.array(
1713
+ z12.object({
1714
+ name: z12.string(),
1715
+ source: z12.union([
1716
+ z12.literal("shell"),
1717
+ z12.object({ plugin: z12.string() }).strict()
1718
+ ]),
1719
+ value: z12.union([
1720
+ z12.string(),
1721
+ z12.object({ masked: z12.literal(true) }).strict()
1722
+ ]),
1723
+ reason: z12.string().optional()
1724
+ }).strict()
1725
+ )
1726
+ }),
1696
1727
  z12.object({
1697
1728
  type: z12.literal("thread/extensionState/updated"),
1698
1729
  threadId: z12.string(),
@@ -4564,7 +4595,8 @@ var sessionReplacedNotificationSchema = z24.object({
4564
4595
  threadId: z24.string().min(1),
4565
4596
  providerThreadId: z24.string().min(1).nullable(),
4566
4597
  reason: z24.string().min(1),
4567
- contextLost: z24.boolean().default(false)
4598
+ contextLost: z24.boolean().default(false),
4599
+ showRuntimeNote: z24.boolean().default(false)
4568
4600
  }).passthrough();
4569
4601
  var providerRawNotificationSchema = z24.object({
4570
4602
  threadId: z24.string().min(1).optional(),
@@ -1980,13 +1980,21 @@ var threadEventItemPresentationTintSchema = z10.object({
1980
1980
  light: z10.string().min(1),
1981
1981
  dark: z10.string().min(1)
1982
1982
  });
1983
+ var THREAD_EVENT_ITEM_PRESENTATION_BADGE_LABEL_MAX_LENGTH = 80;
1984
+ var threadEventItemPresentationBadgeSchema = z10.object({
1985
+ glyph: z10.string().min(1),
1986
+ label: z10.string().min(1).max(THREAD_EVENT_ITEM_PRESENTATION_BADGE_LABEL_MAX_LENGTH),
1987
+ hint: z10.string().min(1).max(THREAD_EVENT_ITEM_PRESENTATION_BADGE_LABEL_MAX_LENGTH),
1988
+ tone: z10.enum(["neutral", "destructive"])
1989
+ });
1983
1990
  var threadEventItemPresentationSchema = z10.object({
1984
1991
  label: threadEventItemPresentationLabelSchema,
1985
1992
  icon: threadEventItemPresentationIconSchema,
1986
1993
  title: z10.string().optional(),
1987
1994
  detail: z10.string().max(THREAD_EVENT_ITEM_PRESENTATION_DETAIL_MAX_LENGTH).optional(),
1988
1995
  suppress: z10.boolean().optional(),
1989
- tint: threadEventItemPresentationTintSchema.optional()
1996
+ tint: threadEventItemPresentationTintSchema.optional(),
1997
+ badge: threadEventItemPresentationBadgeSchema.optional()
1990
1998
  });
1991
1999
 
1992
2000
  // ../domain/src/provider-extension-kind.ts
@@ -2714,6 +2722,10 @@ var threadEventScopeDefinitionByType = {
2714
2722
  policy: "thread",
2715
2723
  rationale: "Subscription usage is account-scoped state that can affect multiple turns and threads."
2716
2724
  },
2725
+ "provider.env-resolved": {
2726
+ policy: "thread",
2727
+ rationale: "Resolved provider environment is session state and can change between turns."
2728
+ },
2717
2729
  "thread/extensionState/updated": {
2718
2730
  policy: "thread",
2719
2731
  rationale: "Plugin-declared thread state is current thread metadata (like goals), not part of a specific turn transcript; latest snapshot per kind wins."
@@ -3357,6 +3369,25 @@ var unscopedProviderEventSchema = z18.discriminatedUnion("type", [
3357
3369
  providerThreadId: z18.string(),
3358
3370
  rateLimits: providerRateLimitStateSchema
3359
3371
  }),
3372
+ z18.object({
3373
+ type: z18.literal("provider.env-resolved"),
3374
+ threadId: z18.string(),
3375
+ providerThreadId: z18.string(),
3376
+ entries: z18.array(
3377
+ z18.object({
3378
+ name: z18.string(),
3379
+ source: z18.union([
3380
+ z18.literal("shell"),
3381
+ z18.object({ plugin: z18.string() }).strict()
3382
+ ]),
3383
+ value: z18.union([
3384
+ z18.string(),
3385
+ z18.object({ masked: z18.literal(true) }).strict()
3386
+ ]),
3387
+ reason: z18.string().optional()
3388
+ }).strict()
3389
+ )
3390
+ }),
3360
3391
  z18.object({
3361
3392
  type: z18.literal("thread/extensionState/updated"),
3362
3393
  threadId: z18.string(),
@@ -4280,7 +4311,8 @@ var sessionReplacedNotificationSchema = z29.object({
4280
4311
  threadId: z29.string().min(1),
4281
4312
  providerThreadId: z29.string().min(1).nullable(),
4282
4313
  reason: z29.string().min(1),
4283
- contextLost: z29.boolean().default(false)
4314
+ contextLost: z29.boolean().default(false),
4315
+ showRuntimeNote: z29.boolean().default(false)
4284
4316
  }).passthrough();
4285
4317
  var providerRawNotificationSchema = z29.object({
4286
4318
  threadId: z29.string().min(1).optional(),
@@ -425,6 +425,7 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
425
425
  const collected = {
426
426
  homepageSections: [],
427
427
  settingsSections: [],
428
+ appOverlays: [],
428
429
  navPanels: [],
429
430
  threadPanelActions: [],
430
431
  newThreadPanelActions: [],
@@ -447,6 +448,7 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
447
448
  const seenIds = {
448
449
  homepageSection: /* @__PURE__ */ new Set(),
449
450
  settingsSection: /* @__PURE__ */ new Set(),
451
+ appOverlay: /* @__PURE__ */ new Set(),
450
452
  navPanel: /* @__PURE__ */ new Set(),
451
453
  threadPanelAction: /* @__PURE__ */ new Set(),
452
454
  newThreadPanelAction: /* @__PURE__ */ new Set(),
@@ -495,6 +497,15 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
495
497
  component: requireComponent(kind, registration.component)
496
498
  });
497
499
  },
500
+ experimental_appOverlay(registration) {
501
+ const kind = "slots.experimental_appOverlay";
502
+ const id = requireSlotId(kind, registration?.id);
503
+ requireUniqueId(kind, seenIds.appOverlay, id);
504
+ collected.appOverlays.push({
505
+ id,
506
+ component: requireComponent(kind, registration.component)
507
+ });
508
+ },
498
509
  navPanel(registration) {
499
510
  const kind = "slots.navPanel";
500
511
  const id = requireSlotId(kind, registration?.id);