@yaklabs-ai/plugin-protocol 0.13.4 → 0.13.6

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