@yaklabs-ai/plugin-protocol 0.13.6 → 0.13.8

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/README.md CHANGED
@@ -11,7 +11,7 @@ flow.
11
11
  ```json
12
12
  {
13
13
  "dependencies": {
14
- "@bonsai/plugin-protocol": "npm:@yaklabs-ai/plugin-protocol@^0.13.6"
14
+ "@bonsai/plugin-protocol": "npm:@yaklabs-ai/plugin-protocol@^0.13.8"
15
15
  }
16
16
  }
17
17
  ```
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "package": "@yaklabs-ai/plugin-protocol",
4
- "version": "0.13.6",
4
+ "version": "0.13.8",
5
5
  "target": "npm",
6
6
  "firstPartyLicense": "MIT",
7
7
  "bundled": [],
package/dist/index.d.ts CHANGED
@@ -1705,6 +1705,26 @@ export declare interface DeclaredKayPluginCompatibility {
1705
1705
  readonly sdk?: string | undefined;
1706
1706
  }
1707
1707
 
1708
+ /**
1709
+ * Where a plugin-declared skill source's bytes come from, as the daemon resolved it: the manifest
1710
+ * declaration (`PluginSkillSourceDeclaration`) less its local id and display name, which grant
1711
+ * nothing. The git channel carries the canonical locator plus the ref and subdir, because the same
1712
+ * repository at another ref or folder is a different source the user never approved; the installer
1713
+ * channel carries the command and its argv exactly, never joined into one string.
1714
+ */
1715
+ export declare const DeclaredSkillSourceEnvelope: z.ZodDiscriminatedUnion<[z.ZodObject<{
1716
+ channel: z.ZodLiteral<"git-clone">;
1717
+ locator: z.ZodString;
1718
+ ref: z.ZodOptional<z.ZodString>;
1719
+ subdir: z.ZodOptional<z.ZodString>;
1720
+ }, z.core.$strict>, z.ZodObject<{
1721
+ channel: z.ZodLiteral<"installer">;
1722
+ command: z.ZodString;
1723
+ args: z.ZodArray<z.ZodString>;
1724
+ }, z.core.$strict>], "channel">;
1725
+
1726
+ export declare type DeclaredSkillSourceEnvelope = z.infer<typeof DeclaredSkillSourceEnvelope>;
1727
+
1708
1728
  /** Drop repeats under {@link sameClaim}, preserving first-seen order (a sort settles the rest). */
1709
1729
  export declare function dedupeClaims(claims: readonly PluginCapabilityClaimV1[]): PluginCapabilityClaimV1[];
1710
1730
 
@@ -1948,6 +1968,12 @@ export declare type InteractionDriverContribution = z.infer<typeof InteractionDr
1948
1968
  /** Whether the report permits the plugin to load. */
1949
1969
  export declare function isCompatible(report: KayPluginCompatibilityReport): boolean;
1950
1970
 
1971
+ /**
1972
+ * Whether a refusal `code` came from the compatibility check: the plugin was written for another
1973
+ * SDK or protocol, as opposed to being malformed.
1974
+ */
1975
+ export declare function isKayPluginCompatibilityRefusal(code: string): code is KayPluginCompatibilityRefusalCode;
1976
+
1951
1977
  /**
1952
1978
  * Discriminates a grant's auth-scheme reference between a local id and an
1953
1979
  * already-qualified global id. Local contribution ids cannot contain dots.
@@ -2030,8 +2056,10 @@ export declare const KAY_APP_DATA_SNAPSHOT_MAX_BYTES: number;
2030
2056
  */
2031
2057
  export declare const KAY_EVENT_PUBLISHER_ID: "kay";
2032
2058
 
2059
+ declare const KAY_PLUGIN_COMPATIBILITY_REFUSAL_CODES: readonly ["unsupported-protocol", "sdk-range-unsatisfied", "sdk-range-unsupported", "host-sdk-version-invalid"];
2060
+
2033
2061
  /** Released SDK contracts still implemented by the host, alongside its current SDK. */
