@yaklabs-ai/plugin-sdk 0.37.0 → 0.38.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/README.md CHANGED
@@ -13,7 +13,7 @@ it under the name your plugin code actually imports:
13
13
  ```json
14
14
  {
15
15
  "dependencies": {
16
- "@bonsai/plugin-sdk": "npm:@yaklabs-ai/plugin-sdk@^0.37.0"
16
+ "@bonsai/plugin-sdk": "npm:@yaklabs-ai/plugin-sdk@^0.38.0"
17
17
  }
18
18
  }
19
19
  ```
@@ -62,7 +62,7 @@ Every tool the entrypoint registers is declared in the manifest too:
62
62
  "description": "Greets people by name.",
63
63
  "version": "0.1.0",
64
64
  "namespace": "widgets",
65
- "compatibility": { "sdk": "^0.37.0" },
65
+ "compatibility": { "sdk": "^0.38.0" },
66
66
  "targets": {
67
67
  "kay": {
68
68
  "agent": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "package": "@yaklabs-ai/plugin-sdk",
4
- "version": "0.37.0",
4
+ "version": "0.38.0",
5
5
  "target": "npm",
6
6
  "firstPartyLicense": "MIT",
7
7
  "bundled": [
@@ -2395,8 +2395,17 @@ declare const KAY_PLUGIN_PROTOCOL_VERSION: "kay.plugin.v1";
2395
2395
  * `contributes` names the `rule`, the `body` that fills the preview, either a `contextOnly` app in
2396
2396
  * the plugin or a body the host ships, and the `address` it is about. Additive. A plugin that
2397
2397
  * declares a preview declares ^0.37.0.
2398
+ *
2399
+ * 0.37.1 adds the required, ungated `featureFlags.value(key)` reader to both backend targets.
2400
+ * Unknown keys return false; the host supplies evaluated values before activation and updates them.
2401
+ * Additive: existing plugins keep loading. A consumer declares ^0.37.1.
2402
+ *
2403
+ * 0.38.0 adds signals (epic #15668). An event definition may declare `signal: true`, and its payload
2404
+ * is then the shared `PluginSignal` v1 with a `related.thread`; a workflow of a plugin the release
2405
+ * carries may start on every plugin's signals with `{ kind: "plugin-event", signals: true }` (the
2406
+ * private `workflows.signals` claim). Additive: a plugin that declares a signal declares ^0.38.0.
2398
2407
  */
2399
- declare const KAY_PLUGIN_SDK_VERSION: "0.37.0";
2408
+ declare const KAY_PLUGIN_SDK_VERSION: "0.38.0";
2400
2409
 
2401
2410
  declare const KAY_PLUGIN_TARGET_NAMES: readonly ["kay.agent", "kay.app", "kay.ui"];
2402
2411
 
@@ -2684,6 +2693,7 @@ declare interface KayAgentPluginApi {
2684
2693
  * the same zone-of-record port the session stamp uses; see {@link KayAppTime.snapshot}.
2685
2694
  */
2686
2695
  readonly time: KayAppTime;
2696
+ readonly featureFlags: PluginFeatureFlags;
2687
2697
  /**
2688
2698
  * File I/O in user folders, run by the host on its own worker threads under a deadline and
2689
2699
  * answered as a typed result. Always present and ungated: it takes absolute paths and checks no
@@ -4332,6 +4342,12 @@ declare const PluginEventPublishInput: z.ZodObject<{
4332
4342
 
4333
4343
  declare type PluginEventPublishInput = z.infer<typeof PluginEventPublishInput>;
4334
4344
 
4345
+ /** Evaluated Bonsai rollout values supplied by the host, without I/O or a grant. */
4346
+ declare interface PluginFeatureFlags {
4347
+ /** Read the current boolean; unknown keys return false. */
4348
+ readonly value: (key: string) => boolean;
4349
+ }
4350
+
4335
4351
  declare const PluginId: z.ZodString;
4336
4352
 
4337
4353
  declare type PluginId = z.infer<typeof PluginId>;
@@ -886,6 +886,7 @@ function createKayAgentProbeCapabilityHandles() {
886
886
  // Dropped: a probe's activation is not the plugin running, so its lines are not the plugin's.
887
887
  log: createKayPluginLog(() => {
888
888
  }),
889
+ featureFlags: { value: () => false },
889
890
  // A probe has no user-time port, so it answers the zone as unknown - the same contract the
890
891
  // real capability keeps for a zone the host cannot read.
891
892
  time: {
@@ -1196,7 +1196,7 @@ declare function FactorMapping(input: [unknown, unknown, unknown, unknown, unkno
1196
1196
  export declare function fauxAuthContext(overrides?: Partial<ExtensionAuthContext>): ExtensionAuthContext;
1197
1197
 
1198
1198
  /** The capability handles a `KayAgentPluginApi` always carries - authority is decided per call. */
1199
- export declare type FauxKayAgentCapabilities = Pick<KayAgentPluginApi, "network" | "webSession" | "process" | "whiteboard" | "interaction" | "interceptToolCall" | "implementTool" | "systemOne" | "events" | "time" | "log" | "userFiles" | "familyFolder" | "vendoredMcp" | "endpoints" | "compiler">;
1199
+ export declare type FauxKayAgentCapabilities = Pick<KayAgentPluginApi, "network" | "webSession" | "process" | "whiteboard" | "interaction" | "interceptToolCall" | "implementTool" | "systemOne" | "events" | "featureFlags" | "time" | "log" | "userFiles" | "familyFolder" | "vendoredMcp" | "endpoints" | "compiler">;
1200
1200
 
1201
1201
  export declare function fauxKayAgentCapabilities(): FauxKayAgentCapabilities;
1202
1202
 
@@ -2449,8 +2449,17 @@ declare const KAY_PLUGIN_PROTOCOL_VERSION: "kay.plugin.v1";
2449
2449
  * `contributes` names the `rule`, the `body` that fills the preview, either a `contextOnly` app in
2450
2450
  * the plugin or a body the host ships, and the `address` it is about. Additive. A plugin that
2451
2451
  * declares a preview declares ^0.37.0.
2452
+ *
2453
+ * 0.37.1 adds the required, ungated `featureFlags.value(key)` reader to both backend targets.
2454
+ * Unknown keys return false; the host supplies evaluated values before activation and updates them.
2455
+ * Additive: existing plugins keep loading. A consumer declares ^0.37.1.
2456
+ *
2457
+ * 0.38.0 adds signals (epic #15668). An event definition may declare `signal: true`, and its payload
2458
+ * is then the shared `PluginSignal` v1 with a `related.thread`; a workflow of a plugin the release
2459
+ * carries may start on every plugin's signals with `{ kind: "plugin-event", signals: true }` (the
2460
+ * private `workflows.signals` claim). Additive: a plugin that declares a signal declares ^0.38.0.
2452
2461
  */
2453
- declare const KAY_PLUGIN_SDK_VERSION: "0.37.0";
2462
+ declare const KAY_PLUGIN_SDK_VERSION: "0.38.0";
2454
2463
 
2455
2464
  declare const KAY_PLUGIN_TARGET_NAMES: readonly ["kay.agent", "kay.app", "kay.ui"];
2456
2465
 
@@ -2735,6 +2744,7 @@ declare interface KayAgentPluginApi {
2735
2744
  * the same zone-of-record port the session stamp uses; see {@link KayAppTime.snapshot}.
2736
2745
  */
2737
2746
  readonly time: KayAppTime;
2747
+ readonly featureFlags: PluginFeatureFlags;
2738
2748
  /**
2739
2749
  * File I/O in user folders, run by the host on its own worker threads under a deadline and
2740
2750
  * answered as a typed result. Always present and ungated: it takes absolute paths and checks no
@@ -4347,6 +4357,12 @@ declare const PluginEventPublishInput: z.ZodObject<{
4347
4357
 
4348
4358
  declare type PluginEventPublishInput = z.infer<typeof PluginEventPublishInput>;
4349
4359
 
4360
+ /** Evaluated Bonsai rollout values supplied by the host, without I/O or a grant. */
4361
+ declare interface PluginFeatureFlags {
4362
+ /** Read the current boolean; unknown keys return false. */
4363
+ readonly value: (key: string) => boolean;
4364
+ }
4365
+
4350
4366
  declare const PluginId: z.ZodString;
4351
4367
 
4352
4368
  declare type PluginId = z.infer<typeof PluginId>;
@@ -5641,9 +5657,9 @@ declare const ResolvedPluginContractV1: z.ZodObject<{
5641
5657
  pluginId: z.ZodString;
5642
5658
  url: z.ZodString;
5643
5659
  auth: z.ZodEnum<{
5660
+ none: "none";
5644
5661
  oauth: "oauth";
5645
5662
  "api-key": "api-key";
5646
- none: "none";
5647
5663
  }>;
5648
5664
  authServiceId: z.ZodOptional<z.ZodString>;
5649
5665
  }, z.core.$strict>>>;
@@ -295,6 +295,7 @@ function fauxKayAgentCapabilities() {
295
295
  // rejecting double would fail tests for a reason production never has. A test asserting what
296
296
  // its plugin publishes overrides this handle after the spread.
297
297
  events: { publish: () => void 0 },
298
+ featureFlags: { value: () => false },
298
299
  // A test double has no user-time port, so it answers the zone as unknown - the same contract
299
300
  // the real capability keeps for a zone the host cannot read. A test that exercises a plugin's
300
301
  // zone-of-record path overrides this handle after the spread.
@@ -2724,8 +2724,17 @@ declare const KAY_PLUGIN_PROTOCOL_VERSION: "kay.plugin.v1";
2724
2724
  * `contributes` names the `rule`, the `body` that fills the preview, either a `contextOnly` app in
2725
2725
  * the plugin or a body the host ships, and the `address` it is about. Additive. A plugin that
2726
2726
  * declares a preview declares ^0.37.0.
2727
+ *
2728
+ * 0.37.1 adds the required, ungated `featureFlags.value(key)` reader to both backend targets.
2729
+ * Unknown keys return false; the host supplies evaluated values before activation and updates them.
2730
+ * Additive: existing plugins keep loading. A consumer declares ^0.37.1.
2731
+ *
2732
+ * 0.38.0 adds signals (epic #15668). An event definition may declare `signal: true`, and its payload
2733
+ * is then the shared `PluginSignal` v1 with a `related.thread`; a workflow of a plugin the release
2734
+ * carries may start on every plugin's signals with `{ kind: "plugin-event", signals: true }` (the
2735
+ * private `workflows.signals` claim). Additive: a plugin that declares a signal declares ^0.38.0.
2727
2736
  */
2728
- declare const KAY_PLUGIN_SDK_VERSION: "0.37.0";
2737
+ declare const KAY_PLUGIN_SDK_VERSION: "0.38.0";
2729
2738
 
2730
2739
  declare const KAY_PLUGIN_TARGET_NAMES: readonly ["kay.agent", "kay.app", "kay.ui"];
2731
2740
 
@@ -3042,6 +3051,7 @@ export declare interface KayAgentPluginApi {
3042
3051
  * the same zone-of-record port the session stamp uses; see {@link KayAppTime.snapshot}.
3043
3052
  */
3044
3053
  readonly time: KayAppTime;
3054
+ readonly featureFlags: PluginFeatureFlags;
3045
3055
  /**
3046
3056
  * File I/O in user folders, run by the host on its own worker threads under a deadline and
3047
3057
  * answered as a typed result. Always present and ungated: it takes absolute paths and checks no
@@ -5082,6 +5092,10 @@ declare const PluginCapabilityRefusalV1: z.ZodObject<{
5082
5092
  target: z.ZodLiteral<"kay.app">;
5083
5093
  slug: z.ZodLiteral<"workflows.define">;
5084
5094
  envelope: z.ZodObject<{}, z.core.$strict>;
5095
+ }, z.core.$strict>, z.ZodObject<{
5096
+ target: z.ZodLiteral<"kay.app">;
5097
+ slug: z.ZodLiteral<"workflows.signals">;
5098
+ envelope: z.ZodObject<{}, z.core.$strict>;
5085
5099
  }, z.core.$strict>, z.ZodObject<{
5086
5100
  target: z.ZodLiteral<"kay.app">;
5087
5101
  slug: z.ZodLiteral<"session-events.subscribe">;
@@ -5363,6 +5377,12 @@ export declare const PluginEventPublishInput: z.ZodObject<{
5363
5377
 
5364
5378
  export declare type PluginEventPublishInput = z.infer<typeof PluginEventPublishInput>;
5365
5379
 
5380
+ /** Evaluated Bonsai rollout values supplied by the host, without I/O or a grant. */
5381
+ export declare interface PluginFeatureFlags {
5382
+ /** Read the current boolean; unknown keys return false. */
5383
+ readonly value: (key: string) => boolean;
5384
+ }
5385
+
5366
5386
  declare const PluginId: z.ZodString;
5367
5387
 
5368
5388
  declare type PluginId = z.infer<typeof PluginId>;
package/dist/kay-app.d.ts CHANGED
@@ -1813,6 +1813,20 @@ declare function IsCodec(value: unknown): value is TCodec;
1813
1813
  /** Returns true if the given value is a TConstructor. */
1814
1814
  declare function IsConstructor(value: unknown): value is TConstructor;
1815
1815
 
1816
+ /**
1817
+ * The recognized credential VALUE formats: one detector for the runtime wire's raw-credential
1818
+ * tripwire (`@bonsai/agent-runtime-protocol`'s `hasRawCredentialField`) and for a plugin that
1819
+ * must keep such text out of what it publishes, so the two cannot disagree on what a hit is.
1820
+ * Lives here, below both, because a plugin cannot import the runtime protocol.
1821
+ */
1822
+ /**
1823
+ * Whether `value` is a string in a recognized credential format (a whole `sk-...`, `ghp_...` or
1824
+ * `xoxb-...` token, a JWT, an Authorization header value, or anything holding a PEM private key
1825
+ * block). A publisher that copies outside text into an event drops or replaces such a string:
1826
+ * the daemon refuses an event that carries one.
1827
+ */
1828
+ export declare function isCredentialShapedText(value: unknown): boolean;
1829
+
1816
1830
  /** Returns true if the given value is a TCyclic. */
1817
1831
  declare function IsCyclic(value: unknown): value is TCyclic;
1818
1832
 
@@ -2686,8 +2700,17 @@ declare const KAY_PLUGIN_PROTOCOL_VERSION: "kay.plugin.v1";
2686
2700
  * `contributes` names the `rule`, the `body` that fills the preview, either a `contextOnly` app in
2687
2701
  * the plugin or a body the host ships, and the `address` it is about. Additive. A plugin that
2688
2702
  * declares a preview declares ^0.37.0.
2703
+ *
2704
+ * 0.37.1 adds the required, ungated `featureFlags.value(key)` reader to both backend targets.
2705
+ * Unknown keys return false; the host supplies evaluated values before activation and updates them.
2706
+ * Additive: existing plugins keep loading. A consumer declares ^0.37.1.
2707
+ *
2708
+ * 0.38.0 adds signals (epic #15668). An event definition may declare `signal: true`, and its payload
2709
+ * is then the shared `PluginSignal` v1 with a `related.thread`; a workflow of a plugin the release
2710
+ * carries may start on every plugin's signals with `{ kind: "plugin-event", signals: true }` (the
2711
+ * private `workflows.signals` claim). Additive: a plugin that declares a signal declares ^0.38.0.
2689
2712
  */
2690
- declare const KAY_PLUGIN_SDK_VERSION: "0.37.0";
2713
+ declare const KAY_PLUGIN_SDK_VERSION: "0.38.0";
2691
2714
 
2692
2715
  declare const KAY_PLUGIN_TARGET_NAMES: readonly ["kay.agent", "kay.app", "kay.ui"];
2693
2716
 
@@ -5095,6 +5118,7 @@ export declare interface KayAppPluginApi {
5095
5118
  * `Intl` or `process.env.TZ`; see {@link KayAppTime.snapshot}.
5096
5119
  */
5097
5120
  readonly time: KayAppTime;
5121
+ readonly featureFlags: PluginFeatureFlags;
5098
5122
  /**
5099
5123
  * A logger whose lines land in Bonsai's own log under this plugin's id. Always present and
5100
5124
  * ungated, like {@link time}: it writes under the plugin's own name, which a plugin's console
@@ -8312,6 +8336,22 @@ export declare interface KayAppWorkflows {
8312
8336
  inspect(localId: string, options?: KayAppWorkflowInspectOptions): Promise<KayAppWorkflowInspection>;
8313
8337
  }
8314
8338
 
8339
+ /**
8340
+ * Every event any plugin declares `signal: true`, from every plugin, including plugins installed
8341
+ * later. The payload of each is `PluginSignal` v1, and `related.thread` names its conversation or
8342
+ * object, so the workflow handles a new source without changing.
8343
+ *
8344
+ * Only a plugin Bonsai ships may define one: it asks for the private `workflows.signals` claim,
8345
+ * and any other plugin's activation is refused. `where` filters take envelope paths,
8346
+ * `related.thread|from|to|cc` and `payload.<PluginSignal field>`.
8347
+ */
8348
+ export declare interface KayAppWorkflowSignalsTrigger {
8349
+ readonly kind: "plugin-event";
8350
+ readonly signals: true;
8351
+ readonly events?: undefined;
8352
+ readonly where?: KayAppAutomationPluginEventCondition["where"];
8353
+ }
8354
+
8315
8355
  export declare type KayAppWorkflowTimeTrigger = Extract<KayAppAutomationConditionInput, {
8316
8356
  readonly kind: "time";
8317
8357
  }>;
@@ -8321,12 +8361,13 @@ export declare type KayAppWorkflowTimeTrigger = Extract<KayAppAutomationConditio
8321
8361
  *
8322
8362
  * An event trigger names full event types (`google.gmail.message.received`) and takes the same
8323
8363
  * filters as a `plugin-event` automation. Each matching event starts one run. Only events this
8324
- * plugin declares are accepted; another plugin's events are refused at `define`.
8364
+ * plugin declares are accepted; another plugin's events are refused at `define`. The one way to
8365
+ * hear other plugins is {@link KayAppWorkflowSignalsTrigger}, for plugins Bonsai ships.
8325
8366
  *
8326
8367
  * A run is not started by an event that one of this workflow's own runs published, as long as the
8327
8368
  * publish names the run: pass `source: { runId: ctx.runId }` (the Poller helper does).
8328
8369
  */
8329
- export declare type KayAppWorkflowTrigger = KayAppWorkflowTimeTrigger | KayAppAutomationPluginEventCondition;
8370
+ export declare type KayAppWorkflowTrigger = KayAppWorkflowTimeTrigger | KayAppAutomationPluginEventCondition | KayAppWorkflowSignalsTrigger;
8330
8371
 
8331
8372
  /**
8332
8373
  * Read/arrange access to the live desktop workspace (tabs, panes, the shell chrome). Always
@@ -9706,6 +9747,26 @@ declare function Pick_2<Type extends TSchema, Indexer extends TSchema>(type: Typ
9706
9747
  /** Creates a deferred Pick action. */
9707
9748
  declare function PickDeferred<Type extends TSchema, Indexer extends TSchema>(type: Type, indexer: Indexer, options?: TSchemaOptions): TPickDeferred<Type, Indexer>;
9708
9749
 
9750
+ /**
9751
+ * The `name` of the error a host throws when it refuses a publish because the event is invalid.
9752
+ * A publisher skips such an event; any other publish failure may be transient.
9753
+ */
9754
+ export declare const PLUGIN_EVENT_REFUSED_ERROR_NAME = "PluginEventRefusedError";
9755
+
9756
+ /** The `kind` values of `PluginSignal` v1. `status` is system state that clears itself. */
9757
+ export declare const PLUGIN_SIGNAL_KINDS: readonly ["message", "request", "mention", "invite", "status"];
9758
+
9759
+ export declare const PLUGIN_SIGNAL_LABEL_MAX = 64;
9760
+
9761
+ export declare const PLUGIN_SIGNAL_LABELS_MAX = 20;
9762
+
9763
+ /** The `related` keys a signal may use; `thread` is required on every signal publish. */
9764
+ export declare const PLUGIN_SIGNAL_RELATED_KEYS: readonly ["thread", "from", "to", "cc"];
9765
+
9766
+ export declare const PLUGIN_SIGNAL_SNIPPET_MAX = 500;
9767
+
9768
+ export declare const PLUGIN_SIGNAL_TITLE_MAX = 300;
9769
+
9709
9770
  export declare const PluginAgentDefinitionPermissionRule: z.ZodObject<{
9710
9771
  effect: z.ZodEnum<{
9711
9772
  allow: "allow";
@@ -9762,6 +9823,12 @@ export declare const PluginEventPublishInput: z.ZodObject<{
9762
9823
 
9763
9824
  export declare type PluginEventPublishInput = z.infer<typeof PluginEventPublishInput>;
9764
9825
 
9826
+ /** Evaluated Bonsai rollout values supplied by the host, without I/O or a grant. */
9827
+ export declare interface PluginFeatureFlags {
9828
+ /** Read the current boolean; unknown keys return false. */
9829
+ readonly value: (key: string) => boolean;
9830
+ }
9831
+
9765
9832
  declare const PluginId: z.ZodString;
9766
9833
 
9767
9834
  declare type PluginId = z.infer<typeof PluginId>;
@@ -9770,6 +9837,86 @@ declare const PluginNamespace: z.ZodString;
9770
9837
 
9771
9838
  declare type PluginNamespace = z.infer<typeof PluginNamespace>;
9772
9839
 
9840
+ export declare const PluginSignal: z.ZodObject<{
9841
+ kind: z.ZodEnum<{
9842
+ message: "message";
9843
+ status: "status";
9844
+ request: "request";
9845
+ mention: "mention";
9846
+ invite: "invite";
9847
+ }>;
9848
+ direction: z.ZodOptional<z.ZodEnum<{
9849
+ out: "out";
9850
+ in: "in";
9851
+ }>>;
9852
+ title: z.ZodOptional<z.ZodString>;
9853
+ snippet: z.ZodOptional<z.ZodString>;
9854
+ actor: z.ZodOptional<z.ZodObject<{
9855
+ name: z.ZodOptional<z.ZodString>;
9856
+ uri: z.ZodString;
9857
+ }, z.core.$strict>>;
9858
+ addressed: z.ZodOptional<z.ZodEnum<{
9859
+ mention: "mention";
9860
+ cc: "cc";
9861
+ direct: "direct";
9862
+ group: "group";
9863
+ none: "none";
9864
+ }>>;
9865
+ labels: z.ZodOptional<z.ZodArray<z.ZodString>>;
9866
+ dueAt: z.ZodOptional<z.ZodISODateTime>;
9867
+ state: z.ZodOptional<z.ZodEnum<{
9868
+ open: "open";
9869
+ resolved: "resolved";
9870
+ }>>;
9871
+ }, z.core.$strict>;
9872
+
9873
+ export declare type PluginSignal = z.infer<typeof PluginSignal>;
9874
+
9875
+ export declare type PluginSignalKind = (typeof PLUGIN_SIGNAL_KINDS)[number];
9876
+
9877
+ export declare const PluginSignalPublish: z.ZodObject<{
9878
+ payload: z.ZodObject<{
9879
+ kind: z.ZodEnum<{
9880
+ message: "message";
9881
+ status: "status";
9882
+ request: "request";
9883
+ mention: "mention";
9884
+ invite: "invite";
9885
+ }>;
9886
+ direction: z.ZodOptional<z.ZodEnum<{
9887
+ out: "out";
9888
+ in: "in";
9889
+ }>>;
9890
+ title: z.ZodOptional<z.ZodString>;
9891
+ snippet: z.ZodOptional<z.ZodString>;
9892
+ actor: z.ZodOptional<z.ZodObject<{
9893
+ name: z.ZodOptional<z.ZodString>;
9894
+ uri: z.ZodString;
9895
+ }, z.core.$strict>>;
9896
+ addressed: z.ZodOptional<z.ZodEnum<{
9897
+ mention: "mention";
9898
+ cc: "cc";
9899
+ direct: "direct";
9900
+ group: "group";
9901
+ none: "none";
9902
+ }>>;
9903
+ labels: z.ZodOptional<z.ZodArray<z.ZodString>>;
9904
+ dueAt: z.ZodOptional<z.ZodISODateTime>;
9905
+ state: z.ZodOptional<z.ZodEnum<{
9906
+ open: "open";
9907
+ resolved: "resolved";
9908
+ }>>;
9909
+ }, z.core.$strict>;
9910
+ related: z.ZodObject<{
9911
+ thread: z.ZodString;
9912
+ from: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
9913
+ to: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
9914
+ cc: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
9915
+ }, z.core.$strict>;
9916
+ }, z.core.$strip>;
9917
+
9918
+ export declare type PluginSignalPublish = z.infer<typeof PluginSignalPublish>;
9919
+
9773
9920
  declare const PluginSourceClass: z.ZodEnum<{
9774
9921
  bundled: "bundled";
9775
9922
  "org-shared": "org-shared";
package/dist/kay-app.js CHANGED
@@ -1,3 +1,62 @@
1
+ // packages/plugin-protocol/dist/plugin-signal-limits.js
2
+ var PLUGIN_EVENT_REFUSED_ERROR_NAME = "PluginEventRefusedError";
3
+ var PLUGIN_SIGNAL_KINDS = [
4
+ "message",
5
+ "request",
6
+ "mention",
7
+ "invite",
8
+ "status"
9
+ ];
10
+ var PLUGIN_SIGNAL_TITLE_MAX = 300;
11
+ var PLUGIN_SIGNAL_SNIPPET_MAX = 500;
12
+ var PLUGIN_SIGNAL_LABELS_MAX = 20;
13
+ var PLUGIN_SIGNAL_LABEL_MAX = 64;
14
+ var PLUGIN_SIGNAL_RELATED_KEYS = [
15
+ "thread",
16
+ "from",
17
+ "to",
18
+ "cc"
19
+ ];
20
+
21
+ // packages/plugin-protocol/dist/credential-text.js
22
+ var CREDENTIAL_VALUE_PATTERNS = [
23
+ // Anthropic / OpenAI-style secret keys (`sk-`, `sk-ant-`, `sk-proj-`).
24
+ /^sk-[A-Za-z0-9_-]{16,}$/u,
25
+ // GitHub classic, fine-grained, app, and OAuth tokens.
26
+ /^gh[pousr]_[A-Za-z0-9]{16,}$/u,
27
+ /^github_pat_[A-Za-z0-9_]{20,}$/u,
28
+ // GitLab personal access tokens.
29
+ /^glpat-[A-Za-z0-9_-]{16,}$/u,
30
+ // Slack bot/user/app tokens.
31
+ /^xox[baprse]-[A-Za-z0-9-]{10,}$/u,
32
+ // AWS access key ids, long-lived and STS-issued.
33
+ /^(?:AKIA|ASIA)[0-9A-Z]{16}$/u,
34
+ // Google API keys, both published shapes.
35
+ /^AIza[0-9A-Za-z_-]{35}$/u,
36
+ /^AQ\.[A-Za-z0-9_-]{20,}$/u,
37
+ // npm automation tokens.
38
+ /^npm_[A-Za-z0-9]{30,}$/u,
39
+ // SendGrid API keys (SG.<key id>.<secret>).
40
+ /^SG\.[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}$/u,
41
+ // HashiCorp Vault service/batch/recovery tokens.
42
+ /^hv[sbr]\.[A-Za-z0-9_-]{20,}$/u,
43
+ // Shopify access tokens.
44
+ /^shp(?:at|ss|ca|pa)_[a-fA-F0-9]{32}$/u,
45
+ // Stripe live/test secret and restricted keys.
46
+ /^(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{16,}$/u,
47
+ // JSON Web Tokens - header.payload.signature, header always starts `eyJ`.
48
+ /^eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]*$/u,
49
+ // A whole Authorization header value carried as data.
50
+ /^(?:Bearer|Basic) [A-Za-z0-9+/._~-]{16,}={0,2}$/iu,
51
+ // PEM private key blocks, anywhere in the string.
52
+ /-----BEGIN (?:[A-Z]+ )?PRIVATE KEY-----/u
53
+ ];
54
+ function isCredentialShapedText(value) {
55
+ if (typeof value !== "string" || value.length === 0)
56
+ return false;
57
+ return CREDENTIAL_VALUE_PATTERNS.some((pattern) => pattern.test(value));
58
+ }
59
+
1
60
  // packages/plugin-protocol/dist/json.js
2
61
  import { z } from "zod";
3
62
  var JsonValue = z.lazy(() => z.union([
@@ -655,6 +714,7 @@ function definePoller(app, localId, options) {
655
714
  let initialized = 0;
656
715
  let skipped = 0;
657
716
  let failed = 0;
717
+ let refused = 0;
658
718
  for (const { account, credential } of accounts) {
659
719
  const saved = previous.find((entry) => entry.schemeId === account.schemeId && entry.accountId === account.accountId);
660
720
  const name = `${account.schemeId}/${account.accountId}`;
@@ -682,15 +742,35 @@ function definePoller(app, localId, options) {
682
742
  continue;
683
743
  }
684
744
  const toPublish = saved === void 0 ? [] : result.events ?? [];
685
- await runStep(async () => {
686
- for (const event of toPublish) {
687
- events.publish(event.localId, {
688
- ...event.input,
689
- source: { poller: localId, runId }
690
- });
691
- }
692
- });
693
- published += toPublish.length;
745
+ let refusedHere = 0;
746
+ try {
747
+ refusedHere = await runStep(async () => {
748
+ let refusedInStep = 0;
749
+ for (const event of toPublish) {
750
+ try {
751
+ events.publish(event.localId, {
752
+ ...event.input,
753
+ source: { poller: localId, runId }
754
+ });
755
+ } catch (error) {
756
+ if (!isPublishRefusal(error))
757
+ throw error;
758
+ refusedInStep++;
759
+ }
760
+ }
761
+ return refusedInStep;
762
+ });
763
+ } catch (error) {
764
+ if (!isPublishRefusal(error))
765
+ throw error;
766
+ refusedHere = Math.max(refusedHere, refusedCountOf(error));
767
+ }
768
+ refused += refusedHere;
769
+ published += toPublish.length - refusedHere;
770
+ if (refusedHere > 0) {
771
+ const names = [...new Set(toPublish.map((event) => event.localId))];
772
+ details.push(`${name}: ${refusedHere} event(s) refused as invalid and skipped (${names.join(", ")})`);
773
+ }
694
774
  if (saved === void 0)
695
775
  initialized++;
696
776
  next.push({
@@ -705,13 +785,20 @@ function definePoller(app, localId, options) {
705
785
  return {
706
786
  state: { accounts: next },
707
787
  summary: {
708
- headline: plainText(`${published} events; ${initialized} initialized; ${skipped} skipped; ${failed} failed`, 100),
788
+ headline: plainText(`${published} events; ${initialized} initialized; ${skipped} skipped; ${failed} failed${refused === 0 ? "" : `; ${refused} refused`}`, 100),
709
789
  ...details.length === 0 ? {} : { details: plainText(details.join("; "), 600) },
710
790
  author: "automation"
711
791
  }
712
792
  };
713
793
  });
714
794
  }
795
+ function isPublishRefusal(error) {
796
+ return error instanceof Error && error.name === PLUGIN_EVENT_REFUSED_ERROR_NAME;
797
+ }
798
+ function refusedCountOf(error) {
799
+ const count = error.refusedCount;
800
+ return typeof count === "number" && Number.isSafeInteger(count) && count > 0 ? count : 1;
801
+ }
715
802
 
716
803
  // packages/plugin-sdk/dist/kay-app/sealing.js
717
804
  var KAY_APP_SEALING_MAX_BYTES = 1048576;
@@ -841,6 +928,13 @@ export {
841
928
  KayAppCredentialRejectedError,
842
929
  KayAppWorkflowFailure,
843
930
  MAX_CHOICE_LABELS,
931
+ PLUGIN_EVENT_REFUSED_ERROR_NAME,
932
+ PLUGIN_SIGNAL_KINDS,
933
+ PLUGIN_SIGNAL_LABELS_MAX,
934
+ PLUGIN_SIGNAL_LABEL_MAX,
935
+ PLUGIN_SIGNAL_RELATED_KEYS,
936
+ PLUGIN_SIGNAL_SNIPPET_MAX,
937
+ PLUGIN_SIGNAL_TITLE_MAX,
844
938
  SIGNAL_TIME_MAX_MS,
845
939
  STORED_TRANSCRIPT_MESSAGE_FILTER,
846
940
  STORED_TRANSCRIPT_MESSAGE_KINDS,
@@ -859,6 +953,7 @@ export {
859
953
  definePoller,
860
954
  failedRunCause,
861
955
  invalidObservation,
956
+ isCredentialShapedText,
862
957
  isRetryable,
863
958
  parseLineSelector,
864
959
  parseStoredTranscriptKindFilter,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yaklabs-ai/plugin-sdk",
3
- "version": "0.37.0",
3
+ "version": "0.38.0",
4
4
  "description": "The Kay plugin SDK — types and helpers for authoring a Kay directory plugin.",
5
5
  "author": "YakLabs",
6
6
  "type": "module",