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