@yaklabs-ai/plugin-protocol 0.33.0 → 0.35.0

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
@@ -9,6 +9,21 @@ var KAY_APP_DATA_SNAPSHOT_MAX_BYTES = 16 * 1024 * 1024;
9
9
  var KAY_APP_DATA_CHANGE_MAX_BYTES = 256 * 1024;
10
10
  var KAY_APP_DATA_READ_REQUEST_MAX_BYTES = 64 * 1024;
11
11
  var KAY_APP_DATA_READ_RESULT_MAX_BYTES = 16 * 1024 * 1024;
12
+ function appDataSourceDeclaration(source) {
13
+ return {
14
+ sourceId: source.localId,
15
+ scope: source.scope,
16
+ snapshotVersion: source.snapshot.version,
17
+ changeVersion: source.change.version,
18
+ ...source.read === void 0 ? {} : {
19
+ read: {
20
+ requestVersion: source.read.request.version,
21
+ resultVersion: source.read.result.version
22
+ }
23
+ },
24
+ ...source.store === void 0 ? {} : { store: source.store }
25
+ };
26
+ }
12
27
 
13
28
  // packages/plugin-protocol/dist/ui-icon-paths.js
14
29
  function declaredUiIconPaths(manifest) {
@@ -238,7 +253,7 @@ var JsonSchema = z4.record(z4.string(), JsonValue);
238
253
  var KAY_PLUGIN_MANIFEST_SIZE_CAP_BYTES = 1024 * 1024;
239
254
  var KAY_PLUGIN_PROTOCOL_VERSION = "kay.plugin.v1";
240
255
  var KAY_PLUGIN_PROTOCOL_PACKAGE_NAME = "@bonsai/plugin-protocol";
241
- var KAY_PLUGIN_SDK_VERSION = "0.33.0";
256
+ var KAY_PLUGIN_SDK_VERSION = "0.35.0";
242
257
  var KAY_PLUGIN_COMPATIBLE_SDK_VERSIONS = [
243
258
  "0.26.3",
244
259
  "0.27.1",
@@ -246,7 +261,9 @@ var KAY_PLUGIN_COMPATIBLE_SDK_VERSIONS = [
246
261
  "0.29.0",
247
262
  "0.30.0",
248
263
  "0.31.0",
249
- "0.32.0"
264
+ "0.32.0",
265
+ "0.33.0",
266
+ "0.34.0"
250
267
  ];
251
268
  var KAY_PLUGIN_TARGET_NAMES = [
252
269
  "kay.agent",
@@ -2832,20 +2849,7 @@ function createPluginEventsSchemas(canonical) {
2832
2849
  var { PluginEventLocalId, PluginEventUri, PluginEventTimestamp, PluginEventRelated, PluginEventPublishSource, PluginEventSource, PluginEventId, PluginEventPublishInput, PluginEventEnvelope } = createPluginEventsSchemas(false);
2833
2850
  var canonicalPluginEventSchemas = createPluginEventsSchemas(true);
2834
2851
 
2835
- // packages/plugin-protocol/dist/declared-commands.js
2836
- function declarationsOfKind(plugins, kind) {
2837
- return plugins.flatMap((plugin) => (plugin.contributes[kind] ?? []).map((declaration) => ({
2838
- plugin,
2839
- declaration
2840
- })));
2841
- }
2842
- function declaredCommandId(pluginId, localId) {
2843
- return `${pluginId}/${localId}`;
2844
- }
2845
- var WHERE_KEY_TYPES = {
2846
- "account.signedIn": "boolean",
2847
- "app.channel": "string"
2848
- };
2852
+ // packages/plugin-protocol/dist/where-expression.js
2849
2853
  var TOKEN = /\s*(?:(\|\||&&|==|!=|!|\(|\))|'([^']*)'|"([^"]*)"|([A-Za-z][A-Za-z0-9]*(?:\.[A-Za-z][A-Za-z0-9]*)*))/y;
2850
2854
  function tokenize(source) {
2851
2855
  const tokens = [];
@@ -2866,10 +2870,7 @@ function tokenize(source) {
2866
2870
  }
2867
2871
  return tokens;
2868
2872
  }
2869
- function isKey(text) {
2870
- return Object.hasOwn(WHERE_KEY_TYPES, text);
2871
- }
2872
- function parseTokens(tokens) {
2873
+ function parseTokens(tokens, keyTypes) {
2873
2874
  let position = 0;
2874
2875
  const takeOperator = (text) => {
2875
2876
  const token = tokens[position];
@@ -2910,22 +2911,23 @@ function parseTokens(tokens) {
2910
2911
  }
2911
2912
  if (token.kind !== "word")
2912
2913
  throw new Error(`unexpected '${token.text}'`);
2913
- if (!isKey(token.text)) {
2914
- throw new Error(`unknown key '${token.text}'; the keys are ${Object.keys(WHERE_KEY_TYPES).join(", ")}`);
2914
+ if (keyTypes !== void 0 && !Object.hasOwn(keyTypes, token.text)) {
2915
+ throw new Error(`unknown key '${token.text}'; the keys are ${Object.keys(keyTypes).join(", ")}`);
2915
2916
  }
2916
2917
  return parseKeyAtom(token.text);
2917
2918
  };
2918
2919
  const parseKeyAtom = (key) => {
2920
+ const keyType = keyTypes?.[key];
2919
2921
  const negated = takeOperator("!=");
2920
2922
  if (!negated && !takeOperator("==")) {
2921
- if (WHERE_KEY_TYPES[key] !== "boolean") {
2923
+ if (keyType === "string") {
2922
2924
  throw new Error(`'${key}' must be compared, with == or !=`);
2923
2925
  }
2924
2926
  return { kind: "key", key };
2925
2927
  }
2926
2928
  const value = parseLiteral();
2927
- if (typeof value !== WHERE_KEY_TYPES[key]) {
2928
- throw new Error(`'${key}' compares to a ${WHERE_KEY_TYPES[key]}`);
2929
+ if (keyType !== void 0 && typeof value !== keyType) {
2930
+ throw new Error(`'${key}' compares to a ${keyType}`);
2929
2931
  }
2930
2932
  return { kind: "equals", key, value, negated };
2931
2933
  };
@@ -2946,49 +2948,82 @@ function parseTokens(tokens) {
2946
2948
  throw new Error(`unexpected '${extra.text}'`);
2947
2949
  return where;
2948
2950
  }
2949
- function parseCommandWhere(source) {
2951
+ function parseWhere(source, keyTypes) {
2950
2952
  try {
2951
- return { ok: true, where: parseTokens(tokenize(source)) };
2953
+ return { ok: true, where: parseTokens(tokenize(source), keyTypes) };
2952
2954
  } catch (error) {
2953
2955
  return { ok: false, message: error.message };
2954
2956
  }
2955
2957
  }
2956
- function resolve(where, values) {
2958
+ function resolve(where, read) {
2957
2959
  switch (where.kind) {
2958
2960
  case "literal":
2959
2961
  return where.value;
2960
2962
  case "key": {
2961
- const value = values[where.key];
2962
- return value === void 0 ? void 0 : value === true;
2963
+ const value = read(where.key);
2964
+ return value === void 0 ? void 0 : Boolean(value);
2963
2965
  }
2964
2966
  case "equals": {
2965
- const value = values[where.key];
2967
+ const value = read(where.key);
2966
2968
  if (value === void 0)
2967
2969
  return void 0;
2968
2970
  return value === where.value !== where.negated;
2969
2971
  }
2970
2972
  case "not": {
2971
- const operand = resolve(where.operand, values);
2973
+ const operand = resolve(where.operand, read);
2972
2974
  return operand === void 0 ? void 0 : !operand;
2973
2975
  }
2974
2976
  case "and": {
2975
- const left = resolve(where.left, values);
2976
- const right = resolve(where.right, values);
2977
+ const left = resolve(where.left, read);
2978
+ const right = resolve(where.right, read);
2977
2979
  if (left === false || right === false)
2978
2980
  return false;
2979
2981
  return left === void 0 || right === void 0 ? void 0 : true;
2980
2982
  }
2981
2983
  case "or": {
2982
- const left = resolve(where.left, values);
2983
- const right = resolve(where.right, values);
2984
+ const left = resolve(where.left, read);
2985
+ const right = resolve(where.right, read);
2984
2986
  if (left === true || right === true)
2985
2987
  return true;
2986
2988
  return left === void 0 || right === void 0 ? void 0 : false;
2987
2989
  }
2988
2990
  }
2989
2991
  }
2992
+ function evaluateWhere(where, read) {
2993
+ return resolve(where, read) === true;
2994
+ }
2995
+ function rowMatchesWhere(where, row) {
2996
+ return evaluateWhere(where, (path) => {
2997
+ let value = row;
2998
+ for (const part of path.split(".")) {
2999
+ if (typeof value !== "object" || value === null || !Object.hasOwn(value, part)) {
3000
+ return null;
3001
+ }
3002
+ value = value[part];
3003
+ }
3004
+ return value ?? null;
3005
+ });
3006
+ }
3007
+
3008
+ // packages/plugin-protocol/dist/declared-commands.js
3009
+ function declarationsOfKind(plugins, kind) {
3010
+ return plugins.flatMap((plugin) => (plugin.contributes[kind] ?? []).map((declaration) => ({
3011
+ plugin,
3012
+ declaration
3013
+ })));
3014
+ }
3015
+ function declaredCommandId(pluginId, localId) {
3016
+ return `${pluginId}/${localId}`;
3017
+ }
3018
+ var WHERE_KEY_TYPES = {
3019
+ "account.signedIn": "boolean",
3020
+ "app.channel": "string"
3021
+ };
3022
+ function parseCommandWhere(source) {
3023
+ return parseWhere(source, WHERE_KEY_TYPES);
3024
+ }
2990
3025
  function evaluateCommandWhere(where, values) {
2991
- return resolve(where, values) === true;
3026
+ return evaluateWhere(where, (key) => values[key]);
2992
3027
  }
2993
3028
 
2994
3029
  // packages/plugin-protocol/dist/contributions.js
@@ -3721,6 +3756,25 @@ function createContributionsSchemas(canonical) {
3721
3756
  }
3722
3757
  }
3723
3758
  });
3759
+ const UiRailBadge = z12.strictObject({
3760
+ source: LocalContributionId2,
3761
+ where: NonEmptyString3.optional(),
3762
+ label: z12.strictObject({
3763
+ one: NonEmptyString3.optional(),
3764
+ other: NonEmptyString3
3765
+ })
3766
+ }).superRefine((badge, ctx) => {
3767
+ if (badge.where === void 0)
3768
+ return;
3769
+ const parsed = parseWhere(badge.where);
3770
+ if (!parsed.ok) {
3771
+ ctx.addIssue({
3772
+ code: "custom",
3773
+ path: ["where"],
3774
+ message: `rail badge has an invalid where: ${parsed.message}`
3775
+ });
3776
+ }
3777
+ });
3724
3778
  const UiRailEntryContribution2 = z12.strictObject({
3725
3779
  id: LocalContributionId2,
3726
3780
  title: NonEmptyString3,
@@ -3729,7 +3783,9 @@ function createContributionsSchemas(canonical) {
3729
3783
  homeLocation: NonEmptyString3.optional(),
3730
3784
  shortcut: NonEmptyString3.optional(),
3731
3785
  order: z12.number().finite().optional(),
3732
- section: z12.enum(["primary", "plugins"]).optional()
3786
+ section: z12.enum(["primary", "plugins"]).optional(),
3787
+ badge: UiRailBadge.optional(),
3788
+ panel: z12.strictObject({ body: LocalContributionId2 }).optional()
3733
3789
  });
3734
3790
  const UiAppFields = z12.strictObject({
3735
3791
  localId: LocalContributionId2,
@@ -4547,6 +4603,34 @@ function createManifestSchemas(canonical) {
4547
4603
  }
4548
4604
  materializedAppDataSources.add(materializer.source);
4549
4605
  }
4606
+ const declaredRowsStores = new Set(manifest.targets?.kay?.app?.contributes?.dataSources?.filter((source) => source.store?.shape === "rows").map((source) => source.localId) ?? []);
4607
+ for (const [index, entry] of (manifest.targets?.kay?.ui?.contributes?.railEntries ?? []).entries()) {
4608
+ if (entry.badge === void 0)
4609
+ continue;
4610
+ const path = [
4611
+ "targets",
4612
+ "kay",
4613
+ "ui",
4614
+ "contributes",
4615
+ "railEntries",
4616
+ index,
4617
+ "badge"
4618
+ ];
4619
+ if (!declaredRowsStores.has(entry.badge.source)) {
4620
+ ctx.addIssue({
4621
+ code: "custom",
4622
+ path: [...path, "source"],
4623
+ message: `rail entry ${entry.id} counts ${entry.badge.source}, which is not one of this plugin's data sources with a rows store`
4624
+ });
4625
+ }
4626
+ if (manifest.targets?.kay?.ui?.entrypoint === void 0) {
4627
+ ctx.addIssue({
4628
+ code: "custom",
4629
+ path,
4630
+ message: `rail entry ${entry.id} declares a badge, so its plugin needs a kay.ui entrypoint: the window starts a plugin's data sources when it loads that code`
4631
+ });
4632
+ }
4633
+ }
4550
4634
  for (const source of declaredAppDataSources) {
4551
4635
  if (materializedAppDataSources.has(source) || declaredAppDataStores.has(source))
4552
4636
  continue;
@@ -4576,6 +4660,26 @@ function createManifestSchemas(canonical) {
4576
4660
  });
4577
4661
  }
4578
4662
  }
4663
+ for (const [index, entry] of (manifest.targets?.kay?.ui?.contributes?.railEntries ?? []).entries()) {
4664
+ const body = entry.panel?.body;
4665
+ const app = manifest.targets?.kay?.ui?.contributes?.apps?.find((candidate) => candidate.localId === body);
4666
+ if (app !== void 0 && app.contextOnly !== true) {
4667
+ ctx.addIssue({
4668
+ code: "custom",
4669
+ path: [
4670
+ "targets",
4671
+ "kay",
4672
+ "ui",
4673
+ "contributes",
4674
+ "railEntries",
4675
+ index,
4676
+ "panel",
4677
+ "body"
4678
+ ],
4679
+ message: `Rail entry ${entry.id} panel body ${app.localId} must be a contextOnly ui app`
4680
+ });
4681
+ }
4682
+ }
4579
4683
  const subscribedUiEvents = new Set(manifest.targets?.kay?.ui?.contributes?.eventSubscriptions?.map((subscription) => subscription.event) ?? []);
4580
4684
  const invokedUiEndpoints = new Set(manifest.permissions?.byTarget["kay.ui"]?.endpoints?.filter((grant) => grant.operations.includes("invoke")).map((grant) => grant.endpoint) ?? []);
4581
4685
  const uriModuleIds = new Set([
@@ -7099,6 +7203,7 @@ export {
7099
7203
  WhiteboardTypeStorage,
7100
7204
  WhiteboardValue,
7101
7205
  WorkflowContribution,
7206
+ appDataSourceDeclaration,
7102
7207
  approvalKindSchema,
7103
7208
  boundPluginDiagnosticMessage,
7104
7209
  captureArtifactProvenance,
@@ -7113,6 +7218,7 @@ export {
7113
7218
  dedupeClaims,
7114
7219
  deriveDirectoryPluginToolName,
7115
7220
  evaluateCommandWhere,
7221
+ evaluateWhere,
7116
7222
  finalizeArtifactProvenanceEnvelope,
7117
7223
  findSkillSuggestionCitations,
7118
7224
  hasClaim,
@@ -7140,6 +7246,7 @@ export {
7140
7246
  parseKayUiBundleIndexV1,
7141
7247
  parseResolvedPluginContractV1,
7142
7248
  parseSemver,
7249
+ parseWhere,
7143
7250
  pluginIconShape,
7144
7251
  precedingPersonMessages,
7145
7252
  readKayPluginDeclaredCompatibility,
@@ -7152,6 +7259,7 @@ export {
7152
7259
  resolveSessionAncestry,
7153
7260
  retiredCompatibilityKeysIn,
7154
7261
  retiredPermissionAsksIn,
7262
+ rowMatchesWhere,
7155
7263
  safeResolveKayPluginContractV1,
7156
7264
  sameClaim,
7157
7265
  satisfiesSemverRange,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yaklabs-ai/plugin-protocol",
3
- "version": "0.33.0",
3
+ "version": "0.35.0",
4
4
  "description": "The Kay plugin manifest schema (`kay.plugin.v1`) — parse and validate a kay-plugin.json.",
5
5
  "author": "YakLabs",
6
6
  "type": "module",