@yaklabs-ai/plugin-protocol 0.34.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.34.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",
@@ -247,7 +262,8 @@ var KAY_PLUGIN_COMPATIBLE_SDK_VERSIONS = [
247
262
  "0.30.0",
248
263
  "0.31.0",
249
264
  "0.32.0",
250
- "0.33.0"
265
+ "0.33.0",
266
+ "0.34.0"
251
267
  ];
252
268
  var KAY_PLUGIN_TARGET_NAMES = [
253
269
  "kay.agent",
@@ -2833,20 +2849,7 @@ function createPluginEventsSchemas(canonical) {
2833
2849
  var { PluginEventLocalId, PluginEventUri, PluginEventTimestamp, PluginEventRelated, PluginEventPublishSource, PluginEventSource, PluginEventId, PluginEventPublishInput, PluginEventEnvelope } = createPluginEventsSchemas(false);
2834
2850
  var canonicalPluginEventSchemas = createPluginEventsSchemas(true);
2835
2851
 
2836
- // packages/plugin-protocol/dist/declared-commands.js
2837
- function declarationsOfKind(plugins, kind) {
2838
- return plugins.flatMap((plugin) => (plugin.contributes[kind] ?? []).map((declaration) => ({
2839
- plugin,
2840
- declaration
2841
- })));
2842
- }
2843
- function declaredCommandId(pluginId, localId) {
2844
- return `${pluginId}/${localId}`;
2845
- }
2846
- var WHERE_KEY_TYPES = {
2847
- "account.signedIn": "boolean",
2848
- "app.channel": "string"
2849
- };
2852
+ // packages/plugin-protocol/dist/where-expression.js
2850
2853
  var TOKEN = /\s*(?:(\|\||&&|==|!=|!|\(|\))|'([^']*)'|"([^"]*)"|([A-Za-z][A-Za-z0-9]*(?:\.[A-Za-z][A-Za-z0-9]*)*))/y;
2851
2854
  function tokenize(source) {
2852
2855
  const tokens = [];
@@ -2867,10 +2870,7 @@ function tokenize(source) {
2867
2870
  }
2868
2871
  return tokens;
2869
2872
  }
2870
- function isKey(text) {
2871
- return Object.hasOwn(WHERE_KEY_TYPES, text);
2872
- }
2873
- function parseTokens(tokens) {
2873
+ function parseTokens(tokens, keyTypes) {
2874
2874
  let position = 0;
2875
2875
  const takeOperator = (text) => {
2876
2876
  const token = tokens[position];
@@ -2911,22 +2911,23 @@ function parseTokens(tokens) {
2911
2911
  }
2912
2912
  if (token.kind !== "word")
2913
2913
  throw new Error(`unexpected '${token.text}'`);
2914
- if (!isKey(token.text)) {
2915
- 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(", ")}`);
2916
2916
  }
2917
2917
  return parseKeyAtom(token.text);
2918
2918
  };
2919
2919
  const parseKeyAtom = (key) => {
2920
+ const keyType = keyTypes?.[key];
2920
2921
  const negated = takeOperator("!=");
2921
2922
  if (!negated && !takeOperator("==")) {
2922
- if (WHERE_KEY_TYPES[key] !== "boolean") {
2923
+ if (keyType === "string") {
2923
2924
  throw new Error(`'${key}' must be compared, with == or !=`);
2924
2925
  }
2925
2926
  return { kind: "key", key };
2926
2927
  }
2927
2928
  const value = parseLiteral();
2928
- if (typeof value !== WHERE_KEY_TYPES[key]) {
2929
- 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}`);
2930
2931
  }
2931
2932
  return { kind: "equals", key, value, negated };
2932
2933
  };
@@ -2947,49 +2948,82 @@ function parseTokens(tokens) {
2947
2948
  throw new Error(`unexpected '${extra.text}'`);
2948
2949
  return where;
2949
2950
  }
2950
- function parseCommandWhere(source) {
2951
+ function parseWhere(source, keyTypes) {
2951
2952
  try {
2952
- return { ok: true, where: parseTokens(tokenize(source)) };
2953
+ return { ok: true, where: parseTokens(tokenize(source), keyTypes) };
2953
2954
  } catch (error) {
2954
2955
  return { ok: false, message: error.message };
2955
2956
  }
2956
2957
  }
2957
- function resolve(where, values) {
2958
+ function resolve(where, read) {
2958
2959
  switch (where.kind) {
2959
2960
  case "literal":
2960
2961
  return where.value;
2961
2962
  case "key": {
2962
- const value = values[where.key];
2963
- return value === void 0 ? void 0 : value === true;
2963
+ const value = read(where.key);
2964
+ return value === void 0 ? void 0 : Boolean(value);
2964
2965
  }
2965
2966
  case "equals": {
2966
- const value = values[where.key];
2967
+ const value = read(where.key);
2967
2968
  if (value === void 0)
2968
2969
  return void 0;
2969
2970
  return value === where.value !== where.negated;
2970
2971
  }
2971
2972
  case "not": {
2972
- const operand = resolve(where.operand, values);
2973
+ const operand = resolve(where.operand, read);
2973
2974
  return operand === void 0 ? void 0 : !operand;
2974
2975
  }
2975
2976
  case "and": {
2976
- const left = resolve(where.left, values);
2977
- const right = resolve(where.right, values);
2977
+ const left = resolve(where.left, read);
2978
+ const right = resolve(where.right, read);
2978
2979
  if (left === false || right === false)
2979
2980
  return false;
2980
2981
  return left === void 0 || right === void 0 ? void 0 : true;
2981
2982
  }
2982
2983
  case "or": {
2983
- const left = resolve(where.left, values);
2984
- const right = resolve(where.right, values);
2984
+ const left = resolve(where.left, read);
2985
+ const right = resolve(where.right, read);
2985
2986
  if (left === true || right === true)
2986
2987
  return true;
2987
2988
  return left === void 0 || right === void 0 ? void 0 : false;
2988
2989
  }
2989
2990
  }
2990
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
+ }
2991
3025
  function evaluateCommandWhere(where, values) {
2992
- return resolve(where, values) === true;
3026
+ return evaluateWhere(where, (key) => values[key]);
2993
3027
  }
2994
3028
 
2995
3029
  // packages/plugin-protocol/dist/contributions.js
@@ -3722,6 +3756,25 @@ function createContributionsSchemas(canonical) {
3722
3756
  }
3723
3757
  }
3724
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
+ });
3725
3778
  const UiRailEntryContribution2 = z12.strictObject({
3726
3779
  id: LocalContributionId2,
3727
3780
  title: NonEmptyString3,
@@ -3731,6 +3784,7 @@ function createContributionsSchemas(canonical) {
3731
3784
  shortcut: NonEmptyString3.optional(),
3732
3785
  order: z12.number().finite().optional(),
3733
3786
  section: z12.enum(["primary", "plugins"]).optional(),
3787
+ badge: UiRailBadge.optional(),
3734
3788
  panel: z12.strictObject({ body: LocalContributionId2 }).optional()
3735
3789
  });
3736
3790
  const UiAppFields = z12.strictObject({
@@ -4549,6 +4603,34 @@ function createManifestSchemas(canonical) {
4549
4603
  }
4550
4604
  materializedAppDataSources.add(materializer.source);
4551
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
+ }
4552
4634
  for (const source of declaredAppDataSources) {
4553
4635
  if (materializedAppDataSources.has(source) || declaredAppDataStores.has(source))
4554
4636
  continue;
@@ -7121,6 +7203,7 @@ export {
7121
7203
  WhiteboardTypeStorage,
7122
7204
  WhiteboardValue,
7123
7205
  WorkflowContribution,
7206
+ appDataSourceDeclaration,
7124
7207
  approvalKindSchema,
7125
7208
  boundPluginDiagnosticMessage,
7126
7209
  captureArtifactProvenance,
@@ -7135,6 +7218,7 @@ export {
7135
7218
  dedupeClaims,
7136
7219
  deriveDirectoryPluginToolName,
7137
7220
  evaluateCommandWhere,
7221
+ evaluateWhere,
7138
7222
  finalizeArtifactProvenanceEnvelope,
7139
7223
  findSkillSuggestionCitations,
7140
7224
  hasClaim,
@@ -7162,6 +7246,7 @@ export {
7162
7246
  parseKayUiBundleIndexV1,
7163
7247
  parseResolvedPluginContractV1,
7164
7248
  parseSemver,
7249
+ parseWhere,
7165
7250
  pluginIconShape,
7166
7251
  precedingPersonMessages,
7167
7252
  readKayPluginDeclaredCompatibility,
@@ -7174,6 +7259,7 @@ export {
7174
7259
  resolveSessionAncestry,
7175
7260
  retiredCompatibilityKeysIn,
7176
7261
  retiredPermissionAsksIn,
7262
+ rowMatchesWhere,
7177
7263
  safeResolveKayPluginContractV1,
7178
7264
  sameClaim,
7179
7265
  satisfiesSemverRange,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yaklabs-ai/plugin-protocol",
3
- "version": "0.34.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",