@yaklabs-ai/plugin-sdk 0.13.1 → 0.13.3

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/kay-app.d.ts CHANGED
@@ -224,6 +224,10 @@ declare interface BackgroundTaskCompletion {
224
224
  readonly resultDelivery?: BackgroundTaskResultDelivery;
225
225
  readonly output?: string;
226
226
  readonly error?: string;
227
+ /** The thrown Error's stack, when a failed task threw one. */
228
+ readonly errorStack?: string;
229
+ /** Why a failed AGENT task's run failed, classified from what it threw; absent for other kinds. */
230
+ readonly failureReason?: RunFailureReason;
227
231
  }
228
232
 
229
233
  declare type BackgroundTaskInspector = () => Promise<string> | string;
@@ -431,6 +435,18 @@ export declare function createFallbackOnlyWithJev(): WithJev;
431
435
  */
432
436
  export declare function createUnavailableSkills(message: string): KayAppSkills;
433
437
 
438
+ /**
439
+ * The `app.tools` a host that cannot describe tools binds: every call answers `not-available`, so
440
+ * a plugin's code path never depends on host composition.
441
+ */
442
+ export declare function createUnavailableTools(): KayAppTools;
443
+
444
+ /**
445
+ * A `KayAppUsage` that answers `unavailable` to every call: what a host with no telemetry lane
446
+ * binds, so `app.usage` stays present on every host.
447
+ */
448
+ export declare function createUnavailableUsage(message: string): KayAppUsage;
449
+
434
450
  declare interface CustomEntry extends EntryBase {
435
451
  type: "custom";
436
452
  customType: string;
@@ -759,7 +775,7 @@ export declare interface JevScoreQuestion {
759
775
  * - The wire. The host serves `classify` over whichever route the user's Jev provider order
760
776
  * picks; a plugin never sees a vendor client, a vendor type, or a route.
761
777
  * - Credential resolution, the `jev.use` decision, the Jev-branch budget, or usage accounting.
762
- * Those are host-side (`@kay/agent-runtime`'s `kay/jev/`).
778
+ * Those are host-side (`@bonsai/agent-runtime`'s `kay/jev/`).
763
779
  * ---
764
780
  *
765
781
  * The vocabulary is Bonsai's own (SDK 0.12.0). Before it, `use` received TypeSafe's `TypeSafeClient`
@@ -1149,6 +1165,24 @@ export declare interface KayAppAgentDefinition {
1149
1165
  * position: the two are separately compared, so moving a rule between them is a different claim.
1150
1166
  */
1151
1167
  readonly permissionsFallback?: readonly PluginAgentDefinitionPermissionRule[];
1168
+ /**
1169
+ * The URI schemes this definition's runs MAINTAIN, e.g. `["memory"]` for a job that curates,
1170
+ * prunes or rewrites the memory notebook. Bare scheme names, lowercase, no `://`.
1171
+ *
1172
+ * What it changes, and only this: a READ under a declared scheme, made by a session of this
1173
+ * definition or by any session in that session's family (its subagents, keyed by root), is not
1174
+ * counted as use of the resource in Bonsai's per-resource read activity (the `uriReadActivity`
1175
+ * metric, `analytics://memory`, and `app.usage`'s answers). A job that keeps a notebook tidy
1176
+ * reads old and irrelevant notes as a matter of course, and counting those reads would make
1177
+ * every note it touches look used. Reads by every other session, including other background
1178
+ * jobs, still count: a job that reads a note to do its own work found the note useful.
1179
+ *
1180
+ * It confers no authority and removes none. The host re-reads it from the live definition at
1181
+ * every activation, like {@link permissions}, and stamps it on the session's activation row.
1182
+ * Adding or removing one scheme here is the whole switch for moving a job between the excluded
1183
+ * and the counted side. Absent means the job maintains nothing. SDK 0.13.3.
1184
+ */
1185
+ readonly maintains?: readonly string[];
1152
1186
  }
1153
1187
 
1154
1188
  /** The inert session-config subset a plugin-authored agent definition may contribute. */
@@ -1921,8 +1955,8 @@ export declare interface KayAppConfig {
1921
1955
  /**
1922
1956
  * Where a folded config value's winner was defined: the config LEVEL that won and the absolute
1923
1957
  * path of the winning file. A JSON-safe twin of the runtime's `KayConfigValueOrigin`
1924
- * (`@kay/product-catalog`) — this SDK cannot import that package, so the shape is re-declared
1925
- * here and an assignability test in `@kay/agent-runtime` pins the two together. The level union
1958
+ * (`@bonsai/product-catalog`) — this SDK cannot import that package, so the shape is re-declared
1959
+ * here and an assignability test in `@bonsai/agent-runtime` pins the two together. The level union
1926
1960
  * is the closed, protocol-owned fold precedence stack (`baseline < learned < global < project`).
1927
1961
  * `"baseline"` names a host-composed, in-memory, build/channel-scoped default with no file
1928
1962
  * behind it (`KayConfigStoreOptions.baselineDefaults`) — a plugin can still be handed one as a
@@ -2671,8 +2705,8 @@ export declare interface KayAppPermissions {
2671
2705
  export declare interface KayAppPhaseShiftSessionEvent extends KayAppSessionEventBase {
2672
2706
  readonly type: "phase-shift";
2673
2707
  /**
2674
- * The accepted observation, in the SURFACE-FRIENDLY resolved shape (`@kay/plugin-protocol`'s
2675
- * `PhaseShiftTimelineRecord`, re-exported from `@kay/plugin-sdk/phase-shift`) rather than the
2708
+ * The accepted observation, in the SURFACE-FRIENDLY resolved shape (`@bonsai/plugin-protocol`'s
2709
+ * `PhaseShiftTimelineRecord`, re-exported from `@bonsai/plugin-sdk/phase-shift`) rather than the
2676
2710
  * raw validated one: source timestamps already resolved, total and pure, no entry read needed
2677
2711
  * to place it in time. Re-validate its onsets against the branch you actually read — a rewind
2678
2712
  * can race between publish and read — the same discipline `resolveClosedPhase` already applies.
@@ -2863,6 +2897,24 @@ export declare interface KayAppPluginApi {
2863
2897
  * present, like {@link signals}.
2864
2898
  */
2865
2899
  readonly skills: KayAppSkills;
2900
+ /**
2901
+ * What a live session's tools and addresses say to the agent, where each comes from, and whether
2902
+ * each is one of Bonsai's own. Each call is checked against `tools.describe`; a refused grant or
2903
+ * a session that is not live resolves to `{ status: "unavailable" }`, never a rejection, while
2904
+ * the plugin is enabled. After it is disabled, a kept handle's methods throw synchronously.
2905
+ * Always present, like {@link skills}.
2906
+ */
2907
+ readonly tools: KayAppTools;
2908
+ /**
2909
+ * Read and change activity for the resources under this plugin's OWN URI schemes, counted under
2910
+ * Bonsai's read rule (reads by a job that declares it maintains the scheme never count). Each
2911
+ * call checks, against the live registry, that the asked prefix is under a scheme this plugin's
2912
+ * registered URI modules serve; any other prefix resolves to `{ status: "refused" }`. A host
2913
+ * with no telemetry lane, or a scan that cannot complete, resolves to `{ status: "unavailable" }`.
2914
+ * No call rejects while the plugin is enabled; after it is disabled, a kept handle's method
2915
+ * throws synchronously. Always present, like {@link skills}.
2916
+ */
2917
+ readonly usage: KayAppUsage;
2866
2918
  /** The app-wide endpoint bus (register handlers a consuming surface invokes). */
2867
2919
  readonly endpoints: KayAppEndpoints;
2868
2920
  /** Publish one event declared by this plugin's `kay.app` manifest target. */
@@ -3076,6 +3128,17 @@ export declare interface KayAppResolvedCredential {
3076
3128
  readonly fields?: Readonly<Record<string, string>>;
3077
3129
  }
3078
3130
 
3131
+ /**
3132
+ * What one run produced, as named counts: `{ suggestions: 2, pullRequests: 0 }`. Optional, and
3133
+ * read by Bonsai's own analytics, not shown to a person.
3134
+ *
3135
+ * Keys are your own names, in camelCase (a letter first, then letters and digits, at most 40
3136
+ * characters), at most 16 per run; values are whole numbers of zero or more. Report a zero rather
3137
+ * than leaving a key out: "made nothing" is the answer a reader is usually asking about. A result
3138
+ * that breaks these rules is dropped whole, with the run otherwise recorded as usual.
3139
+ */
3140
+ export declare type KayAppRunProduced = Readonly<Record<string, number>>;
3141
+
3079
3142
  export declare interface KayAppRunSummary {
3080
3143
  /** One plain-text line, at most 100 characters. */
3081
3144
  readonly headline: string;
@@ -3086,8 +3149,8 @@ export declare interface KayAppRunSummary {
3086
3149
 
3087
3150
  /**
3088
3151
  * The session provenance vocabulary, as the plugin protocol declares it. These used to be spelled
3089
- * out here because the canonical schemas lived in `@kay/agent-runtime-protocol`, which this
3090
- * package may not import; they now live in `@kay/plugin-protocol` (so artifact writers and the
3152
+ * out here because the canonical schemas lived in `@bonsai/agent-runtime-protocol`, which this
3153
+ * package may not import; they now live in `@bonsai/plugin-protocol` (so artifact writers and the
3091
3154
  * daemon share one shape), and a mirror here would be exactly the second declaration the
3092
3155
  * placement law forbids. Each name is kept as an alias so existing plugin code keeps compiling.
3093
3156
  */
@@ -3222,6 +3285,12 @@ export declare interface KayAppSessionEventsSubscribeOptions {
3222
3285
  * immediately.
3223
3286
  */
3224
3287
  readonly serialize?: boolean;
3288
+ /**
3289
+ * Your own name for this handler (the id you would grep a log for). The host names it, with
3290
+ * your plugin id, on the record it writes when the handler throws, so a failure says whose it
3291
+ * was. Optional; unnamed handlers are recorded without it.
3292
+ */
3293
+ readonly handlerId?: string;
3225
3294
  readonly handler: (event: KayAppSessionEvent, context: KayAppSessionEventContext) => void | Promise<void>;
3226
3295
  }
3227
3296
 
@@ -3720,7 +3789,7 @@ export declare type KayAppSignalsAnswerFilter = {
3720
3789
  */
3721
3790
  export declare interface KayAppSignalsDetectorInput {
3722
3791
  /**
3723
- * Stable identifier, e.g. `memory-curator-gate`: a lowercase slug (a-z and 0-9 in words joined
3792
+ * Stable identifier, e.g. `memory-packet`: a lowercase slug (a-z and 0-9 in words joined
3724
3793
  * by single hyphens), at most 64 characters, plugin-scoped. It becomes a `signals://` path
3725
3794
  * segment.
3726
3795
  */
@@ -4155,7 +4224,7 @@ export declare interface KayAppTimeSnapshot {
4155
4224
  * The time zone the user is in, as an IANA id in the spelling ICU resolves (`America/New_York`).
4156
4225
  * One zone can have two ids, and ICU picks one: `Asia/Kolkata` comes back as `Asia/Calcutta`. So
4157
4226
  * never compare zone ids with `===`. A first-party plugin compares with `sameZone` from
4158
- * `@kay/time`. A plugin that imports only this SDK and node builtins resolves each id with
4227
+ * `@bonsai/time`. A plugin that imports only this SDK and node builtins resolves each id with
4159
4228
  * `new Intl.DateTimeFormat("en-US", { timeZone: id }).resolvedOptions().timeZone` and compares the
4160
4229
  * results. Pass `zone` as the `timeZone` of `Intl.DateTimeFormat` or `toLocaleString` to format a
4161
4230
  * time for the user.
@@ -4202,6 +4271,21 @@ export declare type KayAppToolDefinition<TParams extends ToolParametersWire = To
4202
4271
  execute(toolCallId: string, params: ToolExecutionAwareParams<TParams>, signal: AbortSignal | undefined, onUpdate: AgentToolUpdateCallback<TDetails> | undefined, ctx: KayAppToolContext): Promise<AgentToolResult<TDetails>>;
4203
4272
  };
4204
4273
 
4274
+ export declare interface KayAppToolDescription {
4275
+ readonly ref: KayAppToolRef;
4276
+ /** `false`: no such tool is registered, or no module owns that address, in this session. */
4277
+ readonly found: boolean;
4278
+ /**
4279
+ * For a tool, its own registered description. For an address, its help rendered as `help <uri>`
4280
+ * renders it for the agent; for `mcp://<server>`, that is the server's tool list in the server's
4281
+ * own words.
4282
+ */
4283
+ readonly description?: string;
4284
+ readonly origin?: KayAppToolOrigin;
4285
+ /** Whether this is one of Bonsai's own tools or addresses. `false` when not found. */
4286
+ readonly ownedByBonsai: boolean;
4287
+ }
4288
+
4205
4289
  /**
4206
4290
  * The fine-grained, app-wide per-tool event stream (every session's tool executions). Carries the
4207
4291
  * redaction caveat: raw tool args/results are OFF in packaged builds, so a handler must treat
@@ -4214,6 +4298,20 @@ export declare interface KayAppToolEvents {
4214
4298
  subscribe(handler: (event: unknown) => void): () => void;
4215
4299
  }
4216
4300
 
4301
+ /** Where a described tool or address comes from. */
4302
+ export declare type KayAppToolOrigin =
4303
+ /** The agent kernel's own (`bash`, `read`, `help`, `skill://`). */
4304
+ {
4305
+ readonly kind: "core";
4306
+ }
4307
+ /** Bonsai's host, outside any plugin (`task_status`, `config://`). */
4308
+ | {
4309
+ readonly kind: "host";
4310
+ } | {
4311
+ readonly kind: "plugin";
4312
+ readonly pluginId: string;
4313
+ };
4314
+
4217
4315
  /**
4218
4316
  * `app.permissions` — the plugin-facing seam through which a `kay.app` target advertises the
4219
4317
  * permission rows for tools it gates DYNAMICALLY, so they show in Bonsai's permission ledger with
@@ -4264,6 +4362,52 @@ export declare interface KayAppToolPermissionSource {
4264
4362
  readonly list: () => readonly KayAppToolPermissionDeclaration[] | Promise<readonly KayAppToolPermissionDeclaration[]>;
4265
4363
  }
4266
4364
 
4365
+ /**
4366
+ * The plugin-facing `kay.app` tools contract: for the tools and addresses a live session can use,
4367
+ * the text the agent sees for each, where each comes from, and whether each is one of Bonsai's own.
4368
+ *
4369
+ * Every call is checked against the `tools.describe` claim at the call, so a grant or revocation
4370
+ * takes effect on the next one. Like `app.skills`, the member is ALWAYS present and no call rejects
4371
+ * while the plugin is enabled: a refused grant or a session that is not live resolves to
4372
+ * `{ status: "unavailable" }`. After the plugin is disabled, a kept handle's methods throw
4373
+ * synchronously.
4374
+ *
4375
+ * `ownedByBonsai` is a fact declared where each surface is defined (a bundled plugin's manifest, or
4376
+ * the host's own registration), never a list kept by the host. What a plugin does with it is the
4377
+ * plugin's call.
4378
+ */
4379
+ /** A tool or an address to describe. */
4380
+ export declare type KayAppToolRef =
4381
+ /** A registered tool by name, e.g. `bash`, `read`, `mcp`, `submit_final`. */
4382
+ {
4383
+ readonly kind: "tool";
4384
+ readonly name: string;
4385
+ }
4386
+ /** A URI address whose `help` is wanted, e.g. `gmail://` or `mcp://linear`. */
4387
+ | {
4388
+ readonly kind: "address";
4389
+ readonly uri: string;
4390
+ };
4391
+
4392
+ /** `app.tools`: what a live session's tools and addresses say, each call checked against `tools.describe`. */
4393
+ export declare interface KayAppTools {
4394
+ describe(sessionId: string, refs: readonly KayAppToolRef[]): Promise<KayAppToolsDescribeResult>;
4395
+ }
4396
+
4397
+ /**
4398
+ * `not-granted`: the user has not granted `tools.describe`. `no-session`: the session is not live
4399
+ * on this host (only live sessions are described). `not-available`: this host cannot describe
4400
+ * tools.
4401
+ */
4402
+ export declare type KayAppToolsDescribeResult = {
4403
+ readonly status: "ok";
4404
+ /** One per ref, in the order of the refs. */
4405
+ readonly tools: readonly KayAppToolDescription[];
4406
+ } | {
4407
+ readonly status: "unavailable";
4408
+ readonly reason: "not-granted" | "no-session" | "not-available";
4409
+ };
4410
+
4267
4411
  /** An eligible settled turn — the generic door's root event. */
4268
4412
  export declare interface KayAppTurnSettledSessionEvent extends KayAppSessionEventBase {
4269
4413
  readonly type: "turn-settled";
@@ -4276,7 +4420,7 @@ export declare interface KayAppTurnSettledSessionEvent extends KayAppSessionEven
4276
4420
  *
4277
4421
  * Optional on this SDK-facing type only for fixture leniency (a handcrafted test event may omit
4278
4422
  * it); the daemon's own emitter always populates it for a genuine settle — see
4279
- * `TurnSettledSessionEvent.runId` (`@kay/agent-runtime`'s internal twin of this event, which
4423
+ * `TurnSettledSessionEvent.runId` (`@bonsai/agent-runtime`'s internal twin of this event, which
4280
4424
  * DOES require it) for the producer side of that guarantee.
4281
4425
  */
4282
4426
  readonly runId?: string;
@@ -4309,6 +4453,97 @@ export declare interface KayAppUiActionSessionEvent extends KayAppSessionEventBa
4309
4453
  readonly toolCallId: string;
4310
4454
  }
4311
4455
 
4456
+ /** How one resource under the asked prefix has been read and changed. */
4457
+ export declare interface KayAppUriActivity {
4458
+ /** The canonical URI as the read or change recorded it. */
4459
+ readonly uri: string;
4460
+ /** One entry per window, in `KayAppUriActivityAnswer.windowDays` order. */
4461
+ readonly windows: readonly KayAppUriActivityWindow[];
4462
+ /** The newest counted read, ISO-8601 UTC; absent when none fell inside the scan. */
4463
+ readonly lastReadAt?: string;
4464
+ /** The newest change, ISO-8601 UTC; absent when none fell inside the scan. */
4465
+ readonly lastChangedAt?: string;
4466
+ }
4467
+
4468
+ export declare type KayAppUriActivityAnswer = {
4469
+ readonly status: "ok";
4470
+ /** The instant the windows are measured back from, ISO-8601 UTC. */
4471
+ readonly asOf: string;
4472
+ /** The windows every resource reports, in order. */
4473
+ readonly windowDays: readonly number[];
4474
+ /**
4475
+ * Every resource under the prefix the scan saw read or changed. One read only by a
4476
+ * maintaining job is listed with zero counts and no `lastReadAt`.
4477
+ */
4478
+ readonly resources: readonly KayAppUriActivity[];
4479
+ } | {
4480
+ /** The prefix is not under a scheme this plugin's registered URI modules serve. */
4481
+ readonly status: "refused";
4482
+ readonly message: string;
4483
+ } | {
4484
+ /** No telemetry lane on this host, or the scan could not complete. */
4485
+ readonly status: "unavailable";
4486
+ readonly message: string;
4487
+ };
4488
+
4489
+ /**
4490
+ * The plugin-facing `kay.app` usage contract: how the resources under a plugin's OWN URI schemes
4491
+ * have been read and changed, as Bonsai's telemetry records it. SDK 0.13.3; a plugin that calls it
4492
+ * declares `compatibility.sdk` `^0.13.3`.
4493
+ *
4494
+ * Scoped, not gated. A plugin may ask only about a prefix under a scheme one of its own registered
4495
+ * URI modules serves; that check runs at every call against the live registry, and a prefix under
4496
+ * any other scheme answers `{ status: "refused" }`. The member is ALWAYS present and no call
4497
+ * rejects while the plugin is enabled: no telemetry lane on this host, a query that could not
4498
+ * complete, or an answer too large to return all resolve to `{ status: "unavailable" }`. After the
4499
+ * plugin is disabled, a kept handle's method throws synchronously.
4500
+ *
4501
+ * ## What counts as a read
4502
+ *
4503
+ * Every executed read counts, from any session (a person's conversation and its subagents,
4504
+ * automations, loops, watches, Dream passes, any other job), EXCEPT a read made by a session whose
4505
+ * agent definition declares that it maintains the read's scheme (`KayAppAgentDefinition.maintains`)
4506
+ * or by any session in that session's family. Each counted read is split by who it serves:
4507
+ * `personReads` when its session tree was started by a person, `jobReads` otherwise. Changes
4508
+ * (writes and edits) count from every session, maintainers included.
4509
+ *
4510
+ * Reads recorded before the host build that stamps the declaration follow the earlier rule until
4511
+ * they leave the 90-day window: such a read counts only when a person started the session that made it (a person's subagents
4512
+ * did not count under that rule).
4513
+ *
4514
+ * ## Zero and unavailable are different answers
4515
+ *
4516
+ * An `ok` answer describes a complete scan: a resource absent from `resources` was neither read
4517
+ * nor changed inside the scan, so it has zero counted reads. When the scan could not complete the answer is `unavailable`,
4518
+ * never a list of zeros, because "nothing read this" and "nothing could tell" are different facts.
4519
+ */
4520
+ /** One window's activity for one resource. */
4521
+ export declare interface KayAppUriActivityWindow {
4522
+ /** The span, in days, measured back from the answer's `asOf`. */
4523
+ readonly windowDays: number;
4524
+ /** Counted reads: `personReads + jobReads`. */
4525
+ readonly reads: number;
4526
+ /** Counted reads whose session tree a person started. */
4527
+ readonly personReads: number;
4528
+ /** Counted reads by every other session tree (automations, Dream passes, other jobs). */
4529
+ readonly jobReads: number;
4530
+ /** Distinct session trees (keyed by root session) behind the counted reads. */
4531
+ readonly sessions: number;
4532
+ /** Writes and edits of any origin, maintainers included. */
4533
+ readonly changes: number;
4534
+ }
4535
+
4536
+ export declare interface KayAppUsage {
4537
+ /**
4538
+ * Read and change activity for every resource whose URI starts with `prefix`, for example
4539
+ * `memory://` or `memory://projects/`. The prefix must name a scheme (`<scheme>://`) that one of
4540
+ * this plugin's registered URI modules serves.
4541
+ */
4542
+ uriActivity(input: {
4543
+ readonly prefix: string;
4544
+ }): Promise<KayAppUriActivityAnswer>;
4545
+ }
4546
+
4312
4547
  export declare interface KayAppUserFileEntry {
4313
4548
  readonly name: string;
4314
4549
  /** From the directory entry itself: a symlink is reported as `symlink`, never followed. */
@@ -4591,6 +4826,7 @@ export declare interface KayAppWorkflowDefinition {
4591
4826
  }>;
4592
4827
  readonly run: (context: KayAppWorkflowContext) => Promise<{
4593
4828
  readonly summary: KayAppRunSummary;
4829
+ readonly produced?: KayAppRunProduced;
4594
4830
  }>;
4595
4831
  }
4596
4832
 
@@ -4661,7 +4897,7 @@ export declare interface KayAppWorkspace {
4661
4897
  /**
4662
4898
  * The full workspace arrangement verb catalog: tab lifecycle/reorder/grouping, pane split/close/
4663
4899
  * focus/maximize/restore/place, shell panel toggles, and opening a session. A JSON-safe twin of
4664
- * `KayWorkspaceCommand` in `@kay/agent-runtime-protocol`.
4900
+ * `KayWorkspaceCommand` in `@bonsai/agent-runtime-protocol`.
4665
4901
  */
4666
4902
  export declare type KayAppWorkspaceCommand = {
4667
4903
  verb: "tabs.open";
@@ -4739,7 +4975,14 @@ export declare type KayAppWorkspaceCommand = {
4739
4975
  verb: "shell.togglePanel";
4740
4976
  } | {
4741
4977
  verb: "shell.toggleInspector";
4742
- } | {
4978
+ }
4979
+ /**
4980
+ * Open a session without taking the user's focus. A session no pane shows gets a tab of its own
4981
+ * in the background (`opened`); one some pane already shows is left as it is (`applied`). The
4982
+ * active tab and every focus stay as they were. The wire's `reveal` flag, which asks for a
4983
+ * sidebar-click-style open, is not offered here: it is for Bonsai Desktop's own menus.
4984
+ */
4985
+ | {
4743
4986
  verb: "sessions.open";
4744
4987
  sessionId: string;
4745
4988
  title?: string | undefined;
@@ -4747,7 +4990,7 @@ export declare type KayAppWorkspaceCommand = {
4747
4990
 
4748
4991
  /**
4749
4992
  * The one outcome grammar every {@link KayAppWorkspaceCommand} resolves to. A JSON-safe twin of
4750
- * `WorkspaceCommandOutcome` in `@kay/agent-runtime-protocol`.
4993
+ * `WorkspaceCommandOutcome` in `@bonsai/agent-runtime-protocol`.
4751
4994
  */
4752
4995
  export declare type KayAppWorkspaceCommandOutcome = "applied" | "opened" | "focused-existing" | "no-room" | "no-window" | "not-found" | "invalid";
4753
4996
 
@@ -4758,8 +5001,8 @@ export declare interface KayAppWorkspaceExecuteContext {
4758
5001
 
4759
5002
  /**
4760
5003
  * What one pane item shows. A JSON-safe, hand-copied twin of `WorkspacePaneContent` in
4761
- * `@kay/agent-runtime-protocol` — this package cannot import that protocol package (see this
4762
- * module's own doc comment), so the shape is re-declared here. A parity check in `@kay/agent-runtime`
5004
+ * `@bonsai/agent-runtime-protocol` — this package cannot import that protocol package (see this
5005
+ * module's own doc comment), so the shape is re-declared here. A parity check in `@bonsai/agent-runtime`
4763
5006
  * asserts `app.workspace` (the runtime's `KayWorkspaceCapability`, built from the protocol types)
4764
5007
  * stays structurally assignable to {@link KayAppWorkspace} below.
4765
5008
  *
@@ -5503,14 +5746,14 @@ declare interface ScopeRequirement {
5503
5746
  * this list. Two consequences worth knowing:
5504
5747
  *
5505
5748
  * - `sessions.create` and `sessions.run` are the two separately-granted plugin doors
5506
- * (`@kay/plugin-protocol`'s `permissions.ts`: `create` mints a persisted user-visible session,
5749
+ * (`@bonsai/plugin-protocol`'s `permissions.ts`: `create` mints a persisted user-visible session,
5507
5750
  * `run` executes a hidden headless one). Each names ITSELF at the site that mints the session;
5508
5751
  * neither is inferred from the surface string, which cannot tell them apart.
5509
5752
  * - `sessions.create` stamps a plugin creator only for a create that declares a plugin-surfaced
5510
5753
  * `system` origin. The SDK `create` door passes no origin today, so its sessions read as the
5511
5754
  * ordinary chats they are; the value is still the honest one for that door when it does.
5512
5755
  * - `agents.run` (G1, 2026-09) is the generic session-event run door
5513
- * (`app.agents.run(ref, input, cause, {fork?})`, `@kay/plugin-sdk`'s `kay-app/agents.ts`): a
5756
+ * (`app.agents.run(ref, input, cause, {fork?})`, `@bonsai/plugin-sdk`'s `kay-app/agents.ts`): a
5514
5757
  * plugin's `app.sessionEvents.subscribe` handler spins up a bounded agent run in response to a
5515
5758
  * published session event. `callerSessionId` carries the cause's `sourceSessionId` — the session
5516
5759
  * whose event caused this run — and {@link SessionProvenanceRecord.causedByEvent} carries the
@@ -6427,6 +6670,12 @@ declare interface UriHelp {
6427
6670
  readonly templates?: readonly UriTemplate[];
6428
6671
  readonly examples?: readonly UriExample[];
6429
6672
  readonly notes?: readonly string[];
6673
+ /**
6674
+ * Set when this help, for the address it was asked about, carries text a third party wrote and
6675
+ * the module relays as it received it (an MCP server's own tool names and descriptions), rather
6676
+ * than text the module's author wrote. Absent: the module's own text.
6677
+ */
6678
+ readonly thirdPartyContent?: true;
6430
6679
  }
6431
6680
 
6432
6681
  declare interface UriHintTriggers {
@@ -7244,7 +7493,7 @@ declare interface UriValidationMessage {
7244
7493
  * applies label changes"), never wire mechanics or URI shapes. Verbs the
7245
7494
  * module does not support are omitted; at runtime a supported verb with no
7246
7495
  * entry simply renders undocumented (fail-open metadata) — but for a plugin's
7247
- * `kay.agent` URI modules, `auditPluginDisclosure` (`@kay/plugin-sdk/
7496
+ * `kay.agent` URI modules, `auditPluginDisclosure` (`@bonsai/plugin-sdk/
7248
7497
  * disclosure`) enforces coverage of every supported verb at authoring/load
7249
7498
  * time.
7250
7499
  *
package/dist/kay-app.js CHANGED
@@ -503,6 +503,13 @@ function createUnavailableSkills(message) {
503
503
  };
504
504
  }
505
505
 
506
+ // packages/plugin-sdk/dist/kay-app/tools.js
507
+ function createUnavailableTools() {
508
+ return {
509
+ describe: async () => ({ status: "unavailable", reason: "not-available" })
510
+ };
511
+ }
512
+
506
513
  // packages/plugin-sdk/dist/kay-app/transcript-text.js
507
514
  function transcriptMessageTexts(entries) {
508
515
  return entries.flatMap((entry) => {
@@ -531,6 +538,13 @@ function transcriptRoleLabel(role) {
531
538
  return role === "user" ? "User" : "Assistant";
532
539
  }
533
540
 
541
+ // packages/plugin-sdk/dist/kay-app/usage.js
542
+ function createUnavailableUsage(message) {
543
+ return {
544
+ uriActivity: async () => ({ status: "unavailable", message })
545
+ };
546
+ }
547
+
534
548
  // packages/plugin-sdk/dist/kay-app/workflows.js
535
549
  var KayAppWorkflowFailure = class extends Error {
536
550
  summary;
@@ -572,6 +586,8 @@ export {
572
586
  createFallbackOnlySignals,
573
587
  createFallbackOnlyWithJev,
574
588
  createUnavailableSkills,
589
+ createUnavailableTools,
590
+ createUnavailableUsage,
575
591
  invalidObservation,
576
592
  isRetryable,
577
593
  parseLineSelector,
package/dist/signals.d.ts CHANGED
@@ -86,7 +86,7 @@ declare interface JevScoreQuestion {
86
86
  * - The wire. The host serves `classify` over whichever route the user's Jev provider order
87
87
  * picks; a plugin never sees a vendor client, a vendor type, or a route.
88
88
  * - Credential resolution, the `jev.use` decision, the Jev-branch budget, or usage accounting.
89
- * Those are host-side (`@kay/agent-runtime`'s `kay/jev/`).
89
+ * Those are host-side (`@bonsai/agent-runtime`'s `kay/jev/`).
90
90
  * ---
91
91
  *
92
92
  * The vocabulary is Bonsai's own (SDK 0.12.0). Before it, `use` received TypeSafe's `TypeSafeClient`
@@ -301,7 +301,7 @@ export declare type KayAppSignalsAnswerFilter = {
301
301
  */
302
302
  export declare interface KayAppSignalsDetectorInput {
303
303
  /**
304
- * Stable identifier, e.g. `memory-curator-gate`: a lowercase slug (a-z and 0-9 in words joined
304
+ * Stable identifier, e.g. `memory-packet`: a lowercase slug (a-z and 0-9 in words joined
305
305
  * by single hyphens), at most 64 characters, plugin-scoped. It becomes a `signals://` path
306
306
  * segment.
307
307
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yaklabs-ai/plugin-sdk",
3
- "version": "0.13.1",
3
+ "version": "0.13.3",
4
4
  "description": "The Kay plugin SDK — types and helpers for authoring a Kay directory plugin.",
5
5
  "author": "YakLabs",
6
6
  "type": "module",
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: directory-plugin-authoring
3
- description: "Author, scaffold, debug, or iterate on a Bonsai directory plugin (one the user writes in ~/.kay/plugins/<name>). Use when creating a new local plugin, when a plugin does not appear in Bonsai after installation, when enabling it fails with 'pluginActivation names a plugin that is not installed', when Settings → Plugins shows 'failed to load' with no toggle, when @kay/plugin-sdk imports fail to resolve, when a plugin declares a ui.tsx that nothing typechecks, or when changes to a plugin do not take effect. For installing plugins from a git repository source, use the manage-plugins skill instead; for first-party bundled plugins under plugins/ in the kay repo, use the bundled-plugin guidance there."
3
+ description: "Author, scaffold, debug, or iterate on a Bonsai directory plugin (one the user writes in ~/.kay/plugins/<name>). Use when creating a new local plugin, when a plugin does not appear in Bonsai after installation, when enabling it fails with 'pluginActivation names a plugin that is not installed', when Settings → Plugins shows 'failed to load' with no toggle, when @bonsai/plugin-sdk imports fail to resolve, when a plugin declares a ui.tsx that nothing typechecks, or when changes to a plugin do not take effect. For installing plugins from a git repository source, use the manage-plugins skill instead; for first-party bundled plugins under plugins/ in the kay repo, use the bundled-plugin guidance there."
4
4
  ---
5
5
 
6
6
  # Directory plugin authoring
@@ -14,7 +14,7 @@ keeps an agent on the paved path and out of the known pits.
14
14
 
15
15
  `pnpm create-plugin` writes absolute type paths (`tsconfig.json`, `package.json`) pointing at
16
16
  whichever Bonsai checkout invoked it, with no staleness warning. A checkout far behind `origin/main`
17
- — one was 752 commits behind — typechecks the new plugin against stale `@kay/plugin-sdk` types,
17
+ — one was 752 commits behind — typechecks the new plugin against stale `@bonsai/plugin-sdk` types,
18
18
  and it looks clean: every wrong shape it produced (a `content` object instead of
19
19
  `run`/`openBeside` on `PaneActionDescriptor`, `SearchField`'s `onChange` instead of
20
20
  `onValueChange`, wrong `PageState` props) typechecked fine against the old types it was
@@ -27,7 +27,7 @@ git -C <kay-checkout> fetch origin && git -C <kay-checkout> rev-list --count HEA
27
27
  ```
28
28
 
29
29
  A nonzero count means update that checkout first, or scaffold from a fresh `origin/main` worktree
30
- and rebuild `@kay/plugin-sdk` there. A green typecheck against stale types is evidence of nothing.
30
+ and rebuild `@bonsai/plugin-sdk` there. A green typecheck against stale types is evidence of nothing.
31
31
  The scaffold does the second half of this for you: it prints a warning when the checkout trails
32
32
  its last-fetched `origin/main`, and stamps the checkout's commit into the generated
33
33
  `tsconfig.json` header. It never fetches, so the `fetch` above is still yours to run; a checkout
@@ -36,7 +36,7 @@ that has not fetched in a week reads as current to the scaffold.
36
36
  ## Scaffold, never hand-roll
37
37
 
38
38
  ```
39
- pnpm --filter @kay/plugin-sdk build # once per checkout, if not built
39
+ pnpm --filter @bonsai/plugin-sdk build # once per checkout, if not built
40
40
  pnpm create-plugin --id com.example.widgets
41
41
  ```
42
42
 
@@ -44,14 +44,14 @@ Run from the root of a Bonsai checkout. It writes a working plugin (manifest, en
44
44
  README) that already typechecks and loads; `--tier starter` adds a URI module, a bundled skill,
45
45
  and a standalone `node --test` test to copy from. Add `--ui` (either tier) when the plugin needs a
46
46
  page: it writes `ui.tsx`, declares the `kay.ui` entrypoint, and generates the UI typecheck config
47
- described below. `--ui` also needs `pnpm --filter @kay/ui build` once per checkout; the scaffold
47
+ described below. `--ui` also needs `pnpm --filter @bonsai/ui build` once per checkout; the scaffold
48
48
  stops and says so when that build is missing.
49
49
 
50
50
  Never hand-build a plugin as a tsc-compiled package and copy the output into `~/.kay/plugins/`.
51
- That path produces a plugin whose built `dist/` imports `@kay/plugin-sdk` through ordinary
51
+ That path produces a plugin whose built `dist/` imports `@bonsai/plugin-sdk` through ordinary
52
52
  `node_modules` resolution, which cannot work from outside the monorepo — it shipped a
53
53
  failed-to-load plugin and a misfiled bug (#7732). The load fails with `ERR_MODULE_NOT_FOUND`,
54
- and symlinking `node_modules/@kay` into the copy does not rescue it either: pnpm's `.pnpm`
54
+ and symlinking `node_modules/@bonsai` into the copy does not rescue it either: pnpm's `.pnpm`
55
55
  layout does not expose workspace packages that way. The scaffold exists precisely so this
56
56
  cannot happen.
57
57
 
@@ -62,7 +62,7 @@ pnpm plugin:check ~/.kay/plugins/widgets
62
62
  ```
63
63
 
64
64
  Run from the root of a Bonsai checkout, against the plugin directory. It runs the daemon's OWN
65
- manifest schema and contract resolver (imported from `@kay/plugin-protocol`, not re-implemented),
65
+ manifest schema and contract resolver (imported from `@bonsai/plugin-protocol`, not re-implemented),
66
66
  so it answers "would Kay accept this manifest?" in about a second instead of after a load cycle.
67
67
  Run it after every manifest edit, and before concluding a plugin is broken for some deeper reason.
68
68
 
@@ -82,13 +82,13 @@ disclosure audit, or an id another installed plugin already claims.
82
82
 
83
83
  ## The SDK resolution contract
84
84
 
85
- - Plugin source imports `@kay/plugin-sdk/<subpath>` as a **bare specifier**
86
- (`@kay/plugin-sdk/kay-agent`, `/kay-agent/testing`, `/kay-app`, `/disclosure` — only declared
85
+ - Plugin source imports `@bonsai/plugin-sdk/<subpath>` as a **bare specifier**
86
+ (`@bonsai/plugin-sdk/kay-agent`, `/kay-agent/testing`, `/kay-app`, `/disclosure` — only declared
87
87
  exports exist).
88
88
  - The daemon's chord loader bundles each declared TypeScript entrypoint and its relative imports.
89
- It keeps `@kay/plugin-sdk` imports external and resolves them to the running app's own built SDK.
89
+ It keeps `@bonsai/plugin-sdk` imports external and resolves them to the running app's own built SDK.
90
90
  Multi-file plugins are supported, and no plugin-local build is needed for Bonsai to load them.
91
- - Corollary: **bare `node` outside the daemon cannot resolve `@kay/plugin-sdk`** from the plugin
91
+ - Corollary: **bare `node` outside the daemon cannot resolve `@bonsai/plugin-sdk`** from the plugin
92
92
  directory unless the plugin has its own SDK dependency. That failure says nothing about whether
93
93
  the plugin will load in Bonsai. The `starter` tier's test setup creates the symlink needed for its
94
94
  standalone test; a published SDK dependency is the other standalone option.
@@ -106,7 +106,7 @@ entrypoint may import other files in the plugin; `kay.agent` runs in the daemon
106
106
  self-contained module: unlike the daemon targets, `ui.tsx` cannot import sibling files. A
107
107
  plugin UI contributes through `api.slots` (`registerPage`, `registerSidebarItem`,
108
108
  `registerPaneAction`, and the rest of `buildSlots` in
109
- `apps/kay/src/renderer/src/extension-loader/build-extension-api.ts`). A page gets its own
109
+ `packages/kay-renderer/src/renderer/src/extension-loader/build-extension-api.ts`). A page gets its own
110
110
  activity-rail button when a `registerSidebarItem({ pageId, placement: "activityRail" })` from the
111
111
  same plugin points at it.
112
112
 
@@ -119,17 +119,17 @@ and its rail item borrow each other's glyph, so one declaration covers the desti
119
119
  precedence: `packages/kay-frontend-sdk/ARCHITECTURE.md`, "Plugin icon".
120
120
 
121
121
  `ui.tsx` has no `node_modules` of its own. The renderer bundles it and rewrites its `react` and
122
- `@kay/*` imports to the host's `__KAY_UI_RUNTIME__` singletons, so the agent `tsconfig.json`
122
+ `@bonsai/*` imports to the host's `__KAY_UI_RUNTIME__` singletons, so the agent `tsconfig.json`
123
123
  cannot cover it, and a plugin whose UI nothing typechecks has shipped three wrong API shapes at
124
124
  once. `pnpm create-plugin --ui` generates `tsconfig.ui.json` for exactly this: its `paths` are
125
- derived from the bundler's own shim set (`uiRuntimeShimModules` in `@kay/ui-app-bundler`), each
125
+ derived from the bundler's own shim set (`uiRuntimeShimModules` in `@bonsai/ui-app-bundler`), each
126
126
  specifier mapped to the type entry the renderer binds it to, and `npm run typecheck` runs both
127
127
  configs. Do not hand-write the map; when the bundler's set changes, the scaffold's test fails and
128
128
  the generated config follows.
129
129
 
130
130
  Two facts about that config worth knowing when you read errors from it:
131
131
 
132
- - The bare `@kay/frontend-sdk` is typed against the SDK's `ui-runtime` facade, because that is
132
+ - The bare `@bonsai/frontend-sdk` is typed against the SDK's `ui-runtime` facade, because that is
133
133
  what the renderer binds it to. The facade carries the SDK's whole type surface, so
134
134
  `KayUiExtensionApi` and every descriptor type import fine; a **value** only the package's main
135
135
  entry exports fails to compile there (TS1362, "exported using export type"), which is the
@@ -210,9 +210,9 @@ a failure class the load would otherwise be the first thing to surface:
210
210
 
211
211
  1. **Run `pnpm plugin:check <dir>`** from a Bonsai checkout. It validates `kay-plugin.json` against
212
212
  `KayPluginManifestV1` and resolves its contributions with the daemon's own resolver (both from
213
- `@kay/plugin-protocol`), not just "it is valid JSON": that schema and resolver are the gate the
213
+ `@bonsai/plugin-protocol`), not just "it is valid JSON": that schema and resolver are the gate the
214
214
  scan actually runs. A non-zero exit means the plugin would be refused.
215
- 2. **Run the disclosure audit yourself**: `auditPluginDisclosure` from `@kay/plugin-sdk/disclosure`.
215
+ 2. **Run the disclosure audit yourself**: `auditPluginDisclosure` from `@bonsai/plugin-sdk/disclosure`.
216
216
  It is not redundant with typecheck. A plugin shipped a `search` verb with no `verbDocs` entry
217
217
  that typechecked clean and would have failed the whole `kay.agent` target.
218
218
  3. **Typecheck every target**: `npm run typecheck` runs the agent config and, for a `--ui`