@yaklabs-ai/plugin-protocol 0.13.3 → 0.13.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -5,6 +5,12 @@ var KAY_APP_DATA_READ_REQUEST_MAX_BYTES = 64 * 1024;
5
5
  var KAY_APP_DATA_READ_RESULT_MAX_BYTES = 16 * 1024 * 1024;
6
6
 
7
7
  // packages/plugin-protocol/dist/transcript.js
8
+ import { z } from "zod";
9
+ var WorkBlockCoverageSchema = z.strictObject({
10
+ firstToolResultEntryId: z.string().min(1),
11
+ lastToolResultEntryId: z.string().min(1),
12
+ toolResultEntryIds: z.array(z.string().min(1)).min(1).max(4096)
13
+ }).refine((value) => value.firstToolResultEntryId === value.toolResultEntryIds[0] && value.lastToolResultEntryId === value.toolResultEntryIds.at(-1) && new Set(value.toolResultEntryIds).size === value.toolResultEntryIds.length);
8
14
  function branchEntryIds(entries) {
9
15
  const last = entries[entries.length - 1];
10
16
  if (last === void 0)
@@ -109,13 +115,13 @@ function precedingPersonMessages(entries, packet, count) {
109
115
  }
110
116
 
111
117
  // packages/plugin-protocol/dist/app-data-read.js
112
- import { z as z2 } from "zod";
118
+ import { z as z3 } from "zod";
113
119
 
114
120
  // packages/plugin-protocol/dist/common.js
115
- import { z } from "zod";
121
+ import { z as z2 } from "zod";
116
122
  var KAY_PLUGIN_PROTOCOL_VERSION = "kay.plugin.v1";
117
123
  var KAY_PLUGIN_PROTOCOL_PACKAGE_NAME = "@bonsai/plugin-protocol";
118
- var KAY_PLUGIN_SDK_VERSION = "0.13.3";
124
+ var KAY_PLUGIN_SDK_VERSION = "0.13.5";
119
125
  var KAY_PLUGIN_COMPATIBLE_SDK_VERSIONS = [
120
126
  "0.8.0",
121
127
  "0.8.1",
@@ -136,70 +142,72 @@ var KAY_PLUGIN_COMPATIBLE_SDK_VERSIONS = [
136
142
  "0.12.5",
137
143
  "0.13.0",
138
144
  "0.13.1",
139
- "0.13.2"
145
+ "0.13.2",
146
+ "0.13.3",
147
+ "0.13.4"
140
148
  ];
141
149
  var KAY_PLUGIN_TARGET_NAMES = [
142
150
  "kay.agent",
143
151
  "kay.app",
144
152
  "kay.ui"
145
153
  ];
146
- var KayPluginProtocolVersion = z.literal(KAY_PLUGIN_PROTOCOL_VERSION);
147
- var PluginTargetName = z.enum(KAY_PLUGIN_TARGET_NAMES);
148
- var NonEmptyString = z.string().trim().min(1);
149
- var JsonValue = z.lazy(() => z.union([
150
- z.string(),
151
- z.number(),
152
- z.boolean(),
153
- z.null(),
154
- z.array(JsonValue),
155
- z.record(z.string(), JsonValue)
154
+ var KayPluginProtocolVersion = z2.literal(KAY_PLUGIN_PROTOCOL_VERSION);
155
+ var PluginTargetName = z2.enum(KAY_PLUGIN_TARGET_NAMES);
156
+ var NonEmptyString = z2.string().trim().min(1);
157
+ var JsonValue = z2.lazy(() => z2.union([
158
+ z2.string(),
159
+ z2.number(),
160
+ z2.boolean(),
161
+ z2.null(),
162
+ z2.array(JsonValue),
163
+ z2.record(z2.string(), JsonValue)
156
164
  ]));
157
- var JsonObject = z.record(z.string(), JsonValue);
158
- var JsonSchema = z.record(z.string(), JsonValue);
165
+ var JsonObject = z2.record(z2.string(), JsonValue);
166
+ var JsonSchema = z2.record(z2.string(), JsonValue);
159
167
  var PLUGIN_ID_PATTERN = /^[a-z][a-z0-9-]*(?:\.[a-z][a-z0-9-]*)*$/;
160
168
  var LOCAL_CONTRIBUTION_ID_PATTERN = /^[a-z][a-z0-9-]*$/;
161
169
  var PLUGIN_TOOL_NAME_PATTERN = /^[a-z][a-z0-9_-]*$/;
162
170
  var PACKAGE_ASSET_PATH_PATTERN = /^\.\/(?:[A-Za-z0-9._-]+\/)*[A-Za-z0-9._-]+$/;
163
171
  var KAY_EVENT_PUBLISHER_ID = "kay";
164
- var PluginId = z.string().trim().regex(PLUGIN_ID_PATTERN).refine((id) => id !== KAY_EVENT_PUBLISHER_ID, {
172
+ var PluginId = z2.string().trim().regex(PLUGIN_ID_PATTERN).refine((id) => id !== KAY_EVENT_PUBLISHER_ID, {
165
173
  message: `'${KAY_EVENT_PUBLISHER_ID}' is reserved for Bonsai's own event publisher`
166
174
  });
167
175
  var PluginNamespace = PluginId;
168
- var LocalContributionId = z.string().trim().regex(LOCAL_CONTRIBUTION_ID_PATTERN);
169
- var GlobalContributionId = z.string().trim().regex(PLUGIN_ID_PATTERN);
170
- var PluginToolName = z.string().trim().regex(PLUGIN_TOOL_NAME_PATTERN);
176
+ var LocalContributionId = z2.string().trim().regex(LOCAL_CONTRIBUTION_ID_PATTERN);
177
+ var GlobalContributionId = z2.string().trim().regex(PLUGIN_ID_PATTERN);
178
+ var PluginToolName = z2.string().trim().regex(PLUGIN_TOOL_NAME_PATTERN);
171
179
  var AuthServiceReference = GlobalContributionId;
172
180
  var AuthSchemeReference = GlobalContributionId;
173
- var AdapterSelectionKey = z.string().trim().regex(PLUGIN_ID_PATTERN);
174
- var AdapterPlacement = z.enum(["local-only", "anywhere"]);
175
- var UriScheme = z.string().trim().regex(/^[a-z][a-z0-9+.-]*$/);
176
- var MimeTypeString = z.string().trim().regex(/^[a-z0-9][a-z0-9!#$&^_.+-]*\/[a-z0-9][a-z0-9!#$&^_.+-]*$/);
177
- var FileExtensionToken = z.string().trim().regex(/^[a-z0-9]+$/);
181
+ var AdapterSelectionKey = z2.string().trim().regex(PLUGIN_ID_PATTERN);
182
+ var AdapterPlacement = z2.enum(["local-only", "anywhere"]);
183
+ var UriScheme = z2.string().trim().regex(/^[a-z][a-z0-9+.-]*$/);
184
+ var MimeTypeString = z2.string().trim().regex(/^[a-z0-9][a-z0-9!#$&^_.+-]*\/[a-z0-9][a-z0-9!#$&^_.+-]*$/);
185
+ var FileExtensionToken = z2.string().trim().regex(/^[a-z0-9]+$/);
178
186
  var CliBinaryName = NonEmptyString.refine((value) => !value.includes("/"), {
179
187
  message: "cli binding binary/alias must be a basename, not a path (no '/')"
180
188
  });
181
- var CliAuthEnvVarName = z.string().trim().regex(/^[A-Z][A-Z0-9_]*$/);
182
- var PackageAssetPath = z.string().trim().regex(PACKAGE_ASSET_PATH_PATTERN).refine((value) => !value.split("/").includes(".."), {
189
+ var CliAuthEnvVarName = z2.string().trim().regex(/^[A-Z][A-Z0-9_]*$/);
190
+ var PackageAssetPath = z2.string().trim().regex(PACKAGE_ASSET_PATH_PATTERN).refine((value) => !value.split("/").includes(".."), {
183
191
  message: "package asset path must not contain a '..' path segment"
184
192
  });
185
- var PluginSourceClass = z.enum([
193
+ var PluginSourceClass = z2.enum([
186
194
  "bundled",
187
195
  "org-shared",
188
196
  "user-local",
189
197
  "verified-marketplace",
190
198
  "freeform"
191
199
  ]);
192
- var ArtifactGenerationId = z.string().trim().min(1).brand();
193
- var HttpsUrl = z.url({ protocol: /^https$/ });
194
- var RegistrableDomain = z.string().trim().regex(/^[a-z0-9-]+(?:\.[a-z0-9-]+)+$/);
200
+ var ArtifactGenerationId = z2.string().trim().min(1).brand();
201
+ var HttpsUrl = z2.url({ protocol: /^https$/ });
202
+ var RegistrableDomain = z2.string().trim().regex(/^[a-z0-9-]+(?:\.[a-z0-9-]+)+$/);
195
203
  var HOST_LABEL_PATTERN = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;
196
204
  var MAX_HOST_LENGTH = 253;
197
205
  var MAX_HOST_LABEL_LENGTH = 63;
198
206
  var GitHostName = RegistrableDomain.max(MAX_HOST_LENGTH).refine((host) => host.split(".").every((label) => label.length <= MAX_HOST_LABEL_LENGTH && HOST_LABEL_PATTERN.test(label)), {
199
207
  message: "git host labels must be 1-63 characters and start and end with a letter or digit"
200
208
  });
201
- var GitBasicAuthUser = z.string().trim().min(1).max(128).regex(/^[A-Za-z0-9._~-]+$/);
202
- var HttpStatusCode = z.number().int().min(100).max(599);
209
+ var GitBasicAuthUser = z2.string().trim().min(1).max(128).regex(/^[A-Za-z0-9._~-]+$/);
210
+ var HttpStatusCode = z2.number().int().min(100).max(599);
203
211
  var SignedInStatusCode = HttpStatusCode.refine((status) => !(status < 200 || status >= 300 && status < 400), {
204
212
  message: "signedInStatuses cannot include 1xx or 3xx: the probe follows redirects and never observes them as a final status"
205
213
  });
@@ -230,57 +238,57 @@ function refineWebSessionScopeConfined(webSession, ctx) {
230
238
  });
231
239
  }
232
240
  }
233
- var JsonPointer = z.string().trim().regex(/^(?:\/(?:[^/~]|~[01])*)*$/);
234
- var TargetEntrypoint = z.strictObject({
241
+ var JsonPointer = z2.string().trim().regex(/^(?:\/(?:[^/~]|~[01])*)*$/);
242
+ var TargetEntrypoint = z2.strictObject({
235
243
  module: NonEmptyString,
236
244
  export: NonEmptyString.optional()
237
245
  });
238
246
 
239
247
  // packages/plugin-protocol/dist/app-data-read.js
240
- var AppDataVersionedSchema = z2.strictObject({
241
- version: z2.number().int().positive(),
248
+ var AppDataVersionedSchema = z3.strictObject({
249
+ version: z3.number().int().positive(),
242
250
  schema: JsonSchema
243
251
  });
244
- var AppDataSourceRead = z2.strictObject({
252
+ var AppDataSourceRead = z3.strictObject({
245
253
  request: AppDataVersionedSchema,
246
254
  result: AppDataVersionedSchema
247
255
  });
248
256
 
249
257
  // packages/plugin-protocol/dist/artifact-provenance.js
250
- import { z as z4 } from "zod";
258
+ import { z as z5 } from "zod";
251
259
 
252
260
  // packages/plugin-protocol/dist/session-provenance.js
253
- import { z as z3 } from "zod";
254
- var NonEmptyString2 = z3.string().min(1);
261
+ import { z as z4 } from "zod";
262
+ var NonEmptyString2 = z4.string().min(1);
255
263
  var SessionId = NonEmptyString2;
256
- var SessionRelationship = z3.discriminatedUnion("kind", [
264
+ var SessionRelationship = z4.discriminatedUnion("kind", [
257
265
  /** Spawn lineage: this session is a subagent child of `sessionId`. */
258
- z3.strictObject({ kind: z3.literal("child-of"), sessionId: SessionId }),
266
+ z4.strictObject({ kind: z4.literal("child-of"), sessionId: SessionId }),
259
267
  /**
260
268
  * This session was forked from a point in `sessionId`'s transcript — `/fork`, and every
261
269
  * hindsight followup. `atEntryId` pins the fork point when one was given.
262
270
  */
263
- z3.strictObject({
264
- kind: z3.literal("forked-from"),
271
+ z4.strictObject({
272
+ kind: z4.literal("forked-from"),
265
273
  sessionId: SessionId,
266
274
  atEntryId: NonEmptyString2.optional()
267
275
  })
268
276
  ]);
269
- var SdkSessionDoor = z3.enum([
277
+ var SdkSessionDoor = z4.enum([
270
278
  "sessions.create",
271
279
  "sessions.run",
272
280
  "hindsight.runFollowup",
273
281
  "agents.run"
274
282
  ]);
275
- var SessionCreator = z3.discriminatedUnion("kind", [
283
+ var SessionCreator = z4.discriminatedUnion("kind", [
276
284
  /** A person, at the keyboard. `surface` names a scripted experience when one minted it. */
277
- z3.strictObject({
278
- kind: z3.literal("human"),
285
+ z4.strictObject({
286
+ kind: z4.literal("human"),
279
287
  surface: NonEmptyString2.optional()
280
288
  }),
281
289
  /** Another session's agent, through a tool call. */
282
- z3.strictObject({
283
- kind: z3.literal("agent"),
290
+ z4.strictObject({
291
+ kind: z4.literal("agent"),
284
292
  sessionId: SessionId,
285
293
  tool: NonEmptyString2,
286
294
  /**
@@ -298,8 +306,8 @@ var SessionCreator = z3.discriminatedUnion("kind", [
298
306
  toolCallId: NonEmptyString2.optional()
299
307
  }),
300
308
  /** A plugin, through one of its SDK doors. */
301
- z3.strictObject({
302
- kind: z3.literal("plugin"),
309
+ z4.strictObject({
310
+ kind: z4.literal("plugin"),
303
311
  pluginId: NonEmptyString2,
304
312
  door: SdkSessionDoor,
305
313
  callerSessionId: SessionId.optional()
@@ -313,8 +321,8 @@ var SessionCreator = z3.discriminatedUnion("kind", [
313
321
  * schedule nor a session-fact occurrence. Added 2026-08-19, when the automation producers
314
322
  * landed and a watcher's report session had nothing honest to stamp.
315
323
  */
316
- z3.strictObject({
317
- kind: z3.literal("trigger"),
324
+ z4.strictObject({
325
+ kind: z4.literal("trigger"),
318
326
  automationId: NonEmptyString2,
319
327
  /**
320
328
  * The AUTOMATION RUN that fired the binding (R2 provenance). Optional at
@@ -324,10 +332,10 @@ var SessionCreator = z3.discriminatedUnion("kind", [
324
332
  */
325
333
  runId: NonEmptyString2.optional(),
326
334
  bindingName: NonEmptyString2,
327
- triggerKind: z3.enum(["cron", "time", "occurrence", "uri-change", "manual"])
335
+ triggerKind: z4.enum(["cron", "time", "occurrence", "uri-change", "manual"])
328
336
  }),
329
337
  /** The daemon itself, for one of its own capabilities. */
330
- z3.strictObject({ kind: z3.literal("daemon"), capability: NonEmptyString2 })
338
+ z4.strictObject({ kind: z4.literal("daemon"), capability: NonEmptyString2 })
331
339
  ]);
332
340
  var AGENT_RUNTIME_SESSION_CREATOR_KINDS = [
333
341
  "human",
@@ -336,29 +344,30 @@ var AGENT_RUNTIME_SESSION_CREATOR_KINDS = [
336
344
  "trigger",
337
345
  "daemon"
338
346
  ];
339
- var SessionDefiner = z3.discriminatedUnion("layer", [
340
- z3.strictObject({
341
- layer: z3.literal("plugin"),
347
+ var SessionDefiner = z4.discriminatedUnion("layer", [
348
+ z4.strictObject({
349
+ layer: z4.literal("plugin"),
342
350
  pluginId: NonEmptyString2,
343
351
  capability: NonEmptyString2,
344
352
  /** See the type docblock: unpopulated by design until #5230's children land. */
345
353
  version: NonEmptyString2.optional()
346
354
  }),
347
- z3.strictObject({ layer: z3.literal("host"), capability: NonEmptyString2 })
355
+ z4.strictObject({ layer: z4.literal("host"), capability: NonEmptyString2 })
348
356
  ]);
349
- var SessionIntent = z3.enum(["interactive", "headless"]);
350
- var SessionCausedByEventShape = z3.strictObject({
357
+ var SessionIntent = z4.enum(["interactive", "headless"]);
358
+ var SessionCausedByEventShape = z4.strictObject({
351
359
  /** The plugin's own name for the subscribe handler that made this run, e.g. `"work-record"`. */
352
360
  handler: NonEmptyString2,
353
361
  /** Absent reads as `"session-event"` — see this type's own doc comment. */
354
- kind: z3.enum(["session-event", "backfill"]).optional(),
362
+ kind: z4.enum(["session-event", "backfill"]).optional(),
355
363
  /** Required when `kind` is `"session-event"` or absent; must be omitted when `kind` is `"backfill"`. */
356
- event: z3.strictObject({
364
+ event: z4.strictObject({
357
365
  /** {@link KayAppSessionEventType} in `@bonsai/plugin-sdk`, mirrored: a closed, extensible union. */
358
- type: z3.enum([
366
+ type: z4.enum([
359
367
  "turn-settled",
360
368
  "phase-shift",
361
369
  "human-message",
370
+ "assistant-message",
362
371
  "ui-action"
363
372
  ]),
364
373
  entryId: NonEmptyString2,
@@ -383,8 +392,8 @@ var SessionCausedByEvent = SessionCausedByEventShape.refine((value) => (value.ki
383
392
  message: 'event must be omitted when kind is "backfill"',
384
393
  path: ["event"]
385
394
  });
386
- var SessionProvenanceRecord = z3.strictObject({
387
- relationships: z3.array(SessionRelationship),
395
+ var SessionProvenanceRecord = z4.strictObject({
396
+ relationships: z4.array(SessionRelationship),
388
397
  createdBy: SessionCreator,
389
398
  definedBy: SessionDefiner,
390
399
  intent: SessionIntent,
@@ -448,93 +457,93 @@ function isProvenanceJson(input) {
448
457
  }
449
458
  return true;
450
459
  }
451
- var Text = z4.string().min(1).refine((value) => !hasControlCharacter(value), {
460
+ var Text = z5.string().min(1).refine((value) => !hasControlCharacter(value), {
452
461
  message: "Provenance text must not contain control characters"
453
462
  });
454
- var ArtifactProvenanceRevision = z4.strictObject({
463
+ var ArtifactProvenanceRevision = z5.strictObject({
455
464
  storeId: Text,
456
465
  artifactId: Text,
457
466
  uri: Text.optional(),
458
467
  /** The enclosing commit is resolved by the reader, avoiding a self-referential commit hash. */
459
- revision: z4.union([
468
+ revision: z5.union([
460
469
  Text,
461
- z4.strictObject({ kind: z4.literal("enclosing-commit") }),
462
- z4.null()
470
+ z5.strictObject({ kind: z5.literal("enclosing-commit") }),
471
+ z5.null()
463
472
  ]),
464
473
  operationId: Text.nullable(),
465
474
  /** Optional when the store identifies revisions without content addressing (including tombstones). */
466
- digest: z4.strictObject({ algorithm: Text, value: Text }).optional()
475
+ digest: z5.strictObject({ algorithm: Text, value: Text }).optional()
467
476
  });
468
- var ArtifactProvenanceActor = z4.discriminatedUnion("kind", [
469
- z4.strictObject({
470
- kind: z4.literal("session"),
477
+ var ArtifactProvenanceActor = z5.discriminatedUnion("kind", [
478
+ z5.strictObject({
479
+ kind: z5.literal("session"),
471
480
  sessionId: Text,
472
481
  runId: Text.nullable()
473
482
  }),
474
- z4.strictObject({
475
- kind: z4.literal("human"),
483
+ z5.strictObject({
484
+ kind: z5.literal("human"),
476
485
  userId: Text.optional(),
477
486
  surface: Text
478
487
  }),
479
- z4.strictObject({
480
- kind: z4.literal("plugin"),
488
+ z5.strictObject({
489
+ kind: z5.literal("plugin"),
481
490
  pluginId: Text,
482
491
  capability: Text
483
492
  }),
484
- z4.strictObject({ kind: z4.literal("host"), capability: Text }),
485
- z4.strictObject({ kind: z4.literal("import"), source: Text }),
486
- z4.strictObject({ kind: z4.literal("unknown") })
493
+ z5.strictObject({ kind: z5.literal("host"), capability: Text }),
494
+ z5.strictObject({ kind: z5.literal("import"), source: Text }),
495
+ z5.strictObject({ kind: z5.literal("unknown") })
487
496
  ]);
488
- var ArtifactProvenanceCause = z4.discriminatedUnion("kind", [
489
- z4.strictObject({
490
- kind: z4.literal("session"),
497
+ var ArtifactProvenanceCause = z5.discriminatedUnion("kind", [
498
+ z5.strictObject({
499
+ kind: z5.literal("session"),
491
500
  sessionId: Text,
492
501
  runId: Text.nullable()
493
502
  }),
494
- z4.strictObject({
495
- kind: z4.literal("session-event"),
503
+ z5.strictObject({
504
+ kind: z5.literal("session-event"),
496
505
  sessionId: Text,
497
506
  cause: SessionCausedByEvent
498
507
  }),
499
- z4.strictObject({
500
- kind: z4.literal("automation"),
508
+ z5.strictObject({
509
+ kind: z5.literal("automation"),
501
510
  automationId: Text,
502
511
  runId: Text.nullable()
503
512
  }),
504
- z4.strictObject({ kind: z4.literal("operation"), operationId: Text })
513
+ z5.strictObject({ kind: z5.literal("operation"), operationId: Text })
505
514
  ]);
506
- var ArtifactProvenanceOperation = z4.strictObject({
515
+ var ArtifactProvenanceOperation = z5.strictObject({
507
516
  id: Text.nullable(),
508
- at: z4.iso.datetime().nullable(),
517
+ at: z5.iso.datetime().nullable(),
509
518
  name: Text,
510
519
  actor: ArtifactProvenanceActor,
511
520
  /** Null means no tool invocation; a known invocation with an unknown id records a gap. */
512
- invocation: z4.strictObject({
521
+ invocation: z5.strictObject({
513
522
  tool: Text,
514
523
  toolCallId: Text.nullable(),
515
- origin: z4.enum(["model", "host"])
524
+ origin: z5.enum(["model", "host"])
516
525
  }).nullable(),
517
526
  /** Known causes only; unavailable cause capture requires a gap, never a guessed creation cause. */
518
- causes: z4.array(ArtifactProvenanceCause)
527
+ causes: z5.array(ArtifactProvenanceCause)
519
528
  });
520
- var ArtifactProvenanceReference = z4.discriminatedUnion("kind", [
521
- z4.strictObject({
522
- kind: z4.literal("session"),
529
+ var ArtifactProvenanceReference = z5.discriminatedUnion("kind", [
530
+ z5.strictObject({
531
+ kind: z5.literal("session"),
523
532
  sessionId: Text,
524
533
  runId: Text.optional()
525
534
  }),
526
- z4.strictObject({
527
- kind: z4.literal("artifact"),
535
+ z5.strictObject({
536
+ kind: z5.literal("artifact"),
528
537
  revision: ArtifactProvenanceRevision
529
538
  }),
530
- z4.strictObject({
531
- kind: z4.literal("resource"),
539
+ z5.strictObject({
540
+ kind: z5.literal("resource"),
532
541
  uri: Text,
533
542
  revision: Text.nullable()
534
543
  })
535
544
  ]);
536
- var ArtifactProvenanceGap = z4.strictObject({
537
- code: z4.enum([
545
+ var ArtifactProvenanceGap = z5.strictObject({
546
+ code: z5.enum([
538
547
  "unknown",
539
548
  "capture-failed",
540
549
  "legacy-derived",
@@ -547,18 +556,18 @@ var ArtifactProvenanceGap = z4.strictObject({
547
556
  "invalid-record"
548
557
  ]),
549
558
  /** JSON Pointer into this envelope; the empty pointer covers the whole capture. */
550
- at: z4.string().regex(/^(?:\/(?:[^~/]|~[01])*)*$/).refine((value) => !hasControlCharacter(value)),
559
+ at: z5.string().regex(/^(?:\/(?:[^~/]|~[01])*)*$/).refine((value) => !hasControlCharacter(value)),
551
560
  detail: Text.optional()
552
561
  }).refine((gap) => gap.at !== "" || gap.code === "capture-failed", {
553
562
  message: "Only a whole-capture failure may cover the entire envelope"
554
563
  });
555
- var ArtifactProvenanceSession = z4.strictObject({
564
+ var ArtifactProvenanceSession = z5.strictObject({
556
565
  sessionId: Text,
557
- basis: z4.enum(["recorded", "legacy-derived", "unverified-index", "missing"]),
566
+ basis: z5.enum(["recorded", "legacy-derived", "unverified-index", "missing"]),
558
567
  record: SessionProvenanceRecord.nullable()
559
568
  });
560
- var ArtifactProvenanceSource = z4.strictObject({
561
- relationship: z4.enum([
569
+ var ArtifactProvenanceSource = z5.strictObject({
570
+ relationship: z5.enum([
562
571
  "revision-of",
563
572
  "copied-from",
564
573
  "harvested-from",
@@ -568,8 +577,8 @@ var ArtifactProvenanceSource = z4.strictObject({
568
577
  ]),
569
578
  revision: ArtifactProvenanceRevision
570
579
  });
571
- var ArtifactProvenanceMutation = z4.strictObject({
572
- kind: z4.enum([
580
+ var ArtifactProvenanceMutation = z5.strictObject({
581
+ kind: z5.enum([
573
582
  "create",
574
583
  "update",
575
584
  "delete",
@@ -582,16 +591,16 @@ var ArtifactProvenanceMutation = z4.strictObject({
582
591
  target: ArtifactProvenanceRevision,
583
592
  /** Retained from the source on copies/acceptance; operation.actor is the persistence actor. */
584
593
  producer: ArtifactProvenanceOperation,
585
- sources: z4.array(ArtifactProvenanceSource)
594
+ sources: z5.array(ArtifactProvenanceSource)
586
595
  });
587
- var Envelope = z4.strictObject({
588
- version: z4.literal(ARTIFACT_PROVENANCE_VERSION),
596
+ var Envelope = z5.strictObject({
597
+ version: z5.literal(ARTIFACT_PROVENANCE_VERSION),
589
598
  operation: ArtifactProvenanceOperation,
590
- artifacts: z4.array(ArtifactProvenanceMutation).min(1),
591
- sessions: z4.array(ArtifactProvenanceSession),
592
- subjects: z4.array(ArtifactProvenanceReference),
593
- evidence: z4.array(ArtifactProvenanceReference),
594
- gaps: z4.array(ArtifactProvenanceGap)
599
+ artifacts: z5.array(ArtifactProvenanceMutation).min(1),
600
+ sessions: z5.array(ArtifactProvenanceSession),
601
+ subjects: z5.array(ArtifactProvenanceReference),
602
+ evidence: z5.array(ArtifactProvenanceReference),
603
+ gaps: z5.array(ArtifactProvenanceGap)
595
604
  });
596
605
  var UNKNOWN = [
597
606
  "unknown",
@@ -762,18 +771,18 @@ function validateEnvelope(envelope, context) {
762
771
  }
763
772
  checkGraph(envelope, gap, issue);
764
773
  }
765
- var ArtifactProvenanceEnvelopeV1 = z4.unknown().refine(isProvenanceJson, {
774
+ var ArtifactProvenanceEnvelopeV1 = z5.unknown().refine(isProvenanceJson, {
766
775
  message: "Provenance must be plain, acyclic, lossless JSON without control characters"
767
776
  }).pipe(Envelope.superRefine(validateEnvelope));
768
777
  function parseArtifactProvenanceEnvelope(input) {
769
778
  return ArtifactProvenanceEnvelopeV1.parse(input);
770
779
  }
771
- var ArtifactProvenanceCaptureContextSchema = z4.strictObject({
780
+ var ArtifactProvenanceCaptureContextSchema = z5.strictObject({
772
781
  operation: ArtifactProvenanceOperation,
773
- sessions: z4.array(ArtifactProvenanceSession),
774
- subjects: z4.array(ArtifactProvenanceReference),
775
- evidence: z4.array(ArtifactProvenanceReference),
776
- gaps: z4.array(ArtifactProvenanceGap)
782
+ sessions: z5.array(ArtifactProvenanceSession),
783
+ subjects: z5.array(ArtifactProvenanceReference),
784
+ evidence: z5.array(ArtifactProvenanceReference),
785
+ gaps: z5.array(ArtifactProvenanceGap)
777
786
  });
778
787
  function parseArtifactProvenanceCaptureContext(input) {
779
788
  return ArtifactProvenanceCaptureContextSchema.parse(input);
@@ -1071,39 +1080,39 @@ function finalizeArtifactProvenanceEnvelope(capture, artifacts) {
1071
1080
  }
1072
1081
 
1073
1082
  // packages/plugin-protocol/dist/authority.js
1074
- import { z as z6 } from "zod";
1083
+ import { z as z7 } from "zod";
1075
1084
 
1076
1085
  // packages/plugin-protocol/dist/permissions.js
1077
- import { z as z5 } from "zod";
1078
- var AuthGrantOperation = z5.enum([
1086
+ import { z as z6 } from "zod";
1087
+ var AuthGrantOperation = z6.enum([
1079
1088
  "status",
1080
1089
  "connect",
1081
1090
  "disconnect",
1082
1091
  "resolve"
1083
1092
  ]);
1084
- var AuthAccountSelector = z5.discriminatedUnion("kind", [
1085
- z5.strictObject({ kind: z5.literal("active") }),
1086
- z5.strictObject({ kind: z5.literal("account-id"), accountId: NonEmptyString }),
1087
- z5.strictObject({ kind: z5.literal("record-id"), recordId: NonEmptyString })
1093
+ var AuthAccountSelector = z6.discriminatedUnion("kind", [
1094
+ z6.strictObject({ kind: z6.literal("active") }),
1095
+ z6.strictObject({ kind: z6.literal("account-id"), accountId: NonEmptyString }),
1096
+ z6.strictObject({ kind: z6.literal("record-id"), recordId: NonEmptyString })
1088
1097
  ]);
1089
- var AuthScopeDefinition = z5.strictObject({
1098
+ var AuthScopeDefinition = z6.strictObject({
1090
1099
  id: NonEmptyString,
1091
1100
  label: NonEmptyString,
1092
1101
  description: NonEmptyString,
1093
- documentationUrl: z5.url().optional()
1102
+ documentationUrl: z6.url().optional()
1094
1103
  });
1095
- var ScopeNeed = z5.strictObject({
1104
+ var ScopeNeed = z6.strictObject({
1096
1105
  scope: NonEmptyString,
1097
1106
  reason: NonEmptyString.optional()
1098
1107
  });
1099
- var ScopeAlternative = z5.strictObject({
1100
- allOf: z5.array(ScopeNeed).min(1)
1108
+ var ScopeAlternative = z6.strictObject({
1109
+ allOf: z6.array(ScopeNeed).min(1)
1101
1110
  });
1102
- var ScopeRequirement = z5.strictObject({
1111
+ var ScopeRequirement = z6.strictObject({
1103
1112
  purpose: NonEmptyString,
1104
- alternatives: z5.array(ScopeAlternative).min(1)
1113
+ alternatives: z6.array(ScopeAlternative).min(1)
1105
1114
  });
1106
- var AuthGrantRequestBase = z5.strictObject({
1115
+ var AuthGrantRequestBase = z6.strictObject({
1107
1116
  // A local (undotted) service must be declared in this same manifest; a
1108
1117
  // qualified (dotted) service names another plugin's global id and is an
1109
1118
  // external service dependency, recorded on the resolved contract's
@@ -1112,22 +1121,22 @@ var AuthGrantRequestBase = z5.strictObject({
1112
1121
  // Optional for backward compatibility with grants whose service has a
1113
1122
  // single unambiguous scheme. Local ids resolve under the service owner's
1114
1123
  // namespace; qualified ids are preserved.
1115
- schemes: z5.array(AuthSchemeReference).min(1).optional(),
1116
- operations: z5.array(AuthGrantOperation).min(1),
1117
- purposes: z5.array(NonEmptyString).optional(),
1124
+ schemes: z6.array(AuthSchemeReference).min(1).optional(),
1125
+ operations: z6.array(AuthGrantOperation).min(1),
1126
+ purposes: z6.array(NonEmptyString).optional(),
1118
1127
  // Bridged by the runtime into an enforceable `CredentialGrant`:
1119
1128
  // `allowedScopes` is the caller's scope ENVELOPE and
1120
1129
  // `accountSelectors` map through. Absent `accountSelectors` resolves to the
1121
1130
  // narrowest bound (see `ResolvedAuthGrantRequest`); absent scope envelope
1122
1131
  // leaves the bridged grant scope-agnostic.
1123
- allowedScopes: z5.array(NonEmptyString).min(1).optional(),
1132
+ allowedScopes: z6.array(NonEmptyString).min(1).optional(),
1124
1133
  // Legacy spelling for `allowedScopes`; new manifests should use the authority-shaped name.
1125
- requiredScopes: z5.array(NonEmptyString).min(1).optional(),
1134
+ requiredScopes: z6.array(NonEmptyString).min(1).optional(),
1126
1135
  // Preferred proactive consent bundle; runtime resolution still uses `scopeRequirement`.
1127
- connectScopes: z5.array(NonEmptyString).min(1).optional(),
1136
+ connectScopes: z6.array(NonEmptyString).min(1).optional(),
1128
1137
  scopeRequirement: ScopeRequirement.optional(),
1129
- scopeDefinitions: z5.array(AuthScopeDefinition).min(1).optional(),
1130
- accountSelectors: z5.array(AuthAccountSelector).min(1).optional()
1138
+ scopeDefinitions: z6.array(AuthScopeDefinition).min(1).optional(),
1139
+ accountSelectors: z6.array(AuthAccountSelector).min(1).optional()
1131
1140
  });
1132
1141
  function validateAuthGrantRequest(grant, ctx) {
1133
1142
  if (grant.allowedScopes !== void 0 && grant.requiredScopes !== void 0) {
@@ -1207,19 +1216,19 @@ function validateAuthGrantRequest(grant, ctx) {
1207
1216
  }
1208
1217
  }
1209
1218
  var AuthGrantRequest = AuthGrantRequestBase.superRefine(validateAuthGrantRequest);
1210
- var StorageGrantRequest = z5.strictObject({
1211
- kind: z5.enum(["sqlite", "dataDir"]),
1212
- operations: z5.array(z5.enum(["open", "read", "write"])).min(1)
1219
+ var StorageGrantRequest = z6.strictObject({
1220
+ kind: z6.enum(["sqlite", "dataDir"]),
1221
+ operations: z6.array(z6.enum(["open", "read", "write"])).min(1)
1213
1222
  });
1214
- var EventGrantRequest = z5.strictObject({
1223
+ var EventGrantRequest = z6.strictObject({
1215
1224
  event: NonEmptyString,
1216
- operations: z5.array(z5.enum(["subscribe", "publish"])).min(1)
1225
+ operations: z6.array(z6.enum(["subscribe", "publish"])).min(1)
1217
1226
  });
1218
- var EndpointGrantRequest = z5.strictObject({
1227
+ var EndpointGrantRequest = z6.strictObject({
1219
1228
  endpoint: LocalContributionId,
1220
- operations: z5.array(z5.enum(["register", "invoke"])).min(1)
1229
+ operations: z6.array(z6.enum(["register", "invoke"])).min(1)
1221
1230
  });
1222
- var WebSessionOrigin = z5.string().superRefine((value, ctx) => {
1231
+ var WebSessionOrigin = z6.string().superRefine((value, ctx) => {
1223
1232
  try {
1224
1233
  const url = new URL(value);
1225
1234
  if (url.protocol !== "https:" || url.username !== "" || url.password !== "" || url.pathname !== "/" || url.search !== "" || url.hash !== "" || url.origin !== value) {
@@ -1232,7 +1241,7 @@ var WebSessionOrigin = z5.string().superRefine((value, ctx) => {
1232
1241
  ctx.addIssue({ code: "custom", message: "must be a valid HTTPS origin" });
1233
1242
  }
1234
1243
  });
1235
- var WebSessionCsrfSourceUrl = z5.url({ protocol: /^https$/ }).superRefine((value, ctx) => {
1244
+ var WebSessionCsrfSourceUrl = z6.url({ protocol: /^https$/ }).superRefine((value, ctx) => {
1236
1245
  const url = new URL(value);
1237
1246
  if (url.username !== "" || url.password !== "" || url.hash !== "") {
1238
1247
  ctx.addIssue({
@@ -1280,10 +1289,10 @@ function webSessionPathWithinPrefix(pathname, pathPrefix) {
1280
1289
  }
1281
1290
  var WEB_SESSION_CSRF_SELECTOR_PATTERN = /^(?=.)(?:[a-zA-Z][a-zA-Z0-9-]*)?(?:#[a-zA-Z_][\w-]*|\[[a-zA-Z_:][\w:.-]*(?:=(?:"[^"]*"|'[^']*'|[\w-]+))?\])*$/u;
1282
1291
  var WebSessionCsrfSelector = NonEmptyString.regex(WEB_SESSION_CSRF_SELECTOR_PATTERN, "must be a compound simple selector: optional tag, then #id or [attr=value] predicates on that one element (no combinators, classes, or pseudo-classes)");
1283
- var WebSessionGrantRequest = z5.strictObject({
1292
+ var WebSessionGrantRequest = z6.strictObject({
1284
1293
  origin: WebSessionOrigin,
1285
- pathPrefixes: z5.array(WebSessionPathPrefix).min(1),
1286
- csrf: z5.strictObject({
1294
+ pathPrefixes: z6.array(WebSessionPathPrefix).min(1),
1295
+ csrf: z6.strictObject({
1287
1296
  sourceUrl: WebSessionCsrfSourceUrl,
1288
1297
  selector: WebSessionCsrfSelector,
1289
1298
  attribute: NonEmptyString,
@@ -1292,14 +1301,14 @@ var WebSessionGrantRequest = z5.strictObject({
1292
1301
  bodyField: NonEmptyString.optional()
1293
1302
  }).optional()
1294
1303
  });
1295
- var KnowledgeSearchGrantRequest = z5.strictObject({
1296
- scope: z5.literal("own-schemes")
1304
+ var KnowledgeSearchGrantRequest = z6.strictObject({
1305
+ scope: z6.literal("own-schemes")
1297
1306
  });
1298
- var KnownResourcesGrantRequest = z5.strictObject({
1299
- scope: z5.literal("own-modules")
1307
+ var KnownResourcesGrantRequest = z6.strictObject({
1308
+ scope: z6.literal("own-modules")
1300
1309
  });
1301
- var PluginAgentDefinitionPermissionRule = z5.strictObject({
1302
- effect: z5.enum(["allow", "deny", "ask"]),
1310
+ var PluginAgentDefinitionPermissionRule = z6.strictObject({
1311
+ effect: z6.enum(["allow", "deny", "ask"]),
1303
1312
  /** Restrict to one tool name. */
1304
1313
  tool: NonEmptyString.optional(),
1305
1314
  /** Restrict to one classified capability key. */
@@ -1309,7 +1318,7 @@ var PluginAgentDefinitionPermissionRule = z5.strictObject({
1309
1318
  /** Restrict to matching resources (a path glob, or a URI-shaped policy address). */
1310
1319
  resource: NonEmptyString.optional(),
1311
1320
  /** Restrict the rule to one permission mode; omit to apply in all modes. */
1312
- mode: z5.enum(["default", "ask", "allow", "auto"]).optional()
1321
+ mode: z6.enum(["default", "ask", "allow", "auto"]).optional()
1313
1322
  });
1314
1323
  var RETIRED_PERMISSION_ASK_KEYS = [
1315
1324
  "network",
@@ -1375,14 +1384,14 @@ function retiredPermissionAsksIn(rawManifest) {
1375
1384
  }
1376
1385
  return found;
1377
1386
  }
1378
- var TargetPermissionWiring = z5.strictObject({
1379
- auth: z5.array(AuthGrantRequest).optional(),
1380
- storage: z5.array(StorageGrantRequest).optional(),
1381
- events: z5.array(EventGrantRequest).optional(),
1382
- endpoints: z5.array(EndpointGrantRequest).optional(),
1383
- webSession: z5.array(WebSessionGrantRequest).optional(),
1384
- knowledgeSearch: z5.array(KnowledgeSearchGrantRequest).optional(),
1385
- knownResources: z5.array(KnownResourcesGrantRequest).optional()
1387
+ var TargetPermissionWiring = z6.strictObject({
1388
+ auth: z6.array(AuthGrantRequest).optional(),
1389
+ storage: z6.array(StorageGrantRequest).optional(),
1390
+ events: z6.array(EventGrantRequest).optional(),
1391
+ endpoints: z6.array(EndpointGrantRequest).optional(),
1392
+ webSession: z6.array(WebSessionGrantRequest).optional(),
1393
+ knowledgeSearch: z6.array(KnowledgeSearchGrantRequest).optional(),
1394
+ knownResources: z6.array(KnownResourcesGrantRequest).optional()
1386
1395
  }).superRefine((permissions, ctx) => {
1387
1396
  const rows = permissions.webSession ?? [];
1388
1397
  for (const [index, row] of rows.entries()) {
@@ -1400,9 +1409,9 @@ var TargetPermissionWiring = z5.strictObject({
1400
1409
  }
1401
1410
  }
1402
1411
  });
1403
- var TargetPermissionSet = z5.preprocess(stripRetiredPermissionAsks, TargetPermissionWiring);
1404
- var PluginPermissionManifest = z5.strictObject({
1405
- byTarget: z5.strictObject({
1412
+ var TargetPermissionSet = z6.preprocess(stripRetiredPermissionAsks, TargetPermissionWiring);
1413
+ var PluginPermissionManifest = z6.strictObject({
1414
+ byTarget: z6.strictObject({
1406
1415
  "kay.agent": TargetPermissionSet.optional(),
1407
1416
  "kay.app": TargetPermissionSet.optional(),
1408
1417
  "kay.ui": TargetPermissionSet.optional()
@@ -1420,26 +1429,26 @@ var PluginPermissionManifest = z5.strictObject({
1420
1429
  });
1421
1430
  var ResolvedAuthGrantRequest = AuthGrantRequestBase.extend({
1422
1431
  service: GlobalContributionId,
1423
- schemes: z5.array(GlobalContributionId).min(1).optional(),
1432
+ schemes: z6.array(GlobalContributionId).min(1).optional(),
1424
1433
  // Resolution fills an absent binding with the narrowest bound, so a resolved
1425
1434
  // grant ALWAYS carries an explicit, non-broadening account selector — the
1426
1435
  // runtime never has to invent a default and fail open.
1427
- accountSelectors: z5.array(AuthAccountSelector).min(1)
1436
+ accountSelectors: z6.array(AuthAccountSelector).min(1)
1428
1437
  }).superRefine(validateAuthGrantRequest);
1429
1438
  var ResolvedEndpointGrantRequest = EndpointGrantRequest.extend({
1430
1439
  endpoint: GlobalContributionId
1431
1440
  });
1432
- var ResolvedTargetGrantSet = z5.strictObject({
1433
- auth: z5.array(ResolvedAuthGrantRequest).optional(),
1434
- storage: z5.array(StorageGrantRequest).optional(),
1435
- events: z5.array(EventGrantRequest).optional(),
1436
- endpoints: z5.array(ResolvedEndpointGrantRequest).optional(),
1437
- webSession: z5.array(WebSessionGrantRequest).optional(),
1438
- knowledgeSearch: z5.array(KnowledgeSearchGrantRequest).optional(),
1439
- knownResources: z5.array(KnownResourcesGrantRequest).optional()
1440
- });
1441
- var ResolvedPluginGrants = z5.strictObject({
1442
- byTarget: z5.strictObject({
1441
+ var ResolvedTargetGrantSet = z6.strictObject({
1442
+ auth: z6.array(ResolvedAuthGrantRequest).optional(),
1443
+ storage: z6.array(StorageGrantRequest).optional(),
1444
+ events: z6.array(EventGrantRequest).optional(),
1445
+ endpoints: z6.array(ResolvedEndpointGrantRequest).optional(),
1446
+ webSession: z6.array(WebSessionGrantRequest).optional(),
1447
+ knowledgeSearch: z6.array(KnowledgeSearchGrantRequest).optional(),
1448
+ knownResources: z6.array(KnownResourcesGrantRequest).optional()
1449
+ });
1450
+ var ResolvedPluginGrants = z6.strictObject({
1451
+ byTarget: z6.strictObject({
1443
1452
  "kay.agent": ResolvedTargetGrantSet.optional(),
1444
1453
  "kay.app": ResolvedTargetGrantSet.optional(),
1445
1454
  "kay.ui": ResolvedTargetGrantSet.optional()
@@ -1447,24 +1456,24 @@ var ResolvedPluginGrants = z5.strictObject({
1447
1456
  });
1448
1457
 
1449
1458
  // packages/plugin-protocol/dist/authority.js
1450
- var WhiteboardCapabilityScope = z6.enum(["own-types", "all-types"]);
1451
- var WhiteboardCapabilityOperation = z6.enum([
1459
+ var WhiteboardCapabilityScope = z7.enum(["own-types", "all-types"]);
1460
+ var WhiteboardCapabilityOperation = z7.enum([
1452
1461
  "discover",
1453
1462
  "read",
1454
1463
  "create",
1455
1464
  "update",
1456
1465
  "remove"
1457
1466
  ]);
1458
- var WhiteboardCapabilityClaimV1 = z6.strictObject({
1459
- target: z6.enum(["kay.agent", "kay.app"]),
1460
- slug: z6.enum([
1467
+ var WhiteboardCapabilityClaimV1 = z7.strictObject({
1468
+ target: z7.enum(["kay.agent", "kay.app"]),
1469
+ slug: z7.enum([
1461
1470
  "whiteboard.discover",
1462
1471
  "whiteboard.read",
1463
1472
  "whiteboard.create",
1464
1473
  "whiteboard.update",
1465
1474
  "whiteboard.remove"
1466
1475
  ]),
1467
- envelope: z6.strictObject({ scope: WhiteboardCapabilityScope })
1476
+ envelope: z7.strictObject({ scope: WhiteboardCapabilityScope })
1468
1477
  }).superRefine((claim, ctx) => {
1469
1478
  if (claim.target === "kay.app" && claim.slug !== "whiteboard.discover" && claim.slug !== "whiteboard.read") {
1470
1479
  ctx.addIssue({
@@ -1474,91 +1483,91 @@ var WhiteboardCapabilityClaimV1 = z6.strictObject({
1474
1483
  });
1475
1484
  }
1476
1485
  });
1477
- var PluginCapabilityClaimV1 = z6.discriminatedUnion("slug", [
1478
- z6.strictObject({
1479
- target: z6.literal("kay.app"),
1480
- slug: z6.literal("sessions.run"),
1481
- envelope: z6.strictObject({})
1486
+ var PluginCapabilityClaimV1 = z7.discriminatedUnion("slug", [
1487
+ z7.strictObject({
1488
+ target: z7.literal("kay.app"),
1489
+ slug: z7.literal("sessions.run"),
1490
+ envelope: z7.strictObject({})
1482
1491
  }),
1483
- z6.strictObject({
1484
- target: z6.literal("kay.agent"),
1485
- slug: z6.literal("network.connect"),
1486
- envelope: z6.strictObject({ connect: NonEmptyString })
1492
+ z7.strictObject({
1493
+ target: z7.literal("kay.agent"),
1494
+ slug: z7.literal("network.connect"),
1495
+ envelope: z7.strictObject({ connect: NonEmptyString })
1487
1496
  }),
1488
- z6.strictObject({
1489
- target: z6.literal("kay.agent"),
1490
- slug: z6.literal("web-session.request"),
1491
- envelope: z6.strictObject({
1497
+ z7.strictObject({
1498
+ target: z7.literal("kay.agent"),
1499
+ slug: z7.literal("web-session.request"),
1500
+ envelope: z7.strictObject({
1492
1501
  origin: NonEmptyString,
1493
1502
  pathPrefix: NonEmptyString
1494
1503
  })
1495
1504
  }),
1496
- z6.strictObject({
1497
- target: z6.literal("kay.agent"),
1498
- slug: z6.literal("web-session.download"),
1499
- envelope: z6.strictObject({
1505
+ z7.strictObject({
1506
+ target: z7.literal("kay.agent"),
1507
+ slug: z7.literal("web-session.download"),
1508
+ envelope: z7.strictObject({
1500
1509
  origin: NonEmptyString,
1501
1510
  pathPrefix: NonEmptyString
1502
1511
  })
1503
1512
  }),
1504
- z6.strictObject({
1505
- target: z6.literal("kay.agent"),
1506
- slug: z6.literal("process.spawn"),
1507
- envelope: z6.strictObject({
1513
+ z7.strictObject({
1514
+ target: z7.literal("kay.agent"),
1515
+ slug: z7.literal("process.spawn"),
1516
+ envelope: z7.strictObject({
1508
1517
  command: NonEmptyString,
1509
1518
  argvClass: NonEmptyString
1510
1519
  })
1511
1520
  }),
1512
- z6.strictObject({
1513
- target: z6.literal("kay.app"),
1514
- slug: z6.literal("corpus.read"),
1515
- envelope: z6.strictObject({})
1521
+ z7.strictObject({
1522
+ target: z7.literal("kay.app"),
1523
+ slug: z7.literal("corpus.read"),
1524
+ envelope: z7.strictObject({})
1516
1525
  }),
1517
- z6.strictObject({
1526
+ z7.strictObject({
1518
1527
  // Every plugin's recorded Jev signals, not only the caller's own: an empty envelope because
1519
1528
  // the grant itself is the visibility decision. Both first consumers (a session timeline, and
1520
1529
  // an agent loop turning signals into skills) read rows another plugin recorded.
1521
- target: z6.literal("kay.app"),
1522
- slug: z6.literal("signals.read"),
1523
- envelope: z6.strictObject({})
1530
+ target: z7.literal("kay.app"),
1531
+ slug: z7.literal("signals.read"),
1532
+ envelope: z7.strictObject({})
1524
1533
  }),
1525
- z6.strictObject({
1534
+ z7.strictObject({
1526
1535
  // Read-only metadata about every managed skill: identity, versions, history, suggestions.
1527
1536
  // Never a skill's bytes (an agent reads those through `skill://`) and never a write. An
1528
1537
  // empty envelope because the grant itself is the visibility decision, as with `signals.read`.
1529
- target: z6.literal("kay.app"),
1530
- slug: z6.literal("skills.read"),
1531
- envelope: z6.strictObject({})
1538
+ target: z7.literal("kay.app"),
1539
+ slug: z7.literal("skills.read"),
1540
+ envelope: z7.strictObject({})
1532
1541
  }),
1533
- z6.strictObject({
1542
+ z7.strictObject({
1534
1543
  // The text an agent sees for a tool or an address in a live session, where each comes from,
1535
1544
  // and whether it is one of Bonsai's own. Read-only and never a call. An empty envelope because
1536
1545
  // the grant itself is the visibility decision, as with `skills.read`.
1537
- target: z6.literal("kay.app"),
1538
- slug: z6.literal("tools.describe"),
1539
- envelope: z6.strictObject({})
1546
+ target: z7.literal("kay.app"),
1547
+ slug: z7.literal("tools.describe"),
1548
+ envelope: z7.strictObject({})
1540
1549
  }),
1541
- z6.strictObject({
1542
- target: z6.literal("kay.app"),
1543
- slug: z6.literal("workspace.command"),
1544
- envelope: z6.strictObject({})
1550
+ z7.strictObject({
1551
+ target: z7.literal("kay.app"),
1552
+ slug: z7.literal("workspace.command"),
1553
+ envelope: z7.strictObject({})
1545
1554
  }),
1546
- z6.strictObject({
1547
- target: z6.literal("kay.app"),
1548
- slug: z6.literal("sessions.create"),
1549
- envelope: z6.strictObject({})
1555
+ z7.strictObject({
1556
+ target: z7.literal("kay.app"),
1557
+ slug: z7.literal("sessions.create"),
1558
+ envelope: z7.strictObject({})
1550
1559
  }),
1551
- z6.strictObject({
1552
- target: z6.literal("kay.app"),
1553
- slug: z6.literal("sessions.update"),
1554
- envelope: z6.strictObject({})
1560
+ z7.strictObject({
1561
+ target: z7.literal("kay.app"),
1562
+ slug: z7.literal("sessions.update"),
1563
+ envelope: z7.strictObject({})
1555
1564
  }),
1556
- z6.strictObject({
1557
- target: z6.literal("kay.app"),
1558
- slug: z6.literal("models.complete"),
1559
- envelope: z6.strictObject({})
1565
+ z7.strictObject({
1566
+ target: z7.literal("kay.app"),
1567
+ slug: z7.literal("models.complete"),
1568
+ envelope: z7.strictObject({})
1560
1569
  }),
1561
- z6.strictObject({
1570
+ z7.strictObject({
1562
1571
  // Held to `kay.app`, the daemon-lifetime tier, even though the same wrapper is exposed on
1563
1572
  // BOTH the `kay.app` and `kay.agent` plugin SDKs (and to host composition directly): a slug
1564
1573
  // pins exactly one target (see this file's module doc), so one shared claim is simpler and
@@ -1567,104 +1576,104 @@ var PluginCapabilityClaimV1 = z6.discriminatedUnion("slug", [
1567
1576
  // plugin's own pinned authority, which already spans both targets for every other capability
1568
1577
  // (`network.connect`/`tool-interception.register` are decided by the identical per-plugin
1569
1578
  // handle `kay.app`-target claims use).
1570
- target: z6.literal("kay.app"),
1571
- slug: z6.literal("jev.use"),
1572
- envelope: z6.strictObject({})
1579
+ target: z7.literal("kay.app"),
1580
+ slug: z7.literal("jev.use"),
1581
+ envelope: z7.strictObject({})
1573
1582
  }),
1574
- z6.strictObject({
1575
- target: z6.literal("kay.app"),
1576
- slug: z6.literal("automations.write"),
1577
- envelope: z6.strictObject({})
1583
+ z7.strictObject({
1584
+ target: z7.literal("kay.app"),
1585
+ slug: z7.literal("automations.write"),
1586
+ envelope: z7.strictObject({})
1578
1587
  }),
1579
- z6.strictObject({
1580
- target: z6.literal("kay.app"),
1581
- slug: z6.literal("automations.run"),
1582
- envelope: z6.strictObject({})
1588
+ z7.strictObject({
1589
+ target: z7.literal("kay.app"),
1590
+ slug: z7.literal("automations.run"),
1591
+ envelope: z7.strictObject({})
1583
1592
  }),
1584
- z6.strictObject({
1585
- target: z6.literal("kay.app"),
1586
- slug: z6.literal("workflows.define"),
1587
- envelope: z6.strictObject({})
1593
+ z7.strictObject({
1594
+ target: z7.literal("kay.app"),
1595
+ slug: z7.literal("workflows.define"),
1596
+ envelope: z7.strictObject({})
1588
1597
  }),
1589
- z6.strictObject({
1590
- target: z6.literal("kay.app"),
1591
- slug: z6.literal("session-events.subscribe"),
1592
- envelope: z6.strictObject({})
1598
+ z7.strictObject({
1599
+ target: z7.literal("kay.app"),
1600
+ slug: z7.literal("session-events.subscribe"),
1601
+ envelope: z7.strictObject({})
1593
1602
  }),
1594
- z6.strictObject({
1595
- target: z6.literal("kay.app"),
1596
- slug: z6.literal("agents.run"),
1597
- envelope: z6.strictObject({})
1603
+ z7.strictObject({
1604
+ target: z7.literal("kay.app"),
1605
+ slug: z7.literal("agents.run"),
1606
+ envelope: z7.strictObject({})
1598
1607
  }),
1599
- z6.strictObject({
1600
- target: z6.literal("kay.app"),
1601
- slug: z6.literal("dynamic-context.register"),
1608
+ z7.strictObject({
1609
+ target: z7.literal("kay.app"),
1610
+ slug: z7.literal("dynamic-context.register"),
1602
1611
  // The declared `contributes.contextContributors` localId, which doubles as the contributor's
1603
1612
  // section tag at the model boundary — so the row a human consents to names the section.
1604
- envelope: z6.strictObject({ contributor: NonEmptyString })
1613
+ envelope: z7.strictObject({ contributor: NonEmptyString })
1605
1614
  }),
1606
- z6.strictObject({
1607
- target: z6.literal("kay.app"),
1608
- slug: z6.literal("app-data.register"),
1615
+ z7.strictObject({
1616
+ target: z7.literal("kay.app"),
1617
+ slug: z7.literal("app-data.register"),
1609
1618
  /** The declared `contributes.dataSources` localId. */
1610
- envelope: z6.strictObject({ source: NonEmptyString })
1619
+ envelope: z7.strictObject({ source: NonEmptyString })
1611
1620
  }),
1612
- z6.strictObject({
1613
- target: z6.literal("kay.app"),
1614
- slug: z6.literal("account.assert"),
1615
- envelope: z6.strictObject({})
1621
+ z7.strictObject({
1622
+ target: z7.literal("kay.app"),
1623
+ slug: z7.literal("account.assert"),
1624
+ envelope: z7.strictObject({})
1616
1625
  }),
1617
- z6.strictObject({
1618
- target: z6.literal("kay.app"),
1619
- slug: z6.literal("account.update"),
1620
- envelope: z6.strictObject({})
1626
+ z7.strictObject({
1627
+ target: z7.literal("kay.app"),
1628
+ slug: z7.literal("account.update"),
1629
+ envelope: z7.strictObject({})
1621
1630
  }),
1622
- z6.strictObject({
1623
- target: z6.literal("kay.app"),
1624
- slug: z6.literal("agents.permissions"),
1625
- envelope: z6.strictObject({
1631
+ z7.strictObject({
1632
+ target: z7.literal("kay.app"),
1633
+ slug: z7.literal("agents.permissions"),
1634
+ envelope: z7.strictObject({
1626
1635
  /** The definition's local id — WHICH agent these rules are authored onto. */
1627
1636
  agent: NonEmptyString,
1628
1637
  /** `definition.permissions`, in declaration order (order is semantic; first match wins). */
1629
- rules: z6.array(PluginAgentDefinitionPermissionRule),
1638
+ rules: z7.array(PluginAgentDefinitionPermissionRule),
1630
1639
  /** `definition.permissionsFallback`, in declaration order. */
1631
- fallback: z6.array(PluginAgentDefinitionPermissionRule)
1640
+ fallback: z7.array(PluginAgentDefinitionPermissionRule)
1632
1641
  })
1633
1642
  }),
1634
- z6.strictObject({
1635
- target: z6.literal("kay.agent"),
1636
- slug: z6.literal("tool-interception.register"),
1637
- envelope: z6.strictObject({})
1643
+ z7.strictObject({
1644
+ target: z7.literal("kay.agent"),
1645
+ slug: z7.literal("tool-interception.register"),
1646
+ envelope: z7.strictObject({})
1638
1647
  }),
1639
- z6.strictObject({
1640
- target: z6.literal("kay.agent"),
1641
- slug: z6.literal("interaction.surface"),
1648
+ z7.strictObject({
1649
+ target: z7.literal("kay.agent"),
1650
+ slug: z7.literal("interaction.surface"),
1642
1651
  /** The one Bonsai-shipped interaction surface this plugin may drive; one claim per surface. */
1643
- envelope: z6.strictObject({ surface: z6.enum(["browser-pane", "desktop"]) })
1652
+ envelope: z7.strictObject({ surface: z7.enum(["browser-pane", "desktop"]) })
1644
1653
  }),
1645
- z6.strictObject({
1646
- target: z6.literal("plugin"),
1647
- slug: z6.literal("config.declare-section"),
1654
+ z7.strictObject({
1655
+ target: z7.literal("plugin"),
1656
+ slug: z7.literal("config.declare-section"),
1648
1657
  /** The settings-document section key, e.g. `models` or `plugins.com.acme.thing`. */
1649
- envelope: z6.strictObject({ section: NonEmptyString })
1658
+ envelope: z7.strictObject({ section: NonEmptyString })
1650
1659
  }),
1651
- z6.strictObject({
1652
- target: z6.literal("plugin"),
1653
- slug: z6.literal("auth.own-service"),
1660
+ z7.strictObject({
1661
+ target: z7.literal("plugin"),
1662
+ slug: z7.literal("auth.own-service"),
1654
1663
  /** The minted global service id this plugin would own, e.g. `google.account`. */
1655
- envelope: z6.strictObject({ service: NonEmptyString })
1664
+ envelope: z7.strictObject({ service: NonEmptyString })
1656
1665
  }),
1657
- z6.strictObject({
1658
- target: z6.literal("plugin"),
1659
- slug: z6.literal("auth.shared-identity"),
1666
+ z7.strictObject({
1667
+ target: z7.literal("plugin"),
1668
+ slug: z7.literal("auth.shared-identity"),
1660
1669
  /** The foreign global service id whose identity this plugin would resolve against. */
1661
- envelope: z6.strictObject({ service: NonEmptyString })
1670
+ envelope: z7.strictObject({ service: NonEmptyString })
1662
1671
  }),
1663
- z6.strictObject({
1664
- target: z6.literal("plugin"),
1665
- slug: z6.literal("cli.bind"),
1672
+ z7.strictObject({
1673
+ target: z7.literal("plugin"),
1674
+ slug: z7.literal("cli.bind"),
1666
1675
  /** The binary basename a resolved credential would be injected into. */
1667
- envelope: z6.strictObject({ binary: NonEmptyString })
1676
+ envelope: z7.strictObject({ binary: NonEmptyString })
1668
1677
  }),
1669
1678
  WhiteboardCapabilityClaimV1
1670
1679
  ]);
@@ -1709,28 +1718,28 @@ var PLUGIN_CAPABILITY_SLUGS = [
1709
1718
  "whiteboard.update",
1710
1719
  "whiteboard.remove"
1711
1720
  ];
1712
- var PluginCapabilityRefusalLayer = z6.enum(["grant", "binding"]);
1713
- var PluginCapabilityRefusalCode = z6.enum([
1721
+ var PluginCapabilityRefusalLayer = z7.enum(["grant", "binding"]);
1722
+ var PluginCapabilityRefusalCode = z7.enum([
1714
1723
  "not-granted",
1715
1724
  "grant-read-failed",
1716
1725
  "binding-missing",
1717
1726
  "argv-outside-class"
1718
1727
  ]);
1719
- var PluginCapabilityRefusalV1 = z6.strictObject({
1728
+ var PluginCapabilityRefusalV1 = z7.strictObject({
1720
1729
  claim: PluginCapabilityClaimV1,
1721
1730
  layer: PluginCapabilityRefusalLayer,
1722
1731
  code: PluginCapabilityRefusalCode,
1723
1732
  message: NonEmptyString,
1724
1733
  artifactGenerationId: ArtifactGenerationId.optional()
1725
1734
  });
1726
- var PluginCapabilityDecisionV1 = z6.discriminatedUnion("kind", [
1727
- z6.strictObject({
1728
- kind: z6.literal("allowed"),
1735
+ var PluginCapabilityDecisionV1 = z7.discriminatedUnion("kind", [
1736
+ z7.strictObject({
1737
+ kind: z7.literal("allowed"),
1729
1738
  claim: PluginCapabilityClaimV1,
1730
1739
  artifactGenerationId: ArtifactGenerationId.optional()
1731
1740
  }),
1732
- z6.strictObject({
1733
- kind: z6.literal("refused"),
1741
+ z7.strictObject({
1742
+ kind: z7.literal("refused"),
1734
1743
  refusal: PluginCapabilityRefusalV1
1735
1744
  })
1736
1745
  ]);
@@ -2104,6 +2113,14 @@ function isSupportedSemverRange(range) {
2104
2113
  }
2105
2114
 
2106
2115
  // packages/plugin-protocol/dist/compatibility.js
2116
+ function kayPluginHostCompatibility(appVersion) {
2117
+ return {
2118
+ protocolVersion: KAY_PLUGIN_PROTOCOL_VERSION,
2119
+ sdkVersion: KAY_PLUGIN_SDK_VERSION,
2120
+ compatibleSdkVersions: KAY_PLUGIN_COMPATIBLE_SDK_VERSIONS,
2121
+ appVersion
2122
+ };
2123
+ }
2107
2124
  function isCompatible(report) {
2108
2125
  return report.refusal === void 0;
2109
2126
  }
@@ -2190,30 +2207,30 @@ function checkKayPluginHostCompatibility(compatibility, host) {
2190
2207
  }
2191
2208
 
2192
2209
  // packages/plugin-protocol/dist/contributions.js
2193
- import { z as z7 } from "zod";
2210
+ import { z as z8 } from "zod";
2194
2211
  var OptionalDisplayName = NonEmptyString.optional();
2195
- var UriFilesystemBacking = z7.strictObject({
2196
- root: z7.literal("dataDir")
2212
+ var UriFilesystemBacking = z8.strictObject({
2213
+ root: z8.literal("dataDir")
2197
2214
  });
2198
- var ToolContribution = z7.strictObject({
2215
+ var ToolContribution = z8.strictObject({
2199
2216
  localId: LocalContributionId,
2200
2217
  toolName: PluginToolName,
2201
2218
  displayName: OptionalDisplayName,
2202
2219
  description: NonEmptyString.optional()
2203
2220
  });
2204
- var ConverterContribution = z7.strictObject({
2221
+ var ConverterContribution = z8.strictObject({
2205
2222
  localId: LocalContributionId,
2206
2223
  displayName: OptionalDisplayName,
2207
2224
  description: NonEmptyString.optional(),
2208
2225
  /** MIME types this converter claims — contract data for introspection and
2209
2226
  * collision checks; runtime match behavior stays the converter's `matches()`. */
2210
- mimeTypes: z7.array(MimeTypeString).min(1),
2227
+ mimeTypes: z8.array(MimeTypeString).min(1),
2211
2228
  /** Extension fallbacks (no dot) used when a probe has no usable MIME type. */
2212
- extensions: z7.array(FileExtensionToken).min(1).optional()
2229
+ extensions: z8.array(FileExtensionToken).min(1).optional()
2213
2230
  });
2214
- var UriModuleContribution = z7.strictObject({
2231
+ var UriModuleContribution = z8.strictObject({
2215
2232
  localId: LocalContributionId,
2216
- schemes: z7.array(UriScheme).min(1),
2233
+ schemes: z8.array(UriScheme).min(1),
2217
2234
  displayName: OptionalDisplayName,
2218
2235
  // The plugin only requests a projection. The daemon binds the effective root
2219
2236
  // and retains access control at finalization.
@@ -2232,30 +2249,30 @@ var UriModuleContribution = z7.strictObject({
2232
2249
  // `knownResources` permission grant (`api.knownResources`). Present-means-on
2233
2250
  // (`true` or absent; `false` is not a state). Decision record:
2234
2251
  // `lab/user-plugins/decisions/014-known-resources-ledger.md`.
2235
- knownResources: z7.literal(true).optional()
2252
+ knownResources: z8.literal(true).optional()
2236
2253
  });
2237
2254
  var AppUriModuleContribution = UriModuleContribution.omit({
2238
2255
  authService: true,
2239
2256
  filesystemBacking: true,
2240
2257
  knownResources: true
2241
2258
  });
2242
- var AppDataSourceContribution = z7.strictObject({
2259
+ var AppDataSourceContribution = z8.strictObject({
2243
2260
  localId: LocalContributionId,
2244
- scope: z7.enum(["runtime", "account", "session"]),
2245
- snapshot: z7.strictObject({
2246
- version: z7.number().int().positive(),
2261
+ scope: z8.enum(["runtime", "account", "session"]),
2262
+ snapshot: z8.strictObject({
2263
+ version: z8.number().int().positive(),
2247
2264
  schema: JsonSchema
2248
2265
  }),
2249
- change: z7.strictObject({
2250
- version: z7.number().int().positive(),
2266
+ change: z8.strictObject({
2267
+ version: z8.number().int().positive(),
2251
2268
  schema: JsonSchema,
2252
2269
  /** Review-only claim; source schemas and behavioral tests enforce it because the daemon treats changes as opaque. */
2253
- semantics: z7.discriminatedUnion("kind", [
2254
- z7.strictObject({ kind: z7.literal("incremental") }),
2255
- z7.strictObject({
2256
- kind: z7.literal("snapshot-replacement"),
2257
- maxEncodedBytes: z7.number().int().positive(),
2258
- rationale: z7.string().trim().min(1).max(1024)
2270
+ semantics: z8.discriminatedUnion("kind", [
2271
+ z8.strictObject({ kind: z8.literal("incremental") }),
2272
+ z8.strictObject({
2273
+ kind: z8.literal("snapshot-replacement"),
2274
+ maxEncodedBytes: z8.number().int().positive(),
2275
+ rationale: z8.string().trim().min(1).max(1024)
2259
2276
  })
2260
2277
  ]).optional()
2261
2278
  }),
@@ -2269,28 +2286,28 @@ var AppDataSourceContribution = z7.strictObject({
2269
2286
  });
2270
2287
  }
2271
2288
  });
2272
- var WhiteboardTypeStorage = z7.discriminatedUnion("kind", [
2273
- z7.strictObject({ kind: z7.literal("json") }),
2274
- z7.strictObject({ kind: z7.literal("payload") }),
2275
- z7.strictObject({
2276
- kind: z7.literal("markdown"),
2289
+ var WhiteboardTypeStorage = z8.discriminatedUnion("kind", [
2290
+ z8.strictObject({ kind: z8.literal("json") }),
2291
+ z8.strictObject({ kind: z8.literal("payload") }),
2292
+ z8.strictObject({
2293
+ kind: z8.literal("markdown"),
2277
2294
  bodyField: NonEmptyString
2278
2295
  })
2279
2296
  ]);
2280
- var WhiteboardTypeContribution = z7.strictObject({
2297
+ var WhiteboardTypeContribution = z8.strictObject({
2281
2298
  localId: LocalContributionId,
2282
2299
  displayName: NonEmptyString,
2283
- schemaVersion: z7.number().int().positive(),
2300
+ schemaVersion: z8.number().int().positive(),
2284
2301
  storage: WhiteboardTypeStorage,
2285
2302
  valueSchema: JsonSchema,
2286
- presentation: z7.strictObject({
2303
+ presentation: z8.strictObject({
2287
2304
  app: LocalContributionId
2288
2305
  }).optional()
2289
2306
  });
2290
- var AppDataMaterializerContribution = z7.strictObject({
2307
+ var AppDataMaterializerContribution = z8.strictObject({
2291
2308
  source: LocalContributionId
2292
2309
  });
2293
- var ArtifactUriModuleContribution = z7.strictObject({
2310
+ var ArtifactUriModuleContribution = z8.strictObject({
2294
2311
  localId: LocalContributionId,
2295
2312
  /** The single `scheme://` this module owns; also the on-disk artifact kind. */
2296
2313
  scheme: UriScheme,
@@ -2304,17 +2321,17 @@ var ArtifactUriModuleContribution = z7.strictObject({
2304
2321
  * composes its description from the plugin's own display name + scheme — a per-scheme label
2305
2322
  * would have no path to matter, so it is intentionally omitted rather than accepted-and-ignored.
2306
2323
  */
2307
- editable: z7.boolean().optional(),
2324
+ editable: z8.boolean().optional(),
2308
2325
  /** Opt in to `list` over the kind's stored names. Default false. Mirrors
2309
2326
  * `CreateArtifactUriModuleOptions.listable`. */
2310
- listable: z7.boolean().optional(),
2327
+ listable: z8.boolean().optional(),
2311
2328
  /**
2312
2329
  * Opt in to `delete` for same-session entries. Default false. Deletion
2313
2330
  * unlinks the stored file — no trash tier; a kind that wants recoverable
2314
2331
  * deletion is not artifact-backed. Mirrors
2315
2332
  * `CreateArtifactUriModuleOptions.deletable`.
2316
2333
  */
2317
- deletable: z7.boolean().optional(),
2334
+ deletable: z8.boolean().optional(),
2318
2335
  /**
2319
2336
  * Opt in to the `{ content, mode: "append" }` write envelope, which extends
2320
2337
  * stored text instead of replacing it (concurrent-appender-safe: the host
@@ -2322,7 +2339,7 @@ var ArtifactUriModuleContribution = z7.strictObject({
2322
2339
  * keep their verbatim round-trip. Mirrors
2323
2340
  * `CreateArtifactUriModuleOptions.appendable`.
2324
2341
  */
2325
- appendable: z7.boolean().optional(),
2342
+ appendable: z8.boolean().optional(),
2326
2343
  /**
2327
2344
  * Which sessions share one storage namespace. Default `"session"` — the existing
2328
2345
  * per-session behavior (each session gets its own kind directory; other sessions'
@@ -2333,14 +2350,14 @@ var ArtifactUriModuleContribution = z7.strictObject({
2333
2350
  * the scope; the host derives the family root from provenance it already holds, so
2334
2351
  * family identity never crosses the SDK boundary.
2335
2352
  */
2336
- storageScope: z7.enum(["session", "family"]).optional()
2353
+ storageScope: z8.enum(["session", "family"]).optional()
2337
2354
  });
2338
- var CliBindingContribution = z7.strictObject({
2355
+ var CliBindingContribution = z8.strictObject({
2339
2356
  localId: LocalContributionId,
2340
2357
  binary: CliBinaryName,
2341
- aliases: z7.array(CliBinaryName).optional(),
2358
+ aliases: z8.array(CliBinaryName).optional(),
2342
2359
  /** Where the binary comes from. Omitted ⇒ `"vendored"` (decision 007). */
2343
- provider: z7.enum(["vendored", "path"]).optional(),
2360
+ provider: z8.enum(["vendored", "path"]).optional(),
2344
2361
  // A local ref (no dot) must name an auth service declared in this same
2345
2362
  // manifest; a qualified ref (dotted, e.g. `google.account`) names another
2346
2363
  // plugin's already-minted global id and is recorded, not resolved, here (see
@@ -2353,20 +2370,20 @@ var CliBindingContribution = z7.strictObject({
2353
2370
  * MUST be absent for a `path` binding, which can never receive a token.
2354
2371
  */
2355
2372
  authEnvVar: CliAuthEnvVarName.optional(),
2356
- readOnly: z7.array(NonEmptyString),
2357
- write: z7.array(NonEmptyString)
2373
+ readOnly: z8.array(NonEmptyString),
2374
+ write: z8.array(NonEmptyString)
2358
2375
  });
2359
- var GitHostContribution = z7.strictObject({
2376
+ var GitHostContribution = z8.strictObject({
2360
2377
  host: GitHostName,
2361
2378
  authService: LocalContributionId,
2362
2379
  basicAuthUser: GitBasicAuthUser
2363
2380
  });
2364
- var ResourceContribution = z7.strictObject({
2381
+ var ResourceContribution = z8.strictObject({
2365
2382
  localId: LocalContributionId,
2366
2383
  displayName: OptionalDisplayName,
2367
2384
  description: NonEmptyString.optional()
2368
2385
  });
2369
- var SkillContribution = z7.strictObject({
2386
+ var SkillContribution = z8.strictObject({
2370
2387
  localId: LocalContributionId,
2371
2388
  displayName: OptionalDisplayName,
2372
2389
  /** Model-visible one-liner: when to reach for this skill. */
@@ -2374,18 +2391,18 @@ var SkillContribution = z7.strictObject({
2374
2391
  /** The SKILL.md-style file inside the package carrying the full instructions. */
2375
2392
  path: PackageAssetPath
2376
2393
  });
2377
- var PluginSkillSourceDeclaration = z7.discriminatedUnion("channel", [
2378
- z7.strictObject({
2379
- channel: z7.literal("installer"),
2394
+ var PluginSkillSourceDeclaration = z8.discriminatedUnion("channel", [
2395
+ z8.strictObject({
2396
+ channel: z8.literal("installer"),
2380
2397
  localId: LocalContributionId,
2381
2398
  displayName: OptionalDisplayName,
2382
2399
  /** The package-runner executable, e.g. `npx` — checked against the daemon's allowlist. */
2383
2400
  command: NonEmptyString,
2384
2401
  /** Its argv, e.g. `["skills", "add", "clerk/skills"]`. */
2385
- args: z7.array(NonEmptyString)
2402
+ args: z8.array(NonEmptyString)
2386
2403
  }),
2387
- z7.strictObject({
2388
- channel: z7.literal("git-clone"),
2404
+ z8.strictObject({
2405
+ channel: z8.literal("git-clone"),
2389
2406
  localId: LocalContributionId,
2390
2407
  displayName: OptionalDisplayName,
2391
2408
  /** The repository locator — canonicalized and hygiene-checked by the daemon. */
@@ -2396,17 +2413,17 @@ var PluginSkillSourceDeclaration = z7.discriminatedUnion("channel", [
2396
2413
  subdir: NonEmptyString.optional()
2397
2414
  })
2398
2415
  ]);
2399
- var SearchProviderContribution = z7.strictObject({
2416
+ var SearchProviderContribution = z8.strictObject({
2400
2417
  localId: LocalContributionId,
2401
2418
  displayName: OptionalDisplayName,
2402
- schemes: z7.array(UriScheme).optional()
2419
+ schemes: z8.array(UriScheme).optional()
2403
2420
  });
2404
- var InteractionDriverContribution = z7.strictObject({
2421
+ var InteractionDriverContribution = z8.strictObject({
2405
2422
  localId: LocalContributionId,
2406
2423
  displayName: OptionalDisplayName,
2407
- kind: z7.enum(["browser", "computer-use"])
2424
+ kind: z8.enum(["browser", "computer-use"])
2408
2425
  });
2409
- var EntityResolverContribution = z7.strictObject({
2426
+ var EntityResolverContribution = z8.strictObject({
2410
2427
  localId: LocalContributionId,
2411
2428
  displayName: OptionalDisplayName,
2412
2429
  /** The `kay.agent` URI module (this manifest's own `contributes.uriModules[].localId`) whose
@@ -2414,24 +2431,24 @@ var EntityResolverContribution = z7.strictObject({
2414
2431
  uriModule: LocalContributionId,
2415
2432
  /** `person` | `channel` | `repo` | `pull-request` | ... -- drives avatar-first vs glyph-first row
2416
2433
  * anatomy (N10-R2) and lets the renderer request a narrower `entityTypes` filter. */
2417
- entityTypes: z7.array(NonEmptyString).min(1),
2434
+ entityTypes: z8.array(NonEmptyString).min(1),
2418
2435
  /** The URI namespace/route `search()` is called against, e.g. `slack://directory` or
2419
2436
  * `github://search/repositories` -- the resolver's fixed search scope; the live user query is
2420
2437
  * the `search()` call's `query` param, never concatenated into this string. */
2421
2438
  uriHint: NonEmptyString
2422
2439
  });
2423
- var AgentRenderContribution = z7.strictObject({
2440
+ var AgentRenderContribution = z8.strictObject({
2424
2441
  localId: LocalContributionId,
2425
- resultKinds: z7.array(NonEmptyString).min(1)
2442
+ resultKinds: z8.array(NonEmptyString).min(1)
2426
2443
  });
2427
- var EndpointContribution = z7.strictObject({
2444
+ var EndpointContribution = z8.strictObject({
2428
2445
  localId: LocalContributionId,
2429
2446
  displayName: OptionalDisplayName,
2430
2447
  requestSchema: JsonSchema.optional(),
2431
2448
  responseSchema: JsonSchema.optional()
2432
2449
  });
2433
2450
  var MCP_SERVER_LOCAL_HTTP_HOSTNAMES = /* @__PURE__ */ new Set(["localhost", "127.0.0.1"]);
2434
- var McpServerUrl = z7.string().trim().min(1).refine((value) => {
2451
+ var McpServerUrl = z8.string().trim().min(1).refine((value) => {
2435
2452
  let parsed;
2436
2453
  try {
2437
2454
  parsed = new URL(value);
@@ -2444,8 +2461,8 @@ var McpServerUrl = z7.string().trim().min(1).refine((value) => {
2444
2461
  }, {
2445
2462
  message: "mcp server url must be https://, or http:// only for localhost/127.0.0.1 test servers"
2446
2463
  });
2447
- var McpServerAuthMode = z7.enum(["oauth", "none"]);
2448
- var McpServerContribution = z7.strictObject({
2464
+ var McpServerAuthMode = z8.enum(["oauth", "none"]);
2465
+ var McpServerContribution = z8.strictObject({
2449
2466
  url: McpServerUrl,
2450
2467
  auth: McpServerAuthMode.optional(),
2451
2468
  authService: LocalContributionId.optional()
@@ -2458,28 +2475,28 @@ var McpServerContribution = z7.strictObject({
2458
2475
  });
2459
2476
  }
2460
2477
  });
2461
- var McpServerContributions = z7.record(LocalContributionId, McpServerContribution);
2462
- var AppEventSubscription = z7.strictObject({
2478
+ var McpServerContributions = z8.record(LocalContributionId, McpServerContribution);
2479
+ var AppEventSubscription = z8.strictObject({
2463
2480
  localId: LocalContributionId,
2464
2481
  event: NonEmptyString
2465
2482
  });
2466
- var ContextContributorContribution = z7.strictObject({
2483
+ var ContextContributorContribution = z8.strictObject({
2467
2484
  localId: LocalContributionId.max(64),
2468
2485
  displayName: OptionalDisplayName,
2469
2486
  description: NonEmptyString.optional()
2470
2487
  });
2471
- var PluginEventDefinitionContribution = z7.strictObject({
2488
+ var PluginEventDefinitionContribution = z8.strictObject({
2472
2489
  localId: LocalContributionId,
2473
2490
  displayName: OptionalDisplayName,
2474
2491
  description: NonEmptyString.optional(),
2475
- version: z7.number().int().positive().default(1),
2492
+ version: z8.number().int().positive().default(1),
2476
2493
  payloadSchema: JsonSchema
2477
2494
  });
2478
- var PluginNotificationRuleContribution = z7.strictObject({
2495
+ var PluginNotificationRuleContribution = z8.strictObject({
2479
2496
  localId: LocalContributionId,
2480
2497
  /** The same-plugin `eventDefinitions` local id this rule matches. */
2481
2498
  event: LocalContributionId,
2482
- where: z7.array(JsonObject).optional(),
2499
+ where: z8.array(JsonObject).optional(),
2483
2500
  rule: JsonObject
2484
2501
  });
2485
2502
  var PLUGIN_NOTIFICATION_RULE_HOST_KEYS = [
@@ -2487,67 +2504,67 @@ var PLUGIN_NOTIFICATION_RULE_HOST_KEYS = [
2487
2504
  "match",
2488
2505
  "sender"
2489
2506
  ];
2490
- var UiEventSubscriptionContribution = z7.strictObject({
2507
+ var UiEventSubscriptionContribution = z8.strictObject({
2491
2508
  localId: LocalContributionId,
2492
2509
  event: NonEmptyString
2493
2510
  });
2494
- var DeviceDelegationContribution = z7.strictObject({
2511
+ var DeviceDelegationContribution = z8.strictObject({
2495
2512
  localId: LocalContributionId,
2496
- device: z7.enum(["microphone"]),
2497
- delegateAs: z7.enum(["clip", "stream", "status"])
2513
+ device: z8.enum(["microphone"]),
2514
+ delegateAs: z8.enum(["clip", "stream", "status"])
2498
2515
  });
2499
- var CorpusContribution = z7.strictObject({
2516
+ var CorpusContribution = z8.strictObject({
2500
2517
  localId: LocalContributionId,
2501
2518
  displayName: OptionalDisplayName,
2502
- access: z7.enum(["read"]).default("read")
2519
+ access: z8.enum(["read"]).default("read")
2503
2520
  });
2504
- var UiCommandContribution = z7.strictObject({
2521
+ var UiCommandContribution = z8.strictObject({
2505
2522
  localId: LocalContributionId,
2506
2523
  title: NonEmptyString,
2507
2524
  icon: NonEmptyString.optional(),
2508
2525
  placement: NonEmptyString.optional()
2509
2526
  });
2510
- var UiSlotContribution = z7.strictObject({
2527
+ var UiSlotContribution = z8.strictObject({
2511
2528
  localId: LocalContributionId,
2512
2529
  slot: NonEmptyString,
2513
2530
  title: NonEmptyString.optional()
2514
2531
  });
2515
- var SettingsPanelContribution = z7.strictObject({
2532
+ var SettingsPanelContribution = z8.strictObject({
2516
2533
  localId: LocalContributionId,
2517
2534
  title: NonEmptyString,
2518
2535
  configSection: NonEmptyString.optional()
2519
2536
  });
2520
- var ResultRendererContribution = z7.strictObject({
2537
+ var ResultRendererContribution = z8.strictObject({
2521
2538
  localId: LocalContributionId,
2522
- resultKinds: z7.array(NonEmptyString).min(1)
2539
+ resultKinds: z8.array(NonEmptyString).min(1)
2523
2540
  });
2524
- var ReferenceOpenBehavior = z7.discriminatedUnion("kind", [
2525
- z7.strictObject({ kind: z7.literal("working-document") }),
2526
- z7.strictObject({ kind: z7.literal("browser-pane") }),
2541
+ var ReferenceOpenBehavior = z8.discriminatedUnion("kind", [
2542
+ z8.strictObject({ kind: z8.literal("working-document") }),
2543
+ z8.strictObject({ kind: z8.literal("browser-pane") }),
2527
2544
  /**
2528
2545
  * Open one of the presenting plugin's OWN registered pages (`registerPage`'s
2529
2546
  * descriptor id) with the reference's canonical URI as the page's `objectId`.
2530
2547
  * Needs no web address, so a plugin-only resource (`user-todo://items/3`) can pill.
2531
2548
  */
2532
- z7.strictObject({ kind: z7.literal("page"), pageId: NonEmptyString })
2549
+ z8.strictObject({ kind: z8.literal("page"), pageId: NonEmptyString })
2533
2550
  ]);
2534
- var ReferencePresentationVariant = z7.strictObject({
2551
+ var ReferencePresentationVariant = z8.strictObject({
2535
2552
  resourceKind: NonEmptyString,
2536
2553
  presentationPluginId: PluginId.optional()
2537
2554
  });
2538
- var ReferencePresentationVariants = z7.record(MimeTypeString, ReferencePresentationVariant);
2539
- var InlineSvg = z7.string().max(64 * 1024).refine((value) => /^\s*(?:<\?xml[^>]*>\s*)?(?:<!--[\s\S]*?-->\s*)*(?:<!DOCTYPE[^>]*>\s*)?<svg[\s>]/iu.test(value), { message: "brandIcon must be inline SVG markup." });
2540
- var ReferencePresentationUrlClaim = z7.strictObject({
2541
- kind: z7.literal("urlPattern"),
2542
- pattern: z7.strictObject({
2543
- protocol: z7.enum(["http", "https"]),
2555
+ var ReferencePresentationVariants = z8.record(MimeTypeString, ReferencePresentationVariant);
2556
+ var InlineSvg = z8.string().max(64 * 1024).refine((value) => /^\s*(?:<\?xml[^>]*>\s*)?(?:<!--[\s\S]*?-->\s*)*(?:<!DOCTYPE[^>]*>\s*)?<svg[\s>]/iu.test(value), { message: "brandIcon must be inline SVG markup." });
2557
+ var ReferencePresentationUrlClaim = z8.strictObject({
2558
+ kind: z8.literal("urlPattern"),
2559
+ pattern: z8.strictObject({
2560
+ protocol: z8.enum(["http", "https"]),
2544
2561
  hostname: NonEmptyString,
2545
- pathname: z7.string().optional(),
2546
- search: z7.string().optional()
2562
+ pathname: z8.string().optional(),
2563
+ search: z8.string().optional()
2547
2564
  }),
2548
2565
  brandIcon: InlineSvg.optional()
2549
2566
  });
2550
- var ReferencePresentationContribution = z7.strictObject({
2567
+ var ReferencePresentationContribution = z8.strictObject({
2551
2568
  localId: LocalContributionId,
2552
2569
  uriModule: LocalContributionId,
2553
2570
  resourceKind: NonEmptyString,
@@ -2555,7 +2572,7 @@ var ReferencePresentationContribution = z7.strictObject({
2555
2572
  /** MIME-specific resource kinds; absent keys use the base presentation. */
2556
2573
  variants: ReferencePresentationVariants.optional(),
2557
2574
  /** Lexical public URL claims used only for host-rendered browser presentations. */
2558
- claims: z7.array(ReferencePresentationUrlClaim).optional()
2575
+ claims: z8.array(ReferencePresentationUrlClaim).optional()
2559
2576
  }).superRefine((value, ctx) => {
2560
2577
  if (value.claims !== void 0 && value.claims.length > 0 && value.open.kind !== "browser-pane") {
2561
2578
  ctx.addIssue({
@@ -2565,12 +2582,12 @@ var ReferencePresentationContribution = z7.strictObject({
2565
2582
  });
2566
2583
  }
2567
2584
  });
2568
- var RichViewContribution = z7.strictObject({
2585
+ var RichViewContribution = z8.strictObject({
2569
2586
  localId: LocalContributionId,
2570
2587
  title: NonEmptyString,
2571
2588
  route: NonEmptyString.optional()
2572
2589
  });
2573
- var KayUiAppHostCapability = z7.enum([
2590
+ var KayUiAppHostCapability = z8.enum([
2574
2591
  "navigation.open-session",
2575
2592
  "cost.read",
2576
2593
  // Server-rated organization billing, distinct from local/provider cost.
@@ -2601,9 +2618,9 @@ var KayUiAppHostCapability = z7.enum([
2601
2618
  // rearrange the workspace but never remove something the user would have to notice going missing.
2602
2619
  "workspace.arrange"
2603
2620
  ]);
2604
- var UiAppCapabilities = z7.strictObject({
2605
- endpoints: z7.array(LocalContributionId).optional(),
2606
- host: z7.array(KayUiAppHostCapability).optional()
2621
+ var UiAppCapabilities = z8.strictObject({
2622
+ endpoints: z8.array(LocalContributionId).optional(),
2623
+ host: z8.array(KayUiAppHostCapability).optional()
2607
2624
  }).superRefine((capabilities, ctx) => {
2608
2625
  for (const field of ["endpoints", "host"]) {
2609
2626
  const seen = /* @__PURE__ */ new Set();
@@ -2619,47 +2636,47 @@ var UiAppCapabilities = z7.strictObject({
2619
2636
  }
2620
2637
  }
2621
2638
  });
2622
- var UiAppContribution = z7.strictObject({
2639
+ var UiAppContribution = z8.strictObject({
2623
2640
  localId: LocalContributionId,
2624
2641
  displayName: NonEmptyString,
2625
2642
  description: NonEmptyString.optional(),
2626
2643
  icon: PackageAssetPath.optional(),
2627
- runtime: z7.literal("kay.react-app.v1"),
2628
- sdk: z7.strictObject({ range: NonEmptyString }),
2644
+ runtime: z8.literal("kay.react-app.v1"),
2645
+ sdk: z8.strictObject({ range: NonEmptyString }),
2629
2646
  entrypoint: TargetEntrypoint,
2630
- styles: z7.array(PackageAssetPath).optional(),
2631
- assets: z7.array(PackageAssetPath).optional(),
2647
+ styles: z8.array(PackageAssetPath).optional(),
2648
+ assets: z8.array(PackageAssetPath).optional(),
2632
2649
  capabilities: UiAppCapabilities.optional()
2633
2650
  });
2634
- var ThemeContribution = z7.strictObject({
2651
+ var ThemeContribution = z8.strictObject({
2635
2652
  localId: LocalContributionId,
2636
2653
  displayName: NonEmptyString,
2637
- appearance: z7.enum(["light", "dark"]),
2654
+ appearance: z8.enum(["light", "dark"]),
2638
2655
  tokens: PackageAssetPath
2639
2656
  });
2640
- var CommandHandler = z7.discriminatedUnion("kind", [
2641
- z7.strictObject({ kind: z7.literal("skill"), skill: LocalContributionId }),
2642
- z7.strictObject({
2643
- kind: z7.literal("tool"),
2657
+ var CommandHandler = z8.discriminatedUnion("kind", [
2658
+ z8.strictObject({ kind: z8.literal("skill"), skill: LocalContributionId }),
2659
+ z8.strictObject({
2660
+ kind: z8.literal("tool"),
2644
2661
  tool: PluginToolName,
2645
2662
  /** Positional mapping from tokenized `argsText` onto the tool's own input fields — see this
2646
2663
  * union's doc for the exact tokenize/map/last-field-absorbs rule. */
2647
- argumentFields: z7.array(NonEmptyString)
2664
+ argumentFields: z8.array(NonEmptyString)
2648
2665
  }),
2649
- z7.strictObject({
2650
- kind: z7.literal("endpoint"),
2666
+ z8.strictObject({
2667
+ kind: z8.literal("endpoint"),
2651
2668
  endpoint: LocalContributionId
2652
2669
  })
2653
2670
  ]);
2654
- var CommandContribution = z7.strictObject({
2671
+ var CommandContribution = z8.strictObject({
2655
2672
  localId: LocalContributionId,
2656
2673
  displayName: OptionalDisplayName,
2657
2674
  description: NonEmptyString,
2658
- aliases: z7.array(LocalContributionId).optional(),
2675
+ aliases: z8.array(LocalContributionId).optional(),
2659
2676
  argumentHint: NonEmptyString.optional(),
2660
2677
  handler: CommandHandler
2661
2678
  });
2662
- var PluginContributionKind = z7.enum([
2679
+ var PluginContributionKind = z8.enum([
2663
2680
  "tool",
2664
2681
  "converter",
2665
2682
  "uriModule",
@@ -2734,7 +2751,7 @@ function resolveAdapterId(globalId, declaredAdapterId) {
2734
2751
  }
2735
2752
 
2736
2753
  // packages/plugin-protocol/dist/manifest.js
2737
- import { z as z8 } from "zod";
2754
+ import { z as z9 } from "zod";
2738
2755
 
2739
2756
  // packages/plugin-protocol/dist/synthetic-contributions.js
2740
2757
  function resolveConfigSectionContributionLocalId(section) {
@@ -2754,34 +2771,34 @@ var KAY_UI_NATIVE_EVENT_SUBSCRIPTIONS = [
2754
2771
  "native:renderer.contributions.changed"
2755
2772
  ];
2756
2773
  var KAY_UI_NATIVE_EVENT_ALLOWLIST = new Set(KAY_UI_NATIVE_EVENT_SUBSCRIPTIONS);
2757
- var KayAgentTargetManifest = z8.strictObject({
2774
+ var KayAgentTargetManifest = z9.strictObject({
2758
2775
  entrypoint: TargetEntrypoint,
2759
- contributes: z8.strictObject({
2760
- tools: z8.array(ToolContribution).optional(),
2761
- converters: z8.array(ConverterContribution).optional(),
2762
- uriModules: z8.array(UriModuleContribution).optional(),
2776
+ contributes: z9.strictObject({
2777
+ tools: z9.array(ToolContribution).optional(),
2778
+ converters: z9.array(ConverterContribution).optional(),
2779
+ uriModules: z9.array(UriModuleContribution).optional(),
2763
2780
  // Host-composed artifact-backed schemes (see `ArtifactUriModuleContribution`): the plugin
2764
2781
  // declares scheme + editability; the daemon binds each to the kernel's artifact lifecycle
2765
2782
  // per session. Separate from `uriModules` (plugin-implemented backends) precisely because
2766
2783
  // the plugin registers NOTHING for these at activation.
2767
- artifactUriModules: z8.array(ArtifactUriModuleContribution).optional(),
2768
- cliBindings: z8.array(CliBindingContribution).optional(),
2784
+ artifactUriModules: z9.array(ArtifactUriModuleContribution).optional(),
2785
+ cliBindings: z9.array(CliBindingContribution).optional(),
2769
2786
  // Which git hosts this plugin's credential serves (see `GitHostContribution`): a
2770
2787
  // declaration, so a plugin for any git backend gets credentialed clones without
2771
2788
  // the daemon learning its name. Sibling of `cliBindings` because both answer the
2772
2789
  // same question — which of this plugin's auth services a host-side consumer
2773
2790
  // resolves — for two different transports.
2774
- gitHosts: z8.array(GitHostContribution).optional(),
2775
- resources: z8.array(ResourceContribution).optional(),
2776
- skills: z8.array(SkillContribution).optional(),
2777
- searchProviders: z8.array(SearchProviderContribution).optional(),
2778
- interactionDrivers: z8.array(InteractionDriverContribution).optional(),
2779
- entityResolvers: z8.array(EntityResolverContribution).optional(),
2780
- renderers: z8.array(AgentRenderContribution).optional(),
2791
+ gitHosts: z9.array(GitHostContribution).optional(),
2792
+ resources: z9.array(ResourceContribution).optional(),
2793
+ skills: z9.array(SkillContribution).optional(),
2794
+ searchProviders: z9.array(SearchProviderContribution).optional(),
2795
+ interactionDrivers: z9.array(InteractionDriverContribution).optional(),
2796
+ entityResolvers: z9.array(EntityResolverContribution).optional(),
2797
+ renderers: z9.array(AgentRenderContribution).optional(),
2781
2798
  // Handler restricted to skill | tool by the manifest-level refinement below (see
2782
2799
  // `CommandContribution`'s doc for why the restriction is not expressed in the type, and
2783
2800
  // `CommandHandler`'s doc for why there is no promptTemplate variant to declare here).
2784
- commands: z8.array(CommandContribution).optional()
2801
+ commands: z9.array(CommandContribution).optional()
2785
2802
  }).optional(),
2786
2803
  /**
2787
2804
  * The plugin's primer skill — the `localId` of one of its own declared
@@ -2792,6 +2809,16 @@ var KayAgentTargetManifest = z8.strictObject({
2792
2809
  * composition (host-side), so the field stays optional.
2793
2810
  */
2794
2811
  primer: LocalContributionId.optional(),
2812
+ /**
2813
+ * The plugin's onboarding skill — the `localId` of one of its own declared
2814
+ * `contributes.skills[]` entries, designating the instructions that turn the plugin's first
2815
+ * connection into context Bonsai keeps (notes in Memory, projects, a skill, rules). Like
2816
+ * `primer`, a pointer at an existing contribution that the manifest's superRefine validates;
2817
+ * unlike `primer` it has no reserved name and no synthesized fallback, so a plugin with nothing
2818
+ * to hydrate declares nothing. The skill is neutral: it works in any session, and Bonsai's
2819
+ * first-run layer adds its own lines around it. At most one per plugin.
2820
+ */
2821
+ onboarding: LocalContributionId.optional(),
2795
2822
  /**
2796
2823
  * The plugin's prompt doc — a package-relative path (by convention `./prompt.md`) to
2797
2824
  * a free-form Markdown section the host renders INTO the agent's system prompt, under
@@ -2817,55 +2844,55 @@ var KayAgentTargetManifest = z8.strictObject({
2817
2844
  * acquisition, not declared here, so there is nothing for the resolved contract to mint a
2818
2845
  * `globalId` for at parse time.
2819
2846
  */
2820
- skillSources: z8.array(PluginSkillSourceDeclaration).optional()
2847
+ skillSources: z9.array(PluginSkillSourceDeclaration).optional()
2821
2848
  });
2822
- var KayAppTargetManifest = z8.strictObject({
2849
+ var KayAppTargetManifest = z9.strictObject({
2823
2850
  // Optional, like `kay.ui`'s: a target may carry only declarative `contributes` (e.g. a plugin
2824
2851
  // that ships nothing but `mcpServers`) with no app-lifetime module for the host to load.
2825
2852
  entrypoint: TargetEntrypoint.optional(),
2826
- contributes: z8.strictObject({
2853
+ contributes: z9.strictObject({
2827
2854
  // Session tools implemented by the app-lifetime activation (registered once, injected into
2828
2855
  // every session with a host-stamped session context) — the tool counterpart of `uriModules`
2829
2856
  // below. Same descriptor shape as kay.agent tools; `toolName` shares ONE flat session
2830
2857
  // namespace with them (enforced by the manifest-level refinement below).
2831
- tools: z8.array(ToolContribution).optional(),
2832
- endpoints: z8.array(EndpointContribution).optional(),
2833
- uriModules: z8.array(AppUriModuleContribution).optional(),
2834
- dataSources: z8.array(AppDataSourceContribution).optional(),
2835
- whiteboardTypes: z8.array(WhiteboardTypeContribution).optional(),
2836
- eventDefinitions: z8.array(PluginEventDefinitionContribution).optional(),
2858
+ tools: z9.array(ToolContribution).optional(),
2859
+ endpoints: z9.array(EndpointContribution).optional(),
2860
+ uriModules: z9.array(AppUriModuleContribution).optional(),
2861
+ dataSources: z9.array(AppDataSourceContribution).optional(),
2862
+ whiteboardTypes: z9.array(WhiteboardTypeContribution).optional(),
2863
+ eventDefinitions: z9.array(PluginEventDefinitionContribution).optional(),
2837
2864
  // Default notification rules over this plugin's own `eventDefinitions`; seeded by the host
2838
2865
  // (see `PluginNotificationRuleContribution`).
2839
- notificationRules: z8.array(PluginNotificationRuleContribution).optional(),
2840
- eventSubscriptions: z8.array(AppEventSubscription).optional(),
2841
- deviceDelegations: z8.array(DeviceDelegationContribution).optional(),
2842
- corpusConsumers: z8.array(CorpusContribution).optional(),
2843
- contextContributors: z8.array(ContextContributorContribution).optional(),
2866
+ notificationRules: z9.array(PluginNotificationRuleContribution).optional(),
2867
+ eventSubscriptions: z9.array(AppEventSubscription).optional(),
2868
+ deviceDelegations: z9.array(DeviceDelegationContribution).optional(),
2869
+ corpusConsumers: z9.array(CorpusContribution).optional(),
2870
+ contextContributors: z9.array(ContextContributorContribution).optional(),
2844
2871
  // Vendored MCP servers this plugin ships (see `McpServerContributions`). Bundled-plugin-only
2845
2872
  // in practice; this package cannot see plugin origin, so that ceiling is enforced at
2846
2873
  // composition, not here (see ARCHITECTURE.md "Validation Law").
2847
2874
  mcpServers: McpServerContributions.optional(),
2848
2875
  // Handler restricted to endpoint-only by the manifest-level refinement below.
2849
- commands: z8.array(CommandContribution).optional()
2876
+ commands: z9.array(CommandContribution).optional()
2850
2877
  }).optional()
2851
2878
  });
2852
- var KayUiTargetManifest = z8.strictObject({
2879
+ var KayUiTargetManifest = z9.strictObject({
2853
2880
  entrypoint: TargetEntrypoint.optional(),
2854
- contributes: z8.strictObject({
2855
- commands: z8.array(UiCommandContribution).optional(),
2856
- slots: z8.array(UiSlotContribution).optional(),
2857
- settingsPanels: z8.array(SettingsPanelContribution).optional(),
2858
- resultRenderers: z8.array(ResultRendererContribution).optional(),
2859
- referencePresentations: z8.array(ReferencePresentationContribution).optional(),
2860
- views: z8.array(RichViewContribution).optional(),
2861
- apps: z8.array(UiAppContribution).optional(),
2862
- themes: z8.array(ThemeContribution).optional(),
2863
- eventSubscriptions: z8.array(UiEventSubscriptionContribution).optional(),
2864
- dataMaterializers: z8.array(AppDataMaterializerContribution).optional()
2881
+ contributes: z9.strictObject({
2882
+ commands: z9.array(UiCommandContribution).optional(),
2883
+ slots: z9.array(UiSlotContribution).optional(),
2884
+ settingsPanels: z9.array(SettingsPanelContribution).optional(),
2885
+ resultRenderers: z9.array(ResultRendererContribution).optional(),
2886
+ referencePresentations: z9.array(ReferencePresentationContribution).optional(),
2887
+ views: z9.array(RichViewContribution).optional(),
2888
+ apps: z9.array(UiAppContribution).optional(),
2889
+ themes: z9.array(ThemeContribution).optional(),
2890
+ eventSubscriptions: z9.array(UiEventSubscriptionContribution).optional(),
2891
+ dataMaterializers: z9.array(AppDataMaterializerContribution).optional()
2865
2892
  }).optional()
2866
2893
  });
2867
- var PluginConfigScope = z8.enum(["global", "project", "agent"]);
2868
- var PluginConfigSectionManifest = z8.strictObject({
2894
+ var PluginConfigScope = z9.enum(["global", "project", "agent"]);
2895
+ var PluginConfigSectionManifest = z9.strictObject({
2869
2896
  section: NonEmptyString.optional(),
2870
2897
  schema: JsonSchema,
2871
2898
  /**
@@ -2883,25 +2910,25 @@ var PluginConfigSectionManifest = z8.strictObject({
2883
2910
  * is the baseline every section has; `agent` has no runtime mapping (the
2884
2911
  * agent/entity fold is downstream of the document protocol).
2885
2912
  */
2886
- scopes: z8.array(PluginConfigScope).optional()
2913
+ scopes: z9.array(PluginConfigScope).optional()
2887
2914
  });
2888
- var PluginConfigManifest = z8.array(PluginConfigSectionManifest).min(1);
2915
+ var PluginConfigManifest = z9.array(PluginConfigSectionManifest).min(1);
2889
2916
  function configSectionKeysForManifest(manifest) {
2890
2917
  return manifest.config?.map((config) => config.section ?? `plugins.${manifest.id}`) ?? [];
2891
2918
  }
2892
- var PluginStorageManifest = z8.strictObject({
2893
- sqlite: z8.strictObject({
2894
- enabled: z8.boolean(),
2895
- ownerTarget: z8.literal("kay.app").optional(),
2919
+ var PluginStorageManifest = z9.strictObject({
2920
+ sqlite: z9.strictObject({
2921
+ enabled: z9.boolean(),
2922
+ ownerTarget: z9.literal("kay.app").optional(),
2896
2923
  migrations: NonEmptyString.optional()
2897
2924
  }).optional(),
2898
- dataDir: z8.strictObject({
2899
- enabled: z8.boolean(),
2900
- ownerTarget: z8.literal("kay.app").optional()
2925
+ dataDir: z9.strictObject({
2926
+ enabled: z9.boolean(),
2927
+ ownerTarget: z9.literal("kay.app").optional()
2901
2928
  }).optional()
2902
2929
  });
2903
- var PluginOAuthClientSupplier = z8.enum(["kay", "user"]);
2904
- var PluginProvisioningProbe = z8.strictObject({
2930
+ var PluginOAuthClientSupplier = z9.enum(["kay", "user"]);
2931
+ var PluginProvisioningProbe = z9.strictObject({
2905
2932
  /**
2906
2933
  * The API endpoint that answers the question. The host sends the service's OWN credential here,
2907
2934
  * so this must belong to the provider that minted it — enforced by the daemon against the
@@ -2909,13 +2936,13 @@ var PluginProvisioningProbe = z8.strictObject({
2909
2936
  */
2910
2937
  url: HttpsUrl,
2911
2938
  /** Absent ⇒ `GET`. */
2912
- method: z8.enum(["GET"]).optional(),
2939
+ method: z9.enum(["GET"]).optional(),
2913
2940
  /**
2914
2941
  * The statuses that make the response a VERDICT at all. Anything else (a 401 from a stale
2915
2942
  * token, a 5xx, a rate limit) means the probe learned nothing and reports `unknown` — never
2916
2943
  * `unsatisfied`, which would tell a user to go fix setup that is fine.
2917
2944
  */
2918
- verdictStatuses: z8.array(SignedInStatusCode).min(1),
2945
+ verdictStatuses: z9.array(SignedInStatusCode).min(1),
2919
2946
  /**
2920
2947
  * Dot-path to a JSON array in the response body that must be NON-EMPTY for the requirement to
2921
2948
  * count as satisfied (e.g. `installations`). Absent means a verdict status alone is enough.
@@ -2924,7 +2951,7 @@ var PluginProvisioningProbe = z8.strictObject({
2924
2951
  */
2925
2952
  nonEmptyArrayAt: NonEmptyString.optional()
2926
2953
  });
2927
- var PluginProvisioningRequirement = z8.strictObject({
2954
+ var PluginProvisioningRequirement = z9.strictObject({
2928
2955
  /** Stable id, unique within the scheme. */
2929
2956
  id: LocalContributionId,
2930
2957
  /** Human-facing requirement name, e.g. "GitHub App installation". */
@@ -2941,7 +2968,7 @@ var PluginProvisioningRequirement = z8.strictObject({
2941
2968
  probe: PluginProvisioningProbe
2942
2969
  });
2943
2970
  var PluginProvisioningField = {
2944
- provisioning: z8.array(PluginProvisioningRequirement).optional()
2971
+ provisioning: z9.array(PluginProvisioningRequirement).optional()
2945
2972
  };
2946
2973
  var PluginAuthSchemeDescriptionFields = {
2947
2974
  /** Human-facing flow name; the runtime scheme name is the fallback. */
@@ -2954,19 +2981,19 @@ var PluginAuthSchemeDescriptionFields = {
2954
2981
  */
2955
2982
  summary: NonEmptyString.optional()
2956
2983
  };
2957
- var PluginAuthSchemeOAuthPkce = z8.strictObject({
2984
+ var PluginAuthSchemeOAuthPkce = z9.strictObject({
2958
2985
  ...PluginProvisioningField,
2959
2986
  ...PluginAuthSchemeDescriptionFields,
2960
2987
  localId: LocalContributionId,
2961
- kind: z8.literal("oauth2"),
2962
- exchange: z8.literal("pkce"),
2988
+ kind: z9.literal("oauth2"),
2989
+ exchange: z9.literal("pkce"),
2963
2990
  /**
2964
2991
  * Unordered SET of who may supply the client — non-empty, and every entry must be distinct
2965
2992
  * (fail-closed re-assertion of the kernel's construction-time dedupe: TS exhaustiveness never
2966
2993
  * runs on an untrusted manifest, so a hand-built `["kay","kay"]` must be refused here, not
2967
2994
  * silently normalized).
2968
2995
  */
2969
- clientSuppliers: z8.array(PluginOAuthClientSupplier).nonempty().superRefine((suppliers, ctx) => {
2996
+ clientSuppliers: z9.array(PluginOAuthClientSupplier).nonempty().superRefine((suppliers, ctx) => {
2970
2997
  if (new Set(suppliers).size !== suppliers.length) {
2971
2998
  ctx.addIssue({
2972
2999
  code: "custom",
@@ -2974,70 +3001,70 @@ var PluginAuthSchemeOAuthPkce = z8.strictObject({
2974
3001
  });
2975
3002
  }
2976
3003
  }),
2977
- scopes: z8.array(NonEmptyString).optional()
3004
+ scopes: z9.array(NonEmptyString).optional()
2978
3005
  });
2979
- var PluginAuthSchemeOAuthConfidential = z8.strictObject({
3006
+ var PluginAuthSchemeOAuthConfidential = z9.strictObject({
2980
3007
  ...PluginProvisioningField,
2981
3008
  ...PluginAuthSchemeDescriptionFields,
2982
3009
  localId: LocalContributionId,
2983
- kind: z8.literal("oauth2"),
2984
- exchange: z8.literal("confidential"),
3010
+ kind: z9.literal("oauth2"),
3011
+ exchange: z9.literal("confidential"),
2985
3012
  /** Absent means `["kay"]` — a confidential exchange's secret may only ever be Bonsai's. */
2986
- clientSuppliers: z8.tuple([z8.literal("kay")]).optional(),
2987
- scopes: z8.array(NonEmptyString).optional()
3013
+ clientSuppliers: z9.tuple([z9.literal("kay")]).optional(),
3014
+ scopes: z9.array(NonEmptyString).optional()
2988
3015
  });
2989
- var PluginAuthSchemeOAuth2 = z8.discriminatedUnion("exchange", [
3016
+ var PluginAuthSchemeOAuth2 = z9.discriminatedUnion("exchange", [
2990
3017
  PluginAuthSchemeOAuthPkce,
2991
3018
  PluginAuthSchemeOAuthConfidential
2992
3019
  ]);
2993
- var PluginAuthSchemeApiKey = z8.strictObject({
3020
+ var PluginAuthSchemeApiKey = z9.strictObject({
2994
3021
  ...PluginProvisioningField,
2995
3022
  ...PluginAuthSchemeDescriptionFields,
2996
3023
  localId: LocalContributionId,
2997
- kind: z8.literal("api-key"),
2998
- scopes: z8.array(NonEmptyString).optional()
3024
+ kind: z9.literal("api-key"),
3025
+ scopes: z9.array(NonEmptyString).optional()
2999
3026
  });
3000
- var PluginAuthSchemeDelegated = z8.strictObject({
3027
+ var PluginAuthSchemeDelegated = z9.strictObject({
3001
3028
  ...PluginAuthSchemeDescriptionFields,
3002
3029
  localId: LocalContributionId,
3003
- kind: z8.literal("delegated"),
3004
- scopes: z8.array(NonEmptyString).optional()
3030
+ kind: z9.literal("delegated"),
3031
+ scopes: z9.array(NonEmptyString).optional()
3005
3032
  });
3006
- var PluginAuthSchemeExternalCli = z8.strictObject({
3033
+ var PluginAuthSchemeExternalCli = z9.strictObject({
3007
3034
  ...PluginAuthSchemeDescriptionFields,
3008
3035
  localId: LocalContributionId,
3009
- kind: z8.literal("external-cli"),
3010
- scopes: z8.array(NonEmptyString).optional()
3036
+ kind: z9.literal("external-cli"),
3037
+ scopes: z9.array(NonEmptyString).optional()
3011
3038
  });
3012
- var PluginAuthScheme = z8.discriminatedUnion("kind", [
3039
+ var PluginAuthScheme = z9.discriminatedUnion("kind", [
3013
3040
  PluginAuthSchemeOAuth2,
3014
3041
  PluginAuthSchemeApiKey,
3015
3042
  PluginAuthSchemeDelegated,
3016
3043
  PluginAuthSchemeExternalCli
3017
3044
  ]);
3018
- var PluginWebSessionProbe = z8.strictObject({
3045
+ var PluginWebSessionProbe = z9.strictObject({
3019
3046
  url: HttpsUrl,
3020
3047
  /** Absent ⇒ `GET`. `POST` sends an empty JSON object body. */
3021
- method: z8.enum(["GET", "POST"]).optional(),
3022
- signedInStatuses: z8.array(SignedInStatusCode).min(1)
3048
+ method: z9.enum(["GET", "POST"]).optional(),
3049
+ signedInStatuses: z9.array(SignedInStatusCode).min(1)
3023
3050
  });
3024
- var PluginWebSessionDeclaration = z8.strictObject({
3051
+ var PluginWebSessionDeclaration = z9.strictObject({
3025
3052
  /** `required`: capabilities degrade without the site login; `recommended`: it only smooths UX. */
3026
- importance: z8.enum(["required", "recommended"]),
3053
+ importance: z9.enum(["required", "recommended"]),
3027
3054
  loginUrl: HttpsUrl,
3028
- cookieDomains: z8.array(RegistrableDomain).min(1),
3055
+ cookieDomains: z9.array(RegistrableDomain).min(1),
3029
3056
  probe: PluginWebSessionProbe,
3030
- oauthVenue: z8.enum(["embedded", "external"])
3057
+ oauthVenue: z9.enum(["embedded", "external"])
3031
3058
  }).superRefine(refineWebSessionScopeConfined);
3032
- var PluginAuthService = z8.strictObject({
3059
+ var PluginAuthService = z9.strictObject({
3033
3060
  localId: LocalContributionId,
3034
3061
  displayName: NonEmptyString,
3035
- schemes: z8.array(PluginAuthScheme).min(1),
3036
- purposes: z8.array(NonEmptyString).min(1),
3062
+ schemes: z9.array(PluginAuthScheme).min(1),
3063
+ purposes: z9.array(NonEmptyString).min(1),
3037
3064
  webSession: PluginWebSessionDeclaration.optional()
3038
3065
  });
3039
- var PluginAuthManifest = z8.strictObject({
3040
- services: z8.array(PluginAuthService).optional()
3066
+ var PluginAuthManifest = z9.strictObject({
3067
+ services: z9.array(PluginAuthService).optional()
3041
3068
  });
3042
3069
  var RETIRED_COMPATIBILITY_KEYS = ["policy"];
3043
3070
  function stripRetiredCompatibilityKeys(value) {
@@ -3049,8 +3076,8 @@ function stripRetiredCompatibilityKeys(value) {
3049
3076
  delete remaining[key];
3050
3077
  return remaining;
3051
3078
  }
3052
- var PluginCompatibilityManifest = z8.preprocess(stripRetiredCompatibilityKeys, z8.strictObject({
3053
- supportedProtocols: z8.array(KayPluginProtocolVersion).optional(),
3079
+ var PluginCompatibilityManifest = z9.preprocess(stripRetiredCompatibilityKeys, z9.strictObject({
3080
+ supportedProtocols: z9.array(KayPluginProtocolVersion).optional(),
3054
3081
  minKayVersion: NonEmptyString.optional(),
3055
3082
  sdk: NonEmptyString.optional()
3056
3083
  }));
@@ -3066,8 +3093,8 @@ function retiredCompatibilityKeysIn(rawManifest) {
3066
3093
  var KayVersionString = NonEmptyString.regex(SEMVER_PATTERN, {
3067
3094
  message: "version must be semver, for example 1.2.3"
3068
3095
  });
3069
- var KayPluginManifestV1 = z8.strictObject({
3070
- protocol: z8.literal(KAY_PLUGIN_PROTOCOL_VERSION),
3096
+ var KayPluginManifestV1 = z9.strictObject({
3097
+ protocol: z9.literal(KAY_PLUGIN_PROTOCOL_VERSION),
3071
3098
  id: PluginId,
3072
3099
  displayName: NonEmptyString,
3073
3100
  version: KayVersionString,
@@ -3097,8 +3124,8 @@ var KayPluginManifestV1 = z8.strictObject({
3097
3124
  icon: PackageAssetPath.optional(),
3098
3125
  iconDark: PackageAssetPath.optional(),
3099
3126
  namespace: PluginNamespace.optional(),
3100
- targets: z8.strictObject({
3101
- kay: z8.strictObject({
3127
+ targets: z9.strictObject({
3128
+ kay: z9.strictObject({
3102
3129
  agent: KayAgentTargetManifest.optional(),
3103
3130
  app: KayAppTargetManifest.optional(),
3104
3131
  ui: KayUiTargetManifest.optional()
@@ -3115,15 +3142,15 @@ var KayPluginManifestV1 = z8.strictObject({
3115
3142
  * schemes then report `ownedByBonsai`. Honoured only for a plugin that ships with Bonsai: the
3116
3143
  * host reads any other plugin's flag as false. Absent ⇒ false.
3117
3144
  */
3118
- ownedByBonsai: z8.boolean().optional(),
3145
+ ownedByBonsai: z9.boolean().optional(),
3119
3146
  /**
3120
3147
  * Explicit plugin-level dependencies — other plugins this plugin requires to be present in the
3121
3148
  * composed roster. At composition time the runtime checks each id against the accepted
3122
3149
  * registration list and derives a provenance-complete dependency graph (together with implicit
3123
3150
  * auth-service edges from `consumesAuthServices`). Absent ⇒ no explicit dependencies.
3124
3151
  */
3125
- dependencies: z8.strictObject({
3126
- plugins: z8.array(PluginId).optional()
3152
+ dependencies: z9.strictObject({
3153
+ plugins: z9.array(PluginId).optional()
3127
3154
  }).optional()
3128
3155
  }).superRefine((manifest, ctx) => {
3129
3156
  const authServices = new Set(manifest.auth?.services?.map((service) => service.localId) ?? []);
@@ -3320,16 +3347,22 @@ var KayPluginManifestV1 = z8.strictObject({
3320
3347
  converterMimeTypes.set(mimeType, converter.localId);
3321
3348
  }
3322
3349
  }
3350
+ const declaredSkillIds = new Set((manifest.targets?.kay?.agent?.contributes?.skills ?? []).map((skill) => skill.localId));
3323
3351
  const agentPrimer = manifest.targets?.kay?.agent?.primer;
3324
- if (agentPrimer !== void 0) {
3325
- const declaredSkillIds = new Set((manifest.targets?.kay?.agent?.contributes?.skills ?? []).map((skill) => skill.localId));
3326
- if (!declaredSkillIds.has(agentPrimer)) {
3327
- ctx.addIssue({
3328
- code: "custom",
3329
- path: ["targets", "kay", "agent", "primer"],
3330
- message: `primer '${agentPrimer}' does not name a declared kay.agent skill contribution`
3331
- });
3332
- }
3352
+ if (agentPrimer !== void 0 && !declaredSkillIds.has(agentPrimer)) {
3353
+ ctx.addIssue({
3354
+ code: "custom",
3355
+ path: ["targets", "kay", "agent", "primer"],
3356
+ message: `primer '${agentPrimer}' does not name a declared kay.agent skill contribution`
3357
+ });
3358
+ }
3359
+ const agentOnboarding = manifest.targets?.kay?.agent?.onboarding;
3360
+ if (agentOnboarding !== void 0 && !declaredSkillIds.has(agentOnboarding)) {
3361
+ ctx.addIssue({
3362
+ code: "custom",
3363
+ path: ["targets", "kay", "agent", "onboarding"],
3364
+ message: `onboarding '${agentOnboarding}' does not name a declared kay.agent skill contribution`
3365
+ });
3333
3366
  }
3334
3367
  for (const skill of manifest.targets?.kay?.agent?.contributes?.skills ?? []) {
3335
3368
  if (skill.localId === "primer" && agentPrimer !== "primer") {
@@ -3786,37 +3819,46 @@ function pushContributionIds(output, path, items) {
3786
3819
  }
3787
3820
  }
3788
3821
 
3822
+ // packages/plugin-protocol/dist/plugin-directory-verdict.js
3823
+ import { z as z11 } from "zod";
3824
+
3825
+ // packages/plugin-protocol/dist/plugin-load-diagnostic.js
3826
+ var PLUGIN_DIAGNOSTIC_MESSAGE_CAP = 300;
3827
+ function boundPluginDiagnosticMessage(message) {
3828
+ return message.length <= PLUGIN_DIAGNOSTIC_MESSAGE_CAP ? message : `${message.slice(0, PLUGIN_DIAGNOSTIC_MESSAGE_CAP - 1)}\u2026`;
3829
+ }
3830
+
3789
3831
  // packages/plugin-protocol/dist/resolved-contract.js
3790
- import { z as z9 } from "zod";
3791
- var ResolvedPluginContributionId = z9.strictObject({
3832
+ import { z as z10 } from "zod";
3833
+ var ResolvedPluginContributionId = z10.strictObject({
3792
3834
  target: PluginTargetName,
3793
3835
  kind: PluginContributionKind,
3794
3836
  localId: LocalContributionId,
3795
3837
  globalId: GlobalContributionId
3796
3838
  });
3797
- var ResolvedKayAgentTool = z9.strictObject({
3839
+ var ResolvedKayAgentTool = z10.strictObject({
3798
3840
  localId: LocalContributionId,
3799
3841
  globalId: GlobalContributionId,
3800
3842
  toolName: PluginToolName
3801
3843
  });
3802
3844
  var ResolvedKayAppTool = ResolvedKayAgentTool;
3803
- var ResolvedKayAppDataSource = z9.strictObject({
3845
+ var ResolvedKayAppDataSource = z10.strictObject({
3804
3846
  localId: LocalContributionId,
3805
3847
  globalId: GlobalContributionId,
3806
- scope: z9.enum(["runtime", "account", "session"]),
3807
- snapshot: z9.strictObject({
3808
- version: z9.number().int().positive(),
3809
- schema: z9.record(z9.string(), z9.unknown())
3848
+ scope: z10.enum(["runtime", "account", "session"]),
3849
+ snapshot: z10.strictObject({
3850
+ version: z10.number().int().positive(),
3851
+ schema: z10.record(z10.string(), z10.unknown())
3810
3852
  }),
3811
- change: z9.strictObject({
3812
- version: z9.number().int().positive(),
3813
- schema: z9.record(z9.string(), z9.unknown()),
3814
- semantics: z9.discriminatedUnion("kind", [
3815
- z9.strictObject({ kind: z9.literal("incremental") }),
3816
- z9.strictObject({
3817
- kind: z9.literal("snapshot-replacement"),
3818
- maxEncodedBytes: z9.number().int().positive(),
3819
- rationale: z9.string().trim().min(1).max(1024)
3853
+ change: z10.strictObject({
3854
+ version: z10.number().int().positive(),
3855
+ schema: z10.record(z10.string(), z10.unknown()),
3856
+ semantics: z10.discriminatedUnion("kind", [
3857
+ z10.strictObject({ kind: z10.literal("incremental") }),
3858
+ z10.strictObject({
3859
+ kind: z10.literal("snapshot-replacement"),
3860
+ maxEncodedBytes: z10.number().int().positive(),
3861
+ rationale: z10.string().trim().min(1).max(1024)
3820
3862
  })
3821
3863
  ]).optional()
3822
3864
  }),
@@ -3830,66 +3872,66 @@ var ResolvedKayAppDataSource = z9.strictObject({
3830
3872
  });
3831
3873
  }
3832
3874
  });
3833
- var ResolvedKayAppWhiteboardType = z9.strictObject({
3875
+ var ResolvedKayAppWhiteboardType = z10.strictObject({
3834
3876
  localId: LocalContributionId,
3835
3877
  globalId: GlobalContributionId,
3836
3878
  displayName: NonEmptyString,
3837
- schemaVersion: z9.number().int().positive(),
3879
+ schemaVersion: z10.number().int().positive(),
3838
3880
  storage: WhiteboardTypeStorage,
3839
3881
  valueSchema: JsonSchema,
3840
- presentation: z9.strictObject({
3882
+ presentation: z10.strictObject({
3841
3883
  app: GlobalContributionId
3842
3884
  }).optional()
3843
3885
  });
3844
- var ResolvedKayAppMcpServer = z9.strictObject({
3886
+ var ResolvedKayAppMcpServer = z10.strictObject({
3845
3887
  name: LocalContributionId,
3846
3888
  pluginId: PluginId,
3847
3889
  url: McpServerUrl,
3848
3890
  auth: McpServerAuthMode,
3849
3891
  authServiceId: GlobalContributionId.optional()
3850
3892
  });
3851
- var ResolvedKayAgentUriModule = z9.strictObject({
3893
+ var ResolvedKayAgentUriModule = z10.strictObject({
3852
3894
  localId: LocalContributionId,
3853
3895
  globalId: GlobalContributionId,
3854
- schemes: z9.array(UriScheme).min(1),
3896
+ schemes: z10.array(UriScheme).min(1),
3855
3897
  filesystemBacking: UriFilesystemBacking.optional(),
3856
3898
  /** Mirrors `UriModuleContribution.knownResources` (host-side recording opt-in). */
3857
- knownResources: z9.literal(true).optional()
3899
+ knownResources: z10.literal(true).optional()
3858
3900
  });
3859
- var ResolvedKayAgentArtifactUriModule = z9.strictObject({
3901
+ var ResolvedKayAgentArtifactUriModule = z10.strictObject({
3860
3902
  localId: LocalContributionId,
3861
3903
  globalId: GlobalContributionId,
3862
3904
  scheme: UriScheme,
3863
- editable: z9.boolean(),
3864
- listable: z9.boolean(),
3865
- deletable: z9.boolean(),
3866
- appendable: z9.boolean(),
3867
- storageScope: z9.enum(["session", "family"])
3905
+ editable: z10.boolean(),
3906
+ listable: z10.boolean(),
3907
+ deletable: z10.boolean(),
3908
+ appendable: z10.boolean(),
3909
+ storageScope: z10.enum(["session", "family"])
3868
3910
  });
3869
- var ResolvedKayAgentEntityResolver = z9.strictObject({
3911
+ var ResolvedKayAgentEntityResolver = z10.strictObject({
3870
3912
  localId: LocalContributionId,
3871
3913
  globalId: GlobalContributionId,
3872
3914
  displayName: NonEmptyString.optional(),
3873
3915
  uriModule: GlobalContributionId,
3874
- entityTypes: z9.array(NonEmptyString).min(1),
3916
+ entityTypes: z10.array(NonEmptyString).min(1),
3875
3917
  uriHint: NonEmptyString
3876
3918
  });
3877
- var ResolvedKayAgentGitHostClaim = z9.strictObject({
3919
+ var ResolvedKayAgentGitHostClaim = z10.strictObject({
3878
3920
  host: GitHostName,
3879
3921
  authServiceId: GlobalContributionId,
3880
3922
  /** Manifest-declared order; the clone ladder tries them in sequence. */
3881
- authSchemeIds: z9.array(GlobalContributionId).min(1),
3923
+ authSchemeIds: z10.array(GlobalContributionId).min(1),
3882
3924
  /** Non-secret display copy for the claiming service, for clone failure text. */
3883
- authServiceDisplayName: z9.string(),
3925
+ authServiceDisplayName: z10.string(),
3884
3926
  basicAuthUser: GitBasicAuthUser
3885
3927
  });
3886
- var ResolvedKayAgentConverter = z9.strictObject({
3928
+ var ResolvedKayAgentConverter = z10.strictObject({
3887
3929
  localId: LocalContributionId,
3888
3930
  globalId: GlobalContributionId,
3889
- mimeTypes: z9.array(MimeTypeString).min(1),
3890
- extensions: z9.array(FileExtensionToken).min(1).optional()
3931
+ mimeTypes: z10.array(MimeTypeString).min(1),
3932
+ extensions: z10.array(FileExtensionToken).min(1).optional()
3891
3933
  });
3892
- var ResolvedReferencePresentation = z9.strictObject({
3934
+ var ResolvedReferencePresentation = z10.strictObject({
3893
3935
  localId: LocalContributionId,
3894
3936
  globalId: GlobalContributionId,
3895
3937
  uriModule: GlobalContributionId,
@@ -3897,9 +3939,9 @@ var ResolvedReferencePresentation = z9.strictObject({
3897
3939
  open: ReferenceOpenBehavior,
3898
3940
  /** MIME-specific resource kinds; absent keys use the base presentation. */
3899
3941
  variants: ReferencePresentationVariants.optional(),
3900
- claims: z9.array(ReferencePresentationUrlClaim).optional()
3942
+ claims: z10.array(ReferencePresentationUrlClaim).optional()
3901
3943
  });
3902
- var ResolvedPluginProvisioningRequirement = z9.strictObject({
3944
+ var ResolvedPluginProvisioningRequirement = z10.strictObject({
3903
3945
  id: LocalContributionId,
3904
3946
  displayName: NonEmptyString,
3905
3947
  description: NonEmptyString,
@@ -3909,15 +3951,15 @@ var ResolvedPluginProvisioningRequirement = z9.strictObject({
3909
3951
  * URL degrades to "Reconnect" in the UI instead of a broken link.
3910
3952
  */
3911
3953
  remediationUrl: HttpsUrl.optional(),
3912
- probe: z9.strictObject({
3954
+ probe: z10.strictObject({
3913
3955
  url: HttpsUrl,
3914
- method: z9.enum(["GET"]),
3915
- verdictStatuses: z9.array(SignedInStatusCode).min(1),
3956
+ method: z10.enum(["GET"]),
3957
+ verdictStatuses: z10.array(SignedInStatusCode).min(1),
3916
3958
  nonEmptyArrayAt: NonEmptyString.optional()
3917
3959
  })
3918
3960
  });
3919
3961
  var ResolvedProvisioningField = {
3920
- provisioning: z9.array(ResolvedPluginProvisioningRequirement).optional()
3962
+ provisioning: z10.array(ResolvedPluginProvisioningRequirement).optional()
3921
3963
  };
3922
3964
  var ResolvedPluginAuthSchemeDescriptionFields = {
3923
3965
  displayName: NonEmptyString.optional(),
@@ -3929,96 +3971,96 @@ var ResolvedPluginAuthSchemeOAuthBase = {
3929
3971
  ...ResolvedPluginAuthSchemeDescriptionFields,
3930
3972
  localId: LocalContributionId,
3931
3973
  globalId: GlobalContributionId,
3932
- kind: z9.literal("oauth2"),
3933
- scopes: z9.array(z9.string()).optional()
3974
+ kind: z10.literal("oauth2"),
3975
+ scopes: z10.array(z10.string()).optional()
3934
3976
  };
3935
- var ResolvedPluginAuthSchemeOAuthPkce = z9.strictObject({
3977
+ var ResolvedPluginAuthSchemeOAuthPkce = z10.strictObject({
3936
3978
  ...ResolvedPluginAuthSchemeOAuthBase,
3937
- exchange: z9.literal("pkce"),
3938
- clientSuppliers: z9.array(PluginOAuthClientSupplier).nonempty()
3979
+ exchange: z10.literal("pkce"),
3980
+ clientSuppliers: z10.array(PluginOAuthClientSupplier).nonempty()
3939
3981
  });
3940
- var ResolvedPluginAuthSchemeOAuthConfidential = z9.strictObject({
3982
+ var ResolvedPluginAuthSchemeOAuthConfidential = z10.strictObject({
3941
3983
  ...ResolvedPluginAuthSchemeOAuthBase,
3942
- exchange: z9.literal("confidential"),
3943
- clientSuppliers: z9.tuple([z9.literal("kay")])
3984
+ exchange: z10.literal("confidential"),
3985
+ clientSuppliers: z10.tuple([z10.literal("kay")])
3944
3986
  });
3945
- var ResolvedPluginAuthSchemeOAuth2 = z9.discriminatedUnion("exchange", [
3987
+ var ResolvedPluginAuthSchemeOAuth2 = z10.discriminatedUnion("exchange", [
3946
3988
  ResolvedPluginAuthSchemeOAuthPkce,
3947
3989
  ResolvedPluginAuthSchemeOAuthConfidential
3948
3990
  ]);
3949
- var ResolvedPluginAuthSchemeApiKey = z9.strictObject({
3991
+ var ResolvedPluginAuthSchemeApiKey = z10.strictObject({
3950
3992
  ...ResolvedProvisioningField,
3951
3993
  ...ResolvedPluginAuthSchemeDescriptionFields,
3952
3994
  localId: LocalContributionId,
3953
3995
  globalId: GlobalContributionId,
3954
- kind: z9.literal("api-key"),
3955
- scopes: z9.array(z9.string()).optional()
3996
+ kind: z10.literal("api-key"),
3997
+ scopes: z10.array(z10.string()).optional()
3956
3998
  });
3957
- var ResolvedPluginAuthSchemeDelegated = z9.strictObject({
3999
+ var ResolvedPluginAuthSchemeDelegated = z10.strictObject({
3958
4000
  ...ResolvedPluginAuthSchemeDescriptionFields,
3959
4001
  localId: LocalContributionId,
3960
4002
  globalId: GlobalContributionId,
3961
- kind: z9.literal("delegated"),
3962
- scopes: z9.array(z9.string()).optional()
4003
+ kind: z10.literal("delegated"),
4004
+ scopes: z10.array(z10.string()).optional()
3963
4005
  });
3964
- var ResolvedPluginAuthSchemeExternalCli = z9.strictObject({
4006
+ var ResolvedPluginAuthSchemeExternalCli = z10.strictObject({
3965
4007
  ...ResolvedPluginAuthSchemeDescriptionFields,
3966
4008
  localId: LocalContributionId,
3967
4009
  globalId: GlobalContributionId,
3968
- kind: z9.literal("external-cli"),
3969
- scopes: z9.array(z9.string()).optional()
4010
+ kind: z10.literal("external-cli"),
4011
+ scopes: z10.array(z10.string()).optional()
3970
4012
  });
3971
- var ResolvedPluginAuthScheme = z9.discriminatedUnion("kind", [
4013
+ var ResolvedPluginAuthScheme = z10.discriminatedUnion("kind", [
3972
4014
  ResolvedPluginAuthSchemeOAuth2,
3973
4015
  ResolvedPluginAuthSchemeApiKey,
3974
4016
  ResolvedPluginAuthSchemeDelegated,
3975
4017
  ResolvedPluginAuthSchemeExternalCli
3976
4018
  ]);
3977
- var ResolvedPluginWebSession = z9.strictObject({
3978
- importance: z9.enum(["required", "recommended"]),
4019
+ var ResolvedPluginWebSession = z10.strictObject({
4020
+ importance: z10.enum(["required", "recommended"]),
3979
4021
  loginUrl: HttpsUrl,
3980
- cookieDomains: z9.array(RegistrableDomain).min(1),
3981
- probe: z9.strictObject({
4022
+ cookieDomains: z10.array(RegistrableDomain).min(1),
4023
+ probe: z10.strictObject({
3982
4024
  url: HttpsUrl,
3983
- method: z9.enum(["GET", "POST"]),
3984
- signedInStatuses: z9.array(SignedInStatusCode).min(1)
4025
+ method: z10.enum(["GET", "POST"]),
4026
+ signedInStatuses: z10.array(SignedInStatusCode).min(1)
3985
4027
  }),
3986
- oauthVenue: z9.enum(["embedded", "external"])
4028
+ oauthVenue: z10.enum(["embedded", "external"])
3987
4029
  }).superRefine(refineWebSessionScopeConfined);
3988
- var ResolvedPluginAuthService = z9.strictObject({
4030
+ var ResolvedPluginAuthService = z10.strictObject({
3989
4031
  localId: LocalContributionId,
3990
4032
  globalId: GlobalContributionId,
3991
- displayName: z9.string(),
3992
- schemes: z9.array(ResolvedPluginAuthScheme).min(1),
3993
- purposes: z9.array(z9.string()).min(1),
4033
+ displayName: z10.string(),
4034
+ schemes: z10.array(ResolvedPluginAuthScheme).min(1),
4035
+ purposes: z10.array(z10.string()).min(1),
3994
4036
  /** The service's browser half, when the manifest declares one. */
3995
4037
  webSession: ResolvedPluginWebSession.optional()
3996
4038
  });
3997
- var ResolvedKayUiAppEndpointCapability = z9.strictObject({
4039
+ var ResolvedKayUiAppEndpointCapability = z10.strictObject({
3998
4040
  localId: LocalContributionId,
3999
4041
  globalId: GlobalContributionId
4000
4042
  });
4001
- var ResolvedKayUiApp = z9.strictObject({
4043
+ var ResolvedKayUiApp = z10.strictObject({
4002
4044
  localId: LocalContributionId,
4003
4045
  globalId: GlobalContributionId,
4004
4046
  displayName: NonEmptyString,
4005
4047
  description: NonEmptyString.optional(),
4006
4048
  icon: PackageAssetPath.optional(),
4007
- runtime: z9.literal("kay.react-app.v1"),
4008
- sdk: z9.strictObject({ range: NonEmptyString }),
4049
+ runtime: z10.literal("kay.react-app.v1"),
4050
+ sdk: z10.strictObject({ range: NonEmptyString }),
4009
4051
  entrypoint: TargetEntrypoint,
4010
- styles: z9.array(PackageAssetPath).optional(),
4011
- assets: z9.array(PackageAssetPath).optional(),
4012
- capabilities: z9.strictObject({
4013
- endpoints: z9.array(ResolvedKayUiAppEndpointCapability).optional(),
4014
- host: z9.array(KayUiAppHostCapability).optional()
4052
+ styles: z10.array(PackageAssetPath).optional(),
4053
+ assets: z10.array(PackageAssetPath).optional(),
4054
+ capabilities: z10.strictObject({
4055
+ endpoints: z10.array(ResolvedKayUiAppEndpointCapability).optional(),
4056
+ host: z10.array(KayUiAppHostCapability).optional()
4015
4057
  }).optional()
4016
4058
  });
4017
- var ResolvedPluginContractV1 = z9.strictObject({
4018
- protocol: z9.literal("kay.plugin.v1"),
4059
+ var ResolvedPluginContractV1 = z10.strictObject({
4060
+ protocol: z10.literal("kay.plugin.v1"),
4019
4061
  pluginId: PluginId,
4020
4062
  namespace: PluginNamespace,
4021
- contributions: z9.array(ResolvedPluginContributionId),
4063
+ contributions: z10.array(ResolvedPluginContributionId),
4022
4064
  // The deduplicated set of qualified (dotted) external auth-service ids this
4023
4065
  // plugin references, from agent uriModule `authService` refs, cliBinding
4024
4066
  // `authService` refs, and auth-grant `service` refs. Always present — a plugin
@@ -4026,30 +4068,30 @@ var ResolvedPluginContractV1 = z9.strictObject({
4026
4068
  // is a recorded dependency, not a resolution: there is no runtime plugin
4027
4069
  // loader in v1, so nothing here verifies the reference resolves within a
4028
4070
  // composed roster (a composition-time concern owned elsewhere).
4029
- consumesAuthServices: z9.array(GlobalContributionId),
4071
+ consumesAuthServices: z10.array(GlobalContributionId),
4030
4072
  // The explicit plugin-level dependency ids declared in `dependencies.plugins` on the manifest,
4031
4073
  // deduped and validated at parse time. Always present; a plugin with no explicit dependencies
4032
4074
  // carries an empty array. Composition checks each id against the accepted roster and derives the
4033
4075
  // full dependency graph together with auth-inferred edges from `consumesAuthServices`.
4034
- explicitDependencies: z9.array(PluginId),
4076
+ explicitDependencies: z10.array(PluginId),
4035
4077
  // The auth services this plugin OWNS, carrying the global ids its harness
4036
4078
  // target must register and the credential authority keys on. Always present;
4037
4079
  // a plugin that declares no `auth.services` carries an empty array. The dual
4038
4080
  // of `consumesAuthServices` (services it merely references).
4039
- authServices: z9.array(ResolvedPluginAuthService),
4081
+ authServices: z10.array(ResolvedPluginAuthService),
4040
4082
  grants: ResolvedPluginGrants.optional(),
4041
- kayAgentUriModules: z9.array(ResolvedKayAgentUriModule).optional(),
4042
- kayAgentArtifactUriModules: z9.array(ResolvedKayAgentArtifactUriModule).optional(),
4043
- kayAgentEntityResolvers: z9.array(ResolvedKayAgentEntityResolver).optional(),
4044
- kayAgentGitHostClaims: z9.array(ResolvedKayAgentGitHostClaim).optional(),
4045
- kayAgentTools: z9.array(ResolvedKayAgentTool).optional(),
4046
- kayAppTools: z9.array(ResolvedKayAppTool).optional(),
4047
- kayAppDataSources: z9.array(ResolvedKayAppDataSource).optional(),
4048
- kayAppWhiteboardTypes: z9.array(ResolvedKayAppWhiteboardType).optional(),
4049
- kayAppMcpServers: z9.array(ResolvedKayAppMcpServer).optional(),
4050
- kayAgentConverters: z9.array(ResolvedKayAgentConverter).optional(),
4051
- referencePresentations: z9.array(ResolvedReferencePresentation).optional(),
4052
- kayUiApps: z9.array(ResolvedKayUiApp).optional()
4083
+ kayAgentUriModules: z10.array(ResolvedKayAgentUriModule).optional(),
4084
+ kayAgentArtifactUriModules: z10.array(ResolvedKayAgentArtifactUriModule).optional(),
4085
+ kayAgentEntityResolvers: z10.array(ResolvedKayAgentEntityResolver).optional(),
4086
+ kayAgentGitHostClaims: z10.array(ResolvedKayAgentGitHostClaim).optional(),
4087
+ kayAgentTools: z10.array(ResolvedKayAgentTool).optional(),
4088
+ kayAppTools: z10.array(ResolvedKayAppTool).optional(),
4089
+ kayAppDataSources: z10.array(ResolvedKayAppDataSource).optional(),
4090
+ kayAppWhiteboardTypes: z10.array(ResolvedKayAppWhiteboardType).optional(),
4091
+ kayAppMcpServers: z10.array(ResolvedKayAppMcpServer).optional(),
4092
+ kayAgentConverters: z10.array(ResolvedKayAgentConverter).optional(),
4093
+ referencePresentations: z10.array(ResolvedReferencePresentation).optional(),
4094
+ kayUiApps: z10.array(ResolvedKayUiApp).optional()
4053
4095
  });
4054
4096
  function narrowestAccountSelectors() {
4055
4097
  return [{ kind: "active" }];
@@ -4467,29 +4509,217 @@ function safeResolveKayPluginContractV1(manifest) {
4467
4509
  }
4468
4510
  }
4469
4511
 
4512
+ // packages/plugin-protocol/dist/plugin-directory-verdict.js
4513
+ var KAY_PLUGIN_MANIFEST_FILENAME = "kay-plugin.json";
4514
+ var KAY_PLUGIN_MANIFEST_SIZE_CAP_BYTES = 64 * 1024;
4515
+ var RESERVED_DIRECTORY_PLUGIN_ID_PREFIXES = ["herd.", "kay."];
4516
+ async function judgeKayPluginDirectory(input) {
4517
+ const { tree, root, dir, host } = input;
4518
+ const file = KAY_PLUGIN_MANIFEST_FILENAME;
4519
+ const hostSdkVersion = host?.sdkVersion;
4520
+ const warnings = [];
4521
+ const refuse = (stage, code, message) => ({
4522
+ outcome: "refused",
4523
+ hostSdkVersion,
4524
+ refusal: { stage, root, dir, code, message: boundPluginDiagnosticMessage(message) },
4525
+ warnings
4526
+ });
4527
+ let manifestEntry;
4528
+ try {
4529
+ manifestEntry = await tree.entry(file);
4530
+ } catch (error) {
4531
+ return refuse("source-scan", "unreadable-dir", `could not stat ${file}: ${errorText(error)}`);
4532
+ }
4533
+ if (manifestEntry === void 0) {
4534
+ return input.revision === void 0 ? { outcome: "not-a-plugin", hostSdkVersion } : refuse("manifest-parse", "committed-manifest-missing", `commit ${input.revision} has no top-level ${file}; add and commit it`);
4535
+ }
4536
+ if (manifestEntry.kind !== "file") {
4537
+ return refuse("source-scan", "irregular-manifest", `${file} is not a regular file (a symlink, directory, or special file is not a manifest)`);
4538
+ }
4539
+ if (manifestEntry.size > KAY_PLUGIN_MANIFEST_SIZE_CAP_BYTES) {
4540
+ return refuse("source-scan", "oversize-manifest", `${file} is ${manifestEntry.size} bytes, exceeding the ${KAY_PLUGIN_MANIFEST_SIZE_CAP_BYTES}-byte cap`);
4541
+ }
4542
+ let raw;
4543
+ try {
4544
+ raw = await tree.readText(file);
4545
+ } catch (error) {
4546
+ return refuse("source-scan", "unreadable-manifest", `could not read ${file}: ${errorText(error)}`);
4547
+ }
4548
+ if (raw.trim() === "") {
4549
+ return refuse("manifest-parse", "empty-manifest", `${file} is empty or whitespace-only`);
4550
+ }
4551
+ let json;
4552
+ try {
4553
+ json = JSON.parse(raw);
4554
+ } catch (error) {
4555
+ return refuse("manifest-parse", "invalid-json", `${file} is not valid JSON: ${errorText(error)}`);
4556
+ }
4557
+ const head = ReadableManifestHead.safeParse(json);
4558
+ if (host !== void 0 && head.success && head.data.compatibility) {
4559
+ const { refusal } = checkKayPluginHostCompatibility(head.data.compatibility, host);
4560
+ if (refusal !== void 0) {
4561
+ return refuse("contract-resolve", refusal.code, `${namedIn(head.data)} ${refusal.message}`);
4562
+ }
4563
+ }
4564
+ const parsed = KayPluginManifestV1.safeParse(json);
4565
+ if (!parsed.success) {
4566
+ return refuse("manifest-parse", "manifest-schema-invalid", `${file} failed manifest validation: ${firstIssue(parsed.error.issues)}`);
4567
+ }
4568
+ const manifest = parsed.data;
4569
+ const retiredKeys = retiredCompatibilityKeysIn(json);
4570
+ if (retiredKeys.length > 0) {
4571
+ warnings.push({
4572
+ stage: "manifest-parse",
4573
+ root,
4574
+ dir,
4575
+ code: "retired-compatibility-key",
4576
+ message: boundPluginDiagnosticMessage(`${file} sets compatibility ${retiredKeys.map((key) => `'${key}'`).join(", ")}, which Bonsai no longer reads; the plugin loaded without it. Declare the SDK range you support with \`compatibility.sdk\` instead.`)
4577
+ });
4578
+ }
4579
+ for (const retired of retiredPermissionAsksIn(json)) {
4580
+ const named = [
4581
+ ...retired.keys.map((key) => `'${key}'`),
4582
+ ...retired.webSessionOperations ? ["'webSession[].operations'"] : []
4583
+ ].join(", ");
4584
+ warnings.push({
4585
+ stage: "manifest-parse",
4586
+ root,
4587
+ dir,
4588
+ code: "retired-permission-ask",
4589
+ message: boundPluginDiagnosticMessage(`${file} declares ${named} under permissions.byTarget['${retired.target}'], which Bonsai no longer reads (since SDK 0.8.0 the call is the ask and the user's grants decide); the plugin loaded without them. Delete them from the manifest.`)
4590
+ });
4591
+ }
4592
+ const reservedPrefix = RESERVED_DIRECTORY_PLUGIN_ID_PREFIXES.find((prefix) => manifest.id.startsWith(prefix));
4593
+ if (reservedPrefix !== void 0) {
4594
+ return refuse("contract-resolve", "reserved-id-namespace", `plugin id '${manifest.id}' claims the reserved '${reservedPrefix}*' id namespace, which only bundled/kernel plugins may use; a directory plugin must choose its own id`);
4595
+ }
4596
+ const resolved = safeResolveKayPluginContractV1(manifest);
4597
+ if (!resolved.success) {
4598
+ return refuse("contract-resolve", "contract-unresolvable", `contract could not be resolved: ${resolved.error.message}`);
4599
+ }
4600
+ const realDirectory = await tree.realDirectory();
4601
+ if (realDirectory === void 0) {
4602
+ return refuse("source-scan", "unreadable-dir", "could not resolve the real path of the plugin directory");
4603
+ }
4604
+ for (const reference of referencedPaths(manifest)) {
4605
+ if (!await tree.isInside(realDirectory, reference.path)) {
4606
+ return refuse("contract-resolve", "path-escapes-plugin-dir", `${reference.label} path '${reference.path}' resolves outside the plugin directory (no symlink escapes, no traversal)`);
4607
+ }
4608
+ }
4609
+ return {
4610
+ outcome: "loads",
4611
+ hostSdkVersion,
4612
+ manifest,
4613
+ contract: resolved.data,
4614
+ warnings,
4615
+ advisories: host === void 0 ? [] : kayPluginCompatibilityAdvisories({ manifest, host, root })
4616
+ };
4617
+ }
4618
+ function kayPluginCompatibilityAdvisories(input) {
4619
+ const { manifest, host, root } = input;
4620
+ const report = checkKayPluginHostCompatibility(manifest.compatibility, {
4621
+ ...host,
4622
+ bundled: input.bundled === true
4623
+ });
4624
+ return report.advisories.map((advisory) => ({
4625
+ stage: "source-scan",
4626
+ root,
4627
+ code: advisory.code,
4628
+ message: boundPluginDiagnosticMessage(`${manifest.displayName} (${manifest.id}) ${advisory.message}`)
4629
+ }));
4630
+ }
4631
+ var ReadableCompatibility = z11.object({
4632
+ supportedProtocols: z11.array(z11.string()).optional().catch(void 0),
4633
+ minKayVersion: NonEmptyString.optional().catch(void 0),
4634
+ sdk: NonEmptyString.optional().catch(void 0)
4635
+ });
4636
+ var ReadableManifestHead = z11.object({
4637
+ id: z11.string().optional().catch(void 0),
4638
+ displayName: z11.string().optional().catch(void 0),
4639
+ compatibility: ReadableCompatibility.optional().catch(void 0)
4640
+ });
4641
+ function namedIn(head) {
4642
+ if (head.id === void 0)
4643
+ return KAY_PLUGIN_MANIFEST_FILENAME;
4644
+ return head.displayName === void 0 ? head.id : `${head.displayName} (${head.id})`;
4645
+ }
4646
+ function referencedPaths(manifest) {
4647
+ const refs = [];
4648
+ const kayAgent = manifest.targets?.kay?.agent;
4649
+ if (kayAgent !== void 0) {
4650
+ refs.push({
4651
+ label: "kay.agent entrypoint",
4652
+ path: kayAgent.entrypoint.module
4653
+ });
4654
+ }
4655
+ const kayApp = manifest.targets?.kay?.app;
4656
+ if (kayApp?.entrypoint !== void 0) {
4657
+ refs.push({ label: "kay.app entrypoint", path: kayApp.entrypoint.module });
4658
+ }
4659
+ if (manifest.icon !== void 0) {
4660
+ refs.push({ label: "icon", path: manifest.icon });
4661
+ }
4662
+ if (manifest.iconDark !== void 0) {
4663
+ refs.push({ label: "iconDark", path: manifest.iconDark });
4664
+ }
4665
+ for (const skill of kayAgent?.contributes?.skills ?? []) {
4666
+ refs.push({ label: `skill '${skill.localId}'`, path: skill.path });
4667
+ }
4668
+ const kayUi = manifest.targets?.kay?.ui;
4669
+ if (kayUi?.entrypoint !== void 0) {
4670
+ refs.push({ label: "kay.ui entrypoint", path: kayUi.entrypoint.module });
4671
+ }
4672
+ for (const app of kayUi?.contributes?.apps ?? []) {
4673
+ refs.push({
4674
+ label: `kay.ui app '${app.localId}' entrypoint`,
4675
+ path: app.entrypoint.module
4676
+ });
4677
+ for (const style of app.styles ?? []) {
4678
+ refs.push({ label: `kay.ui app '${app.localId}' style`, path: style });
4679
+ }
4680
+ for (const asset of app.assets ?? []) {
4681
+ refs.push({ label: `kay.ui app '${app.localId}' asset`, path: asset });
4682
+ }
4683
+ if (app.icon !== void 0) {
4684
+ refs.push({ label: `kay.ui app '${app.localId}' icon`, path: app.icon });
4685
+ }
4686
+ }
4687
+ return refs;
4688
+ }
4689
+ function firstIssue(issues) {
4690
+ const issue = issues[0];
4691
+ if (issue === void 0)
4692
+ return "unknown validation error";
4693
+ const at = issue.path.length > 0 ? issue.path.join(".") : "<root>";
4694
+ return `${at}: ${issue.message}`;
4695
+ }
4696
+ function errorText(error) {
4697
+ return error instanceof Error ? error.message : String(error);
4698
+ }
4699
+
4470
4700
  // packages/plugin-protocol/dist/session-health.js
4471
- import { z as z10 } from "zod";
4701
+ import { z as z12 } from "zod";
4472
4702
  var SESSION_HEALTH_EXTENSION_ID = "kay.session-health";
4473
4703
  var SESSION_HEALTH_ENTRY_NAME = "session_health";
4474
4704
  var SESSION_HEALTH_CUSTOM_TYPE = `ext:${SESSION_HEALTH_EXTENSION_ID}:${SESSION_HEALTH_ENTRY_NAME}`;
4475
4705
  var SESSION_HEALTH_CLASSIFIER_IDS = ["jev"];
4476
- var sessionHealthEntrySchema = z10.object({
4477
- v: z10.literal(1),
4478
- verdict: z10.enum(["well", "bad", "unknown"]),
4706
+ var sessionHealthEntrySchema = z12.object({
4707
+ v: z12.literal(1),
4708
+ verdict: z12.enum(["well", "bad", "unknown"]),
4479
4709
  /**
4480
4710
  * The model's calibrated confidence in `well`, 0..1, or null when the
4481
4711
  * classifier declined to produce one. Never exported raw: the telemetry
4482
4712
  * event carries only the decile bucket.
4483
4713
  */
4484
- p_well: z10.number().min(0).max(1).nullable(),
4485
- classifier: z10.enum(SESSION_HEALTH_CLASSIFIER_IDS),
4486
- classifier_version: z10.string().min(1).max(64),
4487
- judged_at: z10.number().int().nonnegative(),
4488
- user_entry_id: z10.string().min(1).max(256),
4489
- through_entry_id: z10.string().min(1).max(256),
4490
- usage: z10.strictObject({
4491
- input_tokens: z10.number().int().nonnegative(),
4492
- output_tokens: z10.number().int().nonnegative()
4714
+ p_well: z12.number().min(0).max(1).nullable(),
4715
+ classifier: z12.enum(SESSION_HEALTH_CLASSIFIER_IDS),
4716
+ classifier_version: z12.string().min(1).max(64),
4717
+ judged_at: z12.number().int().nonnegative(),
4718
+ user_entry_id: z12.string().min(1).max(256),
4719
+ through_entry_id: z12.string().min(1).max(256),
4720
+ usage: z12.strictObject({
4721
+ input_tokens: z12.number().int().nonnegative(),
4722
+ output_tokens: z12.number().int().nonnegative()
4493
4723
  }).optional()
4494
4724
  });
4495
4725
  function sessionHealthPWellDecile(pWell) {
@@ -4499,36 +4729,36 @@ function sessionHealthPWellDecile(pWell) {
4499
4729
  }
4500
4730
 
4501
4731
  // packages/plugin-protocol/dist/resource-invocations.js
4502
- import { z as z11 } from "zod";
4503
- var CorpusResourceKind = z11.enum([
4732
+ import { z as z13 } from "zod";
4733
+ var CorpusResourceKind = z13.enum([
4504
4734
  "skill",
4505
4735
  "context-file",
4506
4736
  "prompt-command"
4507
4737
  ]);
4508
- var CorpusResourceInvocationCursor = z11.strictObject({
4509
- at: z11.iso.datetime({ offset: true }),
4510
- eventId: z11.string().min(1)
4738
+ var CorpusResourceInvocationCursor = z13.strictObject({
4739
+ at: z13.iso.datetime({ offset: true }),
4740
+ eventId: z13.string().min(1)
4511
4741
  });
4512
- var CorpusResourceInvocationQuery = z11.strictObject({
4742
+ var CorpusResourceInvocationQuery = z13.strictObject({
4513
4743
  kind: CorpusResourceKind,
4514
- since: z11.iso.datetime({ offset: true }),
4515
- until: z11.iso.datetime({ offset: true }),
4744
+ since: z13.iso.datetime({ offset: true }),
4745
+ until: z13.iso.datetime({ offset: true }),
4516
4746
  after: CorpusResourceInvocationCursor.optional(),
4517
- limit: z11.number().int().min(1).max(1e3).optional(),
4518
- rootCreatedByKind: z11.enum(AGENT_RUNTIME_SESSION_CREATOR_KINDS).optional()
4747
+ limit: z13.number().int().min(1).max(1e3).optional(),
4748
+ rootCreatedByKind: z13.enum(AGENT_RUNTIME_SESSION_CREATOR_KINDS).optional()
4519
4749
  }).refine((value) => Date.parse(value.since) < Date.parse(value.until), {
4520
4750
  message: "since must precede until"
4521
4751
  });
4522
4752
 
4523
4753
  // packages/plugin-protocol/dist/ui-app-package.js
4524
- import { z as z12 } from "zod";
4754
+ import { z as z14 } from "zod";
4525
4755
  var KAY_UI_APP_PACKAGE_PROTOCOL = "kay.ui.app-package.v1";
4526
4756
  var KAY_UI_BUNDLE_INDEX_PROTOCOL = "kay.ui.bundle-index.v1";
4527
- var KayUiBundleOutputPath = z12.string().trim().min(1).refine((value) => !value.startsWith("/") && !value.startsWith("./") && !value.includes("\\") && !value.split("/").includes(".."), { message: "bundle output path must stay relative to the bundle root" });
4528
- var KayUiBundleIndexV1 = z12.strictObject({
4529
- protocol: z12.literal(KAY_UI_BUNDLE_INDEX_PROTOCOL),
4757
+ var KayUiBundleOutputPath = z14.string().trim().min(1).refine((value) => !value.startsWith("/") && !value.startsWith("./") && !value.includes("\\") && !value.split("/").includes(".."), { message: "bundle output path must stay relative to the bundle root" });
4758
+ var KayUiBundleIndexV1 = z14.strictObject({
4759
+ protocol: z14.literal(KAY_UI_BUNDLE_INDEX_PROTOCOL),
4530
4760
  entryPath: KayUiBundleOutputPath,
4531
- files: z12.array(z12.strictObject({
4761
+ files: z14.array(z14.strictObject({
4532
4762
  path: KayUiBundleOutputPath,
4533
4763
  mediaType: NonEmptyString
4534
4764
  })).min(1)
@@ -4555,19 +4785,19 @@ var KayUiBundleIndexV1 = z12.strictObject({
4555
4785
  function parseKayUiBundleIndexV1(input) {
4556
4786
  return KayUiBundleIndexV1.parse(input);
4557
4787
  }
4558
- var KayUiAppPackageFile = z12.strictObject({
4788
+ var KayUiAppPackageFile = z14.strictObject({
4559
4789
  path: PackageAssetPath,
4560
4790
  mediaType: NonEmptyString,
4561
- bytes: z12.instanceof(Uint8Array).refine((bytes) => bytes.byteLength > 0, {
4791
+ bytes: z14.instanceof(Uint8Array).refine((bytes) => bytes.byteLength > 0, {
4562
4792
  message: "app package file bytes must not be empty"
4563
4793
  })
4564
4794
  });
4565
- var KayUiAppPackageV1 = z12.strictObject({
4566
- protocol: z12.literal(KAY_UI_APP_PACKAGE_PROTOCOL),
4795
+ var KayUiAppPackageV1 = z14.strictObject({
4796
+ protocol: z14.literal(KAY_UI_APP_PACKAGE_PROTOCOL),
4567
4797
  appLocalId: LocalContributionId,
4568
4798
  entry: KayUiAppPackageFile,
4569
- styles: z12.array(KayUiAppPackageFile).optional(),
4570
- assets: z12.array(KayUiAppPackageFile).optional()
4799
+ styles: z14.array(KayUiAppPackageFile).optional(),
4800
+ assets: z14.array(KayUiAppPackageFile).optional()
4571
4801
  }).superRefine((appPackage, ctx) => {
4572
4802
  if (appPackage.entry.mediaType !== "application/javascript") {
4573
4803
  ctx.addIssue({
@@ -4604,16 +4834,16 @@ function parseKayUiAppPackageV1(input) {
4604
4834
  }
4605
4835
 
4606
4836
  // packages/plugin-protocol/dist/whiteboard.js
4607
- import { z as z13 } from "zod";
4837
+ import { z as z15 } from "zod";
4608
4838
  var WhiteboardValue = JsonValue;
4609
- var WhiteboardEntryEnvelope = z13.strictObject({
4839
+ var WhiteboardEntryEnvelope = z15.strictObject({
4610
4840
  id: NonEmptyString,
4611
4841
  typeId: GlobalContributionId,
4612
- schemaVersion: z13.number().int().positive(),
4613
- title: z13.string(),
4842
+ schemaVersion: z15.number().int().positive(),
4843
+ title: z15.string(),
4614
4844
  authorSessionId: NonEmptyString.nullable()
4615
4845
  });
4616
- var WhiteboardEntrySummary = z13.strictObject({
4846
+ var WhiteboardEntrySummary = z15.strictObject({
4617
4847
  name: NonEmptyString,
4618
4848
  entry: WhiteboardEntryEnvelope,
4619
4849
  revision: NonEmptyString
@@ -4621,31 +4851,31 @@ var WhiteboardEntrySummary = z13.strictObject({
4621
4851
  var WhiteboardEntrySnapshot = WhiteboardEntrySummary.extend({
4622
4852
  value: WhiteboardValue
4623
4853
  });
4624
- var WhiteboardDiagnostic = z13.strictObject({
4854
+ var WhiteboardDiagnostic = z15.strictObject({
4625
4855
  ruleId: NonEmptyString,
4626
- severity: z13.enum(["error", "warning"]),
4856
+ severity: z15.enum(["error", "warning"]),
4627
4857
  message: NonEmptyString
4628
4858
  });
4629
- var WhiteboardEntryInfo = z13.strictObject({
4859
+ var WhiteboardEntryInfo = z15.strictObject({
4630
4860
  name: NonEmptyString,
4631
4861
  revision: NonEmptyString,
4632
4862
  entry: WhiteboardEntryEnvelope.optional(),
4633
- state: z13.enum(["available", "unavailable", "unsupported-version", "invalid"]),
4634
- mutable: z13.boolean(),
4635
- diagnostics: z13.array(z13.string())
4863
+ state: z15.enum(["available", "unavailable", "unsupported-version", "invalid"]),
4864
+ mutable: z15.boolean(),
4865
+ diagnostics: z15.array(z15.string())
4636
4866
  });
4637
4867
  var WhiteboardEntryInspection = WhiteboardEntryInfo.extend({
4638
4868
  value: WhiteboardValue.optional(),
4639
- text: z13.string(),
4640
- truncated: z13.boolean()
4869
+ text: z15.string(),
4870
+ truncated: z15.boolean()
4641
4871
  });
4642
- var WhiteboardTypeInfo = z13.strictObject({
4872
+ var WhiteboardTypeInfo = z15.strictObject({
4643
4873
  typeId: GlobalContributionId,
4644
4874
  displayName: NonEmptyString,
4645
- schemaVersion: z13.number().int().positive(),
4646
- available: z13.boolean(),
4875
+ schemaVersion: z15.number().int().positive(),
4876
+ available: z15.boolean(),
4647
4877
  /** A plugin-owned readonly presentation; absent types use the host fallback. */
4648
- presentation: z13.strictObject({
4878
+ presentation: z15.strictObject({
4649
4879
  app: GlobalContributionId
4650
4880
  }).optional()
4651
4881
  });
@@ -4713,6 +4943,8 @@ export {
4713
4943
  KAY_APP_DATA_SNAPSHOT_MAX_BYTES,
4714
4944
  KAY_EVENT_PUBLISHER_ID,
4715
4945
  KAY_PLUGIN_COMPATIBLE_SDK_VERSIONS,
4946
+ KAY_PLUGIN_MANIFEST_FILENAME,
4947
+ KAY_PLUGIN_MANIFEST_SIZE_CAP_BYTES,
4716
4948
  KAY_PLUGIN_PROTOCOL_PACKAGE_NAME,
4717
4949
  KAY_PLUGIN_PROTOCOL_VERSION,
4718
4950
  KAY_PLUGIN_SDK_VERSION,
@@ -4741,6 +4973,7 @@ export {
4741
4973
  MimeTypeString,
4742
4974
  NonEmptyString,
4743
4975
  PLUGIN_CAPABILITY_SLUGS,
4976
+ PLUGIN_DIAGNOSTIC_MESSAGE_CAP,
4744
4977
  PLUGIN_ICON_SHAPE_ATTRIBUTE,
4745
4978
  PLUGIN_NOTIFICATION_RULE_HOST_KEYS,
4746
4979
  PackageAssetPath,
@@ -4773,6 +5006,7 @@ export {
4773
5006
  PluginToolName,
4774
5007
  PluginWebSessionDeclaration,
4775
5008
  PluginWebSessionProbe,
5009
+ RESERVED_DIRECTORY_PLUGIN_ID_PREFIXES,
4776
5010
  RETIRED_COMPATIBILITY_KEYS,
4777
5011
  RETIRED_PERMISSION_ASK_KEYS,
4778
5012
  RETIRED_PLUGIN_CAPABILITY_SLUGS,
@@ -4859,6 +5093,7 @@ export {
4859
5093
  WhiteboardTypeInfo,
4860
5094
  WhiteboardTypeStorage,
4861
5095
  WhiteboardValue,
5096
+ boundPluginDiagnosticMessage,
4862
5097
  captureArtifactProvenance,
4863
5098
  captureFailedContext,
4864
5099
  checkKayPluginHostCompatibility,
@@ -4873,6 +5108,9 @@ export {
4873
5108
  isQualifiedAuthSchemeRef,
4874
5109
  isQualifiedAuthServiceRef,
4875
5110
  isSupportedSemverRange,
5111
+ judgeKayPluginDirectory,
5112
+ kayPluginCompatibilityAdvisories,
5113
+ kayPluginHostCompatibility,
4876
5114
  kayUiEventSubscriptionsFromManifest,
4877
5115
  mintOperation,
4878
5116
  normalizeNetworkConnectHost,