2034
- export declare const KAY_PLUGIN_COMPATIBLE_SDK_VERSIONS: readonly ["0.8.0", "0.8.1", "0.8.2", "0.8.3", "0.8.4", "0.8.5", "0.9.0", "0.9.1", "0.10.0", "0.11.0", "0.11.1", "0.12.0", "0.12.1", "0.12.2", "0.12.3", "0.12.4", "0.12.5", "0.13.0", "0.13.1", "0.13.2", "0.13.3", "0.13.4", "0.13.5"];
2062
+ export declare const KAY_PLUGIN_COMPATIBLE_SDK_VERSIONS: readonly ["0.8.0", "0.8.1", "0.8.2", "0.8.3", "0.8.4", "0.8.5", "0.9.0", "0.9.1", "0.10.0", "0.11.0", "0.11.1", "0.12.0", "0.12.1", "0.12.2", "0.12.3", "0.12.4", "0.12.5", "0.13.0", "0.13.1", "0.13.2", "0.13.3", "0.13.4", "0.13.5", "0.13.6", "0.13.7"];
2035
2063
 
2036
2064
  /** The file whose presence makes a directory a plugin. A directory without one is not a plugin. */
2037
2065
  export declare const KAY_PLUGIN_MANIFEST_FILENAME = "kay-plugin.json";
@@ -2314,8 +2342,26 @@ export declare const KAY_PLUGIN_PROTOCOL_VERSION: "kay.plugin.v1";
2314
2342
  * (`turnSegments`), the run records and the work-block and work-headline helpers. Additive: a
2315
2343
  * plugin compiled against 0.13.5 never imports them. A plugin that imports one declares `^0.13.6`,
2316
2344
  * so an older host refuses a directory or repository plugin at load instead of the import failing.
2345
+ *
2346
+ * 0.13.7 adds four subpaths. `@bonsai/plugin-sdk/vendored-mcp` re-exports
2347
+ * `@bonsai/vendored-mcp-integration` (`createVendoredMcpUriModule` and its descriptor types; not
2348
+ * the MCP read-port types). `transcript-review` and `agent-conversation` re-export the session
2349
+ * folds Bonsai's own Sessions and Hindsight plugins share. `app-data` carries the app-data size
2350
+ * caps on an entry with no other import, for code a `kay.ui` page also loads. The protocol it
2351
+ * ships also carries three new capability-claim slugs (`mcp.host-server`, `prompt.resident`,
2352
+ * `skills.declared-source`). Additive: a plugin compiled against 0.13.6 never imports the new
2353
+ * subpaths, and its manifest parses unchanged. A plugin that imports one declares `^0.13.7`, so
2354
+ * an older host refuses a directory or repository plugin at load instead of the import failing.
2355
+ *
2356
+ * 0.13.8 takes the PATCH slot under the addition rule, as `api.withJev` did in 0.8.1: one new
2357
+ * member on the api a plugin RECEIVES, `api.systemOne` / `app.systemOne` (`@bonsai/plugin-sdk/
2358
+ * system-one`), the System One client for `decide` and `extract` on Jev, Clef, Clef Flash and
2359
+ * Clairic. It is non-optional for the same reason `withJev` is, and a host with no System One
2360
+ * binds a client that throws `not-served`. `withJev` stays for every compatible plugin. A
2361
+ * plugin that calls `systemOne` declares `^0.13.8`, so an older host refuses it at load instead
2362
+ * of the member being absent.
2317
2363
  */
2318
- export declare const KAY_PLUGIN_SDK_VERSION: "0.13.6";
2364
+ export declare const KAY_PLUGIN_SDK_VERSION: "0.13.8";
2319
2365
 
2320
2366
  export declare const KAY_PLUGIN_TARGET_NAMES: readonly ["kay.agent", "kay.app", "kay.ui"];
2321
2367
 
@@ -2630,7 +2676,7 @@ export declare interface KayPluginCompatibilityNote<TCode extends string> {
2630
2676
  readonly message: string;
2631
2677
  }
2632
2678
 
2633
- export declare type KayPluginCompatibilityRefusalCode = "unsupported-protocol" | "sdk-range-unsatisfied" | "sdk-range-unsupported" | "host-sdk-version-invalid";
2679
+ export declare type KayPluginCompatibilityRefusalCode = (typeof KAY_PLUGIN_COMPATIBILITY_REFUSAL_CODES)[number];
2634
2680
 
2635
2681
  /**
2636
2682
  * What the check found. `refusal` absent means the plugin may load; advisories
@@ -2656,6 +2702,11 @@ export declare type KayPluginDirectoryVerdict = {
2656
2702
  } | {
2657
2703
  readonly outcome: "refused";
2658
2704
  readonly refusal: PluginLoadDiagnostic;
2705
+ /**
2706
+ * The id the manifest declares, as written, when the refusal came after the manifest was
2707
+ * read; it is not validated, so it may not be a well-formed plugin id.
2708
+ */
2709
+ readonly pluginId?: string;
2659
2710
  /** Notes raised before the refusal; the author still meets them once it is fixed. */
