@yaklabs-ai/plugin-sdk 0.13.0 → 0.13.2

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
@@ -21,7 +21,7 @@ declare interface AccountIdentity {
21
21
  readonly displayName?: string;
22
22
  /** Absolute URL of the account's avatar. */
23
23
  readonly avatarUrl?: string;
24
- /** Issuer-asserted beta-tester flag; only Kay's product-account service sets it. */
24
+ /** Issuer-asserted beta-tester flag; only Bonsai's product-account service sets it. */
25
25
  readonly betaTester?: boolean;
26
26
  readonly activeOrganizationId?: string;
27
27
  readonly organizationSelectionState?: "selected" | "unresolved";
@@ -29,7 +29,7 @@ declare interface AccountIdentity {
29
29
  /**
30
30
  * Provider-native session id claim (WorkOS's `sid`), needed to call the provider's own
31
31
  * session-revocation endpoint at sign-out (`POST /user_management/sessions/revoke`, not yet
32
- * wired — see `docs/kay-account-auth.md`'s "Sign-out guarantee" section). Only Kay's WorkOS
32
+ * wired — see `docs/kay-account-auth.md`'s "Sign-out guarantee" section). Only Bonsai's WorkOS
33
33
  * product-account exchange/refresh sets it; every other provider leaves it absent.
34
34
  */
35
35
  readonly providerSessionId?: string;
@@ -431,6 +431,12 @@ export declare function createFallbackOnlyWithJev(): WithJev;
431
431
  */
432
432
  export declare function createUnavailableSkills(message: string): KayAppSkills;
433
433
 
434
+ /**
435
+ * The `app.tools` a host that cannot describe tools binds: every call answers `not-available`, so
436
+ * a plugin's code path never depends on host composition.
437
+ */
438
+ export declare function createUnavailableTools(): KayAppTools;
439
+
434
440
  declare interface CustomEntry extends EntryBase {
435
441
  type: "custom";
436
442
  customType: string;
@@ -762,7 +768,7 @@ export declare interface JevScoreQuestion {
762
768
  * Those are host-side (`@kay/agent-runtime`'s `kay/jev/`).
763
769
  * ---
764
770
  *
765
- * The vocabulary is Kay's own (SDK 0.12.0). Before it, `use` received TypeSafe's `TypeSafeClient`
771
+ * The vocabulary is Bonsai's own (SDK 0.12.0). Before it, `use` received TypeSafe's `TypeSafeClient`
766
772
  * and plugins coded against a vendor's types. It follows pi's classifier contract, which the host
767
773
  * runs Jev through: a yes/no question is `bool` and answers a `probability`, every instruction and
768
774
  * criterion is text, and the state is a JSON object.
@@ -904,7 +910,7 @@ declare interface KayAgentWhiteboardUpdateInput {
904
910
  }
905
911
 
906
912
  /**
907
- * The signed-in Kay account. Always present on {@link KayAppPluginApi}.
913
+ * The signed-in Bonsai account. Always present on {@link KayAppPluginApi}.
908
914
  *
909
915
  * Reading the profile is ungated: it exposes the signed-in user's own identity to a plugin they
910
916
  * explicitly enabled. The two stronger operations are separate claims, checked per call —
@@ -948,7 +954,7 @@ export declare interface KayAppAccount {
948
954
  assertResult?(): Promise<KayAppAccountAssertionResult>;
949
955
  /**
950
956
  * Change the user-editable part of the signed-in profile (today: the display name). PRESENT
951
- * only with the `update` operation granted. Runs through Kay's own profile-update path — the
957
+ * only with the `update` operation granted. Runs through Bonsai's own profile-update path — the
952
958
  * same one Account settings uses — so the change reaches WorkOS, the local account snapshot,
953
959
  * Memory's account-owned person note, and every `subscribe` listener; later sessions see the
954
960
  * new name in their prompt. Rejects when signed out or when the backend refuses the value
@@ -991,7 +997,7 @@ export declare interface KayAppAccount {
991
997
  * issuer's own JWKS.
992
998
  *
993
999
  * It is **not audience-scoped**. A plugin holding it can present itself as the user to anything
994
- * that accepts a Kay product-account token, not only to the relying party it was fetched for.
1000
+ * that accepts a Bonsai product-account token, not only to the relying party it was fetched for.
995
1001
  * Treat it as live secret material: never log it, never put it in an event payload or an endpoint
996
1002
  * response, never persist it. Read it, use it in the outbound request, drop it.
997
1003
  *
@@ -1004,7 +1010,7 @@ export declare interface KayAppAccountAssertion {
1004
1010
  /**
1005
1011
  * The OIDC issuer that can verify `token`.
1006
1012
  *
1007
- * Travels with the assertion because Kay runs one product-account provider instance per release
1013
+ * Travels with the assertion because Bonsai runs one product-account provider instance per release
1008
1014
  * channel (local-dev, Yak, production). A verifier that hardcodes the production issuer
1009
1015
  * silently rejects every other install.
1010
1016
  */
@@ -1052,8 +1058,8 @@ export declare type KayAppAccountAssertionResult = {
1052
1058
  };
1053
1059
 
1054
1060
  /**
1055
- * Who is signed in to Kay. Metadata only — this carries no secret and cannot be presented to
1056
- * anyone as proof. Derived from the Kay product-account record's stored identity.
1061
+ * Who is signed in to Bonsai. Metadata only — this carries no secret and cannot be presented to
1062
+ * anyone as proof. Derived from the Bonsai product-account record's stored identity.
1057
1063
  */
1058
1064
  export declare interface KayAppAccountProfile {
1059
1065
  /** The account's stable provider `sub`. Survives an email change; prefer it as a durable key. */
@@ -1062,7 +1068,7 @@ export declare interface KayAppAccountProfile {
1062
1068
  readonly displayName?: string;
1063
1069
  readonly avatarUrl?: string;
1064
1070
  /**
1065
- * Whether the account is a Kay beta tester, sourced from the Kay Cloud API's `GET /v1/me`
1071
+ * Whether the account is a Bonsai beta tester, sourced from the Bonsai Cloud API's `GET /v1/me`
1066
1072
  * (authoritative). Absent means unknown, not "no" — a live read that could not run, or a
1067
1073
  * grant that predates the API becoming the source, are both indistinguishable here. A present
1068
1074
  * value is refreshed on a bounded interval, not only at sign-in; see
@@ -1127,6 +1133,10 @@ export declare interface KayAppAgentDefinition {
1127
1133
  * These rules outrank the human's standing settings-page preference (they seed a level above
1128
1134
  * `user`) and cannot be removed by the running session. They are re-read from the definition at
1129
1135
  * every session activation, so a rule the plugin stops declaring stops applying.
1136
+ *
1137
+ * They also bind every subagent such a session spawns with `agent_spawn`, and every subagent
1138
+ * those spawn in turn. A subagent inherits only these rules (and {@link permissionsFallback}),
1139
+ * not this definition's instructions or tool roster.
1130
1140
  */
1131
1141
  readonly permissions?: readonly PluginAgentDefinitionPermissionRule[];
1132
1142
  /**
@@ -1151,8 +1161,8 @@ export declare interface KayAppAgentDefinition {
1151
1161
  export declare interface KayAppAgentDefinitionConfig {
1152
1162
  /**
1153
1163
  * The definition's instructions: what this agent exists to do. Rendered as the
1154
- * agent-configuration trailer at the END of Kay's own prompt document, subordinate to
1155
- * everything above it. A definition never replaces Kay's prompt; it extends it.
1164
+ * agent-configuration trailer at the END of Bonsai's own prompt document, subordinate to
1165
+ * everything above it. A definition never replaces Bonsai's prompt; it extends it.
1156
1166
  */
1157
1167
  readonly instructions?: string;
1158
1168
  readonly activeToolNames?: readonly KayAppSessionRunHostToolName[];
@@ -1161,7 +1171,7 @@ export declare interface KayAppAgentDefinitionConfig {
1161
1171
  readonly thinkingLevel?: KayAppThinkingLevel;
1162
1172
  readonly cwd?: string;
1163
1173
  /**
1164
- * The definition's structured-output contract for a settled turn. Kay's own default agent
1174
+ * The definition's structured-output contract for a settled turn. Bonsai's own default agent
1165
1175
  * carries its standing-recap contract through this field; a plugin-authored definition may
1166
1176
  * carry one too, with the same discipline: keep it optional, and use `whenToSubmit` to say
1167
1177
  * when it applies rather than making every turn terminate through it.
@@ -1493,7 +1503,7 @@ export declare type KayAppAutomationEffectInput = {
1493
1503
  /** The file this automation runs; every stored binding carries one. */
1494
1504
  readonly ref?: KayAppAutomationScriptRef;
1495
1505
  /**
1496
- * Inline source, at CREATE only: Kay saves it into the owning session's scripts folder
1506
+ * Inline source, at CREATE only: Bonsai saves it into the owning session's scripts folder
1497
1507
  * and stores a reference to that file. Pass this OR `ref`, never both.
1498
1508
  */
1499
1509
  readonly source?: string;
@@ -1503,7 +1513,7 @@ export declare type KayAppAutomationEffectInput = {
1503
1513
  /**
1504
1514
  * One thing a run created OUTSIDE this machine — today a GitHub pull request
1505
1515
  * its session opened. A sibling of {@link KayAppAutomationArtifactItem}, not a
1506
- * widening of it: an external resource has no revision, no Kay uri module, and
1516
+ * widening of it: an external resource has no revision, no Bonsai uri module, and
1507
1517
  * nothing on this machine to re-read.
1508
1518
  *
1509
1519
  * `kind` is the run-detail wire's closed external-resource vocabulary and names
@@ -1685,12 +1695,12 @@ export declare type KayAppAutomationRunOutcome = {
1685
1695
  export declare interface KayAppAutomations {
1686
1696
  list(ctx: KayAppAutomationContext): Promise<readonly KayAppAutomationBinding[]>;
1687
1697
  /**
1688
- * Kay's own recurring work. NOT session-scoped, unlike {@link list}: these
1698
+ * Bonsai's own recurring work. NOT session-scoped, unlike {@link list}: these
1689
1699
  * belong to the daemon, so every session sees the same set.
1690
1700
  */
1691
1701
  listManaged(ctx: KayAppAutomationContext): Promise<readonly KayAppManagedAutomation[]>;
1692
1702
  /**
1693
- * Run one of Kay's own automations now, without waiting for its schedule.
1703
+ * Run one of Bonsai's own automations now, without waiting for its schedule.
1694
1704
  *
1695
1705
  * Separate from {@link runNow} because it addresses a different population:
1696
1706
  * `runNow` proves the caller owns the binding, and a managed automation has
@@ -1731,7 +1741,7 @@ export declare interface KayAppAutomations {
1731
1741
  * Switch one automation on or off.
1732
1742
  *
1733
1743
  * Reaches TWO populations, and the result says which one it answered about. A binding this
1734
- * session owns comes back as a full {@link KayAppAutomationBinding}. One of Kay's OWN
1744
+ * session owns comes back as a full {@link KayAppAutomationBinding}. One of Bonsai's OWN
1735
1745
  * automations comes back as a {@link KayAppManagedAutomation} instead: its effect belongs to the
1736
1746
  * daemon and never crosses a plugin boundary, so there is no binding to hand back. That is the
1737
1747
  * whole reason this is a union rather than one shape - a caller reading `binding`
@@ -1820,9 +1830,9 @@ export declare type KayAppAutomationSuggestionItem = {
1820
1830
  });
1821
1831
 
1822
1832
  /**
1823
- * Watch one Kay URI and fire only when what it reads back CHANGES. Carries no
1833
+ * Watch one Bonsai URI and fire only when what it reads back CHANGES. Carries no
1824
1834
  * `sessionId`: unlike the fact-driven conditions, what it watches lives OUTSIDE
1825
- * Kay — which is also why it outlives the session that created it.
1835
+ * Bonsai — which is also why it outlives the session that created it.
1826
1836
  */
1827
1837
  export declare interface KayAppAutomationUriChangeCondition {
1828
1838
  readonly kind: "uri-change";
@@ -2052,6 +2062,14 @@ export declare interface KayAppCorpusEntryBatch {
2052
2062
  /** One stored session, as the granted corpus enumerates them. Keyed by its stable `sessionId`. */
2053
2063
  export declare interface KayAppCorpusSession {
2054
2064
  readonly sessionId: string;
2065
+ /**
2066
+ * Who the session is for, as stamped when it was created: a person's own session (`user`), a
2067
+ * spawned subagent, or a session Bonsai runs with nobody watching (`system`, `followup`). It lets
2068
+ * a reader skip sessions without opening their transcripts. Absent when the index does not know
2069
+ * it (a session older than origin stamping, or a row not yet rebuilt from its transcript): that
2070
+ * is unknown, not `user`.
2071
+ */
2072
+ readonly origin?: KayAppSessionOrigin | undefined;
2055
2073
  }
2056
2074
 
2057
2075
  /** Cheap identity for the current contents of one stored session transcript. */
@@ -2263,7 +2281,7 @@ export declare interface KayAppDynamicContextContribution {
2263
2281
  }
2264
2282
 
2265
2283
  /**
2266
- * One delivery pass's request. For modern Kay sends, `texts` contains one
2284
+ * One delivery pass's request. For modern Bonsai sends, `texts` contains one
2267
2285
  * source-ordered human-input projection with inline paste nodes expanded to
2268
2286
  * their exact bodies. Older paste-aware clients contribute their exact inline
2269
2287
  * paste bodies. UI-generated labels such as `[Pasted 21 lines]` never appear.
@@ -2280,7 +2298,7 @@ export declare interface KayAppDynamicContextRequest {
2280
2298
  readonly search: (opts?: KayAppDynamicContextSearchOptions) => Promise<readonly KayAppDynamicContextSearchHit[]>;
2281
2299
  }
2282
2300
 
2283
- /** One indexed reference from Kay's shared knowledge — routes plus revision identity, never answers. */
2301
+ /** One indexed reference from Bonsai's shared knowledge — routes plus revision identity, never answers. */
2284
2302
  export declare interface KayAppDynamicContextSearchHit {
2285
2303
  readonly uri: string;
2286
2304
  readonly score: number;
@@ -2310,7 +2328,7 @@ export declare interface KayAppDynamicContextSearchOptions {
2310
2328
 
2311
2329
  /**
2312
2330
  * The app-wide endpoint bus. A plugin registers named handlers a consuming surface can invoke; the
2313
- * host routes invocations (e.g. Kay Desktop forwards the renderer's frame-gated call to the daemon,
2331
+ * host routes invocations (e.g. Bonsai Desktop forwards the renderer's frame-gated call to the daemon,
2314
2332
  * where the endpoint is single-homed). The corpus is NEVER reachable here — only what the plugin
2315
2333
  * explicitly exposes. Both `payload` and the handler's return ride strict JSON on the wire.
2316
2334
  */
@@ -2383,7 +2401,7 @@ export declare interface KayAppLifecycle {
2383
2401
  * each write or run is checked against `automations.write` / `automations.run`.
2384
2402
  */
2385
2403
  /**
2386
- * One of Kay's OWN recurring automations — a bundled plugin's nightly
2404
+ * One of Bonsai's OWN recurring automations — a bundled plugin's nightly
2387
2405
  * workflow, the knowledge sweep — as a plugin may see it.
2388
2406
  *
2389
2407
  * A narrow projection rather than a binding: a managed automation's effect
@@ -2495,7 +2513,7 @@ export declare interface KayAppModelFeatures {
2495
2513
  readonly maxOutputTokens?: number;
2496
2514
  }
2497
2515
 
2498
- /** The plugin-safe projection of one model in Kay's live model catalog. */
2516
+ /** The plugin-safe projection of one model in Bonsai's live model catalog. */
2499
2517
  export declare interface KayAppModelInfo {
2500
2518
  readonly modelReference: string;
2501
2519
  readonly provider: string;
@@ -2521,7 +2539,7 @@ export declare type KayAppModelModality = "text" | "image" | "audio" | "video" |
2521
2539
  export declare interface KayAppModels {
2522
2540
  /** Returns the current projection; an empty catalog is an empty array. */
2523
2541
  list(): Promise<readonly KayAppModelInfo[]>;
2524
- /** Present when the host resolves image-model nominations (every Kay daemon does). */
2542
+ /** Present when the host resolves image-model nominations (every Bonsai daemon does). */
2525
2543
  resolveImageModel?(provider: string): Promise<KayAppImageModelInfo>;
2526
2544
  /**
2527
2545
  * Returns the four product model tiers, each with its live point-in-time resolution
@@ -2562,7 +2580,7 @@ export declare type KayAppModelSelection = {
2562
2580
  readonly provider?: string | undefined;
2563
2581
  };
2564
2582
 
2565
- /** Kay's canonical task-difficulty tier vocabulary at the plugin boundary. */
2583
+ /** Bonsai's canonical task-difficulty tier vocabulary at the plugin boundary. */
2566
2584
  export declare type KayAppModelTierId = "small" | "medium" | "large" | "ultra";
2567
2585
 
2568
2586
  /**
@@ -2609,7 +2627,7 @@ export declare interface KayAppPaths {
2609
2627
  */
2610
2628
  readonly sessionsRoot?: string;
2611
2629
  /**
2612
- * Absolute path to Kay's local telemetry directory. The live telemetry lane itself is a
2630
+ * Absolute path to Bonsai's local telemetry directory. The live telemetry lane itself is a
2613
2631
  * Postgres table (`telemetry.usage_events`), not anything under this path; it is never a
2614
2632
  * PostHog credential or a remote-export queue. This directory used to hold the retired
2615
2633
  * file-based store's JSONL journals and compacted Parquet, but those are moved aside once,
@@ -2619,7 +2637,7 @@ export declare interface KayAppPaths {
2619
2637
  */
2620
2638
  readonly telemetryRoot?: string;
2621
2639
  /**
2622
- * Absolute path to Kay's observability log directory. The two JSONL event lanes live here: the
2640
+ * Absolute path to Bonsai's observability log directory. The two JSONL event lanes live here: the
2623
2641
  * Desktop main process appends `kay-<YYYY-MM-DD>.jsonl` (fatal-startup records append into that
2624
2642
  * same lane) and the daemon appends `kay-runtime-<YYYY-MM-DD>.jsonl` — read BOTH lanes, or you
2625
2643
  * are reading half the system. Lane files rotate daily, gain a `.N` suffix past 50 MB, and are
@@ -2683,7 +2701,7 @@ export declare interface KayAppPluginApi {
2683
2701
  /** Register app-lifetime cleanup for plugin-owned processes, sockets, watchers, or timers. */
2684
2702
  readonly lifecycle: KayAppLifecycle;
2685
2703
  /**
2686
- * Manifest-declared app-data sources. Present whenever the host runs an app-data lane (every Kay
2704
+ * Manifest-declared app-data sources. Present whenever the host runs an app-data lane (every Bonsai
2687
2705
  * daemon does); absence means THIS host composed none, never that a grant is missing. Each
2688
2706
  * registration is checked against `app-data.register {source}` for the declared
2689
2707
  * `contributes.dataSources` localId it names.
@@ -2703,7 +2721,7 @@ export declare interface KayAppPluginApi {
2703
2721
  */
2704
2722
  readonly corpus: KayAppCorpus;
2705
2723
  /**
2706
- * The signed-in Kay product account. Present whenever the host runs an account service; absence
2724
+ * The signed-in Bonsai product account. Present whenever the host runs an account service; absence
2707
2725
  * means this host composed none, never that a grant is missing. Reading identity is ungated; the
2708
2726
  * two stronger operations are checked per call against `account.assert` and `account.update`.
2709
2727
  */
@@ -2851,6 +2869,14 @@ export declare interface KayAppPluginApi {
2851
2869
  * present, like {@link signals}.
2852
2870
  */
2853
2871
  readonly skills: KayAppSkills;
2872
+ /**
2873
+ * What a live session's tools and addresses say to the agent, where each comes from, and whether
2874
+ * each is one of Bonsai's own. Each call is checked against `tools.describe`; a refused grant or
2875
+ * a session that is not live resolves to `{ status: "unavailable" }`, never a rejection, while
2876
+ * the plugin is enabled. After it is disabled, a kept handle's methods throw synchronously.
2877
+ * Always present, like {@link skills}.
2878
+ */
2879
+ readonly tools: KayAppTools;
2854
2880
  /** The app-wide endpoint bus (register handlers a consuming surface invokes). */
2855
2881
  readonly endpoints: KayAppEndpoints;
2856
2882
  /** Publish one event declared by this plugin's `kay.app` manifest target. */
@@ -3409,6 +3435,14 @@ export declare interface KayAppSessions {
3409
3435
  /** Omit to inherit the opener; null explicitly selects no project. */
3410
3436
  readonly projectId?: string | null;
3411
3437
  readonly title?: string | undefined;
3438
+ /**
3439
+ * The new session's model, as a tier word (`small`, `medium`, `large`, `ultra`): the daemon
3440
+ * picks the concrete model through the same tier resolution every other tier choice takes.
3441
+ * Absent, the person's own selection applies, so a session a plugin opens on its own account
3442
+ * runs on whatever they happen to be using, Ultra included. Work that does not need a strong
3443
+ * model names a tier. A tier only: an exact model pin is not offered here.
3444
+ */
3445
+ readonly tier?: KayAppModelTierId | undefined;
3412
3446
  /**
3413
3447
  * The session asking for this one, so the daemon can record which session opened it.
3414
3448
  * Pass the calling tool's own `ctx.sessionId` and nothing else: the daemon vets the id
@@ -3447,7 +3481,7 @@ export declare interface KayAppSessions {
3447
3481
  readonly kind: "unavailable";
3448
3482
  }>;
3449
3483
  /**
3450
- * Run one hidden headless system session through Kay's harness and resolve
3484
+ * Run one hidden headless system session through Bonsai's harness and resolve
3451
3485
  * with its final output — the sole sanctioned way for a `kay.app` plugin to
3452
3486
  * spend model tokens outside a session-event handler. Checked per call against
3453
3487
  * the `sessions.run` claim. A plugin may request a model/tier and supply
@@ -3508,6 +3542,10 @@ export declare interface KayAppSignal {
3508
3542
  readonly pluginId: string;
3509
3543
  };
3510
3544
  readonly source: KayAppSignalSource;
3545
+ /** What the signal is about, when its recorder named a subject. */
3546
+ readonly subject?: KayAppSignalSubject;
3547
+ /** The id of the upstream signal this one was chained after, while that row exists. */
3548
+ readonly upstreamId?: number;
3511
3549
  readonly recordedAtMs: number;
3512
3550
  /** Keyed by question name, full probability distributions included. */
3513
3551
  readonly answers: Readonly<Record<string, KayAppSignalAnswer>>;
@@ -3567,12 +3605,20 @@ export declare interface KayAppSignalNoulAnswer {
3567
3605
  *
3568
3606
  * A repeat call over the same (plugin, detector, version, session, entry, input digest) returns
3569
3607
  * the ALREADY-STORED row with `deduplicated: true` and never calls Jev again: replay is free.
3608
+ * A call with `reuse` that finds a recent row for the same subject key returns that row with
3609
+ * `deduplicated: true` and `reused: true`; its `source` is where the row was computed.
3570
3610
  */
3571
3611
  export declare interface KayAppSignalObservation {
3572
3612
  readonly id?: number | undefined;
3573
3613
  readonly status: "classified" | "unavailable" | "invalid";
3574
3614
  readonly detector: KayAppSignalsDetectorRef;
3575
3615
  readonly source: KayAppSignalSource;
3616
+ /** The row's subject, when it was recorded with one. */
3617
+ readonly subject?: KayAppSignalSubject | undefined;
3618
+ /** The row's upstream link: the id of the row it was chained after. */
3619
+ readonly upstreamId?: number | undefined;
3620
+ /** True when the answer is a stored row found through `reuse`, not this call's own. */
3621
+ readonly reused?: boolean | undefined;
3576
3622
  readonly answers?: Record<string, unknown> | undefined;
3577
3623
  readonly model?: string | undefined;
3578
3624
  readonly usage?: {
@@ -3605,6 +3651,18 @@ export declare interface KayAppSignalPage {
3605
3651
  readonly nextCursor?: string;
3606
3652
  }
3607
3653
 
3654
+ /**
3655
+ * Reuse a stored answer for the same subject instead of asking Jev again. Before any Jev call
3656
+ * the host looks for the newest row this plugin recorded with the same detector, version,
3657
+ * subject key and input digest, recorded at most `maxAgeMs` ago, in ANY session. When one
3658
+ * exists, that row is the answer: no Jev call and no new row. The returned observation keeps the
3659
+ * row's own source (where it was computed), with `reused: true`.
3660
+ */
3661
+ declare interface KayAppSignalReuse {
3662
+ /** How old a stored answer may be, in ms: a whole number from 1 to {@link SIGNAL_TIME_MAX_MS}. */
3663
+ readonly maxAgeMs: number;
3664
+ }
3665
+
3608
3666
  /**
3609
3667
  * One question of a stored rubric, as the recording plugin wrote it. Rubrics recorded before
3610
3668
  * SDK 0.12.0 use TypeSafe's vocabulary (`noul` for yes/no, and instructions or criteria that
@@ -3733,6 +3791,12 @@ export declare interface KayAppSignalsDetectorRef extends KayAppSignalsDetectorI
3733
3791
  export declare interface KayAppSignalsObserveInput {
3734
3792
  readonly detector: KayAppSignalsDetectorInput;
3735
3793
  readonly source: KayAppSignalSource;
3794
+ /** What the signal is about. Stored on the row; not part of the dedupe key or the input digest. */
3795
+ readonly subject?: KayAppSignalSubject;
3796
+ /** The upstream row this observation is chained after. Stored on the row as its upstream link. */
3797
+ readonly after?: KayAppSignalUpstreamLink;
3798
+ /** Reuse a recent stored answer for the same subject key. Needs `subject.key`. */
3799
+ readonly reuse?: KayAppSignalReuse;
3736
3800
  /**
3737
3801
  * The exact state to send, already shaped by the caller (a turn packet, a window of messages,
3738
3802
  * or anything else). NOT stored: the row keeps its digest, and a reader re-derives it from the
@@ -3830,6 +3894,34 @@ export declare interface KayAppSignalsSessionQuery {
3830
3894
  readonly limit?: number;
3831
3895
  }
3832
3896
 
3897
+ /**
3898
+ * What a signal is about, named by the recording plugin. The host stores both values and never
3899
+ * interprets them. A signal recorded without a subject has none; every reader treats it as before.
3900
+ */
3901
+ declare interface KayAppSignalSubject {
3902
+ /**
3903
+ * The kind of thing observed, e.g. `turn`: a lowercase slug of at most 64 characters, in the
3904
+ * same grammar as a detector id.
3905
+ */
3906
+ readonly kind: string;
3907
+ /**
3908
+ * The subject's identity ACROSS sessions, when it has one (two sessions can observe the same
3909
+ * subject). Required for {@link KayAppSignalsObserveInput.reuse}. 1 to 256 characters with no
3910
+ * whitespace, `/`, `?`, `#`, or control or invisible character.
3911
+ */
3912
+ readonly key?: string;
3913
+ }
3914
+
3915
+ /**
3916
+ * The upstream signal a chained observation ran after: the stored row whose answers the caller
3917
+ * found passing. The host checks that the row exists and was recorded by the same plugin, and
3918
+ * stores the link on the new row; it never re-judges the caller's pass condition.
3919
+ */
3920
+ declare interface KayAppSignalUpstreamLink {
3921
+ /** The upstream row's `id`: a positive whole number. */
3922
+ readonly observationId: number;
3923
+ }
3924
+
3833
3925
  /** One managed skill, as the skill catalog admits it. */
3834
3926
  export declare interface KayAppSkill {
3835
3927
  /** Canonical id, `<canonical source id>/<name>`. Equal to a skill invocation's `resourceId`. */
@@ -3846,7 +3938,7 @@ export declare interface KayAppSkill {
3846
3938
  export declare interface KayAppSkillDetail extends KayAppSkill {
3847
3939
  readonly versioning: KayAppSkillVersioning;
3848
3940
  /**
3849
- * The version a session loading the skill now receives, as `git-tree:<oid>`. Absent when Kay
3941
+ * The version a session loading the skill now receives, as `git-tree:<oid>`. Absent when Bonsai
3850
3942
  * keeps no history of the skill (`unversioned`), cannot read it, or the skill's files hold
3851
3943
  * bytes no revision has recorded (`uncommitted`).
3852
3944
  */
@@ -3886,7 +3978,7 @@ export declare interface KayAppSkillNotFound {
3886
3978
  readonly message: string;
3887
3979
  }
3888
3980
 
3889
- /** Who made a revision, as Kay recorded it when the revision was made. Absent fields are unknown. */
3981
+ /** Who made a revision, as Bonsai recorded it when the revision was made. Absent fields are unknown. */
3890
3982
  export declare interface KayAppSkillProvenance {
3891
3983
  /** The session whose work the revision records. */
3892
3984
  readonly sessionId?: string;
@@ -4002,9 +4094,9 @@ export declare interface KayAppSkillsUnavailable {
4002
4094
  }
4003
4095
 
4004
4096
  /**
4005
- * Whether Kay keeps a history for the skill, and how its local copy relates to its source.
4006
- * `unversioned`: the skill's files are the user's own, and Kay keeps no history of them.
4007
- * `unavailable`: Kay does keep one and cannot read it right now.
4097
+ * Whether Bonsai keeps a history for the skill, and how its local copy relates to its source.
4098
+ * `unversioned`: the skill's files are the user's own, and Bonsai keeps no history of them.
4099
+ * `unavailable`: Bonsai does keep one and cannot read it right now.
4008
4100
  */
4009
4101
  export declare type KayAppSkillVersioning = "pristine" | "customized" | "update-available" | "diverged" | "unversioned" | "unavailable";
4010
4102
 
@@ -4020,7 +4112,7 @@ export declare interface KayAppStorage {
4020
4112
  readonly dataDir?: KayAppDataDirStorage;
4021
4113
  }
4022
4114
 
4023
- /** Kay's reasoning-effort ladder, in ascending order. */
4115
+ /** Bonsai's reasoning-effort ladder, in ascending order. */
4024
4116
  export declare type KayAppThinkingLevel = "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
4025
4117
 
4026
4118
  /**
@@ -4124,6 +4216,21 @@ export declare type KayAppToolDefinition<TParams extends ToolParametersWire = To
4124
4216
  execute(toolCallId: string, params: ToolExecutionAwareParams<TParams>, signal: AbortSignal | undefined, onUpdate: AgentToolUpdateCallback<TDetails> | undefined, ctx: KayAppToolContext): Promise<AgentToolResult<TDetails>>;
4125
4217
  };
4126
4218
 
4219
+ export declare interface KayAppToolDescription {
4220
+ readonly ref: KayAppToolRef;
4221
+ /** `false`: no such tool is registered, or no module owns that address, in this session. */
4222
+ readonly found: boolean;
4223
+ /**
4224
+ * For a tool, its own registered description. For an address, its help rendered as `help <uri>`
4225
+ * renders it for the agent; for `mcp://<server>`, that is the server's tool list in the server's
4226
+ * own words.
4227
+ */
4228
+ readonly description?: string;
4229
+ readonly origin?: KayAppToolOrigin;
4230
+ /** Whether this is one of Bonsai's own tools or addresses. `false` when not found. */
4231
+ readonly ownedByBonsai: boolean;
4232
+ }
4233
+
4127
4234
  /**
4128
4235
  * The fine-grained, app-wide per-tool event stream (every session's tool executions). Carries the
4129
4236
  * redaction caveat: raw tool args/results are OFF in packaged builds, so a handler must treat
@@ -4136,9 +4243,23 @@ export declare interface KayAppToolEvents {
4136
4243
  subscribe(handler: (event: unknown) => void): () => void;
4137
4244
  }
4138
4245
 
4246
+ /** Where a described tool or address comes from. */
4247
+ export declare type KayAppToolOrigin =
4248
+ /** The agent kernel's own (`bash`, `read`, `help`, `skill://`). */
4249
+ {
4250
+ readonly kind: "core";
4251
+ }
4252
+ /** Bonsai's host, outside any plugin (`task_status`, `config://`). */
4253
+ | {
4254
+ readonly kind: "host";
4255
+ } | {
4256
+ readonly kind: "plugin";
4257
+ readonly pluginId: string;
4258
+ };
4259
+
4139
4260
  /**
4140
4261
  * `app.permissions` — the plugin-facing seam through which a `kay.app` target advertises the
4141
- * permission rows for tools it gates DYNAMICALLY, so they show in Kay's permission ledger with
4262
+ * permission rows for tools it gates DYNAMICALLY, so they show in Bonsai's permission ledger with
4142
4263
  * the same allow / ask / never control every statically declared tool row has.
4143
4264
  *
4144
4265
  * A tool a plugin registers at activation (`registerTool`) is already a row: the host derives it
@@ -4186,6 +4307,52 @@ export declare interface KayAppToolPermissionSource {
4186
4307
  readonly list: () => readonly KayAppToolPermissionDeclaration[] | Promise<readonly KayAppToolPermissionDeclaration[]>;
4187
4308
  }
4188
4309
 
4310
+ /**
4311
+ * The plugin-facing `kay.app` tools contract: for the tools and addresses a live session can use,
4312
+ * the text the agent sees for each, where each comes from, and whether each is one of Bonsai's own.
4313
+ *
4314
+ * Every call is checked against the `tools.describe` claim at the call, so a grant or revocation
4315
+ * takes effect on the next one. Like `app.skills`, the member is ALWAYS present and no call rejects
4316
+ * while the plugin is enabled: a refused grant or a session that is not live resolves to
4317
+ * `{ status: "unavailable" }`. After the plugin is disabled, a kept handle's methods throw
4318
+ * synchronously.
4319
+ *
4320
+ * `ownedByBonsai` is a fact declared where each surface is defined (a bundled plugin's manifest, or
4321
+ * the host's own registration), never a list kept by the host. What a plugin does with it is the
4322
+ * plugin's call.
4323
+ */
4324
+ /** A tool or an address to describe. */
4325
+ export declare type KayAppToolRef =
4326
+ /** A registered tool by name, e.g. `bash`, `read`, `mcp`, `submit_final`. */
4327
+ {
4328
+ readonly kind: "tool";
4329
+ readonly name: string;
4330
+ }
4331
+ /** A URI address whose `help` is wanted, e.g. `gmail://` or `mcp://linear`. */
4332
+ | {
4333
+ readonly kind: "address";
4334
+ readonly uri: string;
4335
+ };
4336
+
4337
+ /** `app.tools`: what a live session's tools and addresses say, each call checked against `tools.describe`. */
4338
+ export declare interface KayAppTools {
4339
+ describe(sessionId: string, refs: readonly KayAppToolRef[]): Promise<KayAppToolsDescribeResult>;
4340
+ }
4341
+
4342
+ /**
4343
+ * `not-granted`: the user has not granted `tools.describe`. `no-session`: the session is not live
4344
+ * on this host (only live sessions are described). `not-available`: this host cannot describe
4345
+ * tools.
4346
+ */
4347
+ export declare type KayAppToolsDescribeResult = {
4348
+ readonly status: "ok";
4349
+ /** One per ref, in the order of the refs. */
4350
+ readonly tools: readonly KayAppToolDescription[];
4351
+ } | {
4352
+ readonly status: "unavailable";
4353
+ readonly reason: "not-granted" | "no-session" | "not-available";
4354
+ };
4355
+
4189
4356
  /** An eligible settled turn — the generic door's root event. */
4190
4357
  export declare interface KayAppTurnSettledSessionEvent extends KayAppSessionEventBase {
4191
4358
  readonly type: "turn-settled";
@@ -4203,7 +4370,7 @@ export declare interface KayAppTurnSettledSessionEvent extends KayAppSessionEven
4203
4370
  */
4204
4371
  readonly runId?: string;
4205
4372
  /**
4206
- * The SCRIPTED experience that minted this session, if one did — Kay's first-run
4373
+ * The SCRIPTED experience that minted this session, if one did — Bonsai's first-run
4207
4374
  * conversation, the overnight handoff. Absent for an ordinary session, and absent whenever
4208
4375
  * the session was created by anything other than a person, so its presence means exactly
4209
4376
  * "a person's session, running a scripted arc".
@@ -4414,8 +4581,8 @@ export declare interface KayAppWhiteboardTypes {
4414
4581
  *
4415
4582
  * ## Your body can run more than once, and that is the point
4416
4583
  *
4417
- * A workflow body is durable: if Kay is killed mid-run (a crash, a quit, a machine that went to
4418
- * sleep), the run is picked up again when Kay comes back. It is picked up by RE-EXECUTING your
4584
+ * A workflow body is durable: if Bonsai is killed mid-run (a crash, a quit, a machine that went to
4585
+ * sleep), the run is picked up again when Bonsai comes back. It is picked up by RE-EXECUTING your
4419
4586
  * callback from the top — not by resuming it where it stopped, which JavaScript cannot do.
4420
4587
  *
4421
4588
  * What makes that safe is that the work you did inside `runStep` and `runAgent` is not done
@@ -4454,11 +4621,11 @@ export declare interface KayAppWorkflowContext {
4454
4621
  /**
4455
4622
  * Record a step's result for replay.
4456
4623
  *
4457
- * Once the result commits, recovery returns it without running the callback again. If Kay
4624
+ * Once the result commits, recovery returns it without running the callback again. If Bonsai
4458
4625
  * stops before that commit, the callback can run again. Use idempotency keys for external
4459
4626
  * effects whose duplicates would matter; recording a step cannot transact with an email send.
4460
4627
  *
4461
- * What you return must be plain data Kay can store (JSON): objects, arrays, strings, numbers,
4628
+ * What you return must be plain data Bonsai can store (JSON): objects, arrays, strings, numbers,
4462
4629
  * booleans, null. Not a class instance, a stream, a function or a handle.
4463
4630
  *
4464
4631
  * `name` labels the step wherever runs are inspected. Give it one; a body whose steps are all
@@ -4470,7 +4637,7 @@ export declare interface KayAppWorkflowContext {
4470
4637
  /**
4471
4638
  * Wait, durably.
4472
4639
  *
4473
- * Unlike `setTimeout`, this survives Kay being restarted: a body that sleeps for an hour and is
4640
+ * Unlike `setTimeout`, this survives Bonsai being restarted: a body that sleeps for an hour and is
4474
4641
  * killed after ten minutes wakes at the original deadline rather than starting the hour again,
4475
4642
  * and it does not hold a process open while it waits.
4476
4643
  */
@@ -4483,14 +4650,14 @@ export declare interface KayAppWorkflowContext {
4483
4650
  * callback settles and every child you admitted has drained. Admission closes the moment your
4484
4651
  * callback settles, so a call made after that is refused rather than orphaned.
4485
4652
  *
4486
- * With an input `key`, Kay records the session before its first turn. Recovery sends a
4653
+ * With an input `key`, Bonsai records the session before its first turn. Recovery sends a
4487
4654
  * continuation to that same persisted session; a new session is created only if its transcript
4488
4655
  * is gone. Settled memo results return directly. A crash after a turn settles but before its
4489
4656
  * memo commits can cause one extra continuation turn in the same session.
4490
4657
  *
4491
4658
  * A keyed child whose turn fails for a transient reason (`network`, `stream_interrupted`,
4492
4659
  * `overloaded`, `rate_limit`, `server_error`, or `timeout` when you declared no `timeoutMs`) is
4493
- * continued the same way: Kay waits, waits for the network when it can probe it, and sends a
4660
+ * continued the same way: Bonsai waits, waits for the network when it can probe it, and sends a
4494
4661
  * continuation to the same session, up to six times and for at most 20 hours after the first
4495
4662
  * failure. A continuation the host refuses counts as one attempt and keeps the failure. Only
4496
4663
  * the final outcome returns and is memoized. Unkeyed children and every other failure return at
@@ -5907,6 +6074,14 @@ export declare interface ToolDefinition<TParams extends ToolParametersWire = Too
5907
6074
  * explicit Stop.
5908
6075
  */
5909
6076
  durationClass?: "fast" | "long";
6077
+ /**
6078
+ * Set only for a tool whose rerun with the same arguments is harmless, such
6079
+ * as one keyed on its own call: after a crash cuts a call off, a pi-durable
6080
+ * session may rerun it with its recorded arguments (without `before_tool`)
6081
+ * instead of ending it as an interrupted error. Absent: never rerun. Ignored
6082
+ * on pi 0.99.1.
6083
+ */
6084
+ replaySafe?: true;
5910
6085
  /**
5911
6086
  * Optional capability⇄scheme binding. When present this tool is auth-gated: discoverable when
5912
6087
  * unauthed, callable once the binding is satisfied. The SDK's {@link withResolvedAuth}
@@ -5990,9 +6165,9 @@ export declare type ToolParametersWire = unknown;
5990
6165
  *
5991
6166
  * The host is trusted to supply honest values; a declared `kind` of `read` moves a call below
5992
6167
  * the protected-path hard-deny (which only fires for non-read kinds), so a tool that could
5993
- * touch protected config must NOT declare `read`. Kay's embedded-experience tools never touch
6168
+ * touch protected config must NOT declare `read`. Bonsai's embedded-experience tools never touch
5994
6169
  * `configDir`, so this is safe for them. `read` is also what every capability surface reports as
5995
- * "read-only" (Kay's Permissions page groups and defaults on it), so it is a claim about what the
6170
+ * "read-only" (Bonsai's Permissions page groups and defaults on it), so it is a claim about what the
5996
6171
  * tool DOES — never a way to buy silence. A tool that should raise no ask on its own account
5997
6172
  * declares {@link ToolPermissionHint.quiet} and keeps its honest `kind`.
5998
6173
  */
@@ -6033,7 +6208,7 @@ export declare interface ToolPermissionHint {
6033
6208
  * because the same tool can read on one input and execute on another, which a static `kind`
6034
6209
  * cannot express.
6035
6210
  *
6036
- * Exemplar — Kay's `mcp` proxy tool, one tool spanning every server: `search`/`describe` derive
6211
+ * Exemplar — Bonsai's `mcp` proxy tool, one tool spanning every server: `search`/`describe` derive
6037
6212
  * `{ kind: "read" }` (metadata lookups), while `call` derives
6038
6213
  * `{ kind: "execute", ruleKey: "mcp:<server>::<tool>", scheme: "<server>" }`, so a
6039
6214
  * `{ scheme: "<server>" }` rule gates a whole server and a `{ ruleKey: "mcp:<server>::<tool>" }`
@@ -6074,7 +6249,7 @@ export declare interface ToolPermissionHint {
6074
6249
  * really had — not that the result is always stricter than the target's. How much gate is left
6075
6250
  * on such a call is exactly how much the CARRIER carries: an `execute` carrier is stricter than
6076
6251
  * a `read` target and equal to a `mutate`/`destructive` one outside allow mode, while a
6077
- * {@link quiet} carrier (Kay's own `call_tool`) contributes no mode default at all, so the
6252
+ * {@link quiet} carrier (Bonsai's own `call_tool`) contributes no mode default at all, so the
6078
6253
  * fallback leaves nothing but the carrier's rules and the protected-path deny — and the carrier
6079
6254
  * names no path, so that deny has nothing to fire on. This is why a carrier must refuse a target
6080
6255
  * that is itself a carrier: no chain long or circular enough to reach the fallback can be built,
@@ -6098,7 +6273,7 @@ export declare interface ToolPermissionHint {
6098
6273
  * whose only effect is invoking the target the gate is already classifying beside it: the
6099
6274
  * target's kind, rules, resources and the protected-path deny all still decide, so a proxied
6100
6275
  * call is gated exactly like the direct one — no more, and no ask the direct call would never
6101
- * have raised. Kay's `call_tool` declares `{ kind: "execute", quiet: true }` (owner ruling,
6276
+ * have raised. Bonsai's `call_tool` declares `{ kind: "execute", quiet: true }` (owner ruling,
6102
6277
  * 2026-08-18): honest about everything it can reach, silent on its own account.
6103
6278
  *
6104
6279
  * Quiet is not ungated, but it IS nearly all the gate a lone carrier has. On a call that
@@ -6341,6 +6516,12 @@ declare interface UriHelp {
6341
6516
  readonly templates?: readonly UriTemplate[];
6342
6517
  readonly examples?: readonly UriExample[];
6343
6518
  readonly notes?: readonly string[];
6519
+ /**
6520
+ * Set when this help, for the address it was asked about, carries text a third party wrote and
6521
+ * the module relays as it received it (an MCP server's own tool names and descriptions), rather
6522
+ * than text the module's author wrote. Absent: the module's own text.
6523
+ */
6524
+ readonly thirdPartyContent?: true;
6344
6525
  }
6345
6526
 
6346
6527
  declare interface UriHintTriggers {
@@ -6452,8 +6633,9 @@ export declare interface UriModule {
6452
6633
  readonly description?: string;
6453
6634
  readonly agentHint?: UriAgentHint;
6454
6635
  /**
6455
- * Route-aware permission facts for operations whose effect is stricter than
6456
- * the generic URI verb implies. Scheme and resource scoping remain
6636
+ * Route-aware permission facts for write/edit/delete routes whose effect is
6637
+ * stricter than the generic URI verb implies (read verbs stay `read`; see
6638
+ * {@link UriOperationPermissionPolicy}). Scheme and resource scoping remain
6457
6639
  * kernel-derived from the canonical URI.
6458
6640
  */
6459
6641
  readonly permission?: UriOperationPermissionPolicy;
@@ -6563,8 +6745,13 @@ export declare interface UriModule {
6563
6745
  * conversion stage, or an already-rendered `string` for synthesizing/text modules
6564
6746
  * (finalize passes those through its identity path). The single transport shape;
6565
6747
  * {@link finalize} (stage 2) turns it into model-facing content.
6748
+ *
6749
+ * Observes only, like `help`, `list` and `search` (the protocol contract in `@herd/uri`):
6750
+ * repeating the call must be harmless, because the kernel reruns one a crash cut off without
6751
+ * asking again.
6566
6752
  */
6567
6753
  read(input: string, ctx: UriResolveContext): Promise<RawResource>;
6754
+ /** Observes only; see {@link read}. */
6568
6755
  help?(input: string, ctx: UriResolveContext): Promise<UriHelp>;
6569
6756
  write?(input: string, content: UriPayload, ctx: UriResolveContext): Promise<UriMutationResult | void>;
6570
6757
  /** Structured write with host-resolved resources delivered beside the model-authored content. */
@@ -6581,7 +6768,9 @@ export declare interface UriModule {
6581
6768
  */
6582
6769
  writeBytes?(input: string, bytes: Uint8Array, source: UriSourceDescriptor, ctx: UriResolveContext): Promise<UriMutationResult | void>;
6583
6770
  edit?(input: string, patch: UriPayload, ctx: UriResolveContext): Promise<UriMutationResult>;
6771
+ /** Observes only; see {@link read}. */
6584
6772
  list?(input: string, params: UriListParams, ctx: UriResolveContext): Promise<UriListResult>;
6773
+ /** Observes only; see {@link read}. */
6585
6774
  search?(input: string, params: UriSearchParams, ctx: UriResolveContext): Promise<UriSearchResult>;
6586
6775
  delete?(input: string, ctx: UriResolveContext): Promise<UriMutationResult>;
6587
6776
  toMarkdown?(input: UriMarkdownRenderInput, ctx: UriResolveContext): string | undefined;
@@ -6679,7 +6868,9 @@ declare interface UriOperationPermissionClassification {
6679
6868
  /**
6680
6869
  * The operation's real effect. The permission classifier only accepts a
6681
6870
  * classification at least as restrictive as the URI verb's built-in
6682
- * classification.
6871
+ * classification, and `read` for `help`/`read`/`list`/`search` (those
6872
+ * verbs only observe; see {@link UriModule.read}). Anything else fails the
6873
+ * preflight closed.
6683
6874
  */
6684
6875
  readonly kind: ToolActionKind;
6685
6876
  /** Optional route-specific rule key (for example, `terminal:input`). */
@@ -6689,8 +6880,9 @@ declare interface UriOperationPermissionClassification {
6689
6880
  declare interface UriOperationPermissionPolicy {
6690
6881
  /**
6691
6882
  * Classify one canonical route without I/O or caller/session state. Throwing,
6692
- * returning an invalid value, or weakening the verb's built-in classification
6693
- * fails the permission preflight closed.
6883
+ * returning an invalid value, weakening the verb's built-in classification, or
6884
+ * moving a `help`/`read`/`list`/`search` route off `read` fails the permission
6885
+ * preflight closed.
6694
6886
  */
6695
6887
  classifyOperation(request: {
6696
6888
  readonly operation: UriOperation;
@@ -6895,7 +7087,7 @@ declare interface UriResolveContext_2 {
6895
7087
  * {@link UriResolveContext.sessionId} and just as un-influenceable by the caller — so a module
6896
7088
  * writing to a store it owns can record the actor without the agent being able to choose one.
6897
7089
  *
6898
- * Free text minted by the host's own runtime (Kay's form is `user`, `subagent`,
7090
+ * Free text minted by the host's own runtime (Bonsai's form is `user`, `subagent`,
6899
7091
  * `system/<surface>`, `followup/<surface>`) rather than a closed union: the surface half is the
6900
7092
  * host's vocabulary, and a second enumeration of it here would drift from the first.
6901
7093
  *