@yaklabs-ai/plugin-sdk 0.55.2 → 0.55.4

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.55.2"
16
+ "@bonsai/plugin-sdk": "npm:@yaklabs-ai/plugin-sdk@^0.55.4"
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.55.2" },
65
+ "compatibility": { "sdk": "^0.55.4" },
66
66
  "targets": {
67
67
  "kay": {
68
68
  "agent": {
@@ -153,7 +153,7 @@ naming both versions, instead of loading it and finding no `activate`.
153
153
  | `@bonsai/plugin-sdk/system-one` | The types and error class for `api.systemOne` / `app.systemOne`, from 0.13.8 |
154
154
  | `@bonsai/plugin-sdk/zod` | `z` (the host's in the daemon), on an entry with no other import, from 0.13.9 |
155
155
 
156
- A plugin that imports these subpaths declares the current supported SDK range (`^0.55.2`).
156
+ A plugin that imports these subpaths declares the current supported SDK range (`^0.55.4`).
157
157
  The rows record when each subpath appeared, not retained runtime compatibility. `vendored-mcp` builds the plugin's URI module (its link cards and help); hosting the
158
158
  vendor's MCP server itself is a separate host decision: Bonsai hosts it once a person approves
159
159
  the plugin's `mcp.host-server` grant for that server's name and URL. A server that needs an OAuth
@@ -161,7 +161,7 @@ sign-in names one of the plugin's auth services in `authService`; that service m
161
161
  one `delegated` scheme, which Bonsai uses to sign the person in to the server. Bonsai declares that
162
162
  scheme at runtime; the plugin's code must not declare it again. From 0.16.2 a plugin's code can also
163
163
  call the server's tools through `api.vendoredMcp.port(<server>)`, typed by this subpath's
164
- `VendoredMcpPort` and `VendoredMcpOutcome` (declare `^0.55.2`).
164
+ `VendoredMcpPort` and `VendoredMcpOutcome` (declare `^0.55.4`).
165
165
 
166
166
  From 0.13.10 the manifest schema carries two facts Bonsai reads for its own plugins only; another
167
167
  plugin's are ignored, with a load diagnostic. An `external-cli` auth scheme's `cli` says how Bonsai
@@ -243,7 +243,7 @@ Provider schemas remain authoritative; declaring a dependency grants no authorit
243
243
  through `app.uri`, parse returned Markdown in the consuming plugin, and retain the read's
244
244
  revision (or `contentDigest` from `/uri`) for edits. The old `memory.read` and `memory.write`
245
245
  grants do not authorize the replacement scheme-and-verb calls. Contracts before 0.49.0 are
246
- refused; migrate and declare `^0.55.2`. The current host also serves the 0.49.0 resource contract.
246
+ refused; migrate and declare `^0.55.4`. The current host also serves the 0.49.0 resource contract.
247
247
 
248
248
  ## What this package is, and is not, at runtime
249
249
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "package": "@yaklabs-ai/plugin-sdk",
4
- "version": "0.55.2",
4
+ "version": "0.55.4",
5
5
  "target": "npm",
6
6
  "firstPartyLicense": "MIT",
7
7
  "bundled": [
@@ -805,6 +805,13 @@ declare interface CollaborationMessageDetails {
805
805
  readonly kind: "message" | "progress";
806
806
  }
807
807
 
808
+ /**
809
+ * Why a compaction committed the code-written fallback text instead of a model-written summary:
810
+ * the standalone executor's reasons, with every provider failure folded into `provider`. A closed
811
+ * set, so the reason can leave the device; `other` holds anything the executor adds later.
812
+ */
813
+ declare const COMPACTION_FALLBACK_REASONS: readonly ["deadline", "invalid-cut", "no-callable-model", "insufficient-context", "provider", "unusable-output", "unsupported-stop-directive", "preparation", "model-resolution", "prompt-preparation", "output-validation", "other"];
814
+
808
815
  declare interface CompactionEntry extends EntryBase {
809
816
  type: "compaction";
810
817
  summary: string;
@@ -826,6 +833,8 @@ declare interface CompactionFailedSessionEvent {
826
833
  readonly durationMs: number;
827
834
  }
828
835
 
836
+ declare type CompactionFallbackReason = (typeof COMPACTION_FALLBACK_REASONS)[number];
837
+
829
838
  /**
830
839
  * Why a session-initiated compaction ran. `threshold` is the pluggable-policy
831
840
  * usage check, now consulted at TWO points - every tool-batch boundary inside a
@@ -1841,6 +1850,12 @@ declare type HerdHarnessEvent = {
1841
1850
  readonly type: "session_compact";
1842
1851
  readonly compactionEntry: CompactionEntry;
1843
1852
  readonly fromHook: boolean;
1853
+ /** The measurements `herd.context.compacted` carries; see its payload. */
1854
+ readonly tokensBefore?: number;
1855
+ readonly durationMs?: number;
1856
+ readonly fallbackReason?: CompactionFallbackReason;
1857
+ readonly fallbackProviderReason?: RunFailureReason;
1858
+ readonly operationId?: string;
1844
1859
  } | {
1845
1860
  readonly type: "summary_operation_settled";
1846
1861
  } | {
@@ -227,7 +227,7 @@ export declare interface AuditPluginDisclosureInput {
227
227
 
228
228
  /**
229
229
  * The codegen-pair equivalence check every bundled-skill plugin hand-rolled (see
230
- * `plugins/ARCHITECTURE.md` -> "Bundled skills", step 4): every exported `PluginSkillDefinition`
230
+ * `plugins/gmail/test/gmail-plugin.test.ts`): every exported `PluginSkillDefinition`
231
231
  * must have a matching manifest declaration (same `localId`, same `description`), and the
232
232
  * declared `SKILL.md` file's decoded YAML name and description must match the export.
233
233
  * The body is compared byte-for-byte after trimming surrounding whitespace.
@@ -2682,8 +2682,18 @@ declare const KAY_PLUGIN_PROTOCOL_VERSION: "kay.plugin.v1";
2682
2682
  * artifact usage declarations. A plugin using these declares ^0.55.1.
2683
2683
  *
2684
2684
  * 0.55.2 adds opt-in query and connection-selector preservation during URI claim normalization.
2685
+ *
2686
+ * 0.55.3 lets a signal carry the item's own text. `PluginSignal` gains an optional `body`: plain
2687
+ * text, at most `PLUGIN_SIGNAL_BODY_MAX` (20,000) characters. Gmail puts a mail's text there, so
2688
+ * Flows can keep the messages a task came from. Additive: a plugin that publishes a body declares
2689
+ * ^0.55.3.
2690
+ *
2691
+ * 0.55.4 adds `app.plugins.listServices()` under the new `plugins.read` claim: every auth service
2692
+ * of the installed, enabled plugins, with the plugin's id and display name and whether the person
2693
+ * has connected it. No account, identity or scope. Built-ins hold the claim; any other plugin needs
2694
+ * a grant. Additive; plugins calling it declare ^0.55.4.
2685
2695
  */
2686
- declare const KAY_PLUGIN_SDK_VERSION: "0.55.2";
2696
+ declare const KAY_PLUGIN_SDK_VERSION: "0.55.4";
2687
2697
 
2688
2698
  declare const KAY_PLUGIN_TARGET_NAMES: readonly ["kay.agent", "kay.app", "kay.ui"];
2689
2699
 
@@ -2736,8 +2736,18 @@ declare const KAY_PLUGIN_PROTOCOL_VERSION: "kay.plugin.v1";
2736
2736
  * artifact usage declarations. A plugin using these declares ^0.55.1.
2737
2737
  *
2738
2738
  * 0.55.2 adds opt-in query and connection-selector preservation during URI claim normalization.
2739
+ *
2740
+ * 0.55.3 lets a signal carry the item's own text. `PluginSignal` gains an optional `body`: plain
2741
+ * text, at most `PLUGIN_SIGNAL_BODY_MAX` (20,000) characters. Gmail puts a mail's text there, so
2742
+ * Flows can keep the messages a task came from. Additive: a plugin that publishes a body declares
2743
+ * ^0.55.3.
2744
+ *
2745
+ * 0.55.4 adds `app.plugins.listServices()` under the new `plugins.read` claim: every auth service
2746
+ * of the installed, enabled plugins, with the plugin's id and display name and whether the person
2747
+ * has connected it. No account, identity or scope. Built-ins hold the claim; any other plugin needs
2748
+ * a grant. Additive; plugins calling it declare ^0.55.4.
2739
2749
  */
2740
- declare const KAY_PLUGIN_SDK_VERSION: "0.55.2";
2750
+ declare const KAY_PLUGIN_SDK_VERSION: "0.55.4";
2741
2751
 
2742
2752
  declare const KAY_PLUGIN_TARGET_NAMES: readonly ["kay.agent", "kay.app", "kay.ui"];
2743
2753
 
@@ -3090,8 +3090,18 @@ declare const KAY_PLUGIN_PROTOCOL_VERSION: "kay.plugin.v1";
3090
3090
  * artifact usage declarations. A plugin using these declares ^0.55.1.
3091
3091
  *
3092
3092
  * 0.55.2 adds opt-in query and connection-selector preservation during URI claim normalization.
3093
+ *
3094
+ * 0.55.3 lets a signal carry the item's own text. `PluginSignal` gains an optional `body`: plain
3095
+ * text, at most `PLUGIN_SIGNAL_BODY_MAX` (20,000) characters. Gmail puts a mail's text there, so
3096
+ * Flows can keep the messages a task came from. Additive: a plugin that publishes a body declares
3097
+ * ^0.55.3.
3098
+ *
3099
+ * 0.55.4 adds `app.plugins.listServices()` under the new `plugins.read` claim: every auth service
3100
+ * of the installed, enabled plugins, with the plugin's id and display name and whether the person
3101
+ * has connected it. No account, identity or scope. Built-ins hold the claim; any other plugin needs
3102
+ * a grant. Additive; plugins calling it declare ^0.55.4.
3093
3103
  */
3094
- declare const KAY_PLUGIN_SDK_VERSION: "0.55.2";
3104
+ declare const KAY_PLUGIN_SDK_VERSION: "0.55.4";
3095
3105
 
3096
3106
  declare const KAY_PLUGIN_TARGET_NAMES: readonly ["kay.agent", "kay.app", "kay.ui"];
3097
3107
 
@@ -5436,6 +5446,10 @@ declare const PluginCapabilityRefusalV1: z.ZodObject<{
5436
5446
  target: z.ZodLiteral<"kay.app">;
5437
5447
  slug: z.ZodLiteral<"plugins.set-enabled">;
5438
5448
  envelope: z.ZodObject<{}, z.core.$strict>;
5449
+ }, z.core.$strict>, z.ZodObject<{
5450
+ target: z.ZodLiteral<"kay.app">;
5451
+ slug: z.ZodLiteral<"plugins.read">;
5452
+ envelope: z.ZodObject<{}, z.core.$strict>;
5439
5453
  }, z.core.$strict>, z.ZodObject<{
5440
5454
  target: z.ZodLiteral<"kay.app">;
5441
5455
  slug: z.ZodLiteral<"sessions.assign-project">;
@@ -2230,6 +2230,14 @@ declare interface KayAppSessions {
2230
2230
  * against `sessions.read`. Unsupported hosts may omit it.
2231
2231
  */
2232
2232
  listSessionPage?(request: KayAppSessionListRequest): Promise<KayAppSessionList>;
2233
+ /**
2234
+ * Called after a stored session's index row changes (its title, folder or project, or its
2235
+ * removal); a change without `sessionId` means any session may have changed. Checked against
2236
+ * `sessions.read`. Returns the unsubscribe. Unsupported hosts may omit it.
2237
+ */
2238
+ subscribeChanges?(listener: (change: {
2239
+ readonly sessionId?: string;
2240
+ }) => void): () => void;
2233
2241
  /**
2234
2242
  * Read a cheap transcript change marker without loading the entry log. Unknown or deleted
2235
2243
  * sessions yield `undefined`.
package/dist/kay-app.d.ts CHANGED
@@ -1045,7 +1045,7 @@ declare type AgentRuntimeSessionOutcomeConfidence = z.infer<typeof AgentRuntimeS
1045
1045
 
1046
1046
  /**
1047
1047
  * How a session's work is judged to have served the user (telemetry lane
1048
- * PR 5, `docs/telemetry-lane-pr5-contracts.md` §2.1).
1048
+ * PR 5, `docs/records/telemetry-lane-pr5-contracts.md` §2.1).
1049
1049
  *
1050
1050
  * `"unclear"` is a FIRST-CLASS verdict, not an error code: a judge that cannot
1051
1051
  * tell must say so rather than guess, and the share of `unclear` is itself a
@@ -4392,8 +4392,18 @@ declare const KAY_PLUGIN_PROTOCOL_VERSION: "kay.plugin.v1";
4392
4392
  * artifact usage declarations. A plugin using these declares ^0.55.1.
4393
4393
  *
4394
4394
  * 0.55.2 adds opt-in query and connection-selector preservation during URI claim normalization.
4395
+ *
4396
+ * 0.55.3 lets a signal carry the item's own text. `PluginSignal` gains an optional `body`: plain
4397
+ * text, at most `PLUGIN_SIGNAL_BODY_MAX` (20,000) characters. Gmail puts a mail's text there, so
4398
+ * Flows can keep the messages a task came from. Additive: a plugin that publishes a body declares
4399
+ * ^0.55.3.
4400
+ *
4401
+ * 0.55.4 adds `app.plugins.listServices()` under the new `plugins.read` claim: every auth service
4402
+ * of the installed, enabled plugins, with the plugin's id and display name and whether the person
4403
+ * has connected it. No account, identity or scope. Built-ins hold the claim; any other plugin needs
4404
+ * a grant. Additive; plugins calling it declare ^0.55.4.
4395
4405
  */
4396
- declare const KAY_PLUGIN_SDK_VERSION: "0.55.2";
4406
+ declare const KAY_PLUGIN_SDK_VERSION: "0.55.4";
4397
4407
 
4398
4408
  declare const KAY_PLUGIN_TARGET_NAMES: readonly ["kay.agent", "kay.app", "kay.ui"];
4399
4409
 
@@ -6731,7 +6741,7 @@ export declare interface KayAppPluginApi {
6731
6741
  * in the daemon process and could walk the disk to find these directories anyway, so withholding
6732
6742
  * the path would buy friction rather than safety. It is not a containment boundary. Expect this
6733
6743
  * posture to tighten if plugin execution is ever isolated (deferred: D1 in
6734
- * `docs/plugins/trust-model-decisions.md`).
6744
+ * `docs/decisions/2026-08-24-plugins-trust-model-decisions.md`).
6735
6745
  */
6736
6746
  readonly paths: KayAppPaths;
6737
6747
  /**
@@ -6907,9 +6917,11 @@ export declare interface KayAppPluginApi {
6907
6917
  */
6908
6918
  readonly soul?: KayAppSoul;
6909
6919
  /**
6910
- * Private API: only plugins Bonsai ships; refused for any other. Turns installed plugins on and
6911
- * off, each call checked against `plugins.set-enabled`. Absent when the host cannot change
6912
- * which plugins run.
6920
+ * The installed plugins. `listServices()` answers each enabled plugin's auth services and whether
6921
+ * each is connected, checked against `plugins.read`. `setEnabled()` is private API (only plugins
6922
+ * Bonsai ships; refused for any other): it turns installed plugins on and off, checked against
6923
+ * `plugins.set-enabled`. Absent when the host composed neither; a method the host did not
6924
+ * compose rejects.
6913
6925
  */
6914
6926
  readonly plugins?: KayAppPlugins;
6915
6927
  /**
@@ -6981,21 +6993,30 @@ export declare interface KayAppPluginApi {
6981
6993
  implementWorkflow(localId: string, run: KayAppWorkflowImplementation): void;
6982
6994
  }
6983
6995
 
6996
+ /** What `kay.app` code may add to one publish beyond the event itself. */
6997
+ export declare interface KayAppPluginEventPublishOptions {
6998
+ /**
6999
+ * A session this plugin created through `sessions.create`: the host records it as the event's
7000
+ * session, so a notification rule's `session-unfocused` stays quiet while that session is the
7001
+ * focused pane. The host refuses a session this plugin did not create. Absent publishes an
7002
+ * app-lifetime event, as before.
7003
+ */
7004
+ readonly sessionId?: string;
7005
+ }
7006
+
6984
7007
  export declare interface KayAppPluginEvents {
6985
- publish(localId: string, input: PluginEventPublishInput): void;
7008
+ publish(localId: string, input: PluginEventPublishInput, options?: KayAppPluginEventPublishOptions): void;
6986
7009
  }
6987
7010
 
6988
7011
  /**
6989
- * The `kay.app` plugins contract (`app.plugins`): the user's installed plugins.
6990
- */
6991
- /**
6992
- * Private API: only plugins Bonsai ships; refused for any other. Each call is checked against
6993
- * `plugins.set-enabled`. A refused call rejects with an `Error`.
7012
+ * Each method is checked against its own claim at the call. A refused call rejects with an
7013
+ * `Error`.
6994
7014
  */
6995
7015
  export declare interface KayAppPlugins {
6996
7016
  /**
6997
- * Turn an installed plugin on, which starts its code under the grants the user gave it, or off,
6998
- * which stops it. `changed` is false when it was already in that state.
7017
+ * Private API: only plugins Bonsai ships; refused for any other. Checked against
7018
+ * `plugins.set-enabled`. Turn an installed plugin on, which starts its code under the grants the
7019
+ * user gave it, or off, which stops it. `changed` is false when it was already in that state.
6999
7020
  */
7000
7021
  setEnabled(request: {
7001
7022
  readonly pluginId: string;
@@ -7003,6 +7024,34 @@ export declare interface KayAppPlugins {
7003
7024
  }): Promise<{
7004
7025
  readonly changed: boolean;
7005
7026
  }>;
7027
+ /**
7028
+ * Checked against `plugins.read`. Every auth service of the installed, enabled plugins, one row
7029
+ * per service, sorted by plugin name then service id. A plugin with no auth service is not
7030
+ * listed. Never resolves, decrypts, refreshes or calls a provider.
7031
+ */
7032
+ listServices(): Promise<readonly KayAppPluginService[]>;
7033
+ }
7034
+
7035
+ /**
7036
+ * The `kay.app` plugins contract (`app.plugins`): the user's installed plugins.
7037
+ */
7038
+ /**
7039
+ * One auth service an installed, enabled plugin declares, and whether the person has connected
7040
+ * it. Metadata only: no account, identity, scope or credential.
7041
+ */
7042
+ export declare interface KayAppPluginService {
7043
+ /** The plugin that declares the service: `com.kay.integration.ramp`. */
7044
+ readonly pluginId: string;
7045
+ /** The plugin's display name, as the person reads it: `Ramp`. */
7046
+ readonly pluginName: string;
7047
+ /** The service's global id, the one a connect card names: `ramp.account`. */
7048
+ readonly serviceId: string;
7049
+ /**
7050
+ * True when any scheme of the service has a usable account. An account that needs reconnecting
7051
+ * does not count, so a service with only such accounts reads as not connected. Not proof that a
7052
+ * provider call will authenticate.
7053
+ */
7054
+ readonly connected: boolean;
7006
7055
  }
7007
7056
 
7008
7057
  export declare interface KayAppPollerEvent {
@@ -7927,6 +7976,14 @@ export declare interface KayAppSessions {
7927
7976
  * against `sessions.read`. Unsupported hosts may omit it.
7928
7977
  */
7929
7978
  listSessionPage?(request: KayAppSessionListRequest): Promise<KayAppSessionList>;
7979
+ /**
7980
+ * Called after a stored session's index row changes (its title, folder or project, or its
7981
+ * removal); a change without `sessionId` means any session may have changed. Checked against
7982
+ * `sessions.read`. Returns the unsubscribe. Unsupported hosts may omit it.
7983
+ */
7984
+ subscribeChanges?(listener: (change: {
7985
+ readonly sessionId?: string;
7986
+ }) => void): () => void;
7930
7987
  /**
7931
7988
  * Read a cheap transcript change marker without loading the entry log. Unknown or deleted
7932
7989
  * sessions yield `undefined`.
@@ -10055,13 +10112,20 @@ export declare interface KayAppWorkingDocuments {
10055
10112
  * recovery data.
10056
10113
  */
10057
10114
  export declare interface KayAppWorkspace {
10115
+ /**
10116
+ * Called after the window publishes a new snapshot (tabs, groups, panes or titles changed). Read
10117
+ * `snapshot()` for the new state. Returns the unsubscribe.
10118
+ */
10119
+ subscribe(listener: () => void): () => void;
10058
10120
  snapshot(): Promise<{
10059
10121
  readonly kind: "snapshot";
10060
10122
  readonly snapshot: KayAppWorkspaceSnapshot;
10061
10123
  } | {
10062
10124
  readonly kind: "unavailable";
10063
10125
  }>;
10064
- execute(command: KayAppWorkspaceCommand, ctx: KayAppWorkspaceExecuteContext): Promise<{
10126
+ execute(command: KayAppWorkspaceCommand,
10127
+ /** The session the command is issued for; absent for a plugin's own background work. */
10128
+ ctx?: KayAppWorkspaceExecuteContext): Promise<{
10065
10129
  readonly kind: "outcome";
10066
10130
  readonly outcome: KayAppWorkspaceCommandOutcome;
10067
10131
  readonly validPageIds?: readonly string[];
@@ -10105,6 +10169,23 @@ export declare type KayAppWorkspaceCommand = {
10105
10169
  } | {
10106
10170
  verb: "tabs.ungroup";
10107
10171
  tabIds: readonly string[];
10172
+ } | {
10173
+ /**
10174
+ * Set the membership and look of this plugin's own linked tab groups, computed from the
10175
+ * snapshot numbered `rev` (`stale` when the tabs changed since). Each listed group ends up
10176
+ * holding exactly `tabIds` plus its guests, created when missing; only ungrouped Tabs join.
10177
+ * One of this plugin's groups left unlisted keeps only its guests. Never recorded as the
10178
+ * person's own edit.
10179
+ */
10180
+ verb: "tabs.syncLinkedGroups";
10181
+ rev: number;
10182
+ groups: readonly {
10183
+ readonly key: string;
10184
+ readonly name: string;
10185
+ readonly color?: KayAppWorkspaceTabGroupColor | undefined;
10186
+ readonly icon?: string | undefined;
10187
+ readonly tabIds: readonly string[];
10188
+ }[];
10108
10189
  } | {
10109
10190
  verb: "panes.split";
10110
10191
  tabId: string;
@@ -10263,15 +10344,21 @@ export declare type KayAppWorkspacePlaceContent = {
10263
10344
  };
10264
10345
 
10265
10346
  /** The full workspace tree, app-wide (every tab, not one session's). */
10266
- export declare interface KayAppWorkspaceSnapshot {
10267
- readonly rev: number;
10268
- readonly activeTabId: string;
10269
- readonly tabs: readonly KayAppWorkspaceTabSnapshot[];
10270
- }
10347
+ /**
10348
+ * The workspace as the window last published it: every Tab, the tab groups (`link` present only on
10349
+ * a linked tab group), and the person's linked-group guests and dismissals in this window.
10350
+ */
10351
+ export declare type KayAppWorkspaceSnapshot = ReadonlyContract<WorkspaceSnapshot>;
10271
10352
 
10272
10353
  /** The tab-group colour palette, by name (Chrome's nine); mirrors the wire schema's enum. */
10273
10354
  export declare type KayAppWorkspaceTabGroupColor = "grey" | "blue" | "red" | "yellow" | "green" | "pink" | "purple" | "cyan" | "orange";
10274
10355
 
10356
+ /** The plugin a linked tab group belongs to and the key that plugin chose for it. */
10357
+ export declare type KayAppWorkspaceTabGroupLink = NonNullable<KayAppWorkspaceTabGroupSnapshot["link"]>;
10358
+
10359
+ /** One tab group in the strip. */
10360
+ export declare type KayAppWorkspaceTabGroupSnapshot = NonNullable<KayAppWorkspaceSnapshot["groups"]>[number];
10361
+
10275
10362
  export declare type KayAppWorkspaceTabSnapshot = ReadonlyContract<WorkspaceTabSnapshot>;
10276
10363
 
10277
10364
  /**
@@ -11534,6 +11621,12 @@ export declare const PLUGIN_SIGNAL_ATTACHMENT_TYPE_MAX = 127;
11534
11621
  /** At most this many entries in a signal's `attachments`; a source lists the first ones. */
11535
11622
  export declare const PLUGIN_SIGNAL_ATTACHMENTS_MAX = 10;
11536
11623
 
11624
+ /**
11625
+ * A signal's `body`, the item's own text, at most this many characters: a source cuts longer text
11626
+ * and marks the cut. Enough for a long email with its quoted history.
11627
+ */
11628
+ export declare const PLUGIN_SIGNAL_BODY_MAX = 20000;
11629
+
11537
11630
  /** The `kind` values of `PluginSignal` v1. `status` is system state that clears itself. */
11538
11631
  export declare const PLUGIN_SIGNAL_KINDS: readonly ["message", "request", "mention", "invite", "status"];
11539
11632
 
@@ -11715,6 +11808,7 @@ export declare const PluginSignal: z.ZodObject<{
11715
11808
  }>>;
11716
11809
  title: z.ZodOptional<z.ZodString>;
11717
11810
  snippet: z.ZodOptional<z.ZodString>;
11811
+ body: z.ZodOptional<z.ZodString>;
11718
11812
  actor: z.ZodOptional<z.ZodObject<{
11719
11813
  name: z.ZodOptional<z.ZodString>;
11720
11814
  uri: z.ZodString;
@@ -11759,6 +11853,7 @@ export declare const PluginSignalPublish: z.ZodObject<{
11759
11853
  }>>;
11760
11854
  title: z.ZodOptional<z.ZodString>;
11761
11855
  snippet: z.ZodOptional<z.ZodString>;
11856
+ body: z.ZodOptional<z.ZodString>;
11762
11857
  actor: z.ZodOptional<z.ZodObject<{
11763
11858
  name: z.ZodOptional<z.ZodString>;
11764
11859
  uri: z.ZodString;
@@ -19170,6 +19265,7 @@ declare const WorkspaceCommandOutcome: z.ZodEnum<{
19170
19265
  "no-window": "no-window";
19171
19266
  "not-found": "not-found";
19172
19267
  applied: "applied";
19268
+ stale: "stale";
19173
19269
  }>;
19174
19270
 
19175
19271
  declare type WorkspaceCommandOutcome = z.infer<typeof WorkspaceCommandOutcome>;
@@ -19222,11 +19318,64 @@ declare type WorkspacePaneNode = {
19222
19318
 
19223
19319
  declare const WorkspacePaneNode: z.ZodType<WorkspacePaneNode>;
19224
19320
 
19321
+ /**
19322
+ * The full workspace tree, app-wide (every tab, not one session's). `rev` is a monotonic counter the
19323
+ * renderer stamps on push (mirroring the `<kay_tab_context>` block's `rev`), so a reader can tell a
19324
+ * pulled snapshot apart from one already in hand.
19325
+ */
19326
+ declare const WorkspaceSnapshot: z.ZodObject<{
19327
+ rev: z.ZodNumber;
19328
+ activeTabId: z.ZodString;
19329
+ tabs: z.ZodArray<z.ZodObject<{
19330
+ id: z.ZodString;
19331
+ label: z.ZodString;
19332
+ active: z.ZodBoolean;
19333
+ variable: z.ZodOptional<z.ZodBoolean>;
19334
+ preview: z.ZodOptional<z.ZodBoolean>;
19335
+ groupId: z.ZodOptional<z.ZodString>;
19336
+ sessionIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
19337
+ focusedPaneId: z.ZodString;
19338
+ maximizedPaneId: z.ZodNullable<z.ZodString>;
19339
+ root: z.ZodType<WorkspacePaneNode, unknown, z.core.$ZodTypeInternals<WorkspacePaneNode, unknown>>;
19340
+ }, z.core.$strict>>;
19341
+ groups: z.ZodOptional<z.ZodArray<z.ZodObject<{
19342
+ id: z.ZodString;
19343
+ name: z.ZodString;
19344
+ color: z.ZodEnum<{
19345
+ grey: "grey";
19346
+ blue: "blue";
19347
+ red: "red";
19348
+ yellow: "yellow";
19349
+ green: "green";
19350
+ pink: "pink";
19351
+ purple: "purple";
19352
+ cyan: "cyan";
19353
+ orange: "orange";
19354
+ }>;
19355
+ collapsed: z.ZodOptional<z.ZodBoolean>;
19356
+ icon: z.ZodOptional<z.ZodString>;
19357
+ link: z.ZodOptional<z.ZodObject<{
19358
+ pluginId: z.ZodString;
19359
+ key: z.ZodString;
19360
+ }, z.core.$strict>>;
19361
+ }, z.core.$strict>>>;
19362
+ linkedGroupGuests: z.ZodOptional<z.ZodArray<z.ZodString>>;
19363
+ linkedGroupsDismissed: z.ZodOptional<z.ZodArray<z.ZodObject<{
19364
+ pluginId: z.ZodString;
19365
+ key: z.ZodString;
19366
+ }, z.core.$strict>>>;
19367
+ }, z.core.$strict>;
19368
+
19369
+ declare type WorkspaceSnapshot = z.infer<typeof WorkspaceSnapshot>;
19370
+
19225
19371
  declare const WorkspaceTabSnapshot: z.ZodObject<{
19226
19372
  id: z.ZodString;
19227
19373
  label: z.ZodString;
19228
19374
  active: z.ZodBoolean;
19229
19375
  variable: z.ZodOptional<z.ZodBoolean>;
19376
+ preview: z.ZodOptional<z.ZodBoolean>;
19377
+ groupId: z.ZodOptional<z.ZodString>;
19378
+ sessionIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
19230
19379
  focusedPaneId: z.ZodString;
19231
19380
  maximizedPaneId: z.ZodNullable<z.ZodString>;
19232
19381
  root: z.ZodType<WorkspacePaneNode, unknown, z.core.$ZodTypeInternals<WorkspacePaneNode, unknown>>;
package/dist/kay-app.js CHANGED
@@ -371,6 +371,7 @@ var PLUGIN_SIGNAL_KINDS = [
371
371
  ];
372
372
  var PLUGIN_SIGNAL_TITLE_MAX = 300;
373
373
  var PLUGIN_SIGNAL_SNIPPET_MAX = 500;
374
+ var PLUGIN_SIGNAL_BODY_MAX = 2e4;
374
375
  var PLUGIN_SIGNAL_LABELS_MAX = 20;
375
376
  var PLUGIN_SIGNAL_LABEL_MAX = 64;
376
377
  var PLUGIN_SIGNAL_ATTACHMENTS_MAX = 10;
@@ -1205,6 +1206,7 @@ export {
1205
1206
  PLUGIN_SIGNAL_ATTACHMENTS_MAX,
1206
1207
  PLUGIN_SIGNAL_ATTACHMENT_NAME_MAX,
1207
1208
  PLUGIN_SIGNAL_ATTACHMENT_TYPE_MAX,
1209
+ PLUGIN_SIGNAL_BODY_MAX,
1208
1210
  PLUGIN_SIGNAL_KINDS,
1209
1211
  PLUGIN_SIGNAL_LABELS_MAX,
1210
1212
  PLUGIN_SIGNAL_LABEL_MAX,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yaklabs-ai/plugin-sdk",
3
- "version": "0.55.2",
3
+ "version": "0.55.4",
4
4
  "description": "The Kay plugin SDK — types and helpers for authoring a Kay directory plugin.",
5
5
  "author": "YakLabs",
6
6
  "type": "module",
@@ -145,7 +145,7 @@ the plugin (`"./assets/rail.svg"`). Only its shape is used, painted in the rail'
145
145
  in the file are ignored, and it must be transparent where nothing should draw. A missing file is a
146
146
  load diagnostic and the entry falls back to the plugin icon. The page the entry opens wears the same
147
147
  icon. Full
148
- precedence: `packages/kay-frontend-sdk/ARCHITECTURE.md`, "Plugin icon".
148
+ precedence: `packages/kay-renderer/src/renderer/src/shell/contribution-icons.ts`.
149
149
 
150
150
  `ui.tsx` has no `node_modules` of its own. Bonsai compiles it and rewrites its `react` and
151
151
  `@bonsai/plugin-ui-sdk` imports to the host's `__KAY_UI_RUNTIME__` singletons, so the agent `tsconfig.json`