2660
2711
  readonly warnings: readonly PluginLoadDiagnostic[];
2661
2712
  } | {
@@ -3765,8 +3816,9 @@ export declare type McpServerAuthMode = z.infer<typeof McpServerAuthMode>;
3765
3816
  * or omitted `auth`) requires `authService`; `auth: "none"` may omit it. `authService` is a local
3766
3817
  * id that must resolve within this same manifest; unlike `uriModule.authService`, qualified foreign
3767
3818
  * service refs are not permitted because the MCP binding belongs to the plugin that ships it.
3768
- * Declaring `mcpServers` at
3769
- * all is bundled-plugin-only — enforced at composition, not by this schema (see `ARCHITECTURE.md`).
3819
+ * A declared server is hosted
3820
+ * only for a plugin holding `mcp.host-server` for its name and URL (the release's own plugins hold
3821
+ * it) — decided at composition, not by this schema (see `ARCHITECTURE.md`).
3770
3822
  */
3771
3823
  export declare const McpServerContribution: z.ZodObject<{
3772
3824
  url: z.ZodString;
@@ -3908,7 +3960,7 @@ export declare function parseResolvedPluginContractV1(value: unknown): ResolvedP
3908
3960
  export declare function parseSemver(value: string): ParsedSemver | undefined;
3909
3961
 
3910
3962
  /** Every capability slug {@link PluginCapabilityClaimV1} can express, for exhaustive table checks. */
3911
- export declare const PLUGIN_CAPABILITY_SLUGS: readonly ["sessions.run", "network.connect", "web-session.request", "web-session.download", "process.spawn", "corpus.read", "signals.read", "skills.read", "tools.describe", "workspace.command", "sessions.create", "sessions.update", "models.complete", "jev.use", "automations.write", "automations.run", "workflows.define", "session-events.subscribe", "agents.run", "dynamic-context.register", "app-data.register", "account.assert", "account.update", "agents.permissions", "tool-interception.register", "interaction.surface", "config.declare-section", "auth.own-service", "auth.shared-identity", "cli.bind", "whiteboard.discover", "whiteboard.read", "whiteboard.create", "whiteboard.update", "whiteboard.remove"];
3963
+ export declare const PLUGIN_CAPABILITY_SLUGS: readonly ["sessions.run", "network.connect", "web-session.request", "web-session.download", "process.spawn", "corpus.read", "signals.read", "skills.read", "tools.describe", "workspace.command", "sessions.create", "sessions.update", "models.complete", "jev.use", "automations.write", "automations.run", "workflows.define", "session-events.subscribe", "agents.run", "dynamic-context.register", "app-data.register", "account.assert", "account.update", "agents.permissions", "tool-interception.register", "interaction.surface", "config.declare-section", "auth.own-service", "auth.shared-identity", "cli.bind", "mcp.host-server", "prompt.resident", "skills.declared-source", "whiteboard.discover", "whiteboard.read", "whiteboard.create", "whiteboard.update", "whiteboard.remove"];
3912
3964
 
3913
3965
  /** Diagnostic messages carry plugin-controlled text (parse errors, module errors); bound it so a
3914
3966
  * hostile or accidental multi-megabyte error can never blow up a log line or a render surface. */
@@ -4285,17 +4337,20 @@ export declare type PluginAuthService = z.infer<typeof PluginAuthService>;
4285
4337
  * `target` names that scope, and carries ONE value beyond the three plugin targets
4286
4338
  * (`PluginTargetName`): `"plugin"`, for a claim held by the plugin as a whole rather than by one
4287
4339
  * of its targets. Composition decides those — owning a shared auth service, consuming another
4288
- * plugin's identity, binding a CLI credential, declaring a config section — before any target
4289
- * code is loaded, so there is no target to charge them to. They are still exactly claims: one
4340
+ * plugin's identity, binding a CLI credential, declaring a config section, hosting an MCP server,
4341
+ * a resident prompt section, a plugin-declared skill source — before any target code is loaded, so
4342
+ * there is no target to charge them to. They are still exactly claims: one
4290
4343
  * exact envelope, one grant row, one consent.
4291
4344
  *
4292
4345
  * `process.spawn` additionally carries `argvClass`: the declared CLASS of argument vector the
4293
4346
  * plugin will spawn with. It is an opaque exact string here — this module never interprets it —
4294
4347
  * and the broker packet that consumes it owns what a class permits.
4295
4348
  *
4296
- * `agents.permissions` is the one variant whose envelope is not flat: it carries the permission
4349
+ * Two variants carry an envelope that is not flat. `agents.permissions` carries the permission
4297
4350
  * rules themselves, in declaration order, because a human approving it must read the rules they
4298
- * are approving. Its equality is still exact — see {@link sameClaim}.
4351
+ * are approving. `skills.declared-source` carries one of two source shapes
4352
+ * ({@link DeclaredSkillSourceEnvelope}), because a git source and an installer differ in what
4353
+ * pins them. Equality for both is still exact — see {@link sameClaim}.
4299
4354
  */
4300
4355
  export declare const PluginCapabilityClaimV1: z.ZodDiscriminatedUnion<[z.ZodObject<{
4301
4356
  target: z.ZodLiteral<"kay.app">;
@@ -4481,6 +4536,30 @@ export declare const PluginCapabilityClaimV1: z.ZodDiscriminatedUnion<[z.ZodObje
4481
4536
  envelope: z.ZodObject<{
4482
4537
  binary: z.ZodString;
4483
4538
  }, z.core.$strict>;
4539
+ }, z.core.$strict>, z.ZodObject<{
4540
+ target: z.ZodLiteral<"plugin">;
4541
+ slug: z.ZodLiteral<"mcp.host-server">;
4542
+ envelope: z.ZodObject<{
4543
+ name: z.ZodString;
4544
+ url: z.ZodString;
4545
+ }, z.core.$strict>;
4546
+ }, z.core.$strict>, z.ZodObject<{
4547
+ target: z.ZodLiteral<"plugin">;
4548
+ slug: z.ZodLiteral<"prompt.resident">;
4549
+ envelope: z.ZodObject<{}, z.core.$strict>;
4550
+ }, z.core.$strict>, z.ZodObject<{
4551
+ target: z.ZodLiteral<"plugin">;
4552
+ slug: z.ZodLiteral<"skills.declared-source">;
4553
+ envelope: z.ZodDiscriminatedUnion<[z.ZodObject<{
4554
+ channel: z.ZodLiteral<"git-clone">;
4555
+ locator: z.ZodString;
4556
+ ref: z.ZodOptional<z.ZodString>;
4557
+ subdir: z.ZodOptional<z.ZodString>;
4558
+ }, z.core.$strict>, z.ZodObject<{
4559
+ channel: z.ZodLiteral<"installer">;
4560
+ command: z.ZodString;
4561
+ args: z.ZodArray<z.ZodString>;
4562
+ }, z.core.$strict>], "channel">;
4484
4563
  }, z.core.$strict>, z.ZodObject<{
4485
4564
  target: z.ZodEnum<{
4486
4565
  "kay.agent": "kay.agent";
@@ -4693,6 +4772,30 @@ export declare const PluginCapabilityDecisionV1: z.ZodDiscriminatedUnion<[z.ZodO
4693
4772
  envelope: z.ZodObject<{
4694
4773
  binary: z.ZodString;
4695
4774
  }, z.core.$strict>;
4775
+ }, z.core.$strict>, z.ZodObject<{
4776
+ target: z.ZodLiteral<"plugin">;
4777
+ slug: z.ZodLiteral<"mcp.host-server">;
4778
+ envelope: z.ZodObject<{
4779
+ name: z.ZodString;
4780
+ url: z.ZodString;
4781
+ }, z.core.$strict>;
4782
+ }, z.core.$strict>, z.ZodObject<{
4783
+ target: z.ZodLiteral<"plugin">;
4784
+ slug: z.ZodLiteral<"prompt.resident">;
4785
+ envelope: z.ZodObject<{}, z.core.$strict>;
4786
+ }, z.core.$strict>, z.ZodObject<{
4787
+ target: z.ZodLiteral<"plugin">;
4788
+ slug: z.ZodLiteral<"skills.declared-source">;
4789
+ envelope: z.ZodDiscriminatedUnion<[z.ZodObject<{
4790
+ channel: z.ZodLiteral<"git-clone">;
4791
+ locator: z.ZodString;
4792
+ ref: z.ZodOptional<z.ZodString>;
4793
+ subdir: z.ZodOptional<z.ZodString>;
4794
+ }, z.core.$strict>, z.ZodObject<{
4795
+ channel: z.ZodLiteral<"installer">;
4796
+ command: z.ZodString;
4797
+ args: z.ZodArray<z.ZodString>;
4798
+ }, z.core.$strict>], "channel">;
4696
4799
  }, z.core.$strict>, z.ZodObject<{
4697
4800
  target: z.ZodEnum<{
4698
4801
  "kay.agent": "kay.agent";
@@ -4900,6 +5003,30 @@ export declare const PluginCapabilityDecisionV1: z.ZodDiscriminatedUnion<[z.ZodO
4900
5003
  envelope: z.ZodObject<{
4901
5004
  binary: z.ZodString;
4902
5005
  }, z.core.$strict>;
5006
+ }, z.core.$strict>, z.ZodObject<{
5007
+ target: z.ZodLiteral<"plugin">;
5008
+ slug: z.ZodLiteral<"mcp.host-server">;
5009
+ envelope: z.ZodObject<{
5010
+ name: z.ZodString;
5011
+ url: z.ZodString;
5012
+ }, z.core.$strict>;
5013
+ }, z.core.$strict>, z.ZodObject<{
5014
+ target: z.ZodLiteral<"plugin">;
5015
+ slug: z.ZodLiteral<"prompt.resident">;
5016
+ envelope: z.ZodObject<{}, z.core.$strict>;
5017
+ }, z.core.$strict>, z.ZodObject<{
5018
+ target: z.ZodLiteral<"plugin">;
5019
+ slug: z.ZodLiteral<"skills.declared-source">;
5020
+ envelope: z.ZodDiscriminatedUnion<[z.ZodObject<{
5021
+ channel: z.ZodLiteral<"git-clone">;
5022
+ locator: z.ZodString;
5023
+ ref: z.ZodOptional<z.ZodString>;
5024
+ subdir: z.ZodOptional<z.ZodString>;
5025
+ }, z.core.$strict>, z.ZodObject<{
5026
+ channel: z.ZodLiteral<"installer">;
5027
+ command: z.ZodString;
5028
+ args: z.ZodArray<z.ZodString>;
5029
+ }, z.core.$strict>], "channel">;
4903
5030
  }, z.core.$strict>, z.ZodObject<{
4904
5031
  target: z.ZodEnum<{
4905
5032
  "kay.agent": "kay.agent";
@@ -5170,6 +5297,30 @@ export declare const PluginCapabilityRefusalV1: z.ZodObject<{
5170
5297
  envelope: z.ZodObject<{
5171
5298
  binary: z.ZodString;
5172
5299
  }, z.core.$strict>;
5300
+ }, z.core.$strict>, z.ZodObject<{
5301
+ target: z.ZodLiteral<"plugin">;
5302
+ slug: z.ZodLiteral<"mcp.host-server">;
5303
+ envelope: z.ZodObject<{
5304
+ name: z.ZodString;
5305
+ url: z.ZodString;
5306
+ }, z.core.$strict>;
5307
+ }, z.core.$strict>, z.ZodObject<{
5308
+ target: z.ZodLiteral<"plugin">;
5309
+ slug: z.ZodLiteral<"prompt.resident">;
5310
+ envelope: z.ZodObject<{}, z.core.$strict>;
5311
+ }, z.core.$strict>, z.ZodObject<{
5312
+ target: z.ZodLiteral<"plugin">;
5313
+ slug: z.ZodLiteral<"skills.declared-source">;
5314
+ envelope: z.ZodDiscriminatedUnion<[z.ZodObject<{
5315
+ channel: z.ZodLiteral<"git-clone">;
5316
+ locator: z.ZodString;
5317
+ ref: z.ZodOptional<z.ZodString>;
5318
+ subdir: z.ZodOptional<z.ZodString>;
5319
+ }, z.core.$strict>, z.ZodObject<{
5320
+ channel: z.ZodLiteral<"installer">;
5321
+ command: z.ZodString;
5322
+ args: z.ZodArray<z.ZodString>;
5323
+ }, z.core.$strict>], "channel">;
5173
5324
  }, z.core.$strict>, z.ZodObject<{
5174
5325
  target: z.ZodEnum<{
5175
5326
  "kay.agent": "kay.agent";
package/dist/index.js CHANGED
@@ -136,7 +136,7 @@ var JsonSchema = z2.record(z2.string(), JsonValue);
136
136
  // packages/plugin-protocol/dist/common.js
137
137
  var KAY_PLUGIN_PROTOCOL_VERSION = "kay.plugin.v1";
138
138
  var KAY_PLUGIN_PROTOCOL_PACKAGE_NAME = "@bonsai/plugin-protocol";
139
- var KAY_PLUGIN_SDK_VERSION = "0.13.6";
139
+ var KAY_PLUGIN_SDK_VERSION = "0.13.8";
140
140
  var KAY_PLUGIN_COMPATIBLE_SDK_VERSIONS = [
141
141
  "0.8.0",
142
142
  "0.8.1",
@@ -160,7 +160,9 @@ var KAY_PLUGIN_COMPATIBLE_SDK_VERSIONS = [
160
160
  "0.13.2",
161
161
  "0.13.3",
162
162
  "0.13.4",
163
- "0.13.5"
163
+ "0.13.5",
164
+ "0.13.6",
165
+ "0.13.7"
164
166
  ];
165
167
  var KAY_PLUGIN_TARGET_NAMES = [
166
168
  "kay.agent",
@@ -1489,6 +1491,19 @@ var WhiteboardCapabilityClaimV1 = z8.strictObject({
1489
1491
  });
1490
1492
  }
1491
1493
  });
1494
+ var DeclaredSkillSourceEnvelope = z8.discriminatedUnion("channel", [
1495
+ z8.strictObject({
1496
+ channel: z8.literal("git-clone"),
1497
+ locator: NonEmptyString,
1498
+ ref: NonEmptyString.optional(),
1499
+ subdir: NonEmptyString.optional()
1500
+ }),
1501
+ z8.strictObject({
1502
+ channel: z8.literal("installer"),
1503
+ command: NonEmptyString,
1504
+ args: z8.array(NonEmptyString)
1505
+ })
1506
+ ]);
1492
1507
  var PluginCapabilityClaimV1 = z8.discriminatedUnion("slug", [
1493
1508
  z8.strictObject({
1494
1509
  target: z8.literal("kay.app"),
@@ -1681,6 +1696,25 @@ var PluginCapabilityClaimV1 = z8.discriminatedUnion("slug", [
1681
1696
  /** The binary basename a resolved credential would be injected into. */
1682
1697
  envelope: z8.strictObject({ binary: NonEmptyString })
1683
1698
  }),
1699
+ z8.strictObject({
1700
+ target: z8.literal("plugin"),
1701
+ slug: z8.literal("mcp.host-server"),
1702
+ // The daemon dials this endpoint, holds its sign-in, and serves it as `mcp://<name>`, so the
1703
+ // endpoint becomes daemon execution authority. One claim per exact name and URL.
1704
+ envelope: z8.strictObject({ name: NonEmptyString, url: NonEmptyString })
1705
+ }),
1706
+ z8.strictObject({
1707
+ target: z8.literal("plugin"),
1708
+ slug: z8.literal("prompt.resident"),
1709
+ // A section of the plugin's own text in every session's system prompt. An empty envelope
1710
+ // because the grant itself is the decision; the host caps the section's length.
1711
+ envelope: z8.strictObject({})
1712
+ }),
1713
+ z8.strictObject({
1714
+ target: z8.literal("plugin"),
1715
+ slug: z8.literal("skills.declared-source"),
1716
+ envelope: DeclaredSkillSourceEnvelope
1717
+ }),
1684
1718
  WhiteboardCapabilityClaimV1
1685
1719
  ]);
1686
1720
  var RETIRED_PLUGIN_CAPABILITY_SLUGS = [
@@ -1718,6 +1752,9 @@ var PLUGIN_CAPABILITY_SLUGS = [
1718
1752
  "auth.own-service",
1719
1753
  "auth.shared-identity",
1720
1754
  "cli.bind",
1755
+ "mcp.host-server",
1756
+ "prompt.resident",
1757
+ "skills.declared-source",
1721
1758
  "whiteboard.discover",
1722
1759
  "whiteboard.read",
1723
1760
  "whiteboard.create",
@@ -1815,6 +1852,7 @@ function sameClaim(a, b) {
1815
1852
  case "account.assert":
1816
1853
  case "account.update":
1817
1854
  case "tool-interception.register":
1855
+ case "prompt.resident":
1818
1856
  return true;
1819
1857
  case "network.connect":
1820
1858
  return b.slug === "network.connect" && a.envelope.connect === b.envelope.connect;
@@ -1838,6 +1876,10 @@ function sameClaim(a, b) {
1838
1876
  return (b.slug === "auth.own-service" || b.slug === "auth.shared-identity") && a.envelope.service === b.envelope.service;
1839
1877
  case "cli.bind":
1840
1878
  return b.slug === "cli.bind" && a.envelope.binary === b.envelope.binary;
1879
+ case "mcp.host-server":
1880
+ return b.slug === "mcp.host-server" && a.envelope.name === b.envelope.name && a.envelope.url === b.envelope.url;
1881
+ case "skills.declared-source":
1882
+ return b.slug === "skills.declared-source" && declaredSourcePairs(a.envelope, b.envelope).every(([left, right]) => left === right);
1841
1883
  case "whiteboard.discover":
1842
1884
  case "whiteboard.read":
1843
1885
  case "whiteboard.create":
@@ -1880,6 +1922,7 @@ function envelopePairs(a, b) {
1880
1922
  case "account.assert":
1881
1923
  case "account.update":
1882
1924
  case "tool-interception.register":
1925
+ case "prompt.resident":
1883
1926
  return [];
1884
1927
  case "network.connect":
1885
1928
  return b.slug === "network.connect" ? [[a.envelope.connect, b.envelope.connect]] : [];
@@ -1919,6 +1962,13 @@ function envelopePairs(a, b) {
1919
1962
  return b.slug === "auth.own-service" || b.slug === "auth.shared-identity" ? [[a.envelope.service, b.envelope.service]] : [];
1920
1963
  case "cli.bind":
1921
1964
  return b.slug === "cli.bind" ? [[a.envelope.binary, b.envelope.binary]] : [];
1965
+ case "mcp.host-server":
1966
+ return b.slug === "mcp.host-server" ? [
1967
+ [a.envelope.name, b.envelope.name],
1968
+ [a.envelope.url, b.envelope.url]
1969
+ ] : [];
1970
+ case "skills.declared-source":
1971
+ return b.slug === "skills.declared-source" ? declaredSourcePairs(a.envelope, b.envelope) : [];
1922
1972
  case "whiteboard.discover":
1923
1973
  case "whiteboard.read":
1924
1974
  case "whiteboard.create":
@@ -1927,6 +1977,24 @@ function envelopePairs(a, b) {
1927
1977
  return b.slug === a.slug && "scope" in b.envelope ? [[a.envelope.scope, b.envelope.scope]] : [];
1928
1978
  }
1929
1979
  }
1980
+ function declaredSourcePairs(a, b) {
1981
+ if (a.channel === "git-clone" && b.channel === "git-clone") {
1982
+ return [
1983
+ [a.channel, b.channel],
1984
+ [a.locator, b.locator],
1985
+ [a.ref ?? "", b.ref ?? ""],
1986
+ [a.subdir ?? "", b.subdir ?? ""]
1987
+ ];
1988
+ }
1989
+ if (a.channel === "installer" && b.channel === "installer") {
1990
+ return [
1991
+ [a.channel, b.channel],
1992
+ [a.command, b.command],
1993
+ [JSON.stringify(a.args), JSON.stringify(b.args)]
1994
+ ];
1995
+ }
1996
+ return [[a.channel, b.channel]];
1997
+ }
1930
1998
  function whiteboardCapabilityClaim(operation, scope, target = "kay.agent") {
1931
1999
  if (target === "kay.app" && operation !== "discover" && operation !== "read") {
1932
2000
  throw new TypeError("kay.app Whiteboard claims are read-only");
@@ -2127,6 +2195,15 @@ function kayPluginHostCompatibility(appVersion) {
2127
2195
  appVersion
2128
2196
  };
2129
2197
  }
2198
+ var KAY_PLUGIN_COMPATIBILITY_REFUSAL_CODES = [
2199
+ "unsupported-protocol",
2200
+ "sdk-range-unsatisfied",
2201
+ "sdk-range-unsupported",
2202
+ "host-sdk-version-invalid"
2203
+ ];
2204
+ function isKayPluginCompatibilityRefusal(code) {
2205
+ return KAY_PLUGIN_COMPATIBILITY_REFUSAL_CODES.includes(code);
2206
+ }
2130
2207
  function isCompatible(report) {
2131
2208
  return report.refusal === void 0;
2132
2209
  }
@@ -2838,9 +2915,9 @@ var KayAgentTargetManifest = z10.strictObject({
2838
2915
  * routing, so it should say what the capability is and when to reach for it, not how to
2839
2916
  * operate it — that is the primer's job, and the host appends the primer route after the body.
2840
2917
  *
2841
- * Policy the HOST applies (never trust this field alone): a body over 500 words is dropped,
2842
- * and a directory/repository-origin plugin's declaration is ignored — a third-party manifest
2843
- * does not buy prompt residency (mirrors the skill-exposure clamp).
2918
+ * Policy the HOST applies (never trust this field alone): the doc renders only for a plugin
2919
+ * holding the `prompt.resident` claim (Bonsai's own plugins hold it; any other plugin needs a
2920
+ * grant a person approved), and a body over 500 words is dropped.
2844
2921
  */
2845
2922
  prompt: PackageAssetPath.optional(),
2846
2923
  /**
@@ -2877,8 +2954,8 @@ var KayAppTargetManifest = z10.strictObject({
2877
2954
  deviceDelegations: z10.array(DeviceDelegationContribution).optional(),
2878
2955
  corpusConsumers: z10.array(CorpusContribution).optional(),
2879
2956
  contextContributors: z10.array(ContextContributorContribution).optional(),
2880
- // Vendored MCP servers this plugin ships (see `McpServerContributions`). Bundled-plugin-only
2881
- // in practice; this package cannot see plugin origin, so that ceiling is enforced at
2957
+ // Vendored MCP servers this plugin ships (see `McpServerContributions`). Each is hosted only
2958
+ // for a plugin holding `mcp.host-server` for its name and URL; that is decided at
2882
2959
  // composition, not here (see ARCHITECTURE.md "Validation Law").
2883
2960
  mcpServers: McpServerContributions.optional(),
2884
2961
  // Handler restricted to endpoint-only by the manifest-level refinement below.
@@ -4527,10 +4604,12 @@ async function judgeKayPluginDirectory(input) {
4527
4604
  const file = KAY_PLUGIN_MANIFEST_FILENAME;
4528
4605
  const hostSdkVersion = host?.sdkVersion;
4529
4606
  const warnings = [];
4607
+ let pluginId;
4530
4608
  const refuse = (stage, code, message) => ({
4531
4609
  outcome: "refused",
4532
4610
  hostSdkVersion,
4533
4611
  refusal: { stage, root, dir, code, message: boundPluginDiagnosticMessage(message) },
4612
+ ...pluginId === void 0 ? {} : { pluginId },
4534
4613
  warnings
4535
4614
  });
4536
4615
  let manifestEntry;
@@ -4564,6 +4643,8 @@ async function judgeKayPluginDirectory(input) {
4564
4643
  return refuse("manifest-parse", "invalid-json", `${file} is not valid JSON: ${errorText(error)}`);
4565
4644
  }
4566
4645
  const head = ReadableManifestHead.safeParse(json);
4646
+ if (head.success)
4647
+ pluginId = head.data.id;
4567
4648
  if (host !== void 0 && head.success && head.data.compatibility) {
4568
4649
  const { refusal } = checkKayPluginHostCompatibility(head.data.compatibility, host);
4569
4650
  if (refusal !== void 0) {
@@ -4714,6 +4795,9 @@ function referencedPaths(manifest) {
4714
4795
  if (manifest.iconDark !== void 0) {
4715
4796
  refs.push({ label: "iconDark", path: manifest.iconDark });
4716
4797
  }
4798
+ if (kayAgent?.prompt !== void 0) {
4799
+ refs.push({ label: "kay.agent prompt", path: kayAgent.prompt });
4800
+ }
4717
4801
  for (const skill of kayAgent?.contributes?.skills ?? []) {
4718
4802
  refs.push({ label: `skill '${skill.localId}'`, path: skill.path });
4719
4803
  }
@@ -4972,6 +5056,7 @@ export {
4972
5056
  CorpusResourceInvocationCursor,
4973
5057
  CorpusResourceInvocationQuery,
4974
5058
  CorpusResourceKind,
5059
+ DeclaredSkillSourceEnvelope,
4975
5060
  DeviceDelegationContribution,
4976
5061
  EndpointContribution,
4977
5062
  EndpointGrantRequest,
@@ -5158,6 +5243,7 @@ export {
5158
5243
  hasClaim,
5159
5244
  hostWithinDomain,
5160
5245
  isCompatible,
5246
+ isKayPluginCompatibilityRefusal,
5161
5247
  isQualifiedAuthSchemeRef,
5162
5248
  isQualifiedAuthServiceRef,
5163
5249
  isSupportedSemverRange,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yaklabs-ai/plugin-protocol",
3
- "version": "0.13.6",
3
+ "version": "0.13.8",
4
4
  "description": "The Kay plugin manifest schema (`kay.plugin.v1`) — parse and validate a kay-plugin.json.",
5
5
  "author": "YakLabs",
6
6
  "type": "module",