@yaklabs-ai/plugin-protocol 0.53.0 → 0.54.1

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
@@ -30,12 +30,6 @@ function declaredUiIconPaths(manifest) {
30
30
  const contributes = manifest.targets?.kay?.ui?.contributes;
31
31
  return [
32
32
  ...(contributes?.railEntries ?? []).flatMap((entry) => entry.icon === void 0 ? [] : [{ label: `kay.ui rail entry '${entry.id}' icon`, path: entry.icon }]),
33
- ...(contributes?.railEntries ?? []).flatMap((entry) => entry.featureFlagVariant?.icon === void 0 ? [] : [
34
- {
35
- label: "kay.ui rail variant icon",
36
- path: entry.featureFlagVariant.icon
37
- }
38
- ]),
39
33
  ...(contributes?.pages ?? []).flatMap((page) => page.icon === void 0 ? [] : [{ label: `kay.ui page '${page.id}' icon`, path: page.icon }]),
40
34
  ...(contributes?.commands ?? []).flatMap((command) => command.icon === void 0 ? [] : [
41
35
  {
@@ -266,8 +260,10 @@ var JsonSchema = z4.record(z4.string(), JsonValue);
266
260
  var KAY_PLUGIN_MANIFEST_SIZE_CAP_BYTES = 1024 * 1024;
267
261
  var KAY_PLUGIN_PROTOCOL_VERSION = "kay.plugin.v1";
268
262
  var KAY_PLUGIN_PROTOCOL_PACKAGE_NAME = "@bonsai/plugin-protocol";
269
- var KAY_PLUGIN_SDK_VERSION = "0.53.0";
263
+ var KAY_PLUGIN_SDK_VERSION = "0.54.1";
270
264
  var KAY_PLUGIN_COMPATIBLE_SDK_VERSIONS = [
265
+ "0.54.0",
266
+ "0.53.0",
271
267
  "0.52.1",
272
268
  "0.52.0",
273
269
  "0.51.0",
@@ -1807,6 +1803,9 @@ var PLUGIN_CAPABILITY_SLUGS = [
1807
1803
  "skills.write",
1808
1804
  "skills.share",
1809
1805
  "plugins.set-enabled",
1806
+ "sessions.assign-project",
1807
+ "artifacts.resolve-file",
1808
+ "process.run",
1810
1809
  "sessions.annotate",
1811
1810
  "sessions.compact",
1812
1811
  "soul.write",
@@ -1856,7 +1855,10 @@ var PRIVATE_PLUGIN_CAPABILITY_SLUGS = [
1856
1855
  "skills.share",
1857
1856
  "plugins.set-enabled",
1858
1857
  "system-prompt.register",
1859
- "workflows.signals"
1858
+ "workflows.signals",
1859
+ "sessions.assign-project",
1860
+ "artifacts.resolve-file",
1861
+ "process.run"
1860
1862
  ];
1861
1863
  function isPrivateCapabilityClaim(claim) {
1862
1864
  return PRIVATE_PLUGIN_CAPABILITY_SLUGS.includes(claim.slug);
@@ -2008,6 +2010,29 @@ function createAuthoritySchemas(canonical) {
2008
2010
  slug: z11.literal("plugins.set-enabled"),
2009
2011
  envelope: z11.strictObject({})
2010
2012
  }),
2013
+ z11.strictObject({
2014
+ // Set the project of sessions no current call or event is about (accepting a project
2015
+ // suggestion, undoing an automatic filing). Private (PRIVATE_PLUGIN_CAPABILITY_SLUGS): whether
2016
+ // a plugin may write to sessions other than the one it is answering is not decided.
2017
+ target: z11.literal("kay.app"),
2018
+ slug: z11.literal("sessions.assign-project"),
2019
+ envelope: z11.strictObject({})
2020
+ }),
2021
+ z11.strictObject({
2022
+ // Turn an address a session's agent can read into the absolute path of its file. Private
2023
+ // (PRIVATE_PLUGIN_CAPABILITY_SLUGS): a path names where a person's files live on disk.
2024
+ target: z11.literal("kay.app"),
2025
+ slug: z11.literal("artifacts.resolve-file"),
2026
+ envelope: z11.strictObject({})
2027
+ }),
2028
+ z11.strictObject({
2029
+ // Run a program the host bound for this plugin from its app code, each run still checked
2030
+ // against the exact `process.spawn` claim. Private (PRIVATE_PLUGIN_CAPABILITY_SLUGS): the
2031
+ // host binds programs only for plugins it ships.
2032
+ target: z11.literal("kay.app"),
2033
+ slug: z11.literal("process.run"),
2034
+ envelope: z11.strictObject({})
2035
+ }),
2011
2036
  z11.strictObject({
2012
2037
  // Write a steward entry (recap, next steps, title, work headlines) into the session whose
2013
2038
  // event the calling handler is answering. Bound to that session: a call for any other is
@@ -2337,6 +2362,9 @@ function sameClaim(a, b) {
2337
2362
  case "skills.write":
2338
2363
  case "skills.share":
2339
2364
  case "plugins.set-enabled":
2365
+ case "sessions.assign-project":
2366
+ case "artifacts.resolve-file":
2367
+ case "process.run":
2340
2368
  case "sessions.annotate":
2341
2369
  case "sessions.compact":
2342
2370
  case "soul.write":
@@ -2429,6 +2457,9 @@ function envelopePairs(a, b) {
2429
2457
  case "skills.write":
2430
2458
  case "skills.share":
2431
2459
  case "plugins.set-enabled":
2460
+ case "sessions.assign-project":
2461
+ case "artifacts.resolve-file":
2462
+ case "process.run":
2432
2463
  case "sessions.annotate":
2433
2464
  case "sessions.compact":
2434
2465
  case "soul.write":
@@ -3754,6 +3785,8 @@ function createContributionsSchemas(canonical) {
3754
3785
  const UriModuleFacts2 = z14.strictObject(UriModuleFactsShape);
3755
3786
  const UriModuleContribution2 = z14.strictObject({
3756
3787
  localId: LocalContributionId2,
3788
+ /** Opaque adapter id for account-bound connections; never namespaced. */
3789
+ adapterId: z14.string().min(1).optional(),
3757
3790
  schemes: z14.array(UriScheme2).min(1),
3758
3791
  displayName: OptionalDisplayName,
3759
3792
  ...UriModuleFactsShape,
@@ -3788,6 +3821,7 @@ function createContributionsSchemas(canonical) {
3788
3821
  looksUpWebLinks: z14.literal(true).optional()
3789
3822
  });
3790
3823
  const AppUriModuleContribution2 = UriModuleContribution2.omit({
3824
+ adapterId: true,
3791
3825
  authActions: true,
3792
3826
  authService: true,
3793
3827
  authScheme: true,
@@ -4399,6 +4433,13 @@ function createContributionsSchemas(canonical) {
4399
4433
  });
4400
4434
  const KayUiAppHostCapability2 = z14.enum([
4401
4435
  "navigation.open-session",
4436
+ "navigation.open-external",
4437
+ "configuration.read",
4438
+ "auth-services.read",
4439
+ "connect-flows.read",
4440
+ "connect-flows.dismiss",
4441
+ "support.report",
4442
+ "navigation.open-page",
4402
4443
  // Lets `navigation.openChat` create a blank chat (no message, no model
4403
4444
  // turn) when no session id is given. It never sends anything.
4404
4445
  "sessions.create",
@@ -4408,12 +4449,15 @@ function createContributionsSchemas(canonical) {
4408
4449
  // Draws Bonsai's markdown document view in the app's page (`BonsaiMarkdownDocumentView`).
4409
4450
  // It reads and saves nothing: the app supplies the text and keeps the edits.
4410
4451
  "markdown.document-view",
4411
- "models.complete",
4412
4452
  // Draws links the host resolves and opens (`BonsaiReferencePill`, `BonsaiReferenceRow`,
4413
4453
  // `BonsaiReferenceMarkdown`). A person's click on one can open a session or another plugin's page.
4414
4454
  "references.open",
4415
4455
  // Server-rated organization billing, distinct from local/provider cost.
4416
4456
  "billing.read",
4457
+ "account.read",
4458
+ "plugins.read",
4459
+ "plugins.settings",
4460
+ "permissions.manage",
4417
4461
  "automations.read",
4418
4462
  "automations.run",
4419
4463
  // Lists the shared artifacts the signed-in account may open and opens one in Bonsai's shared
@@ -4471,7 +4515,7 @@ function createContributionsSchemas(canonical) {
4471
4515
  }
4472
4516
  });
4473
4517
  const UiRailBadge = z14.strictObject({
4474
- source: LocalContributionId2,
4518
+ source: UiAppCapabilityReference2,
4475
4519
  where: NonEmptyString3.optional(),
4476
4520
  label: z14.strictObject({
4477
4521
  one: NonEmptyString3.optional(),
@@ -4500,12 +4544,7 @@ function createContributionsSchemas(canonical) {
4500
4544
  section: z14.enum(["primary", "plugins"]).optional(),
4501
4545
  badge: UiRailBadge.optional(),
4502
4546
  panel: z14.strictObject({ body: LocalContributionId2 }).optional(),
4503
- featureFlagVariant: z14.strictObject({
4504
- flag: NonEmptyString3,
4505
- title: NonEmptyString3.optional(),
4506
- icon: PackageAssetPath2.optional(),
4507
- panel: z14.literal(false).optional()
4508
- }).optional()
4547
+ visibleWhen: z14.strictObject({ flag: NonEmptyString3, enabled: z14.boolean() }).optional()
4509
4548
  });
4510
4549
  const UiToastPreviewContribution2 = z14.strictObject({
4511
4550
  rule: LocalContributionId2,
@@ -4518,6 +4557,8 @@ function createContributionsSchemas(canonical) {
4518
4557
  icon: PackageAssetPath2.optional(),
4519
4558
  companion: z14.boolean().optional(),
4520
4559
  sessionBinding: z14.enum(["session", "family"]).optional(),
4560
+ /** Lists this page in Settings beside native workspace sections, in the same order scale. */
4561
+ settings: z14.strictObject({ order: z14.number().optional() }).optional(),
4521
4562
  aliases: z14.array(NonEmptyString3).optional(),
4522
4563
  openedEvent: NonEmptyString3.optional()
4523
4564
  });
@@ -4732,28 +4773,53 @@ __export(manifest_exports, {
4732
4773
  validateKayUiEventSubscription: () => validateKayUiEventSubscription
4733
4774
  });
4734
4775
 
4735
- // packages/plugin-protocol/dist/shell-commands.js
4776
+ // packages/plugin-protocol/dist/project-directories.js
4736
4777
  import { z as z15 } from "zod";
4737
- var PluginShellCommand = z15.strictObject({
4738
- name: z15.string().regex(/^[a-z][a-z0-9-]*$/),
4739
- aliases: z15.array(z15.string().regex(/^[a-z][a-z0-9-]*$/)).optional(),
4778
+ var PluginProjectDirectories = z15.strictObject({
4779
+ /** An endpoint this plugin's app target declares; called with a {@link ProjectDirectoryRequest}. */
4740
4780
  endpoint: z15.string().min(1),
4741
- usage: z15.string().min(1)
4781
+ /** A scheme this plugin's URI modules serve; a project is addressed as `<scheme>://<id>`. */
4782
+ scheme: z15.string().min(1)
4783
+ });
4784
+ var ProjectDirectoryRequest = z15.strictObject({
4785
+ /** The project's stable id. */
4786
+ id: z15.string().min(1)
4787
+ });
4788
+ var ProjectDirectory = z15.strictObject({
4789
+ id: z15.string().min(1),
4790
+ /** Absolute path of the project's folder. */
4791
+ path: z15.string().min(1),
4792
+ /** Absolute path a new session in this project starts in. */
4793
+ defaultCwd: z15.string().min(1),
4794
+ /** Ancestor project ids, root first. */
4795
+ ancestorIds: z15.array(z15.string().min(1))
4796
+ });
4797
+ var ProjectDirectoryResponse = z15.strictObject({
4798
+ project: ProjectDirectory.nullable()
4799
+ });
4800
+
4801
+ // packages/plugin-protocol/dist/shell-commands.js
4802
+ import { z as z16 } from "zod";
4803
+ var PluginShellCommand = z16.strictObject({
4804
+ name: z16.string().regex(/^[a-z][a-z0-9-]*$/),
4805
+ aliases: z16.array(z16.string().regex(/^[a-z][a-z0-9-]*$/)).optional(),
4806
+ endpoint: z16.string().min(1),
4807
+ usage: z16.string().min(1)
4742
4808
  });
4743
- var ShellCommandOutcome = z15.strictObject({
4744
- exitCode: z15.number().int(),
4809
+ var ShellCommandOutcome = z16.strictObject({
4810
+ exitCode: z16.number().int(),
4745
4811
  envelope: JsonValue,
4746
4812
  result: JsonValue.optional()
4747
4813
  });
4748
- var ShellCommandRequest = z15.strictObject({
4749
- argv: z15.array(z15.string()),
4750
- cwd: z15.string(),
4751
- outcomes: z15.array(ShellCommandOutcome).max(3)
4814
+ var ShellCommandRequest = z16.strictObject({
4815
+ argv: z16.array(z16.string()),
4816
+ cwd: z16.string(),
4817
+ outcomes: z16.array(ShellCommandOutcome).max(3)
4752
4818
  });
4753
- var ShellCommandStep = z15.discriminatedUnion("kind", [
4754
- z15.strictObject({
4755
- kind: z15.literal("invoke"),
4756
- toolName: z15.enum([
4819
+ var ShellCommandStep = z16.discriminatedUnion("kind", [
4820
+ z16.strictObject({
4821
+ kind: z16.literal("invoke"),
4822
+ toolName: z16.enum([
4757
4823
  "read",
4758
4824
  "list",
4759
4825
  "search",
@@ -4762,24 +4828,24 @@ var ShellCommandStep = z15.discriminatedUnion("kind", [
4762
4828
  "delete",
4763
4829
  "help"
4764
4830
  ]),
4765
- input: z15.record(z15.string(), JsonValue),
4766
- flags: z15.record(z15.string(), z15.string())
4831
+ input: z16.record(z16.string(), JsonValue),
4832
+ flags: z16.record(z16.string(), z16.string())
4767
4833
  }),
4768
- z15.strictObject({
4769
- kind: z15.literal("finish"),
4770
- exitCode: z15.number().int(),
4771
- stdout: z15.string()
4834
+ z16.strictObject({
4835
+ kind: z16.literal("finish"),
4836
+ exitCode: z16.number().int(),
4837
+ stdout: z16.string()
4772
4838
  })
4773
4839
  ]);
4774
4840
 
4775
4841
  // packages/plugin-protocol/dist/manifest.js
4776
- import { z as z17 } from "zod";
4842
+ import { z as z18 } from "zod";
4777
4843
 
4778
4844
  // packages/plugin-protocol/dist/workload-purposes.js
4779
- import { z as z16 } from "zod";
4780
- var PluginWorkloadPurpose = z16.strictObject({
4781
- purpose: z16.string().regex(/^[a-z][a-z0-9-]*$/),
4782
- workloadClass: z16.enum(["dreaming", "hindsight"])
4845
+ import { z as z17 } from "zod";
4846
+ var PluginWorkloadPurpose = z17.strictObject({
4847
+ purpose: z17.string().max(128).regex(/^[a-z][a-z0-9_-]*(?:\/[a-z][a-z0-9_-]*)*$/),
4848
+ workloadClass: z17.enum(["dreaming", "hindsight"])
4783
4849
  });
4784
4850
 
4785
4851
  // packages/plugin-protocol/dist/synthetic-contributions.js
@@ -4805,34 +4871,34 @@ function createManifestSchemas(canonical) {
4805
4871
  const { AgentRenderContribution: AgentRenderContribution2, ApprovalTypeContribution: ApprovalTypeContribution2, WorkflowContribution: WorkflowContribution2, PluginCardContribution: PluginCardContribution2, AppDataMaterializerContribution: AppDataMaterializerContribution2, AppDataSourceContribution: AppDataSourceContribution2, AppUriModuleContribution: AppUriModuleContribution2, AppEventSubscription: AppEventSubscription2, ArtifactUriModuleContribution: ArtifactUriModuleContribution2, CliBindingContribution: CliBindingContribution2, CommandContribution: CommandContribution2, ContextContributorContribution: ContextContributorContribution2, ConverterContribution: ConverterContribution2, SessionReaderContribution: SessionReaderContribution2, DeviceDelegationContribution: DeviceDelegationContribution2, EndpointContribution: EndpointContribution2, EntityResolverContribution: EntityResolverContribution2, GitHostContribution: GitHostContribution2, McpServerContributions: McpServerContributions2, PluginEventDefinitionContribution: PluginEventDefinitionContribution2, PluginNotificationRuleContribution: PluginNotificationRuleContribution2, PluginProductEventContribution: PluginProductEventContribution2, ResourceContribution: ResourceContribution2, ReferencePresentationContribution: ReferencePresentationContribution2, PluginSkillSourceDeclaration: PluginSkillSourceDeclaration2, InteractionDriverContribution: InteractionDriverContribution2, SearchProviderContribution: SearchProviderContribution2, SkillContribution: SkillContribution2, ThemeContribution: ThemeContribution2, AgentToolContribution: AgentToolContribution2, ToolContribution: ToolContribution2, UiCommandContribution: UiCommandContribution2, UiAppContribution: UiAppContribution2, UiRailEntryContribution: UiRailEntryContribution2, UiToastPreviewContribution: UiToastPreviewContribution2, UiPageContribution: UiPageContribution2, UiEventSubscriptionContribution: UiEventSubscriptionContribution2, UiSlotContribution: UiSlotContribution2, UriModuleContribution: UriModuleContribution2, WhiteboardTypeContribution: WhiteboardTypeContribution2 } = canonical ? canonicalContributionSchemas : contributions_exports;
4806
4872
  const { HttpsUrl: HttpsUrl2, LocalContributionId: LocalContributionId2, NonEmptyString: NonEmptyString3, PackageAssetPath: PackageAssetPath2, PluginId: PluginId2, PluginNamespace: PluginNamespace2, RegistrableDomain: RegistrableDomain2, SignedInStatusCode: SignedInStatusCode2, TargetEntrypoint: TargetEntrypoint2 } = canonical ? canonicalCommonSchemas : common_exports;
4807
4873
  const { PluginPermissionManifest: PluginPermissionManifest2 } = canonical ? canonicalPermissionSchemas : permissions_exports;
4808
- const KayAgentTargetManifest2 = z17.strictObject({
4874
+ const KayAgentTargetManifest2 = z18.strictObject({
4809
4875
  entrypoint: TargetEntrypoint2,
4810
- contributes: z17.strictObject({
4811
- tools: z17.array(AgentToolContribution2).optional(),
4812
- converters: z17.array(ConverterContribution2).optional(),
4813
- uriModules: z17.array(UriModuleContribution2).optional(),
4876
+ contributes: z18.strictObject({
4877
+ tools: z18.array(AgentToolContribution2).optional(),
4878
+ converters: z18.array(ConverterContribution2).optional(),
4879
+ uriModules: z18.array(UriModuleContribution2).optional(),
4814
4880
  // Host-composed artifact-backed schemes (see `ArtifactUriModuleContribution`): the plugin
4815
4881
  // declares scheme + editability; the daemon binds each to the kernel's artifact lifecycle
4816
4882
  // per session. Separate from `uriModules` (plugin-implemented backends) precisely because
4817
4883
  // the plugin registers NOTHING for these at activation.
4818
- artifactUriModules: z17.array(ArtifactUriModuleContribution2).optional(),
4819
- cliBindings: z17.array(CliBindingContribution2).optional(),
4884
+ artifactUriModules: z18.array(ArtifactUriModuleContribution2).optional(),
4885
+ cliBindings: z18.array(CliBindingContribution2).optional(),
4820
4886
  // Which git hosts this plugin's credential serves (see `GitHostContribution`): a
4821
4887
  // declaration, so a plugin for any git backend gets credentialed clones without
4822
4888
  // the daemon learning its name. Sibling of `cliBindings` because both answer the
4823
4889
  // same question - which of this plugin's auth services a host-side consumer
4824
4890
  // resolves - for two different transports.
4825
- gitHosts: z17.array(GitHostContribution2).optional(),
4826
- resources: z17.array(ResourceContribution2).optional(),
4827
- skills: z17.array(SkillContribution2).optional(),
4828
- searchProviders: z17.array(SearchProviderContribution2).optional(),
4829
- interactionDrivers: z17.array(InteractionDriverContribution2).optional(),
4830
- entityResolvers: z17.array(EntityResolverContribution2).optional(),
4831
- renderers: z17.array(AgentRenderContribution2).optional(),
4891
+ gitHosts: z18.array(GitHostContribution2).optional(),
4892
+ resources: z18.array(ResourceContribution2).optional(),
4893
+ skills: z18.array(SkillContribution2).optional(),
4894
+ searchProviders: z18.array(SearchProviderContribution2).optional(),
4895
+ interactionDrivers: z18.array(InteractionDriverContribution2).optional(),
4896
+ entityResolvers: z18.array(EntityResolverContribution2).optional(),
4897
+ renderers: z18.array(AgentRenderContribution2).optional(),
4832
4898
  // Handler restricted to skill | tool by the manifest-level refinement below (see
4833
4899
  // `CommandContribution`'s doc for why the restriction is not expressed in the type, and
4834
4900
  // `CommandHandler`'s doc for why there is no promptTemplate variant to declare here).
4835
- commands: z17.array(CommandContribution2).optional()
4901
+ commands: z18.array(CommandContribution2).optional()
4836
4902
  }).optional(),
4837
4903
  /**
4838
4904
  * The plugin's primer skill - the `localId` of one of its own declared
@@ -4868,8 +4934,8 @@ function createManifestSchemas(canonical) {
4868
4934
  * grant a person approved), and a body over 500 words is dropped.
4869
4935
  */
4870
4936
  prompt: PackageAssetPath2.optional(),
4871
- promptOrder: z17.number().finite().optional(),
4872
- familyFolder: z17.strictObject({ scope: z17.literal("root") }).optional(),
4937
+ promptOrder: z18.number().finite().optional(),
4938
+ familyFolder: z18.strictObject({ scope: z18.literal("root") }).optional(),
4873
4939
  /**
4874
4940
  * External origins of skills this plugin claims as its own (see
4875
4941
  * {@link PluginSkillSourceDeclaration}). Acquired by the daemon at boot and landed under the
@@ -4880,61 +4946,61 @@ function createManifestSchemas(canonical) {
4880
4946
  * acquisition, not declared here, so there is nothing for the resolved contract to mint a
4881
4947
  * `globalId` for at parse time.
4882
4948
  */
4883
- skillSources: z17.array(PluginSkillSourceDeclaration2).optional()
4949
+ skillSources: z18.array(PluginSkillSourceDeclaration2).optional()
4884
4950
  });
4885
- const KayAppTargetManifest2 = z17.strictObject({
4951
+ const KayAppTargetManifest2 = z18.strictObject({
4886
4952
  // Optional, like `kay.ui`'s: a target may carry only declarative `contributes` (e.g. a plugin
4887
4953
  // that ships nothing but `mcpServers`) with no app-lifetime module for the host to load.
4888
4954
  entrypoint: TargetEntrypoint2.optional(),
4889
- contributes: z17.strictObject({
4955
+ contributes: z18.strictObject({
4890
4956
  // Session tools implemented by the app-lifetime activation (registered once, injected into
4891
4957
  // every session with a host-stamped session context) - the tool counterpart of `uriModules`
4892
4958
  // below. Same descriptor shape as kay.agent tools; `toolName` shares ONE flat session
4893
4959
  // namespace with them (enforced by the manifest-level refinement below).
4894
- tools: z17.array(ToolContribution2).optional(),
4895
- endpoints: z17.array(EndpointContribution2).optional(),
4896
- cards: z17.array(PluginCardContribution2).optional(),
4897
- uriModules: z17.array(AppUriModuleContribution2).optional(),
4898
- dataSources: z17.array(AppDataSourceContribution2).optional(),
4899
- whiteboardTypes: z17.array(WhiteboardTypeContribution2).optional(),
4900
- approvalTypes: z17.array(ApprovalTypeContribution2).optional(),
4901
- workflows: z17.array(WorkflowContribution2).optional(),
4902
- eventDefinitions: z17.array(PluginEventDefinitionContribution2).optional(),
4960
+ tools: z18.array(ToolContribution2).optional(),
4961
+ endpoints: z18.array(EndpointContribution2).optional(),
4962
+ cards: z18.array(PluginCardContribution2).optional(),
4963
+ uriModules: z18.array(AppUriModuleContribution2).optional(),
4964
+ dataSources: z18.array(AppDataSourceContribution2).optional(),
4965
+ whiteboardTypes: z18.array(WhiteboardTypeContribution2).optional(),
4966
+ approvalTypes: z18.array(ApprovalTypeContribution2).optional(),
4967
+ workflows: z18.array(WorkflowContribution2).optional(),
4968
+ eventDefinitions: z18.array(PluginEventDefinitionContribution2).optional(),
4903
4969
  // Default notification rules over this plugin's own `eventDefinitions`; seeded by the host
4904
4970
  // (see `PluginNotificationRuleContribution`).
4905
- notificationRules: z17.array(PluginNotificationRuleContribution2).optional(),
4906
- productEvents: z17.array(PluginProductEventContribution2).optional(),
4907
- eventSubscriptions: z17.array(AppEventSubscription2).optional(),
4908
- deviceDelegations: z17.array(DeviceDelegationContribution2).optional(),
4909
- sessionReaders: z17.array(SessionReaderContribution2).optional(),
4910
- contextContributors: z17.array(ContextContributorContribution2).optional(),
4971
+ notificationRules: z18.array(PluginNotificationRuleContribution2).optional(),
4972
+ productEvents: z18.array(PluginProductEventContribution2).optional(),
4973
+ eventSubscriptions: z18.array(AppEventSubscription2).optional(),
4974
+ deviceDelegations: z18.array(DeviceDelegationContribution2).optional(),
4975
+ sessionReaders: z18.array(SessionReaderContribution2).optional(),
4976
+ contextContributors: z18.array(ContextContributorContribution2).optional(),
4911
4977
  // Vendored MCP servers this plugin ships (see `McpServerContributions`). Each is hosted only
4912
4978
  // for a plugin holding `mcp.host-server` for its name and URL; that is decided at
4913
4979
  // composition, not here (see ARCHITECTURE.md "Validation Law").
4914
4980
  mcpServers: McpServerContributions2.optional(),
4915
4981
  // Handler restricted to endpoint-only by the manifest-level refinement below.
4916
- commands: z17.array(CommandContribution2).optional()
4982
+ commands: z18.array(CommandContribution2).optional()
4917
4983
  }).optional()
4918
4984
  });
4919
- const KayUiTargetManifest2 = z17.strictObject({
4985
+ const KayUiTargetManifest2 = z18.strictObject({
4920
4986
  entrypoint: TargetEntrypoint2.extend({
4921
- format: z17.literal("compiled-bundle").optional()
4987
+ format: z18.literal("compiled-bundle").optional()
4922
4988
  }).optional(),
4923
- contributes: z17.strictObject({
4924
- commands: z17.array(UiCommandContribution2).optional(),
4925
- slots: z17.array(UiSlotContribution2).optional(),
4926
- referencePresentations: z17.array(ReferencePresentationContribution2).optional(),
4927
- apps: z17.array(UiAppContribution2).optional(),
4928
- railEntries: z17.array(UiRailEntryContribution2).optional(),
4929
- toastPreviews: z17.array(UiToastPreviewContribution2).optional(),
4930
- pages: z17.array(UiPageContribution2).optional(),
4931
- themes: z17.array(ThemeContribution2).optional(),
4932
- eventSubscriptions: z17.array(UiEventSubscriptionContribution2).optional(),
4933
- dataMaterializers: z17.array(AppDataMaterializerContribution2).optional()
4989
+ contributes: z18.strictObject({
4990
+ commands: z18.array(UiCommandContribution2).optional(),
4991
+ slots: z18.array(UiSlotContribution2).optional(),
4992
+ referencePresentations: z18.array(ReferencePresentationContribution2).optional(),
4993
+ apps: z18.array(UiAppContribution2).optional(),
4994
+ railEntries: z18.array(UiRailEntryContribution2).optional(),
4995
+ toastPreviews: z18.array(UiToastPreviewContribution2).optional(),
4996
+ pages: z18.array(UiPageContribution2).optional(),
4997
+ themes: z18.array(ThemeContribution2).optional(),
4998
+ eventSubscriptions: z18.array(UiEventSubscriptionContribution2).optional(),
4999
+ dataMaterializers: z18.array(AppDataMaterializerContribution2).optional()
4934
5000
  }).optional()
4935
5001
  });
4936
- const PluginConfigScope2 = z17.enum(["global", "project", "agent"]);
4937
- const PluginConfigSectionManifest2 = z17.strictObject({
5002
+ const PluginConfigScope2 = z18.enum(["global", "project", "agent"]);
5003
+ const PluginConfigSectionManifest2 = z18.strictObject({
4938
5004
  section: NonEmptyString3.optional(),
4939
5005
  schema: JsonSchema,
4940
5006
  /**
@@ -4952,23 +5018,23 @@ function createManifestSchemas(canonical) {
4952
5018
  * is the baseline every section has; `agent` has no runtime mapping (the
4953
5019
  * agent/entity fold is downstream of the document protocol).
4954
5020
  */
4955
- scopes: z17.array(PluginConfigScope2).optional()
5021
+ scopes: z18.array(PluginConfigScope2).optional()
4956
5022
  });
4957
- const PluginConfigManifest2 = z17.array(PluginConfigSectionManifest2).min(1);
4958
- const PluginStorageManifest2 = z17.strictObject({
4959
- sqlite: z17.strictObject({
4960
- enabled: z17.boolean(),
4961
- ownerTarget: z17.literal("kay.app").optional(),
5023
+ const PluginConfigManifest2 = z18.array(PluginConfigSectionManifest2).min(1);
5024
+ const PluginStorageManifest2 = z18.strictObject({
5025
+ sqlite: z18.strictObject({
5026
+ enabled: z18.boolean(),
5027
+ ownerTarget: z18.literal("kay.app").optional(),
4962
5028
  migrations: NonEmptyString3.optional()
4963
5029
  }).optional(),
4964
- dataDir: z17.strictObject({
4965
- enabled: z17.boolean(),
4966
- ownerTarget: z17.literal("kay.app").optional(),
5030
+ dataDir: z18.strictObject({
5031
+ enabled: z18.boolean(),
5032
+ ownerTarget: z18.literal("kay.app").optional(),
4967
5033
  sharedWith: PluginId2.optional()
4968
5034
  }).optional()
4969
5035
  });
4970
- const PluginOAuthClientSupplier2 = z17.enum(["kay", "user"]);
4971
- const PluginProvisioningProbe2 = z17.strictObject({
5036
+ const PluginOAuthClientSupplier2 = z18.enum(["kay", "user"]);
5037
+ const PluginProvisioningProbe2 = z18.strictObject({
4972
5038
  /**
4973
5039
  * The API endpoint that answers the question. The host sends the service's OWN credential here,
4974
5040
  * so this must belong to the provider that minted it - enforced by the daemon against the
@@ -4976,13 +5042,13 @@ function createManifestSchemas(canonical) {
4976
5042
  */
4977
5043
  url: HttpsUrl2,
4978
5044
  /** Absent => `GET`. */
4979
- method: z17.enum(["GET"]).optional(),
5045
+ method: z18.enum(["GET"]).optional(),
4980
5046
  /**
4981
5047
  * The statuses that make the response a VERDICT at all. Anything else (a 401 from a stale
4982
5048
  * token, a 5xx, a rate limit) means the probe learned nothing and reports `unknown` - never
4983
5049
  * `unsatisfied`, which would tell a user to go fix setup that is fine.
4984
5050
  */
4985
- verdictStatuses: z17.array(SignedInStatusCode2).min(1),
5051
+ verdictStatuses: z18.array(SignedInStatusCode2).min(1),
4986
5052
  /**
4987
5053
  * Dot-path to a JSON array in the response body that must be NON-EMPTY for the requirement to
4988
5054
  * count as satisfied (e.g. `installations`). Absent means a verdict status alone is enough.
@@ -4991,7 +5057,7 @@ function createManifestSchemas(canonical) {
4991
5057
  */
4992
5058
  nonEmptyArrayAt: NonEmptyString3.optional()
4993
5059
  });
4994
- const PluginProvisioningRequirement2 = z17.strictObject({
5060
+ const PluginProvisioningRequirement2 = z18.strictObject({
4995
5061
  /** Stable id, unique within the scheme. */
4996
5062
  id: LocalContributionId2,
4997
5063
  /** Human-facing requirement name, e.g. "GitHub App installation". */
@@ -5008,7 +5074,7 @@ function createManifestSchemas(canonical) {
5008
5074
  probe: PluginProvisioningProbe2
5009
5075
  });
5010
5076
  const PluginProvisioningField = {
5011
- provisioning: z17.array(PluginProvisioningRequirement2).optional()
5077
+ provisioning: z18.array(PluginProvisioningRequirement2).optional()
5012
5078
  };
5013
5079
  const PluginAuthSchemeDescriptionFields = {
5014
5080
  /** Human-facing flow name; absent, the service's name stands in. */
@@ -5024,17 +5090,21 @@ function createManifestSchemas(canonical) {
5024
5090
  const PluginAuthSchemeOAuthEndpointFields = {
5025
5091
  authorizationUrl: HttpsUrl2,
5026
5092
  tokenUrl: HttpsUrl2,
5093
+ /** Initial connect scopes; absent uses `scopes`, while an empty array requests none. */
5094
+ connectScopes: z18.array(NonEmptyString3).optional(),
5027
5095
  /** Provider-specific query parameters added to the authorize URL. */
5028
- extraAuthorizeParams: z17.record(NonEmptyString3, z17.string()).optional()
5096
+ extraAuthorizeParams: z18.record(NonEmptyString3, z18.string()).optional(),
5097
+ /** Additional authorization parameters when this service already holds an account. */
5098
+ extraAuthorizeParamsWhenAccountHeld: z18.record(NonEmptyString3, z18.string()).optional()
5029
5099
  };
5030
- const PluginAuthSchemeAccountLookup = z17.literal("lookup");
5031
- const PluginAuthSchemeOAuthPkce = z17.strictObject({
5100
+ const PluginAuthSchemeAccountLookup = z18.literal("lookup");
5101
+ const PluginAuthSchemeOAuthPkce = z18.strictObject({
5032
5102
  ...PluginProvisioningField,
5033
5103
  ...PluginAuthSchemeDescriptionFields,
5034
5104
  ...PluginAuthSchemeOAuthEndpointFields,
5035
5105
  localId: LocalContributionId2,
5036
- kind: z17.literal("oauth2"),
5037
- exchange: z17.literal("pkce"),
5106
+ kind: z18.literal("oauth2"),
5107
+ exchange: z18.literal("pkce"),
5038
5108
  byoocProfile: PluginByoocProfile.optional(),
5039
5109
  /**
5040
5110
  * A public client id the plugin ships for its own sign-in. Only an installed plugin's is used:
@@ -5058,7 +5128,7 @@ function createManifestSchemas(canonical) {
5058
5128
  * runs on an untrusted manifest, so a hand-built `["kay","kay"]` must be refused here, not
5059
5129
  * silently normalized).
5060
5130
  */
5061
- clientSuppliers: z17.array(PluginOAuthClientSupplier2).nonempty().superRefine((suppliers, ctx) => {
5131
+ clientSuppliers: z18.array(PluginOAuthClientSupplier2).nonempty().superRefine((suppliers, ctx) => {
5062
5132
  if (new Set(suppliers).size !== suppliers.length) {
5063
5133
  ctx.addIssue({
5064
5134
  code: "custom",
@@ -5066,7 +5136,7 @@ function createManifestSchemas(canonical) {
5066
5136
  });
5067
5137
  }
5068
5138
  }),
5069
- scopes: z17.array(NonEmptyString3).optional()
5139
+ scopes: z18.array(NonEmptyString3).optional()
5070
5140
  }).refine((scheme) => scheme.byoocProfile === void 0 || scheme.clientSuppliers.includes("user"), {
5071
5141
  message: "An own-client profile requires the user client supplier.",
5072
5142
  path: ["byoocProfile"]
@@ -5077,33 +5147,33 @@ function createManifestSchemas(canonical) {
5077
5147
  message: "a scheme with its own clientId names where its account comes from (`account`)",
5078
5148
  path: ["account"]
5079
5149
  });
5080
- const PluginAuthSchemeOAuthConfidential = z17.strictObject({
5150
+ const PluginAuthSchemeOAuthConfidential = z18.strictObject({
5081
5151
  ...PluginProvisioningField,
5082
5152
  ...PluginAuthSchemeDescriptionFields,
5083
5153
  ...PluginAuthSchemeOAuthEndpointFields,
5084
5154
  localId: LocalContributionId2,
5085
- kind: z17.literal("oauth2"),
5086
- exchange: z17.literal("confidential"),
5155
+ kind: z18.literal("oauth2"),
5156
+ exchange: z18.literal("confidential"),
5087
5157
  /** Absent means `["kay"]` - a confidential exchange's secret may only ever be Bonsai's. */
5088
- clientSuppliers: z17.tuple([z17.literal("kay")]).optional(),
5089
- scopes: z17.array(NonEmptyString3).optional(),
5158
+ clientSuppliers: z18.tuple([z18.literal("kay")]).optional(),
5159
+ scopes: z18.array(NonEmptyString3).optional(),
5090
5160
  /** Where the account comes from (see {@link PluginAuthSchemeAccountLookup}). */
5091
- account: z17.union([PluginAuthSchemeAccountLookup, z17.literal("sign-in")])
5161
+ account: z18.union([PluginAuthSchemeAccountLookup, z18.literal("sign-in")])
5092
5162
  });
5093
- const PluginAuthSchemeOAuth2 = z17.discriminatedUnion("exchange", [
5163
+ const PluginAuthSchemeOAuth2 = z18.discriminatedUnion("exchange", [
5094
5164
  PluginAuthSchemeOAuthPkce,
5095
5165
  PluginAuthSchemeOAuthConfidential
5096
5166
  ]);
5097
- const PluginAuthSchemeApiKey = z17.strictObject({
5167
+ const PluginAuthSchemeApiKey = z18.strictObject({
5098
5168
  ...PluginProvisioningField,
5099
5169
  ...PluginAuthSchemeDescriptionFields,
5100
5170
  localId: LocalContributionId2,
5101
- kind: z17.literal("api-key"),
5102
- scopes: z17.array(NonEmptyString3).optional(),
5171
+ kind: z18.literal("api-key"),
5172
+ scopes: z18.array(NonEmptyString3).optional(),
5103
5173
  /** The connect prompt's label for the key. Absent: "<service name> API key". */
5104
5174
  inputLabel: NonEmptyString3.optional(),
5105
5175
  /** Two or more labeled inputs for a secret that comes in parts; absent asks for one key. */
5106
- fields: z17.array(z17.strictObject({ id: LocalContributionId2, label: NonEmptyString3 })).min(2).superRefine((fields, ctx) => {
5176
+ fields: z18.array(z18.strictObject({ id: LocalContributionId2, label: NonEmptyString3 })).min(2).superRefine((fields, ctx) => {
5107
5177
  if (new Set(fields.map((field) => field.id)).size !== fields.length) {
5108
5178
  ctx.addIssue({
5109
5179
  code: "custom",
@@ -5112,7 +5182,7 @@ function createManifestSchemas(canonical) {
5112
5182
  }
5113
5183
  }).optional(),
5114
5184
  /** Where and how the person creates the key outside Bonsai. */
5115
- setup: z17.strictObject({ instructions: NonEmptyString3, url: HttpsUrl2 }).optional(),
5185
+ setup: z18.strictObject({ instructions: NonEmptyString3, url: HttpsUrl2 }).optional(),
5116
5186
  /**
5117
5187
  * `"lookup"`: the plugin checks a key before it is saved and names its account, with the function
5118
5188
  * it registers (`api.auth.registerAccountLookup`). Absent: the key is saved unchecked, under the
@@ -5120,27 +5190,27 @@ function createManifestSchemas(canonical) {
5120
5190
  */
5121
5191
  account: PluginAuthSchemeAccountLookup.optional()
5122
5192
  });
5123
- const PluginAuthSchemeDelegated = z17.strictObject({
5193
+ const PluginAuthSchemeDelegated = z18.strictObject({
5124
5194
  ...PluginAuthSchemeDescriptionFields,
5125
5195
  localId: LocalContributionId2,
5126
- kind: z17.literal("delegated"),
5127
- scopes: z17.array(NonEmptyString3).optional()
5196
+ kind: z18.literal("delegated"),
5197
+ scopes: z18.array(NonEmptyString3).optional()
5128
5198
  });
5129
- const ExternalCliArgument = z17.string().min(1).max(16384).refine((value) => ![...value].some(isUnsafeArgumentCharacter), {
5199
+ const ExternalCliArgument = z18.string().min(1).max(16384).refine((value) => ![...value].some(isUnsafeArgumentCharacter), {
5130
5200
  message: "an argument may hold tabs and line breaks, but no other control character, no invisible character and no bidirectional override"
5131
5201
  });
5132
- const ExternalCliCommand = z17.string().max(128).regex(/^[A-Za-z0-9][A-Za-z0-9._+-]*$/, {
5202
+ const ExternalCliCommand = z18.string().max(128).regex(/^[A-Za-z0-9][A-Za-z0-9._+-]*$/, {
5133
5203
  message: "a command is an executable's basename (letters, digits, '.', '_', '+', '-'), never a path"
5134
5204
  });
5135
5205
  const ExternalCliHint = NonEmptyString3.max(2048);
5136
- const ExternalCliArguments = z17.array(ExternalCliArgument).max(64);
5206
+ const ExternalCliArguments = z18.array(ExternalCliArgument).max(64);
5137
5207
  const SignedOutMarker = ExternalCliArgument.refine((value) => value.trim() !== "", { message: "a signed-out marker needs text beyond whitespace" });
5138
- const PluginExternalCliConnect2 = z17.strictObject({
5208
+ const PluginExternalCliConnect2 = z18.strictObject({
5139
5209
  /** A basename the host finds on `PATH` (`osascript`, `wrangler`), never a path. */
5140
5210
  binary: ExternalCliCommand,
5141
- probe: z17.strictObject({
5211
+ probe: z18.strictObject({
5142
5212
  args: ExternalCliArguments.min(1),
5143
- timeoutMs: z17.number().int().min(1).max(12e4).optional(),
5213
+ timeoutMs: z18.number().int().min(1).max(12e4).optional(),
5144
5214
  /**
5145
5215
  * The CLI's own signed-out marker: text a failed probe's output (stderr, else stdout) contains
5146
5216
  * when the CLI is signed out. A failure that carries it is a sign-in problem, and only such a
@@ -5148,13 +5218,13 @@ function createManifestSchemas(canonical) {
5148
5218
  * unavailable. Required when `login` is declared, so a timeout never starts a sign-in. A list
5149
5219
  * is for a CLI with several signed-out messages; any one of them counts.
5150
5220
  */
5151
- signedOutMarker: z17.union([SignedOutMarker, z17.array(SignedOutMarker).min(1)]).optional()
5221
+ signedOutMarker: z18.union([SignedOutMarker, z18.array(SignedOutMarker).min(1)]).optional()
5152
5222
  }),
5153
5223
  /** The CLI's interactive sign-in. Absent: connect only probes and reports. */
5154
- login: z17.strictObject({
5224
+ login: z18.strictObject({
5155
5225
  args: ExternalCliArguments.min(1),
5156
- timeoutMs: z17.number().int().min(1).max(6e5).optional(),
5157
- pasteCode: z17.strictObject({
5226
+ timeoutMs: z18.number().int().min(1).max(6e5).optional(),
5227
+ pasteCode: z18.strictObject({
5158
5228
  /** The redeeming argv; the host appends the code as its last argument. */
5159
5229
  args: ExternalCliArguments.min(1),
5160
5230
  /** What the prompt says, for a person. */
@@ -5166,12 +5236,12 @@ function createManifestSchemas(canonical) {
5166
5236
  * for display, or hands it to an agent session that runs it behind the ordinary bash approval.
5167
5237
  * Absent for a binary the OS ships (`osascript`).
5168
5238
  */
5169
- install: z17.strictObject({
5239
+ install: z18.strictObject({
5170
5240
  command: ExternalCliCommand,
5171
5241
  args: ExternalCliArguments
5172
5242
  }).optional(),
5173
5243
  /** Prose for a person: `install` when the binary is missing, `login` when the probe fails. */
5174
- hints: z17.strictObject({
5244
+ hints: z18.strictObject({
5175
5245
  install: ExternalCliHint,
5176
5246
  login: ExternalCliHint
5177
5247
  })
@@ -5184,50 +5254,50 @@ function createManifestSchemas(canonical) {
5184
5254
  });
5185
5255
  }
5186
5256
  });
5187
- const PluginAuthSchemeExternalCli = z17.strictObject({
5257
+ const PluginAuthSchemeExternalCli = z18.strictObject({
5188
5258
  ...PluginAuthSchemeDescriptionFields,
5189
5259
  localId: LocalContributionId2,
5190
- kind: z17.literal("external-cli"),
5191
- scopes: z17.array(NonEmptyString3).optional(),
5260
+ kind: z18.literal("external-cli"),
5261
+ scopes: z18.array(NonEmptyString3).optional(),
5192
5262
  cli: PluginExternalCliConnect2.optional()
5193
5263
  });
5194
- const PluginAuthScheme2 = z17.discriminatedUnion("kind", [
5264
+ const PluginAuthScheme2 = z18.discriminatedUnion("kind", [
5195
5265
  PluginAuthSchemeOAuth2,
5196
5266
  PluginAuthSchemeApiKey,
5197
5267
  PluginAuthSchemeDelegated,
5198
5268
  PluginAuthSchemeExternalCli
5199
5269
  ]);
5200
- const PluginWebSessionProbe2 = z17.strictObject({
5270
+ const PluginWebSessionProbe2 = z18.strictObject({
5201
5271
  url: HttpsUrl2,
5202
5272
  /** Absent => `GET`. `POST` sends an empty JSON object body. */
5203
- method: z17.enum(["GET", "POST"]).optional(),
5204
- signedInStatuses: z17.array(SignedInStatusCode2).min(1)
5273
+ method: z18.enum(["GET", "POST"]).optional(),
5274
+ signedInStatuses: z18.array(SignedInStatusCode2).min(1)
5205
5275
  });
5206
- const PluginWebSessionDeclaration2 = z17.strictObject({
5276
+ const PluginWebSessionDeclaration2 = z18.strictObject({
5207
5277
  /** `required`: capabilities degrade without the site login; `recommended`: it only smooths UX. */
5208
- importance: z17.enum(["required", "recommended"]),
5278
+ importance: z18.enum(["required", "recommended"]),
5209
5279
  loginUrl: HttpsUrl2,
5210
- cookieDomains: z17.array(RegistrableDomain2).min(1),
5280
+ cookieDomains: z18.array(RegistrableDomain2).min(1),
5211
5281
  probe: PluginWebSessionProbe2,
5212
- oauthVenue: z17.enum(["embedded", "external"]),
5282
+ oauthVenue: z18.enum(["embedded", "external"]),
5213
5283
  /**
5214
5284
  * Where a page goes first when it opens in one of Bonsai's browser panes and this site login
5215
5285
  * is missing: a sign-in page that continues to the page. A template with `:email` and `:url`
5216
5286
  * (see `UriClaimTemplate`), on a host within `cookieDomains`.
5217
5287
  */
5218
- signInFirst: z17.string().optional()
5288
+ signInFirst: z18.string().optional()
5219
5289
  }).superRefine(refineWebSessionScopeConfined);
5220
- const PluginAuthService2 = z17.strictObject({
5290
+ const PluginAuthService2 = z18.strictObject({
5221
5291
  localId: LocalContributionId2,
5222
5292
  displayName: NonEmptyString3,
5223
5293
  /** One plain sentence on what connecting this service gives Bonsai. */
5224
5294
  summary: NonEmptyString3.optional(),
5225
- schemes: z17.array(PluginAuthScheme2).min(1),
5226
- purposes: z17.array(NonEmptyString3).min(1),
5295
+ schemes: z18.array(PluginAuthScheme2).min(1),
5296
+ purposes: z18.array(NonEmptyString3).min(1),
5227
5297
  webSession: PluginWebSessionDeclaration2.optional()
5228
5298
  });
5229
- const PluginAuthManifest2 = z17.strictObject({
5230
- services: z17.array(PluginAuthService2).optional()
5299
+ const PluginAuthManifest2 = z18.strictObject({
5300
+ services: z18.array(PluginAuthService2).optional()
5231
5301
  });
5232
5302
  function stripRetiredCompatibilityKeys(value) {
5233
5303
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
@@ -5238,17 +5308,17 @@ function createManifestSchemas(canonical) {
5238
5308
  delete remaining[key];
5239
5309
  return remaining;
5240
5310
  }
5241
- const PluginCompatibilityFields = z17.strictObject({
5242
- supportedProtocols: z17.array(KayPluginProtocolVersion).optional(),
5311
+ const PluginCompatibilityFields = z18.strictObject({
5312
+ supportedProtocols: z18.array(KayPluginProtocolVersion).optional(),
5243
5313
  minKayVersion: NonEmptyString3.optional(),
5244
5314
  sdk: NonEmptyString3.optional()
5245
5315
  });
5246
- const PluginCompatibilityManifest2 = canonical ? PluginCompatibilityFields : z17.preprocess(stripRetiredCompatibilityKeys, PluginCompatibilityFields);
5316
+ const PluginCompatibilityManifest2 = canonical ? PluginCompatibilityFields : z18.preprocess(stripRetiredCompatibilityKeys, PluginCompatibilityFields);
5247
5317
  const KayVersionString2 = NonEmptyString3.regex(SEMVER_PATTERN, {
5248
5318
  message: "version must be semver, for example 1.2.3"
5249
5319
  });
5250
- const KayPluginManifestV12 = z17.strictObject({
5251
- protocol: z17.literal(KAY_PLUGIN_PROTOCOL_VERSION),
5320
+ const KayPluginManifestV12 = z18.strictObject({
5321
+ protocol: z18.literal(KAY_PLUGIN_PROTOCOL_VERSION),
5252
5322
  id: PluginId2,
5253
5323
  displayName: NonEmptyString3,
5254
5324
  version: KayVersionString2,
@@ -5276,8 +5346,12 @@ function createManifestSchemas(canonical) {
5276
5346
  icon: PackageAssetPath2.optional(),
5277
5347
  iconDark: PackageAssetPath2.optional(),
5278
5348
  namespace: PluginNamespace2.optional(),
5279
- targets: z17.strictObject({
5280
- kay: z17.strictObject({
5349
+ workers: z18.array(z18.strictObject({
5350
+ localId: LocalContributionId2,
5351
+ module: PackageAssetPath2
5352
+ })).optional(),
5353
+ targets: z18.strictObject({
5354
+ kay: z18.strictObject({
5281
5355
  agent: KayAgentTargetManifest2.optional(),
5282
5356
  app: KayAppTargetManifest2.optional(),
5283
5357
  ui: KayUiTargetManifest2.optional()
@@ -5285,8 +5359,9 @@ function createManifestSchemas(canonical) {
5285
5359
  }).optional(),
5286
5360
  config: PluginConfigManifest2.optional(),
5287
5361
  storage: PluginStorageManifest2.optional(),
5288
- workloadPurposes: z17.array(PluginWorkloadPurpose).optional(),
5289
- shellCommands: z17.array(PluginShellCommand).optional(),
5362
+ workloadPurposes: z18.array(PluginWorkloadPurpose).optional(),
5363
+ shellCommands: z18.array(PluginShellCommand).optional(),
5364
+ projectDirectories: PluginProjectDirectories.optional(),
5290
5365
  auth: PluginAuthManifest2.optional(),
5291
5366
  permissions: PluginPermissionManifest2.optional(),
5292
5367
  compatibility: PluginCompatibilityManifest2.optional(),
@@ -5296,17 +5371,18 @@ function createManifestSchemas(canonical) {
5296
5371
  * schemes then report `ownedByBonsai`. Honoured only for a plugin that ships with Bonsai: the
5297
5372
  * host reads any other plugin's flag as false. Absent => false.
5298
5373
  */
5299
- ownedByBonsai: z17.boolean().optional(),
5374
+ ownedByBonsai: z18.boolean().optional(),
5300
5375
  /**
5301
5376
  * Explicit plugin-level dependencies - other plugins this plugin requires to be present in the
5302
5377
  * composed roster. At composition time the runtime checks each id against the accepted
5303
5378
  * registration list and derives a provenance-complete dependency graph (together with implicit
5304
5379
  * auth-service edges from `consumesAuthServices`). Absent => no explicit dependencies.
5305
5380
  */
5306
- dependencies: z17.strictObject({
5307
- plugins: z17.array(PluginId2).optional()
5381
+ dependencies: z18.strictObject({
5382
+ plugins: z18.array(PluginId2).optional()
5308
5383
  }).optional()
5309
5384
  }).superRefine((manifest, ctx) => {
5385
+ reportDuplicateLocalIds(ctx, ["workers"], manifest.workers, "worker");
5310
5386
  const sharedWith = manifest.storage?.dataDir?.sharedWith;
5311
5387
  if (sharedWith !== void 0 && (!manifest.storage?.dataDir?.enabled || sharedWith === manifest.id || !manifest.dependencies?.plugins?.includes(sharedWith))) {
5312
5388
  ctx.addIssue({
@@ -5471,7 +5547,7 @@ function createManifestSchemas(canonical) {
5471
5547
  index,
5472
5548
  "badge"
5473
5549
  ];
5474
- if (!declaredRowsStores.has(entry.badge.source)) {
5550
+ if (typeof entry.badge.source === "string" && !declaredRowsStores.has(entry.badge.source)) {
5475
5551
  ctx.addIssue({
5476
5552
  code: "custom",
5477
5553
  path: [...path, "source"],
@@ -5598,6 +5674,22 @@ function createManifestSchemas(canonical) {
5598
5674
  ...manifest.targets?.kay?.agent?.contributes?.uriModules ?? [],
5599
5675
  ...manifest.targets?.kay?.app?.contributes?.uriModules ?? []
5600
5676
  ].flatMap((module) => module.schemes));
5677
+ if (manifest.projectDirectories !== void 0) {
5678
+ if (!endpointIds.has(manifest.projectDirectories.endpoint)) {
5679
+ ctx.addIssue({
5680
+ code: "custom",
5681
+ path: ["projectDirectories", "endpoint"],
5682
+ message: "Project directories must name an endpoint declared by this plugin's app target."
5683
+ });
5684
+ }
5685
+ if (!servedSchemes.has(manifest.projectDirectories.scheme)) {
5686
+ ctx.addIssue({
5687
+ code: "custom",
5688
+ path: ["projectDirectories", "scheme"],
5689
+ message: "Project directories must name a scheme this plugin serves."
5690
+ });
5691
+ }
5692
+ }
5601
5693
  for (const [index, type] of types.entries()) {
5602
5694
  if ((type.directory !== void 0 || type.handover === true) && manifest.targets?.kay?.agent?.familyFolder?.scope !== "root") {
5603
5695
  ctx.addIssue({
@@ -6182,15 +6274,21 @@ function createManifestSchemas(canonical) {
6182
6274
  });
6183
6275
  }
6184
6276
  }
6185
- for (const [appIndex, app] of (manifest.targets?.kay?.ui?.contributes?.apps ?? []).entries()) {
6277
+ const endpointSurfaces = (manifest.targets?.kay?.ui?.contributes?.apps ?? []).map((app, index) => ({
6278
+ id: app.localId,
6279
+ kind: "apps",
6280
+ index,
6281
+ capabilities: app.capabilities
6282
+ }));
6283
+ for (const app of endpointSurfaces) {
6186
6284
  for (const [endpointIndex, endpoint] of (app.capabilities?.endpoints ?? []).entries()) {
6187
6285
  const path = [
6188
6286
  "targets",
6189
6287
  "kay",
6190
6288
  "ui",
6191
6289
  "contributes",
6192
- "apps",
6193
- appIndex,
6290
+ app.kind,
6291
+ app.index,
6194
6292
  "capabilities",
6195
6293
  "endpoints",
6196
6294
  endpointIndex
@@ -6201,13 +6299,13 @@ function createManifestSchemas(canonical) {
6201
6299
  ctx.addIssue({
6202
6300
  code: "custom",
6203
6301
  path,
6204
- message: `ui app ${app.localId} references unknown endpoint ${endpoint}`
6302
+ message: `ui app ${app.id} references unknown endpoint ${endpoint}`
6205
6303
  });
6206
6304
  } else if (!invokedUiEndpoints.has(endpoint)) {
6207
6305
  ctx.addIssue({
6208
6306
  code: "custom",
6209
6307
  path,
6210
- message: `ui app ${app.localId} endpoint ${endpoint} requires a kay.ui invoke grant`
6308
+ message: `ui app ${app.id} endpoint ${endpoint} requires a kay.ui invoke grant`
6211
6309
  });
6212
6310
  }
6213
6311
  }
@@ -6497,7 +6595,7 @@ function pushContributionIds(output, path, items) {
6497
6595
  }
6498
6596
 
6499
6597
  // packages/plugin-protocol/dist/plugin-directory-verdict.js
6500
- import { z as z19 } from "zod";
6598
+ import { z as z20 } from "zod";
6501
6599
 
6502
6600
  // packages/plugin-protocol/dist/plugin-load-diagnostic.js
6503
6601
  var PLUGIN_DIAGNOSTIC_MESSAGE_CAP = 300;
@@ -6506,14 +6604,14 @@ function boundPluginDiagnosticMessage(message) {
6506
6604
  }
6507
6605
 
6508
6606
  // packages/plugin-protocol/dist/resolved-contract.js
6509
- import { z as z18 } from "zod";
6607
+ import { z as z19 } from "zod";
6510
6608
  function createResolvedContractSchemas(canonical) {
6511
6609
  const { PluginEventLocalId: PluginEventLocalId2 } = canonical ? canonicalPluginEventSchemas : plugin_events_exports;
6512
6610
  const { ApprovalTypeContribution: ApprovalTypeContribution2, KayUiAppHostCapability: KayUiAppHostCapability2, McpServerAuthMode: McpServerAuthMode2, McpServerUrl: McpServerUrl2, PluginContributionKind: PluginContributionKindSchema, ReferenceOpenBehavior: ReferenceOpenBehavior2, ReferencePresentationUriPattern: ReferencePresentationUriPattern2, ReferencePresentationAccountLinks: ReferencePresentationAccountLinks2, ReferencePresentationAddress: ReferencePresentationAddress2, ReferencePresentationUrlClaim: ReferencePresentationUrlClaim2, ReferencePresentationVariants: ReferencePresentationVariants2, ReferencePresentationWords: ReferencePresentationWords2, UriModuleFacts: UriModuleFacts2, WhiteboardTypeContribution: WhiteboardTypeContribution2 } = canonical ? canonicalContributionSchemas : contributions_exports;
6513
6611
  const { FileExtensionToken: FileExtensionToken2, GitBasicAuthUser: GitBasicAuthUser2, GitHostName: GitHostName2, GlobalContributionId: GlobalContributionId2, HttpsUrl: HttpsUrl2, LocalContributionId: LocalContributionId2, MimeTypeString: MimeTypeString2, NonEmptyString: NonEmptyString3, PackageAssetPath: PackageAssetPath2, PluginId: PluginId2, PluginNamespace: PluginNamespace2, PluginToolName: PluginToolName2, RegistrableDomain: RegistrableDomain2, SignedInStatusCode: SignedInStatusCode2, TargetEntrypoint: TargetEntrypoint2, UriScheme: UriScheme2 } = canonical ? canonicalCommonSchemas : common_exports;
6514
6612
  const { PluginExternalCliConnect: PluginExternalCliConnect2, PluginOAuthClientSupplier: PluginOAuthClientSupplier2 } = canonical ? canonicalManifestSchemas : manifest_exports;
6515
6613
  const { ResolvedPluginGrants: ResolvedPluginGrants2 } = canonical ? canonicalPermissionSchemas : permissions_exports;
6516
- const ResolvedPluginContributionId2 = z18.strictObject({
6614
+ const ResolvedPluginContributionId2 = z19.strictObject({
6517
6615
  target: PluginTargetName,
6518
6616
  kind: PluginContributionKindSchema,
6519
6617
  localId: PluginEventLocalId2,
@@ -6527,55 +6625,55 @@ function createResolvedContractSchemas(canonical) {
6527
6625
  });
6528
6626
  }
6529
6627
  });
6530
- const ResolvedKayToolId = z18.strictObject({
6628
+ const ResolvedKayToolId = z19.strictObject({
6531
6629
  localId: LocalContributionId2,
6532
6630
  globalId: GlobalContributionId2,
6533
6631
  toolName: PluginToolName2
6534
6632
  });
6535
- const ResolvedKayAgentTool2 = z18.strictObject({
6633
+ const ResolvedKayAgentTool2 = z19.strictObject({
6536
6634
  ...ResolvedKayToolId.shape,
6537
6635
  displayName: NonEmptyString3.optional(),
6538
6636
  description: NonEmptyString3.optional(),
6539
6637
  parameters: JsonSchema.optional(),
6540
- executionMode: z18.enum(["sequential", "parallel"]).optional(),
6638
+ executionMode: z19.enum(["sequential", "parallel"]).optional(),
6541
6639
  promptSnippet: NonEmptyString3.optional(),
6542
- promptGuidelines: z18.array(NonEmptyString3).optional(),
6543
- requiresAuth: z18.strictObject({
6640
+ promptGuidelines: z19.array(NonEmptyString3).optional(),
6641
+ requiresAuth: z19.strictObject({
6544
6642
  serviceId: GlobalContributionId2,
6545
6643
  schemeId: GlobalContributionId2.optional()
6546
6644
  }).optional(),
6547
6645
  permission: canonical ? canonicalContributionSchemas.ToolPermission.optional() : ToolPermission.optional()
6548
6646
  });
6549
6647
  const ResolvedKayAppTool2 = ResolvedKayAgentTool2.omit({ requiresAuth: true });
6550
- const ResolvedKayAppDataSource2 = z18.strictObject({
6648
+ const ResolvedKayAppDataSource2 = z19.strictObject({
6551
6649
  localId: LocalContributionId2,
6552
6650
  globalId: GlobalContributionId2,
6553
- scope: z18.enum(["runtime", "account", "session"]),
6554
- snapshot: z18.strictObject({
6555
- version: z18.number().int().positive(),
6556
- schema: z18.record(z18.string(), z18.unknown())
6651
+ scope: z19.enum(["runtime", "account", "session"]),
6652
+ snapshot: z19.strictObject({
6653
+ version: z19.number().int().positive(),
6654
+ schema: z19.record(z19.string(), z19.unknown())
6557
6655
  }),
6558
- change: z18.strictObject({
6559
- version: z18.number().int().positive(),
6560
- schema: z18.record(z18.string(), z18.unknown()),
6561
- semantics: z18.discriminatedUnion("kind", [
6562
- z18.strictObject({ kind: z18.literal("incremental") }),
6563
- z18.strictObject({
6564
- kind: z18.literal("snapshot-replacement"),
6565
- maxEncodedBytes: z18.number().int().positive(),
6656
+ change: z19.strictObject({
6657
+ version: z19.number().int().positive(),
6658
+ schema: z19.record(z19.string(), z19.unknown()),
6659
+ semantics: z19.discriminatedUnion("kind", [
6660
+ z19.strictObject({ kind: z19.literal("incremental") }),
6661
+ z19.strictObject({
6662
+ kind: z19.literal("snapshot-replacement"),
6663
+ maxEncodedBytes: z19.number().int().positive(),
6566
6664
  rationale: pluginString(canonical).min(1).max(1024)
6567
6665
  })
6568
6666
  ]).optional()
6569
6667
  }),
6570
6668
  read: AppDataSourceRead.optional(),
6571
- messageDraft: z18.strictObject({ schemes: z18.array(UriScheme2).min(1) }).optional(),
6572
- store: z18.discriminatedUnion("shape", [
6573
- z18.strictObject({
6574
- shape: z18.literal("rows"),
6575
- rowsField: z18.string().min(1),
6576
- key: z18.array(z18.string().min(1)).min(1)
6669
+ messageDraft: z19.strictObject({ schemes: z19.array(UriScheme2).min(1) }).optional(),
6670
+ store: z19.discriminatedUnion("shape", [
6671
+ z19.strictObject({
6672
+ shape: z19.literal("rows"),
6673
+ rowsField: z19.string().min(1),
6674
+ key: z19.array(z19.string().min(1)).min(1)
6577
6675
  }),
6578
- z18.strictObject({ shape: z18.literal("value") })
6676
+ z19.strictObject({ shape: z19.literal("value") })
6579
6677
  ]).optional()
6580
6678
  }).superRefine((source, ctx) => {
6581
6679
  if (source.read !== void 0 && source.scope !== "session") {
@@ -6595,122 +6693,123 @@ function createResolvedContractSchemas(canonical) {
6595
6693
  /** The auth service that module signs in through, whose accounts a card may send from. */
6596
6694
  authService: GlobalContributionId2.optional()
6597
6695
  });
6598
- const ResolvedPluginCard2 = z18.strictObject({
6696
+ const ResolvedPluginCard2 = z19.strictObject({
6599
6697
  localId: LocalContributionId2,
6600
6698
  globalId: GlobalContributionId2,
6601
6699
  pluginId: PluginId2,
6602
6700
  description: NonEmptyString3,
6603
6701
  inputs: JsonSchema,
6604
- readEndpoint: z18.strictObject({
6702
+ readEndpoint: z19.strictObject({
6605
6703
  localId: LocalContributionId2,
6606
6704
  globalId: GlobalContributionId2
6607
6705
  }),
6608
- submitEndpoint: z18.strictObject({
6706
+ submitEndpoint: z19.strictObject({
6609
6707
  localId: LocalContributionId2,
6610
6708
  globalId: GlobalContributionId2
6611
6709
  }),
6612
6710
  authService: GlobalContributionId2.optional()
6613
6711
  });
6614
- const ResolvedKayAppWorkflow2 = z18.strictObject({
6712
+ const ResolvedKayAppWorkflow2 = z19.strictObject({
6615
6713
  localId: LocalContributionId2,
6616
6714
  globalId: GlobalContributionId2,
6617
6715
  name: NonEmptyString3,
6618
6716
  description: NonEmptyString3,
6619
- everyMs: z18.number().int().positive(),
6620
- auth: z18.strictObject({
6717
+ everyMs: z19.number().int().positive(),
6718
+ auth: z19.strictObject({
6621
6719
  serviceId: GlobalContributionId2,
6622
6720
  schemeId: GlobalContributionId2,
6623
- scopes: z18.array(NonEmptyString3).min(1).optional()
6721
+ scopes: z19.array(NonEmptyString3).min(1).optional()
6624
6722
  }).optional()
6625
6723
  });
6626
6724
  const ResolvedKayAppWhiteboardType2 = WhiteboardTypeContribution2.safeExtend({
6627
6725
  globalId: GlobalContributionId2
6628
6726
  });
6629
- const ResolvedKayAppMcpServer2 = z18.strictObject({
6727
+ const ResolvedKayAppMcpServer2 = z19.strictObject({
6630
6728
  name: LocalContributionId2,
6631
6729
  pluginId: PluginId2,
6632
6730
  url: McpServerUrl2,
6633
6731
  auth: McpServerAuthMode2,
6634
6732
  authServiceId: GlobalContributionId2.optional()
6635
6733
  });
6636
- const ResolvedKayAgentUriModule2 = z18.strictObject({
6734
+ const ResolvedKayAgentUriModule2 = z19.strictObject({
6637
6735
  localId: LocalContributionId2,
6736
+ adapterId: z19.string().min(1).optional(),
6638
6737
  globalId: GlobalContributionId2,
6639
- schemes: z18.array(UriScheme2).min(1),
6738
+ schemes: z19.array(UriScheme2).min(1),
6640
6739
  displayName: NonEmptyString3.optional(),
6641
6740
  authServiceId: GlobalContributionId2.optional(),
6642
6741
  /** Mirrors `UriModuleContribution.authScheme`; a local ref takes the plugin's namespace. */
6643
6742
  authSchemeId: GlobalContributionId2.optional(),
6644
6743
  /** Mirrors `UriModuleContribution.knownResources` (host-side recording opt-in). */
6645
- knownResources: z18.literal(true).optional(),
6744
+ knownResources: z19.literal(true).optional(),
6646
6745
  /** Mirrors `UriModuleContribution.describesOperations`. */
6647
- describesOperations: z18.literal(true).optional(),
6746
+ describesOperations: z19.literal(true).optional(),
6648
6747
  /** Mirrors `UriModuleContribution.looksUpWebLinks`. */
6649
- looksUpWebLinks: z18.literal(true).optional(),
6748
+ looksUpWebLinks: z19.literal(true).optional(),
6650
6749
  ...UriModuleFacts2.shape
6651
6750
  });
6652
- const ResolvedKayAgentArtifactUriModule2 = z18.strictObject({
6751
+ const ResolvedKayAgentArtifactUriModule2 = z19.strictObject({
6653
6752
  localId: LocalContributionId2,
6654
6753
  globalId: GlobalContributionId2,
6655
6754
  scheme: UriScheme2,
6656
- editable: z18.boolean(),
6657
- listable: z18.boolean(),
6658
- deletable: z18.boolean(),
6659
- appendable: z18.boolean(),
6660
- storageScope: z18.enum(["session", "family"])
6755
+ editable: z19.boolean(),
6756
+ listable: z19.boolean(),
6757
+ deletable: z19.boolean(),
6758
+ appendable: z19.boolean(),
6759
+ storageScope: z19.enum(["session", "family"])
6661
6760
  });
6662
- const ResolvedKayAgentEntityResolver2 = z18.strictObject({
6761
+ const ResolvedKayAgentEntityResolver2 = z19.strictObject({
6663
6762
  localId: LocalContributionId2,
6664
6763
  globalId: GlobalContributionId2,
6665
6764
  displayName: NonEmptyString3.optional(),
6666
6765
  uriModule: GlobalContributionId2,
6667
- entityTypes: z18.array(NonEmptyString3).min(1),
6766
+ entityTypes: z19.array(NonEmptyString3).min(1),
6668
6767
  uriHint: NonEmptyString3
6669
6768
  });
6670
- const ResolvedKayAgentGitHostClaim2 = z18.strictObject({
6769
+ const ResolvedKayAgentGitHostClaim2 = z19.strictObject({
6671
6770
  host: GitHostName2,
6672
6771
  authServiceId: GlobalContributionId2,
6673
6772
  /** Manifest-declared order; the clone ladder tries them in sequence. */
6674
- authSchemeIds: z18.array(GlobalContributionId2).min(1),
6773
+ authSchemeIds: z19.array(GlobalContributionId2).min(1),
6675
6774
  /** Non-secret display copy for the claiming service, for clone failure text. */
6676
- authServiceDisplayName: z18.string(),
6775
+ authServiceDisplayName: z19.string(),
6677
6776
  basicAuthUser: GitBasicAuthUser2
6678
6777
  });
6679
- const ResolvedKayAgentConverter2 = z18.strictObject({
6778
+ const ResolvedKayAgentConverter2 = z19.strictObject({
6680
6779
  localId: LocalContributionId2,
6681
6780
  globalId: GlobalContributionId2,
6682
6781
  description: NonEmptyString3.optional(),
6683
- mimeTypes: z18.array(MimeTypeString2).min(1),
6684
- extensions: z18.array(FileExtensionToken2).min(1).optional()
6782
+ mimeTypes: z19.array(MimeTypeString2).min(1),
6783
+ extensions: z19.array(FileExtensionToken2).min(1).optional()
6685
6784
  });
6686
6785
  const ResolvedReferencePresentationUrlClaim = ReferencePresentationUrlClaim2.extend({
6687
- brandIcon: z18.string().max(64 * 1024).optional()
6786
+ brandIcon: z19.string().max(64 * 1024).optional()
6688
6787
  });
6689
- const ResolvedReferencePresentation2 = z18.strictObject({
6788
+ const ResolvedReferencePresentation2 = z19.strictObject({
6690
6789
  localId: LocalContributionId2,
6691
6790
  globalId: GlobalContributionId2,
6692
6791
  uriModule: GlobalContributionId2.optional(),
6693
6792
  /** The schemes this presentation is about: its `scheme`, or its module's. */
6694
- schemes: z18.array(UriScheme2).min(1).optional(),
6793
+ schemes: z19.array(UriScheme2).min(1).optional(),
6695
6794
  /** The module's `displayName`: the source's name in a row. */
6696
6795
  displayName: NonEmptyString3.optional(),
6697
6796
  /** The module's auth service, qualified: whose accounts `accountLinks` reads. */
6698
6797
  authService: GlobalContributionId2.optional(),
6699
6798
  accountLinks: ReferencePresentationAccountLinks2.optional(),
6700
- addresses: z18.array(ReferencePresentationAddress2).min(1).optional(),
6799
+ addresses: z19.array(ReferencePresentationAddress2).min(1).optional(),
6701
6800
  /** Comes with `open`. A presentation with neither only words its module's addresses. */
6702
6801
  resourceKind: NonEmptyString3.optional(),
6703
6802
  open: ReferenceOpenBehavior2.optional(),
6704
6803
  /** MIME-specific resource kinds; absent keys use the base presentation. */
6705
6804
  variants: ReferencePresentationVariants2.optional(),
6706
- claims: z18.array(ResolvedReferencePresentationUrlClaim).optional(),
6707
- tooltip: z18.strictObject({
6805
+ claims: z19.array(ResolvedReferencePresentationUrlClaim).optional(),
6806
+ tooltip: z19.strictObject({
6708
6807
  app: GlobalContributionId2,
6709
6808
  pattern: ReferencePresentationUriPattern2
6710
6809
  }).optional(),
6711
6810
  words: ReferencePresentationWords2.optional()
6712
6811
  });
6713
- const ResolvedPluginProvisioningRequirement2 = z18.strictObject({
6812
+ const ResolvedPluginProvisioningRequirement2 = z19.strictObject({
6714
6813
  id: LocalContributionId2,
6715
6814
  displayName: NonEmptyString3,
6716
6815
  description: NonEmptyString3,
@@ -6720,15 +6819,15 @@ function createResolvedContractSchemas(canonical) {
6720
6819
  * URL degrades to "Reconnect" in the UI instead of a broken link.
6721
6820
  */
6722
6821
  remediationUrl: HttpsUrl2.optional(),
6723
- probe: z18.strictObject({
6822
+ probe: z19.strictObject({
6724
6823
  url: HttpsUrl2,
6725
- method: z18.enum(["GET"]),
6726
- verdictStatuses: z18.array(SignedInStatusCode2).min(1),
6824
+ method: z19.enum(["GET"]),
6825
+ verdictStatuses: z19.array(SignedInStatusCode2).min(1),
6727
6826
  nonEmptyArrayAt: NonEmptyString3.optional()
6728
6827
  })
6729
6828
  });
6730
6829
  const ResolvedProvisioningField = {
6731
- provisioning: z18.array(ResolvedPluginProvisioningRequirement2).optional()
6830
+ provisioning: z19.array(ResolvedPluginProvisioningRequirement2).optional()
6732
6831
  };
6733
6832
  const ResolvedPluginAuthSchemeDescriptionFields = {
6734
6833
  displayName: NonEmptyString3.optional(),
@@ -6740,118 +6839,120 @@ function createResolvedContractSchemas(canonical) {
6740
6839
  ...ResolvedPluginAuthSchemeDescriptionFields,
6741
6840
  localId: LocalContributionId2,
6742
6841
  globalId: GlobalContributionId2,
6743
- kind: z18.literal("oauth2"),
6744
- scopes: z18.array(z18.string()).optional(),
6842
+ kind: z19.literal("oauth2"),
6843
+ scopes: z19.array(z19.string()).optional(),
6844
+ connectScopes: z19.array(NonEmptyString3).optional(),
6745
6845
  authorizationUrl: HttpsUrl2,
6746
6846
  tokenUrl: HttpsUrl2,
6747
- extraAuthorizeParams: z18.record(z18.string(), z18.string()).optional()
6847
+ extraAuthorizeParams: z19.record(z19.string(), z19.string()).optional(),
6848
+ extraAuthorizeParamsWhenAccountHeld: z19.record(NonEmptyString3, z19.string()).optional()
6748
6849
  };
6749
- const ResolvedPluginAuthSchemeOAuthPkce = z18.strictObject({
6850
+ const ResolvedPluginAuthSchemeOAuthPkce = z19.strictObject({
6750
6851
  ...ResolvedPluginAuthSchemeOAuthBase,
6751
- exchange: z18.literal("pkce"),
6852
+ exchange: z19.literal("pkce"),
6752
6853
  byoocProfile: PluginByoocProfile.optional(),
6753
- clientSuppliers: z18.array(PluginOAuthClientSupplier2).nonempty(),
6854
+ clientSuppliers: z19.array(PluginOAuthClientSupplier2).nonempty(),
6754
6855
  clientId: NonEmptyString3.optional(),
6755
6856
  clientSecret: NonEmptyString3.optional(),
6756
- account: z18.literal("lookup").optional()
6857
+ account: z19.literal("lookup").optional()
6757
6858
  });
6758
- const ResolvedPluginAuthSchemeOAuthConfidential = z18.strictObject({
6859
+ const ResolvedPluginAuthSchemeOAuthConfidential = z19.strictObject({
6759
6860
  ...ResolvedPluginAuthSchemeOAuthBase,
6760
- exchange: z18.literal("confidential"),
6761
- clientSuppliers: z18.tuple([z18.literal("kay")]),
6762
- account: z18.enum(["lookup", "sign-in"])
6861
+ exchange: z19.literal("confidential"),
6862
+ clientSuppliers: z19.tuple([z19.literal("kay")]),
6863
+ account: z19.enum(["lookup", "sign-in"])
6763
6864
  });
6764
- const ResolvedPluginAuthSchemeOAuth2 = z18.discriminatedUnion("exchange", [
6865
+ const ResolvedPluginAuthSchemeOAuth2 = z19.discriminatedUnion("exchange", [
6765
6866
  ResolvedPluginAuthSchemeOAuthPkce,
6766
6867
  ResolvedPluginAuthSchemeOAuthConfidential
6767
6868
  ]);
6768
- const ResolvedPluginAuthSchemeApiKey = z18.strictObject({
6869
+ const ResolvedPluginAuthSchemeApiKey = z19.strictObject({
6769
6870
  ...ResolvedProvisioningField,
6770
6871
  ...ResolvedPluginAuthSchemeDescriptionFields,
6771
6872
  localId: LocalContributionId2,
6772
6873
  globalId: GlobalContributionId2,
6773
- kind: z18.literal("api-key"),
6774
- scopes: z18.array(z18.string()).optional(),
6874
+ kind: z19.literal("api-key"),
6875
+ scopes: z19.array(z19.string()).optional(),
6775
6876
  /** Resolution applies the manifest's default, "<service name> API key". */
6776
6877
  inputLabel: NonEmptyString3,
6777
- fields: z18.array(z18.strictObject({ id: z18.string(), label: z18.string() })).optional(),
6778
- setup: z18.strictObject({ instructions: z18.string(), url: HttpsUrl2 }).optional(),
6779
- account: z18.literal("lookup").optional()
6878
+ fields: z19.array(z19.strictObject({ id: z19.string(), label: z19.string() })).optional(),
6879
+ setup: z19.strictObject({ instructions: z19.string(), url: HttpsUrl2 }).optional(),
6880
+ account: z19.literal("lookup").optional()
6780
6881
  });
6781
- const ResolvedPluginAuthSchemeDelegated = z18.strictObject({
6882
+ const ResolvedPluginAuthSchemeDelegated = z19.strictObject({
6782
6883
  ...ResolvedPluginAuthSchemeDescriptionFields,
6783
6884
  localId: LocalContributionId2,
6784
6885
  globalId: GlobalContributionId2,
6785
- kind: z18.literal("delegated"),
6786
- scopes: z18.array(z18.string()).optional()
6886
+ kind: z19.literal("delegated"),
6887
+ scopes: z19.array(z19.string()).optional()
6787
6888
  });
6788
- const ResolvedPluginAuthSchemeExternalCli = z18.strictObject({
6889
+ const ResolvedPluginAuthSchemeExternalCli = z19.strictObject({
6789
6890
  ...ResolvedPluginAuthSchemeDescriptionFields,
6790
6891
  localId: LocalContributionId2,
6791
6892
  globalId: GlobalContributionId2,
6792
- kind: z18.literal("external-cli"),
6793
- scopes: z18.array(z18.string()).optional(),
6893
+ kind: z19.literal("external-cli"),
6894
+ scopes: z19.array(z19.string()).optional(),
6794
6895
  /** The manifest's connect facts, verbatim. */
6795
6896
  cli: PluginExternalCliConnect2.optional()
6796
6897
  });
6797
- const ResolvedPluginAuthScheme2 = z18.discriminatedUnion("kind", [
6898
+ const ResolvedPluginAuthScheme2 = z19.discriminatedUnion("kind", [
6798
6899
  ResolvedPluginAuthSchemeOAuth2,
6799
6900
  ResolvedPluginAuthSchemeApiKey,
6800
6901
  ResolvedPluginAuthSchemeDelegated,
6801
6902
  ResolvedPluginAuthSchemeExternalCli
6802
6903
  ]);
6803
- const ResolvedPluginWebSession2 = z18.strictObject({
6804
- importance: z18.enum(["required", "recommended"]),
6904
+ const ResolvedPluginWebSession2 = z19.strictObject({
6905
+ importance: z19.enum(["required", "recommended"]),
6805
6906
  loginUrl: HttpsUrl2,
6806
- cookieDomains: z18.array(RegistrableDomain2).min(1),
6807
- probe: z18.strictObject({
6907
+ cookieDomains: z19.array(RegistrableDomain2).min(1),
6908
+ probe: z19.strictObject({
6808
6909
  url: HttpsUrl2,
6809
- method: z18.enum(["GET", "POST"]),
6810
- signedInStatuses: z18.array(SignedInStatusCode2).min(1)
6910
+ method: z19.enum(["GET", "POST"]),
6911
+ signedInStatuses: z19.array(SignedInStatusCode2).min(1)
6811
6912
  }),
6812
- oauthVenue: z18.enum(["embedded", "external"]),
6813
- signInFirst: z18.string().optional()
6913
+ oauthVenue: z19.enum(["embedded", "external"]),
6914
+ signInFirst: z19.string().optional()
6814
6915
  }).superRefine(refineWebSessionScopeConfined);
6815
- const ResolvedPluginAuthService2 = z18.strictObject({
6916
+ const ResolvedPluginAuthService2 = z19.strictObject({
6816
6917
  localId: LocalContributionId2,
6817
6918
  globalId: GlobalContributionId2,
6818
- displayName: z18.string(),
6819
- summary: z18.string().optional(),
6820
- schemes: z18.array(ResolvedPluginAuthScheme2).min(1),
6821
- purposes: z18.array(z18.string()).min(1),
6919
+ displayName: z19.string(),
6920
+ summary: z19.string().optional(),
6921
+ schemes: z19.array(ResolvedPluginAuthScheme2).min(1),
6922
+ purposes: z19.array(z19.string()).min(1),
6822
6923
  /** The service's browser half, when the manifest declares one. */
6823
6924
  webSession: ResolvedPluginWebSession2.optional()
6824
6925
  });
6825
- const ResolvedKayUiAppEndpointCapability2 = z18.union([
6826
- z18.strictObject({
6926
+ const ResolvedKayUiAppEndpointCapability2 = z19.union([
6927
+ z19.strictObject({
6827
6928
  localId: LocalContributionId2,
6828
6929
  globalId: GlobalContributionId2
6829
6930
  }),
6830
- z18.strictObject({ pluginId: PluginId2, localId: LocalContributionId2 })
6931
+ z19.strictObject({ pluginId: PluginId2, localId: LocalContributionId2 })
6831
6932
  ]);
6832
- const ResolvedKayUiApp2 = z18.strictObject({
6933
+ const ResolvedKayUiApp2 = z19.strictObject({
6833
6934
  localId: LocalContributionId2,
6834
6935
  globalId: GlobalContributionId2,
6835
6936
  displayName: NonEmptyString3,
6836
- contextOnly: z18.literal(true).optional(),
6937
+ contextOnly: z19.literal(true).optional(),
6837
6938
  description: NonEmptyString3.optional(),
6838
6939
  icon: PackageAssetPath2.optional(),
6839
- runtime: z18.literal("kay.react-app.v1"),
6840
- sdk: z18.strictObject({ range: NonEmptyString3 }),
6940
+ runtime: z19.literal("kay.react-app.v1"),
6941
+ sdk: z19.strictObject({ range: NonEmptyString3 }),
6841
6942
  entrypoint: TargetEntrypoint2,
6842
- styles: z18.array(PackageAssetPath2).optional(),
6843
- assets: z18.array(PackageAssetPath2).optional(),
6844
- capabilities: z18.strictObject({
6845
- endpoints: z18.array(ResolvedKayUiAppEndpointCapability2).optional(),
6846
- host: z18.array(KayUiAppHostCapability2).optional(),
6847
- feeds: z18.array((canonical ? canonicalContributionSchemas : contributions_exports).UiAppCapabilityReference).optional()
6943
+ styles: z19.array(PackageAssetPath2).optional(),
6944
+ assets: z19.array(PackageAssetPath2).optional(),
6945
+ capabilities: z19.strictObject({
6946
+ endpoints: z19.array(ResolvedKayUiAppEndpointCapability2).optional(),
6947
+ host: z19.array(KayUiAppHostCapability2).optional(),
6948
+ feeds: z19.array((canonical ? canonicalContributionSchemas : contributions_exports).UiAppCapabilityReference).optional()
6848
6949
  }).optional()
6849
6950
  });
6850
- const ResolvedPluginContractV12 = z18.strictObject({
6851
- protocol: z18.literal("kay.plugin.v1"),
6951
+ const ResolvedPluginContractV12 = z19.strictObject({
6952
+ protocol: z19.literal("kay.plugin.v1"),
6852
6953
  pluginId: PluginId2,
6853
6954
  namespace: PluginNamespace2,
6854
- contributions: z18.array(ResolvedPluginContributionId2),
6955
+ contributions: z19.array(ResolvedPluginContributionId2),
6855
6956
  // The deduplicated set of qualified (dotted) external auth-service ids this
6856
6957
  // plugin references, from agent uriModule, tool and cliBinding
6857
6958
  // `authService` refs, card sign-in refs, and auth-grant `service` refs. Always present - a plugin
@@ -6859,39 +6960,44 @@ function createResolvedContractSchemas(canonical) {
6859
6960
  // is a recorded dependency, not a resolution: there is no runtime plugin
6860
6961
  // loader in v1, so nothing here verifies the reference resolves within a
6861
6962
  // composed roster (a composition-time concern owned elsewhere).
6862
- consumesAuthServices: z18.array(GlobalContributionId2),
6963
+ consumesAuthServices: z19.array(GlobalContributionId2),
6863
6964
  // The explicit plugin-level dependency ids declared in `dependencies.plugins` on the manifest,
6864
6965
  // deduped and validated at parse time. Always present; a plugin with no explicit dependencies
6865
6966
  // carries an empty array. Composition checks each id against the accepted roster and derives the
6866
6967
  // full dependency graph together with auth-inferred edges from `consumesAuthServices`.
6867
- explicitDependencies: z18.array(PluginId2),
6968
+ explicitDependencies: z19.array(PluginId2),
6868
6969
  dataDirSharedWith: PluginId2.optional(),
6869
- workloadPurposes: z18.array(PluginWorkloadPurpose).optional(),
6870
- shellCommands: z18.array(PluginShellCommand.omit({ endpoint: true }).extend({
6970
+ workers: z19.array(z19.strictObject({
6971
+ localId: LocalContributionId2,
6972
+ module: PackageAssetPath2
6973
+ })).optional(),
6974
+ workloadPurposes: z19.array(PluginWorkloadPurpose).optional(),
6975
+ shellCommands: z19.array(PluginShellCommand.omit({ endpoint: true }).extend({
6871
6976
  endpointId: GlobalContributionId2
6872
6977
  })).optional(),
6978
+ projectDirectories: PluginProjectDirectories.omit({ endpoint: true }).extend({ endpointId: GlobalContributionId2 }).optional(),
6873
6979
  // The auth services this plugin OWNS, carrying the global ids its harness
6874
6980
  // target must register and the credential authority keys on. Always present;
6875
6981
  // a plugin that declares no `auth.services` carries an empty array. The dual
6876
6982
  // of `consumesAuthServices` (services it merely references).
6877
- authServices: z18.array(ResolvedPluginAuthService2),
6983
+ authServices: z19.array(ResolvedPluginAuthService2),
6878
6984
  grants: ResolvedPluginGrants2.optional(),
6879
- kayAgentFamilyFolder: z18.strictObject({ scope: z18.literal("root") }).optional(),
6880
- kayAgentUriModules: z18.array(ResolvedKayAgentUriModule2).optional(),
6881
- kayAgentArtifactUriModules: z18.array(ResolvedKayAgentArtifactUriModule2).optional(),
6882
- kayAgentEntityResolvers: z18.array(ResolvedKayAgentEntityResolver2).optional(),
6883
- kayAgentGitHostClaims: z18.array(ResolvedKayAgentGitHostClaim2).optional(),
6884
- kayAgentTools: z18.array(ResolvedKayAgentTool2).optional(),
6885
- kayAppTools: z18.array(ResolvedKayAppTool2).optional(),
6886
- kayAppApprovalTypes: z18.array(ResolvedKayAppApprovalType2).optional(),
6887
- kayAppWorkflows: z18.array(ResolvedKayAppWorkflow2).optional(),
6888
- kayAppCards: z18.array(ResolvedPluginCard2).optional(),
6889
- kayAppDataSources: z18.array(ResolvedKayAppDataSource2).optional(),
6890
- kayAppWhiteboardTypes: z18.array(ResolvedKayAppWhiteboardType2).optional(),
6891
- kayAppMcpServers: z18.array(ResolvedKayAppMcpServer2).optional(),
6892
- kayAgentConverters: z18.array(ResolvedKayAgentConverter2).optional(),
6893
- referencePresentations: z18.array(ResolvedReferencePresentation2).optional(),
6894
- kayUiApps: z18.array(ResolvedKayUiApp2).optional()
6985
+ kayAgentFamilyFolder: z19.strictObject({ scope: z19.literal("root") }).optional(),
6986
+ kayAgentUriModules: z19.array(ResolvedKayAgentUriModule2).optional(),
6987
+ kayAgentArtifactUriModules: z19.array(ResolvedKayAgentArtifactUriModule2).optional(),
6988
+ kayAgentEntityResolvers: z19.array(ResolvedKayAgentEntityResolver2).optional(),
6989
+ kayAgentGitHostClaims: z19.array(ResolvedKayAgentGitHostClaim2).optional(),
6990
+ kayAgentTools: z19.array(ResolvedKayAgentTool2).optional(),
6991
+ kayAppTools: z19.array(ResolvedKayAppTool2).optional(),
6992
+ kayAppApprovalTypes: z19.array(ResolvedKayAppApprovalType2).optional(),
6993
+ kayAppWorkflows: z19.array(ResolvedKayAppWorkflow2).optional(),
6994
+ kayAppCards: z19.array(ResolvedPluginCard2).optional(),
6995
+ kayAppDataSources: z19.array(ResolvedKayAppDataSource2).optional(),
6996
+ kayAppWhiteboardTypes: z19.array(ResolvedKayAppWhiteboardType2).optional(),
6997
+ kayAppMcpServers: z19.array(ResolvedKayAppMcpServer2).optional(),
6998
+ kayAgentConverters: z19.array(ResolvedKayAgentConverter2).optional(),
6999
+ referencePresentations: z19.array(ResolvedReferencePresentation2).optional(),
7000
+ kayUiApps: z19.array(ResolvedKayUiApp2).optional()
6895
7001
  });
6896
7002
  return {
6897
7003
  ResolvedPluginContributionId: ResolvedPluginContributionId2,
@@ -7121,6 +7227,12 @@ function resolveAuthServices(namespace, manifest) {
7121
7227
  const endpointFields = {
7122
7228
  authorizationUrl: scheme.authorizationUrl,
7123
7229
  tokenUrl: scheme.tokenUrl,
7230
+ ...scheme.connectScopes === void 0 ? {} : { connectScopes: [...scheme.connectScopes] },
7231
+ ...scheme.extraAuthorizeParamsWhenAccountHeld === void 0 ? {} : {
7232
+ extraAuthorizeParamsWhenAccountHeld: {
7233
+ ...scheme.extraAuthorizeParamsWhenAccountHeld
7234
+ }
7235
+ },
7124
7236
  ...scheme.extraAuthorizeParams === void 0 ? {} : { extraAuthorizeParams: { ...scheme.extraAuthorizeParams } }
7125
7237
  };
7126
7238
  return scheme.exchange === "pkce" ? {
@@ -7316,6 +7428,7 @@ function resolveKayPluginContractV1(manifest) {
7316
7428
  }));
7317
7429
  const kayAgentUriModules = manifest.targets?.kay?.agent?.contributes?.uriModules?.map((module) => ({
7318
7430
  localId: module.localId,
7431
+ ...module.adapterId === void 0 ? {} : { adapterId: module.adapterId },
7319
7432
  globalId: resolveGlobalContributionId(namespace, module.localId),
7320
7433
  schemes: [...module.schemes],
7321
7434
  ...module.displayName === void 0 ? {} : { displayName: module.displayName },
@@ -7424,6 +7537,7 @@ function resolveKayPluginContractV1(manifest) {
7424
7537
  ...manifest.dependencies?.plugins ?? []
7425
7538
  ],
7426
7539
  authServices,
7540
+ ...manifest.workers === void 0 ? {} : { workers: manifest.workers },
7427
7541
  ...manifest.storage?.dataDir?.sharedWith === void 0 ? {} : { dataDirSharedWith: manifest.storage.dataDir.sharedWith },
7428
7542
  ...manifest.workloadPurposes === void 0 ? {} : { workloadPurposes: manifest.workloadPurposes },
7429
7543
  ...manifest.shellCommands === void 0 ? {} : {
@@ -7432,6 +7546,12 @@ function resolveKayPluginContractV1(manifest) {
7432
7546
  endpointId: resolveGlobalContributionId(namespace, endpoint)
7433
7547
  }))
7434
7548
  },
7549
+ ...manifest.projectDirectories === void 0 ? {} : {
7550
+ projectDirectories: {
7551
+ scheme: manifest.projectDirectories.scheme,
7552
+ endpointId: resolveGlobalContributionId(namespace, manifest.projectDirectories.endpoint)
7553
+ }
7554
+ },
7435
7555
  ...grants && Object.keys(grants.byTarget).length > 0 ? { grants } : {},
7436
7556
  ...manifest.targets?.kay?.agent?.familyFolder === void 0 ? {} : { kayAgentFamilyFolder: manifest.targets.kay.agent.familyFolder },
7437
7557
  ...kayAgentUriModules && kayAgentUriModules.length > 0 ? { kayAgentUriModules } : {},
@@ -7480,7 +7600,7 @@ function presentationSource(namespace, manifest, presentation) {
7480
7600
  } : {}
7481
7601
  };
7482
7602
  }
7483
- function uriModuleFacts({ localId: _localId, schemes: _schemes, displayName: _displayName, authService: _authService, authScheme: _authScheme, knownResources: _knownResources, describesOperations: _describesOperations, looksUpWebLinks: _looksUpWebLinks, ...facts }) {
7603
+ function uriModuleFacts({ localId: _localId, adapterId: _adapterId, schemes: _schemes, displayName: _displayName, authService: _authService, authScheme: _authScheme, knownResources: _knownResources, describesOperations: _describesOperations, looksUpWebLinks: _looksUpWebLinks, ...facts }) {
7484
7604
  return facts;
7485
7605
  }
7486
7606
 
@@ -7594,6 +7714,17 @@ async function judgeKayPluginDirectory(input) {
7594
7714
  return refuse("contract-resolve", "path-escapes-plugin-dir", `${reference.label} path '${reference.path}' resolves outside the plugin directory (no symlink escapes, no traversal)`);
7595
7715
  }
7596
7716
  }
7717
+ for (const worker of manifest.workers ?? []) {
7718
+ let entry;
7719
+ try {
7720
+ entry = await tree.entry(worker.module);
7721
+ } catch {
7722
+ return refuse("contract-resolve", "invalid-worker-module", "A declared worker module could not be inspected.");
7723
+ }
7724
+ if (entry?.kind !== "file") {
7725
+ return refuse("contract-resolve", "invalid-worker-module", `worker '${worker.localId}' must name an existing regular file`);
7726
+ }
7727
+ }
7597
7728
  return {
7598
7729
  outcome: "loads",
7599
7730
  hostSdkVersion,
@@ -7616,14 +7747,14 @@ function kayPluginCompatibilityAdvisories(input) {
7616
7747
  message: boundPluginDiagnosticMessage(`${manifest.displayName} (${manifest.id}) ${advisory.message}`)
7617
7748
  }));
7618
7749
  }
7619
- var ReadableCompatibility = z19.object({
7620
- supportedProtocols: z19.array(z19.string()).optional().catch(void 0),
7750
+ var ReadableCompatibility = z20.object({
7751
+ supportedProtocols: z20.array(z20.string()).optional().catch(void 0),
7621
7752
  minKayVersion: NonEmptyString.optional().catch(void 0),
7622
7753
  sdk: NonEmptyString.optional().catch(void 0)
7623
7754
  });
7624
- var ReadableManifestHead = z19.object({
7625
- id: z19.string().optional().catch(void 0),
7626
- displayName: z19.string().optional().catch(void 0),
7755
+ var ReadableManifestHead = z20.object({
7756
+ id: z20.string().optional().catch(void 0),
7757
+ displayName: z20.string().optional().catch(void 0),
7627
7758
  compatibility: ReadableCompatibility.optional().catch(void 0)
7628
7759
  });
7629
7760
  function keepNamespaceDerivedTools(contract, grandfathered) {
@@ -7669,7 +7800,10 @@ function namedIn(head) {
7669
7800
  return head.displayName === void 0 ? head.id : `${head.displayName} (${head.id})`;
7670
7801
  }
7671
7802
  function referencedPaths(manifest) {
7672
- const refs = [];
7803
+ const refs = (manifest.workers ?? []).map((worker) => ({
7804
+ label: `worker '${worker.localId}'`,
7805
+ path: worker.module
7806
+ }));
7673
7807
  const kayAgent = manifest.targets?.kay?.agent;
7674
7808
  if (kayAgent !== void 0) {
7675
7809
  refs.push({
@@ -7727,28 +7861,28 @@ function errorText(error) {
7727
7861
  }
7728
7862
 
7729
7863
  // packages/plugin-protocol/dist/session-health.js
7730
- import { z as z20 } from "zod";
7864
+ import { z as z21 } from "zod";
7731
7865
  var SESSION_HEALTH_EXTENSION_ID = "kay.session-health";
7732
7866
  var SESSION_HEALTH_ENTRY_NAME = "session_health";
7733
7867
  var SESSION_HEALTH_CUSTOM_TYPE = `ext:${SESSION_HEALTH_EXTENSION_ID}:${SESSION_HEALTH_ENTRY_NAME}`;
7734
7868
  var SESSION_HEALTH_CLASSIFIER_IDS = ["jev"];
7735
- var sessionHealthEntrySchema = z20.object({
7736
- v: z20.literal(1),
7737
- verdict: z20.enum(["well", "bad", "unknown"]),
7869
+ var sessionHealthEntrySchema = z21.object({
7870
+ v: z21.literal(1),
7871
+ verdict: z21.enum(["well", "bad", "unknown"]),
7738
7872
  /**
7739
7873
  * The model's calibrated confidence in `well`, 0..1, or null when the
7740
7874
  * classifier declined to produce one. Never exported raw: the telemetry
7741
7875
  * event carries only the decile bucket.
7742
7876
  */
7743
- p_well: z20.number().min(0).max(1).nullable(),
7744
- classifier: z20.enum(SESSION_HEALTH_CLASSIFIER_IDS),
7745
- classifier_version: z20.string().min(1).max(64),
7746
- judged_at: z20.number().int().nonnegative(),
7747
- user_entry_id: z20.string().min(1).max(256),
7748
- through_entry_id: z20.string().min(1).max(256),
7749
- usage: z20.strictObject({
7750
- input_tokens: z20.number().int().nonnegative(),
7751
- output_tokens: z20.number().int().nonnegative()
7877
+ p_well: z21.number().min(0).max(1).nullable(),
7878
+ classifier: z21.enum(SESSION_HEALTH_CLASSIFIER_IDS),
7879
+ classifier_version: z21.string().min(1).max(64),
7880
+ judged_at: z21.number().int().nonnegative(),
7881
+ user_entry_id: z21.string().min(1).max(256),
7882
+ through_entry_id: z21.string().min(1).max(256),
7883
+ usage: z21.strictObject({
7884
+ input_tokens: z21.number().int().nonnegative(),
7885
+ output_tokens: z21.number().int().nonnegative()
7752
7886
  }).optional()
7753
7887
  });
7754
7888
  function sessionHealthPWellDecile(pWell) {
@@ -7758,23 +7892,28 @@ function sessionHealthPWellDecile(pWell) {
7758
7892
  }
7759
7893
 
7760
7894
  // packages/plugin-protocol/dist/resource-invocations.js
7761
- import { z as z21 } from "zod";
7762
- var CorpusResourceKind = z21.enum([
7895
+ import { z as z23 } from "zod";
7896
+
7897
+ // packages/plugin-protocol/dist/resource-invocation-cursor.js
7898
+ import { z as z22 } from "zod";
7899
+ var CorpusResourceInvocationCursor = z22.strictObject({
7900
+ at: z22.iso.datetime({ offset: true }),
7901
+ eventId: z22.string().min(1)
7902
+ });
7903
+
7904
+ // packages/plugin-protocol/dist/resource-invocations.js
7905
+ var CorpusResourceKind = z23.enum([
7763
7906
  "skill",
7764
7907
  "context-file",
7765
7908
  "prompt-command"
7766
7909
  ]);
7767
- var CorpusResourceInvocationCursor = z21.strictObject({
7768
- at: z21.iso.datetime({ offset: true }),
7769
- eventId: z21.string().min(1)
7770
- });
7771
- var CorpusResourceInvocationQuery = z21.strictObject({
7910
+ var CorpusResourceInvocationQuery = z23.strictObject({
7772
7911
  kind: CorpusResourceKind,
7773
- since: z21.iso.datetime({ offset: true }),
7774
- until: z21.iso.datetime({ offset: true }),
7912
+ since: z23.iso.datetime({ offset: true }),
7913
+ until: z23.iso.datetime({ offset: true }),
7775
7914
  after: CorpusResourceInvocationCursor.optional(),
7776
- limit: z21.number().int().min(1).max(1e3).optional(),
7777
- rootCreatedByKind: z21.enum(AGENT_RUNTIME_SESSION_CREATOR_KINDS).optional()
7915
+ limit: z23.number().int().min(1).max(1e3).optional(),
7916
+ rootCreatedByKind: z23.enum(AGENT_RUNTIME_SESSION_CREATOR_KINDS).optional()
7778
7917
  }).refine((value) => Date.parse(value.since) < Date.parse(value.until), {
7779
7918
  message: "since must precede until"
7780
7919
  });
@@ -7954,14 +8093,14 @@ function skillSuggestionEvidenceItems(evidence, options = {}) {
7954
8093
  }
7955
8094
 
7956
8095
  // packages/plugin-protocol/dist/ui-app-package.js
7957
- import { z as z22 } from "zod";
8096
+ import { z as z24 } from "zod";
7958
8097
  var KAY_UI_APP_PACKAGE_PROTOCOL = "kay.ui.app-package.v1";
7959
8098
  var KAY_UI_BUNDLE_INDEX_PROTOCOL = "kay.ui.bundle-index.v1";
7960
- var KayUiBundleOutputPath = z22.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" });
7961
- var KayUiBundleIndexV1 = z22.strictObject({
7962
- protocol: z22.literal(KAY_UI_BUNDLE_INDEX_PROTOCOL),
8099
+ var KayUiBundleOutputPath = z24.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" });
8100
+ var KayUiBundleIndexV1 = z24.strictObject({
8101
+ protocol: z24.literal(KAY_UI_BUNDLE_INDEX_PROTOCOL),
7963
8102
  entryPath: KayUiBundleOutputPath,
7964
- files: z22.array(z22.strictObject({
8103
+ files: z24.array(z24.strictObject({
7965
8104
  path: KayUiBundleOutputPath,
7966
8105
  mediaType: NonEmptyString
7967
8106
  })).min(1)
@@ -7988,19 +8127,19 @@ var KayUiBundleIndexV1 = z22.strictObject({
7988
8127
  function parseKayUiBundleIndexV1(input) {
7989
8128
  return KayUiBundleIndexV1.parse(input);
7990
8129
  }
7991
- var KayUiAppPackageFile = z22.strictObject({
8130
+ var KayUiAppPackageFile = z24.strictObject({
7992
8131
  path: PackageAssetPath,
7993
8132
  mediaType: NonEmptyString,
7994
- bytes: z22.instanceof(Uint8Array).refine((bytes) => bytes.byteLength > 0, {
8133
+ bytes: z24.instanceof(Uint8Array).refine((bytes) => bytes.byteLength > 0, {
7995
8134
  message: "app package file bytes must not be empty"
7996
8135
  })
7997
8136
  });
7998
- var KayUiAppPackageV1 = z22.strictObject({
7999
- protocol: z22.literal(KAY_UI_APP_PACKAGE_PROTOCOL),
8137
+ var KayUiAppPackageV1 = z24.strictObject({
8138
+ protocol: z24.literal(KAY_UI_APP_PACKAGE_PROTOCOL),
8000
8139
  appLocalId: LocalContributionId,
8001
8140
  entry: KayUiAppPackageFile,
8002
- styles: z22.array(KayUiAppPackageFile).optional(),
8003
- assets: z22.array(KayUiAppPackageFile).optional()
8141
+ styles: z24.array(KayUiAppPackageFile).optional(),
8142
+ assets: z24.array(KayUiAppPackageFile).optional()
8004
8143
  }).superRefine((appPackage, ctx) => {
8005
8144
  if (appPackage.entry.mediaType !== "application/javascript") {
8006
8145
  ctx.addIssue({
@@ -8037,28 +8176,28 @@ function parseKayUiAppPackageV1(input) {
8037
8176
  }
8038
8177
 
8039
8178
  // packages/plugin-protocol/dist/product-events.js
8040
- import { z as z23 } from "zod";
8179
+ import { z as z25 } from "zod";
8041
8180
  var exportable = {
8042
- class: z23.literal("exportable"),
8043
- optional: z23.boolean().optional()
8181
+ class: z25.literal("exportable"),
8182
+ optional: z25.boolean().optional()
8044
8183
  };
8045
- var PluginProductEventField = z23.union([
8046
- z23.strictObject({ class: z23.literal("local") }),
8047
- z23.strictObject({
8184
+ var PluginProductEventField = z25.union([
8185
+ z25.strictObject({ class: z25.literal("local") }),
8186
+ z25.strictObject({
8048
8187
  ...exportable,
8049
- type: z23.literal("enum"),
8050
- values: z23.array(z23.string())
8188
+ type: z25.literal("enum"),
8189
+ values: z25.array(z25.string())
8051
8190
  }),
8052
- z23.strictObject({
8191
+ z25.strictObject({
8053
8192
  ...exportable,
8054
- type: z23.literal("number"),
8055
- min: z23.number(),
8056
- max: z23.number(),
8057
- integer: z23.boolean().optional()
8193
+ type: z25.literal("number"),
8194
+ min: z25.number(),
8195
+ max: z25.number(),
8196
+ integer: z25.boolean().optional()
8058
8197
  }),
8059
- z23.strictObject({
8198
+ z25.strictObject({
8060
8199
  ...exportable,
8061
- type: z23.enum([
8200
+ type: z25.enum([
8062
8201
  "boolean",
8063
8202
  "id",
8064
8203
  "identifier",
@@ -8074,9 +8213,9 @@ function isPluginProductEventName(name) {
8074
8213
  }
8075
8214
 
8076
8215
  // packages/plugin-protocol/dist/artifact-outputs.js
8077
- import { z as z24 } from "zod";
8216
+ import { z as z26 } from "zod";
8078
8217
  var ARTIFACT_OUTPUT_PAGE_MAX = 200;
8079
- var Segment = z24.string().min(1).max(1024).refine((value) => !/[^A-Za-z0-9._-]/.test(value)).refine((value) => value !== "." && value !== "..");
8218
+ var Segment = z26.string().min(1).max(1024).refine((value) => !/[^A-Za-z0-9._-]/.test(value)).refine((value) => value !== "." && value !== "..");
8080
8219
  function parseArtifactOutputUri(uri) {
8081
8220
  const match = /^output:\/\/([^/]+)\/([^/]+)$/.exec(uri);
8082
8221
  if (match === null || !Segment.safeParse(match[1]).success || !Segment.safeParse(match[2]).success)
@@ -8086,12 +8225,12 @@ function parseArtifactOutputUri(uri) {
8086
8225
  function isCanonicalArtifactOutputUri(uri) {
8087
8226
  return parseArtifactOutputUri(uri) !== void 0;
8088
8227
  }
8089
- var ArtifactOutputUri = z24.string().refine(isCanonicalArtifactOutputUri, "Expected a canonical output://session/name URI");
8090
- var ArtifactOutputChange = z24.union([
8091
- z24.strictObject({
8092
- uris: z24.array(ArtifactOutputUri).min(1).max(ARTIFACT_OUTPUT_PAGE_MAX)
8228
+ var ArtifactOutputUri = z26.string().refine(isCanonicalArtifactOutputUri, "Expected a canonical output://session/name URI");
8229
+ var ArtifactOutputChange = z26.union([
8230
+ z26.strictObject({
8231
+ uris: z26.array(ArtifactOutputUri).min(1).max(ARTIFACT_OUTPUT_PAGE_MAX)
8093
8232
  }),
8094
- z24.strictObject({ sessionId: Segment })
8233
+ z26.strictObject({ sessionId: Segment })
8095
8234
  ]);
8096
8235
 
8097
8236
  // packages/plugin-protocol/dist/credential-text.js
@@ -8134,25 +8273,25 @@ function isCredentialShapedText(value) {
8134
8273
  }
8135
8274
 
8136
8275
  // packages/plugin-protocol/dist/ui-module-bundle.js
8137
- import { z as z25 } from "zod";
8276
+ import { z as z27 } from "zod";
8138
8277
  var KAY_UI_MODULE_BUNDLE_PROTOCOL = "kay.ui.module-bundle.v1";
8139
8278
  var KAY_UI_MODULE_FILE_MAX_BYTES = 8 * 1024 * 1024;
8140
8279
  var KAY_UI_MODULE_BUNDLE_MAX_BYTES = 32 * 1024 * 1024;
8141
8280
  var KAY_UI_MODULE_BUNDLE_MAX_FILES = 256;
8142
- var OutputPath = z25.string().min(1).max(1024).refine((value) => {
8281
+ var OutputPath = z27.string().min(1).max(1024).refine((value) => {
8143
8282
  const parsed = KayUiBundleIndexV1.shape.entryPath.safeParse(value);
8144
8283
  return parsed.success && parsed.data === value && value.split("/").every((part) => part !== "" && part !== ".") && // oxlint-disable-next-line eslint/no-control-regex -- Untrusted artifact paths must reject literal control characters.
8145
8284
  !/[\u0000-\u001f?#:%]/.test(value);
8146
8285
  }, { message: "bundle path must contain only unambiguous relative segments" });
8147
- var Sha256 = z25.string().regex(/^[a-f0-9]{64}$/);
8148
- var KayUiModuleBundleIndexV1 = z25.strictObject({
8149
- protocol: z25.literal(KAY_UI_MODULE_BUNDLE_PROTOCOL),
8286
+ var Sha256 = z27.string().regex(/^[a-f0-9]{64}$/);
8287
+ var KayUiModuleBundleIndexV1 = z27.strictObject({
8288
+ protocol: z27.literal(KAY_UI_MODULE_BUNDLE_PROTOCOL),
8150
8289
  entryPath: OutputPath,
8151
- stylePaths: z25.array(OutputPath).max(KAY_UI_MODULE_BUNDLE_MAX_FILES),
8152
- files: z25.array(z25.strictObject({
8290
+ stylePaths: z27.array(OutputPath).max(KAY_UI_MODULE_BUNDLE_MAX_FILES),
8291
+ files: z27.array(z27.strictObject({
8153
8292
  path: OutputPath,
8154
- mediaType: z25.string().min(1).max(128).regex(/^[a-zA-Z0-9!#$&^_.+-]+\/[a-zA-Z0-9!#$&^_.+-]+$/),
8155
- byteLength: z25.number().int().min(1).max(KAY_UI_MODULE_FILE_MAX_BYTES),
8293
+ mediaType: z27.string().min(1).max(128).regex(/^[a-zA-Z0-9!#$&^_.+-]+\/[a-zA-Z0-9!#$&^_.+-]+$/),
8294
+ byteLength: z27.number().int().min(1).max(KAY_UI_MODULE_FILE_MAX_BYTES),
8156
8295
  sha256: Sha256
8157
8296
  })).min(1).max(KAY_UI_MODULE_BUNDLE_MAX_FILES)
8158
8297
  }).superRefine((index, ctx) => {
@@ -8182,9 +8321,9 @@ var KayUiModuleBundleIndexV1 = z25.strictObject({
8182
8321
  message: "bundle exceeds byte cap"
8183
8322
  });
8184
8323
  });
8185
- var KayUiModuleBundleReference = z25.strictObject({
8324
+ var KayUiModuleBundleReference = z27.strictObject({
8186
8325
  generationId: Sha256,
8187
- revision: z25.string().min(1).max(4096).refine((value) => value.trim() === value),
8326
+ revision: z27.string().min(1).max(4096).refine((value) => value.trim() === value),
8188
8327
  index: KayUiModuleBundleIndexV1
8189
8328
  });
8190
8329
  export {
@@ -8351,6 +8490,7 @@ export {
8351
8490
  PluginPickerRound,
8352
8491
  PluginProductEventContribution,
8353
8492
  PluginProductEventField,
8493
+ PluginProjectDirectories,
8354
8494
  PluginProvisioningProbe,
8355
8495
  PluginProvisioningRequirement,
8356
8496
  PluginShellCommand,
@@ -8364,6 +8504,9 @@ export {
8364
8504
  PluginWebSessionDeclaration,
8365
8505
  PluginWebSessionProbe,
8366
8506
  PluginWorkloadPurpose,
8507
+ ProjectDirectory,
8508
+ ProjectDirectoryRequest,
8509
+ ProjectDirectoryResponse,
8367
8510
  RENAMED_PLUGIN_CAPABILITY_SLUGS,
8368
8511
  RESERVED_DIRECTORY_PLUGIN_ID_PREFIXES,
8369
8512
  RETIRED_COMPATIBILITY_KEYS,