@yaklabs-ai/plugin-sdk 0.15.3 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  import { z } from 'zod';
2
2
 
3
3
  /**
4
- * Who a connected account *belongs to* — the human, as the provider reports them. Derived at connect
4
+ * Who a connected account *belongs to* - the human, as the provider reports them. Derived at connect
5
5
  * time by a scheme's `resolveAccountId` hook from the provider's own profile endpoint, and surfaced
6
6
  * to the agent so it never has to ask "what is your email?" for a service the user already
7
7
  * connected.
@@ -9,7 +9,7 @@ import { z } from 'zod';
9
9
  * Distinct from {@link AccountProvenance}: an account can be firmly identified
10
10
  * (`externalId`/`provider`) while nothing is known about its owner, and a workspace's name is not a
11
11
  * person's name. Field-for-field the same shape the credential authority persists, so identity
12
- * crosses the daemon⇄kernel boundary without a lossy projection.
12
+ * crosses the daemon<->kernel boundary without a lossy projection.
13
13
  */
14
14
  declare interface AccountIdentity {
15
15
  /** Provider handle (GitHub `login`, Slack `user`). */
@@ -28,7 +28,7 @@ declare interface AccountIdentity {
28
28
  /**
29
29
  * Provider-native session id claim (WorkOS's `sid`), needed to call the provider's own
30
30
  * session-revocation endpoint at sign-out (`POST /user_management/sessions/revoke`, not yet
31
- * wired — see `docs/kay-account-auth.md`'s "Sign-out guarantee" section). Only Bonsai's WorkOS
31
+ * wired - see `docs/kay-account-auth.md`'s "Sign-out guarantee" section). Only Bonsai's WorkOS
32
32
  * product-account exchange/refresh sets it; every other provider leaves it absent.
33
33
  */
34
34
  readonly providerSessionId?: string;
@@ -36,7 +36,7 @@ declare interface AccountIdentity {
36
36
 
37
37
  /**
38
38
  * Structured, non-secret *provenance* for a connected account: which record on the provider's side
39
- * this credential points at. Says nothing about the human — a Notion `displayName` here is the
39
+ * this credential points at. Says nothing about the human - a Notion `displayName` here is the
40
40
  * workspace name, a Slack one is the team name. To describe the person, see {@link AccountIdentity}.
41
41
  */
42
42
  declare interface AccountProvenance {
@@ -50,6 +50,17 @@ declare interface AccountProvenance {
50
50
  readonly raw?: Readonly<Record<string, unknown>>;
51
51
  }
52
52
 
53
+ declare const AdapterPlacement: z.ZodEnum<{
54
+ "local-only": "local-only";
55
+ anywhere: "anywhere";
56
+ }>;
57
+
58
+ declare type AdapterPlacement = z.infer<typeof AdapterPlacement>;
59
+
60
+ declare const AdapterSelectionKey: z.ZodString;
61
+
62
+ declare type AdapterSelectionKey = z.infer<typeof AdapterSelectionKey>;
63
+
53
64
  /** Applies an AddImmutable action to a type. */
54
65
  declare function AddImmutable<Type extends TSchema>(type: Type, options?: TSchemaOptions): TAddImmutable<Type>;
55
66
 
@@ -146,21 +157,6 @@ declare function Any(options?: TSchemaOptions): TAny;
146
157
 
147
158
  declare type Api = KnownApi | (string & {});
148
159
 
149
- /** One labeled secret input of a multi-field api-key scheme. */
150
- declare interface ApiKeyAuthSchemeField {
151
- /** Stable key — the `fields` Record key on the stored material and resolved credential. */
152
- readonly id: string;
153
- /** Per-field prompt copy, e.g. "Access Client ID". */
154
- readonly label: string;
155
- }
156
-
157
- /** Provider-owned instructions for creating a credential outside Bonsai. */
158
- declare interface ApiKeyAuthSchemeSetup {
159
- readonly instructions: string;
160
- /** Absolute HTTPS page where the user can create or manage the credential. */
161
- readonly url: string;
162
- }
163
-
164
160
  /** One non-secret capability observation made while validating a credential. */
165
161
  declare interface ApiKeyCapabilityCheck {
166
162
  /** Stable service capability id the scheme checked. */
@@ -178,13 +174,17 @@ declare function _Array_<Type extends TSchema>(items: Type, options?: TArrayOpti
178
174
  /** Extracts options from a TArray. */
179
175
  declare function ArrayOptions(type: TArray): TArrayOptions;
180
176
 
177
+ declare const ArtifactGenerationId: z.core.$ZodBranded<z.ZodString, "ArtifactGenerationId", "out">;
178
+
179
+ declare type ArtifactGenerationId = z.infer<typeof ArtifactGenerationId>;
180
+
181
181
  /**
182
182
  * Performs an Object assign using the Left and Right object types. We track this operation as it
183
183
  * creates a new GC handle per assignment.
184
184
  */
185
185
  declare function Assign<Left extends ObjectLike, Right extends ObjectLike>(left: Left, right: Right): TAssign<Left, Right>;
186
186
 
187
- /** A connected account under one `(serviceId, schemeId)` — the multi-account unit. */
187
+ /** A connected account under one `(serviceId, schemeId)` - the multi-account unit. */
188
188
  declare interface AuthAccount {
189
189
  readonly accountId: string;
190
190
  readonly displayName: string;
@@ -199,12 +199,66 @@ declare interface AuthAccount {
199
199
  /**
200
200
  * Trust-lost marker carried through from `StoredCredentialSummary.needsReconnect`
201
201
  * (kay#7852): the account's credential is dead (revoked or terminally unrefreshable) and the
202
- * user must reconnect it. The account stays listed — with this flag — so the agent can see it
202
+ * user must reconnect it. The account stays listed - with this flag - so the agent can see it
203
203
  * and point the user at a reconnect; token resolution for it still fails closed.
204
204
  */
205
205
  readonly needsReconnect?: boolean;
206
206
  }
207
207
 
208
+ declare namespace authoringCommonSchemas {
209
+ export {
210
+ hostWithinDomain,
211
+ urlHostWithinDomain,
212
+ refineWebSessionScopeConfined,
213
+ KAY_PLUGIN_PROTOCOL_VERSION,
214
+ KAY_PLUGIN_PROTOCOL_PACKAGE_NAME,
215
+ KAY_PLUGIN_SDK_VERSION,
216
+ KAY_PLUGIN_COMPATIBLE_SDK_VERSIONS,
217
+ KAY_PLUGIN_TARGET_NAMES,
218
+ KayPluginProtocolVersion,
219
+ PluginTargetName,
220
+ KAY_EVENT_PUBLISHER_ID,
221
+ NonEmptyString,
222
+ PluginId,
223
+ PluginNamespace,
224
+ LocalContributionId,
225
+ GlobalContributionId,
226
+ PluginToolName,
227
+ AuthServiceReference,
228
+ AuthSchemeReference,
229
+ AdapterSelectionKey,
230
+ AdapterPlacement,
231
+ UriScheme,
232
+ MimeTypeString,
233
+ FileExtensionToken,
234
+ CliBinaryName,
235
+ CliAuthEnvVarName,
236
+ PackageAssetPath,
237
+ PluginSourceClass,
238
+ ArtifactGenerationId,
239
+ HttpsUrl,
240
+ RegistrableDomain,
241
+ GitHostName,
242
+ GitBasicAuthUser,
243
+ HttpStatusCode,
244
+ SignedInStatusCode,
245
+ JsonPointer,
246
+ TargetEntrypoint,
247
+ canonicalCommonSchemas,
248
+ JsonObject,
249
+ JsonSchema_2 as JsonSchema,
250
+ JsonValue_2 as JsonValue
251
+ }
252
+ }
253
+
254
+ declare const AuthSchemeReference: z.ZodString;
255
+
256
+ declare type AuthSchemeReference = z.infer<typeof AuthSchemeReference>;
257
+
258
+ declare const AuthServiceReference: z.ZodString;
259
+
260
+ declare type AuthServiceReference = z.infer<typeof AuthServiceReference>;
261
+
208
262
  declare interface Availability {
209
263
  readonly available: boolean;
210
264
  readonly reason?: string;
@@ -256,7 +310,7 @@ declare type BackgroundTaskRun = (ctx: BackgroundTaskRunContext) => Promise<stri
256
310
  declare interface BackgroundTaskRunContext {
257
311
  readonly taskId: string;
258
312
  readonly signal: AbortSignal;
259
- /** `this: void` — task bodies destructure this reporter off the context. */
313
+ /** `this: void` - task bodies destructure this reporter off the context. */
260
314
  reportProgress(this: void, text: string, details?: Record<string, unknown>): void;
261
315
  }
262
316
 
@@ -320,6 +374,47 @@ declare function Call<Target extends TSchema, Arguments extends TSchema[]>(targe
320
374
 
321
375
  declare function CallConstruct<Target extends TSchema, Arguments extends TSchema[]>(target: Target, arguments_: [...Arguments]): TCallConstruct<Target, Arguments>;
322
376
 
377
+ declare const canonicalCommonSchemas: {
378
+ NonEmptyString: z.ZodString;
379
+ PluginId: z.ZodString;
380
+ PluginNamespace: z.ZodString;
381
+ LocalContributionId: z.ZodString;
382
+ GlobalContributionId: z.ZodString;
383
+ PluginToolName: z.ZodString;
384
+ AuthServiceReference: z.ZodString;
385
+ AuthSchemeReference: z.ZodString;
386
+ AdapterSelectionKey: z.ZodString;
387
+ AdapterPlacement: z.ZodEnum<{
388
+ "local-only": "local-only";
389
+ anywhere: "anywhere";
390
+ }>;
391
+ UriScheme: z.ZodString;
392
+ MimeTypeString: z.ZodString;
393
+ FileExtensionToken: z.ZodString;
394
+ CliBinaryName: z.ZodString;
395
+ CliAuthEnvVarName: z.ZodString;
396
+ PackageAssetPath: z.ZodString;
397
+ PluginSourceClass: z.ZodEnum<{
398
+ bundled: "bundled";
399
+ "org-shared": "org-shared";
400
+ "user-local": "user-local";
401
+ "verified-marketplace": "verified-marketplace";
402
+ freeform: "freeform";
403
+ }>;
404
+ ArtifactGenerationId: z.core.$ZodBranded<z.ZodString, "ArtifactGenerationId", "out">;
405
+ HttpsUrl: z.ZodURL;
406
+ RegistrableDomain: z.ZodString;
407
+ GitHostName: z.ZodString;
408
+ GitBasicAuthUser: z.ZodString;
409
+ HttpStatusCode: z.ZodNumber;
410
+ SignedInStatusCode: z.ZodNumber;
411
+ JsonPointer: z.ZodString;
412
+ TargetEntrypoint: z.ZodObject<{
413
+ module: z.ZodString;
414
+ export: z.ZodOptional<z.ZodString>;
415
+ }, z.core.$strict>;
416
+ };
417
+
323
418
  /** Applies a Capitalize action to the given type. */
324
419
  declare function Capitalize_2<Type extends TSchema>(type: Type, options?: TSchemaOptions): TCapitalize<Type>;
325
420
 
@@ -353,6 +448,14 @@ declare namespace Char {
353
448
  }
354
449
  }
355
450
 
451
+ declare const CliAuthEnvVarName: z.ZodString;
452
+
453
+ declare type CliAuthEnvVarName = z.infer<typeof CliAuthEnvVarName>;
454
+
455
+ declare const CliBinaryName: z.ZodString;
456
+
457
+ declare type CliBinaryName = z.infer<typeof CliBinaryName>;
458
+
356
459
  /**
357
460
  * Returns a Clone of the given value. This function is similar to structuredClone()
358
461
  * but also supports deep cloning instances of Map, Set and TypeArray.
@@ -414,7 +517,13 @@ declare interface ContentConverter {
414
517
  */
415
518
  readonly description?: string;
416
519
  matches(probe: ContentProbe): boolean;
417
- convert(bytes: Uint8Array, probe: ContentProbe, ctx: ConvertContext): Promise<ConversionResult>;
520
+ /**
521
+ * Converts the file `matches` claimed. Resolves `undefined` to decline it after all: the read
522
+ * pipeline then tries the next converter that claimed it, as if this one had not. A converter
523
+ * that answers elsewhere (the plugin host's stand-in, which learns only there which converter
524
+ * takes the file) declines this way; one that decides in `matches` never needs to.
525
+ */
526
+ convert(bytes: Uint8Array, probe: ContentProbe, ctx: ConvertContext): Promise<ConversionResult | undefined>;
418
527
  }
419
528
 
420
529
  /**
@@ -438,7 +547,7 @@ declare interface ContentProbe {
438
547
 
439
548
  /**
440
549
  * The convert return shape. `content` is the agent-facing
441
- * {@link ModelContent} — text and/or image blocks — and is
550
+ * {@link ModelContent} - text and/or image blocks - and is
442
551
  * the field the read pipeline consumes (finalize windows/truncates TEXT blocks and
443
552
  * passes IMAGE blocks through unchanged). `contentType`/`artifacts`/`structure`/
444
553
  * `notes` are reserved metadata that no consumer renders yet. The converter does
@@ -615,7 +724,7 @@ declare function Deferred<Action extends string, Types extends TSchema[]>(action
615
724
  * What `service_connect` hands a delegated scheme's {@link DelegatedAuthScheme.connect}: the
616
725
  * scope being connected plus the host's browser-redirect capability when one is configured.
617
726
  * `authorize`/`redirectUri` wrap the host `OAuthRedirectTransport` (`@herd/herd-agent`)
618
- * — both absent when the host has none; the scheme decides whether it needs them.
727
+ * - both absent when the host has none; the scheme decides whether it needs them.
619
728
  */
620
729
  declare interface DelegatedConnectContext {
621
730
  readonly serviceId: string;
@@ -648,7 +757,7 @@ declare interface DelegatedConnectResult {
648
757
  /**
649
758
  * Token material minted by a delegated scheme's extension-provided flow. Core reads only
650
759
  * `accessToken`/`expiresAt` (resolution + proactive refresh); `data` is an opaque blob the
651
- * scheme round-trips through `refresh` (refresh token, DCR client info, …) — never read by core.
760
+ * scheme round-trips through `refresh` (refresh token, DCR client info, ...) - never read by core.
652
761
  */
653
762
  declare interface DelegatedSecretMaterial {
654
763
  readonly kind: "delegated";
@@ -674,7 +783,7 @@ declare function DependentOptions(type: TDependent): TSchemaOptions;
674
783
  * can derive per-call via {@link ToolPermissionHint.deriveClassification}. Every field is
675
784
  * optional: a present field overrides the static hint for that call; an absent field falls back
676
785
  * to the static hint (then to the fail-closed default). `resources` stays a separate deriver
677
- * ({@link ToolPermissionHint.deriveResources}) — these are the fields that decide which rule a
786
+ * ({@link ToolPermissionHint.deriveResources}) - these are the fields that decide which rule a
678
787
  * call matches, not the paths it touches.
679
788
  */
680
789
  declare interface DerivedToolClassification {
@@ -683,6 +792,13 @@ declare interface DerivedToolClassification {
683
792
  readonly scheme?: string;
684
793
  }
685
794
 
795
+ /**
796
+ * The definition the host builds for the tool `contract` describes under `localId`, running
797
+ * `execute`: name, parameters, auth binding and permission all come from the manifest, as in a
798
+ * session.
799
+ */
800
+ export declare function describedToolForTest(contract: ResolvedPluginContractV1, localId: string, execute: KayAgentToolExecute): ToolDefinition;
801
+
686
802
  declare const Digit: TDigit;
687
803
 
688
804
  /** Discards multiple property keys from the given object value */
@@ -834,18 +950,19 @@ declare function ExtendsTrue<Inferred extends TProperties>(inferred: TProperties
834
950
  declare function ExtendsUnion<Inferred extends TProperties>(inferred: TProperties): TExtendsUnion<Inferred>;
835
951
 
836
952
  /**
837
- * The execute-time auth surface the SDK wrappers read off `ctx.auth`. Slice 3 attaches a
838
- * concrete implementation (vault + pkce refresh + active-account store) to ExtensionContext;
839
- * defining the contract here lets the wrappers compile and be unit-tested against a double.
953
+ * The auth resolver: the host resolves a capability's credential through it before calling the
954
+ * capability, and an extension's event handlers read it off `ctx.auth`. Tools, URI verbs and search
955
+ * providers never see it; they receive the {@link ResolvedCredential} the host resolved.
840
956
  */
841
957
  declare interface ExtensionAuthContext {
842
958
  /**
843
959
  * Resolve a live token for a service and an account: the explicit `accountId` when given, else
844
- * the session-active account. `schemeId` is a preference, not an address — an explicit account
960
+ * the session-active account. `schemeId` is a preference, not an address - an explicit account
845
961
  * resolves against its OWN backing scheme even when a different scheme is named/bound, and an
846
962
  * absent `schemeId` resolves service-level across the injectable schemes. Refreshes oauth near
847
963
  * expiry under the hood. Returns an actionable {@link ResolveTokenFailure} (never throws) when
848
- * there is no connection or the account is ambiguous, so wrappers can short-circuit gracefully.
964
+ * there is no connection or the account is ambiguous, which the host answers with instead of
965
+ * calling the capability.
849
966
  */
850
967
  readonly resolveToken: (input: {
851
968
  readonly serviceId: string;
@@ -854,7 +971,7 @@ declare interface ExtensionAuthContext {
854
971
  /**
855
972
  * The invoking capability's `requiresAuth.requiredScopes`, threaded down to the vault load so a
856
973
  * grant-enforcing vault can refuse a plugin whose granted scopes don't cover them. The
857
- * caller identity itself is not a per-call argument — it is fixed by the owner-scoped context
974
+ * caller identity itself is not a per-call argument - it is fixed by the owner-scoped context
858
975
  * (see `CreateExtensionAuthContextInput.callerId`).
859
976
  */
860
977
  readonly requiredScopes?: readonly string[];
@@ -906,7 +1023,7 @@ declare interface ExtensionBackgroundTasksApi {
906
1023
 
907
1024
  /**
908
1025
  * Host-provided, per-extension writable data root surfaced on {@link ToolContext.paths}. Isolation is
909
- * the DIRECTORY itself — exactly like the per-extension SQLite db files keyed by extension id: the host
1026
+ * the DIRECTORY itself - exactly like the per-extension SQLite db files keyed by extension id: the host
910
1027
  * provisions a distinct path per owning extension, the extension owns everything inside it. The kernel
911
1028
  * never decides *where* this lives; it carries an opaque host-resolved path and exposes it, so an
912
1029
  * extension can read/write files (caches, scratch state, downloads) under a sanctioned root without the
@@ -1051,18 +1168,22 @@ declare function FactorMapping(input: [unknown, unknown, unknown, unknown, unkno
1051
1168
  * A default-permissive {@link ExtensionAuthContext} double: every method resolves
1052
1169
  * to a benign "not connected" outcome unless overridden. Kernel test fixtures that
1053
1170
  * need real account-selection semantics (active/sole/ambiguous account picking) or
1054
- * call-recording pass their own `resolveToken`/`listAccounts`/etc via `overrides` —
1171
+ * call-recording pass their own `resolveToken`/`listAccounts`/etc via `overrides` -
1055
1172
  * this owns only the four-method boilerplate shell that four kernel test files
1056
1173
  * used to hand-roll independently (see `extensions-auth-sdk.test.ts`'s `stubAuth`,
1057
1174
  * the double this was derived from).
1058
1175
  */
1059
1176
  export declare function fauxAuthContext(overrides?: Partial<ExtensionAuthContext>): ExtensionAuthContext;
1060
1177
 
1061
- /** The capability handles a `KayAgentPluginApi` always carries — authority is decided per call. */
1062
- export declare type FauxKayAgentCapabilities = Pick<KayAgentPluginApi, "network" | "webSession" | "process" | "whiteboard" | "interaction" | "interceptToolCall" | "systemOne" | "events" | "time" | "userFiles" | "familyFolder">;
1178
+ /** The capability handles a `KayAgentPluginApi` always carries - authority is decided per call. */
1179
+ export declare type FauxKayAgentCapabilities = Pick<KayAgentPluginApi, "network" | "webSession" | "process" | "whiteboard" | "interaction" | "interceptToolCall" | "implementTool" | "systemOne" | "events" | "time" | "log" | "userFiles" | "familyFolder" | "vendoredMcp" | "endpoints" | "compiler">;
1063
1180
 
1064
1181
  export declare function fauxKayAgentCapabilities(): FauxKayAgentCapabilities;
1065
1182
 
1183
+ declare const FileExtensionToken: z.ZodString;
1184
+
1185
+ declare type FileExtensionToken = z.infer<typeof FileExtensionToken>;
1186
+
1066
1187
  declare type ForecastInterval = "step" | "minute" | "hour" | "day" | "week" | "month" | "quarter" | "year";
1067
1188
 
1068
1189
  /** Creates a Function type. */
@@ -1126,6 +1247,36 @@ declare const GenericType: (input: string) => [unknown, string] | [];
1126
1247
 
1127
1248
  declare function GenericTypeMapping(input: [unknown, unknown, unknown]): unknown;
1128
1249
 
1250
+ declare const GitBasicAuthUser: z.ZodString;
1251
+
1252
+ declare type GitBasicAuthUser = z.infer<typeof GitBasicAuthUser>;
1253
+
1254
+ declare const GitHostName: z.ZodString;
1255
+
1256
+ declare type GitHostName = z.infer<typeof GitHostName>;
1257
+
1258
+ declare const GlobalContributionId: z.ZodString;
1259
+
1260
+ declare type GlobalContributionId = z.infer<typeof GlobalContributionId>;
1261
+
1262
+ /**
1263
+ * The cookie suffix rule shared by every web-session boundary: whether `host`
1264
+ * is `domain` or a subdomain of it. Coined ONCE here - the manifest's scope
1265
+ * confinement, the resolved/wire re-checks, and the desktop probe's
1266
+ * redirect-landing classification must all agree on it, or a login bounce
1267
+ * inside the declared scope could read as "unknown" on one side of a seam and
1268
+ * "signed-out" on the other.
1269
+ */
1270
+ declare function hostWithinDomain(host: string, domain: string): boolean;
1271
+
1272
+ declare const HttpStatusCode: z.ZodNumber;
1273
+
1274
+ declare type HttpStatusCode = z.infer<typeof HttpStatusCode>;
1275
+
1276
+ declare const HttpsUrl: z.ZodURL;
1277
+
1278
+ declare type HttpsUrl = z.infer<typeof HttpsUrl>;
1279
+
1129
1280
  declare const Hyphen = "-";
1130
1281
 
1131
1282
  /** Matches if next is an Ident */
@@ -1134,13 +1285,6 @@ declare function Ident<Input extends string>(input: Input): TIdent<Input>;
1134
1285
  /** Creates an Identifier. */
1135
1286
  declare function Identifier<Name extends string>(name: Name): TIdentifier<Name>;
1136
1287
 
1137
- /**
1138
- * Whether a scheme acts *as the user* (the fully-built PKCE path) or *on behalf of the user
1139
- * as an app* (a declared seam — see {@link OAuthPkceAuthScheme.mintToken}). It's a property of
1140
- * the scheme, not the call, so the resolver knows the identity without per-call ambiguity.
1141
- */
1142
- declare type IdentityMode = "as-user" | "on-behalf-of-app";
1143
-
1144
1288
  declare interface ImageContent {
1145
1289
  type: "image";
1146
1290
  data: string;
@@ -1270,6 +1414,12 @@ declare interface InteractionCandidate {
1270
1414
  readonly checked?: string | undefined;
1271
1415
  readonly selected?: string | undefined;
1272
1416
  readonly expanded?: string | undefined;
1417
+ /**
1418
+ * What a page driver found the element to be in the DOM, not what the page calls it: `link` is an
1419
+ * anchor that navigates to another http(s) page; `widget` is an element that is no form control.
1420
+ * Absent means unknown, and the engine then treats the element as any other.
1421
+ */
1422
+ readonly look?: "link" | "widget" | undefined;
1273
1423
  readonly delta?: number | undefined;
1274
1424
  /** Where an element outside the visible area sits; absent means on screen. */
1275
1425
  readonly position?: "above" | "below" | "beside" | undefined;
@@ -1445,18 +1595,18 @@ declare class InvalidLiteralValue extends Error {
1445
1595
 
1446
1596
  /**
1447
1597
  * Invoke a plugin tool definition's `execute` in a test, owning the **one sanctioned cast** past
1448
- * `ToolExecutionAwareParams<unknown>` — the phantom-wire-shaped type every `ToolDefinition`'s
1598
+ * `ToolExecutionAwareParams<unknown>` - the phantom-wire-shaped type every `ToolDefinition`'s
1449
1599
  * `execute` resolves to once auth-gated by `withResolvedAuth` (whose synthesized `execute` does not
1450
1600
  * go through `defineTool`'s `PluginToolDefinition` -> `InferToolInput` mapping, so there is no
1451
- * zod-inferred params type to type-check `params` against at the call site — see decision 002's
1601
+ * zod-inferred params type to type-check `params` against at the call site - see decision 002's
1452
1602
  * problem statement). `tool` is typed `ToolDefinition<any, TDetails>`, the same
1453
1603
  * accept-any-params-shape idiom the kernel itself uses for generic tool-definition plumbing
1454
- * (`core/tools/execution-policy.ts`, `core/tools/tool-definition-wrapper.ts`) — the `any` is this
1604
+ * (`core/tools/execution-policy.ts`, `core/tools/tool-definition-wrapper.ts`) - the `any` is this
1455
1605
  * function's entire reason to exist, not a shortcut taken to avoid one.
1456
1606
  *
1457
- * Fixes `toolCallId` to `"test-call"`, `signal` to `undefined`, and `onUpdate` to `undefined` —
1607
+ * Fixes `toolCallId` to `"test-call"`, `signal` to `undefined`, and `onUpdate` to `undefined` -
1458
1608
  * the values every fixture invocation wants and no fal-style test had a reason to vary. Pass a
1459
- * `ctx` (with `auth: fauxAuthContext(...)` for an auth-gated tool) to exercise anything beyond the
1609
+ * `ctx` (with a `credential` for an auth-gated tool) to exercise anything beyond the
1460
1610
  * happy-path default.
1461
1611
  */
1462
1612
  export declare function invokeToolForTest<TDetails = unknown>(tool: ToolDefinition<any, TDetails>, params: Record<string, unknown>, ctx?: ToolContext): Promise<AgentToolResult<TDetails>>;
@@ -1620,10 +1770,22 @@ declare function IsUnsafe(value: unknown): value is TUnsafe;
1620
1770
  /** Returns true if the given value is TVoid. */
1621
1771
  declare function IsVoid(value: unknown): value is TVoid;
1622
1772
 
1773
+ declare const JsonObject: z.ZodRecord<z.ZodString, z.ZodType<JsonValue_2, unknown, z.core.$ZodTypeInternals<JsonValue_2, unknown>>>;
1774
+
1775
+ declare type JsonObject = z.infer<typeof JsonObject>;
1776
+
1777
+ declare const JsonPointer: z.ZodString;
1778
+
1779
+ declare type JsonPointer = z.infer<typeof JsonPointer>;
1780
+
1623
1781
  declare type JsonPrimitive = string | number | boolean | null;
1624
1782
 
1625
1783
  declare type JsonSchema = Record<string, unknown>;
1626
1784
 
1785
+ declare const JsonSchema_2: z.ZodRecord<z.ZodString, z.ZodType<JsonValue_2, unknown, z.core.$ZodTypeInternals<JsonValue_2, unknown>>>;
1786
+
1787
+ declare type JsonSchema_2 = z.infer<typeof JsonSchema_2>;
1788
+
1627
1789
  declare type JsonValue = JsonPrimitive | {
1628
1790
  readonly [key: string]: JsonValue;
1629
1791
  } | readonly JsonValue[];
@@ -1638,6 +1800,633 @@ declare type JsonValue_3 = null | boolean | number | string | JsonValue_3[] | {
1638
1800
  [key: string]: JsonValue_3;
1639
1801
  };
1640
1802
 
1803
+ /**
1804
+ * The publisher id Bonsai's own subsystems publish declared events under (skill
1805
+ * changes, wallet notices, automation failures). A notification rule matches a
1806
+ * declared event by (publisher id, event local id), so no plugin may take this
1807
+ * id or it could publish events that Bonsai's default rules read as Bonsai's own.
1808
+ */
1809
+ declare const KAY_EVENT_PUBLISHER_ID: "kay";
1810
+
1811
+ /** Released SDK contracts still implemented by the host, alongside its current SDK. */
1812
+ declare const KAY_PLUGIN_COMPATIBLE_SDK_VERSIONS: readonly string[];
1813
+
1814
+ declare const KAY_PLUGIN_PROTOCOL_PACKAGE_NAME: "@bonsai/plugin-protocol";
1815
+
1816
+ declare const KAY_PLUGIN_PROTOCOL_VERSION: "kay.plugin.v1";
1817
+
1818
+ /**
1819
+ * The plugin SDK version this host ships, and the number a plugin's
1820
+ * `compatibility.sdk` range is matched against.
1821
+ *
1822
+ * -- Why this is the compatibility axis, and the app version is not ----------
1823
+ * A plugin never bundles the SDK: the host injects its own `@bonsai/plugin-sdk`
1824
+ * dist at import time. So the SDK surface a plugin was written against is the
1825
+ * thing that can break under it, and the Bonsai app version is only correlated
1826
+ * with that - it moves for reasons a plugin cannot observe.
1827
+ *
1828
+ * -- Two lines, deliberately, not one ----------------------------------------
1829
+ * This continues the published `@yaklabs-ai/plugin-sdk` line, currently in 0.x.
1830
+ * `KAY_UI_SDK_VERSION` in `@bonsai/protocol` is a SEPARATE line at its own number,
1831
+ * and the two are never compared: a `kay.ui` app package declares against the
1832
+ * UI SDK, a plugin manifest declares `compatibility.sdk` against this one, and
1833
+ * no manifest field takes both. Unifying them would have to publish the plugin
1834
+ * SDK at the UI line's 1.x, claiming a stability this surface does not have -
1835
+ * 0.x says "breaking minors" honestly, which is the truth pre-product.
1836
+ *
1837
+ * -- Bumping it --------------------------------------------------------------
1838
+ * A protocol or SDK surface break bumps this constant IN THE SAME PR, and
1839
+ * `scripts/check-sdk-release-due.mjs` then reports a release due at the new
1840
+ * number. The constant is the declared version, not a derived one: the release
1841
+ * publishes exactly what is written here.
1842
+ *
1843
+ * An ADDITION takes the patch slot, not the minor. Under 0.x npm's caret makes
1844
+ * the minor the breaking slot, so a minor bump refuses
1845
+ * (`sdk-range-unsatisfied`) every plugin still declaring the previous one - a
1846
+ * fleet-wide break, never the price of one new entrypoint. 0.7.1 carried the
1847
+ * additive `@bonsai/plugin-sdk/phase-shift` surface that way, while `^0.7.0`
1848
+ * plugins kept loading.
1849
+ *
1850
+ * 0.8.0 IS that fleet-wide break, deliberately, and it spends the one break on
1851
+ * two changes at once.
1852
+ *
1853
+ * FIRST, a plugin no longer declares the capabilities it wants, because the
1854
+ * CALL is the ask. Every capability ask left `permissions.byTarget` (an
1855
+ * installed manifest that still carries one is stripped with a
1856
+ * `retired-permission-ask` diagnostic, never refused - the same law
1857
+ * `RETIRED_COMPATIBILITY_KEYS` follows), every brokered capability object is
1858
+ * unconditionally present on the SDK surface (presence is no longer a grant
1859
+ * signal to feature-detect), and authority is one exact claim checked against
1860
+ * the user's grant ledger at the call.
1861
+ *
1862
+ * SECOND, `app.hindsight` (`KayAppHindsight` - lane registration, the lane
1863
+ * event, the lane context, and the followup DTOs) is DELETED, along with the
1864
+ * daemon-side lane dispatcher it registered onto. Its replacement is two
1865
+ * generic doors a plugin composes itself, `app.sessionEvents.subscribe` and
1866
+ * `app.agents.run`, and their authority is two claims in the same ledger
1867
+ * (`session-events.subscribe`, `agents.run`). There is no shim, because a shim
1868
+ * would have to fake a dispatcher that no longer exists.
1869
+ *
1870
+ * Either half alone breaks a `^0.7` plugin: the TYPE surface it compiles
1871
+ * against moved under it - the ask keys are gone from the manifest type, the
1872
+ * capability objects are required rather than optional, and the hindsight door
1873
+ * is gone - which is what the minor bump signals. A plugin declaring `^0.7` is
1874
+ * refused (`sdk-range-unsatisfied`) rather than loaded against a contract it
1875
+ * was not written to.
1876
+ *
1877
+ * 0.8.1 takes the PATCH slot under the addition rule above: `api.withJev`
1878
+ * (`@bonsai/plugin-sdk/jev`) - Jev typed-decision inference with a required
1879
+ * fallback - is one new member on an api a plugin RECEIVES. A `^0.8.0` plugin
1880
+ * keeps loading and keeps compiling; it simply never reaches for the member.
1881
+ * The member is non-optional for the same reason 0.8.0 made every brokered
1882
+ * capability unconditional: presence is not a grant signal, and an optional one
1883
+ * would invite the feature-detect branch that skips the required fallback.
1884
+ *
1885
+ * 0.8.2 adds the received Whiteboard handles, type contributions, and session
1886
+ * app-data readers. Existing 0.8 plugins keep loading without using them.
1887
+ *
1888
+ * 0.8.3 adds the recorded Jev signal reads, `app.signals.list` and
1889
+ * `app.signals.listDetectors`, behind the new `signals.read` claim. It is also
1890
+ * the first number that guarantees `app.signals.observe`, which reached hosts
1891
+ * still advertising 0.8.2. A plugin that reads signals declares `^0.8.3`, so an
1892
+ * older host refuses it at load instead of failing at the call. 0.8.3's
1893
+ * `observe` also answers `invalid`, recording nothing, for a detector id,
1894
+ * version, question name, choice label, or source id outside the recorded-name
1895
+ * grammar (`invalidObservation` in `@bonsai/plugin-sdk/signals`): names a reader
1896
+ * could not later address, filter on, or copy back. A 0.8.2 host recorded such
1897
+ * names, so a plugin moving to 0.8.3 checks its names against that grammar.
1898
+ *
1899
+ * 0.8.4 adds `api.events` on `kay.agent` (publish a declared event from agent
1900
+ * code, host-stamped with the session) and the `kay.app` manifest key
1901
+ * `notificationRules` (default notification rules for a plugin's own events).
1902
+ * Both are additions: a `^0.8` plugin keeps loading. The manifest key is new
1903
+ * schema, so an older host refuses a manifest that uses it at parse. `api.events`
1904
+ * carries no such schema backstop - it is a call, not a manifest field - so a
1905
+ * plugin that calls it, or declares `notificationRules`, declares `^0.8.4`: a
1906
+ * host still advertising 0.8.3 (signals only, landed separately) refuses it at
1907
+ * load instead of failing at the call.
1908
+ *
1909
+ * 0.8.5 republishes `@yaklabs-ai/plugin-sdk` to include the `./jev` and
1910
+ * `./signals` entrypoints: the workspace package has exported them since 0.8.1
1911
+ * (`jev`) and 0.8.3 (`signals`), but `scripts/build-publishable-packages.mjs`'s
1912
+ * hand-maintained `entrypoints` allowlist had omitted both. This packages
1913
+ * EXISTING apis; the type contract does not change. It still takes the patch
1914
+ * slot: nothing a `^0.8.1`/`^0.8.3` plugin already compiles against changes
1915
+ * shape, and the fix is which bytes reach npm, not what the contract promises.
1916
+ *
1917
+ * 0.9.0 adds timer_cancelled and requires workflow descriptions and summary
1918
+ * returns. This is an authoring-type break only: the host retains the 0.8
1919
+ * runtime contracts.
1920
+ *
1921
+ * 0.9.1 adds bounded corpus invocation reads (`app.corpus.listResourceInvocations`).
1922
+ * Existing received APIs are unchanged, so this is additive only.
1923
+ *
1924
+ * 0.10.0 removes the `spawn-session` variant from `KayAppAutomationEffectInput`
1925
+ * (and its daemon-facing mirror, `KayAutomationEffectInput`): an agent or
1926
+ * plugin can no longer create a spawn-session automation binding (owner
1927
+ * ruling, 2026-09-28) - durable recurring agent work is a plugin workflow
1928
+ * (`app.workflows.define` + `ctx.runAgent`) or a direct `session/run`. A
1929
+ * binding created before this version, or by daemon-internal code, still
1930
+ * stores and reads the effect fine (`KayAppAutomationEffect` keeps it); only
1931
+ * the create-time input type is narrower. Mostly an authoring-type break -
1932
+ * 0.9.0 and 0.9.1 stay in the runtime-contract retention list below, so a
1933
+ * plugin still running bytecode compiled against either keeps loading and
1934
+ * working - except for the one call this ruling actually closes:
1935
+ * `app.automations.create` with a `spawn-session` effect now throws
1936
+ * explicitly at the call site instead of being accepted, for any plugin
1937
+ * regardless of its declared SDK range.
1938
+ *
1939
+ * 0.11.0 adds `producedResources` to `KayAppAutomationRunDetail` (every URI a
1940
+ * run wrote, edited or declared, as one list deduplicated by URI) and the
1941
+ * `produced-resource-unnamed` member to `KayAppProvenanceGapCode`. An
1942
+ * authoring-type break only: code that builds a run detail must supply the
1943
+ * new list, and an exhaustive switch over gap codes must handle the new one.
1944
+ * 0.10.0 stays in the runtime-contract retention list below, because a plugin
1945
+ * compiled against it reads the same run detail and simply ignores the list.
1946
+ *
1947
+ * 0.11.1 adds read-only skill metadata (`app.skills`: `list`, `read`, `history`),
1948
+ * checked per call against the new `skills.read` claim. Additive: a plugin
1949
+ * compiled against 0.11.0 never reads the member. A plugin that calls it
1950
+ * declares `^0.11.1`, so an older host refuses it at load instead of the call
1951
+ * failing.
1952
+ *
1953
+ * 0.12.0 replaces the vendor client `api.withJev` hands its callback. `use`
1954
+ * now receives Bonsai's own `JevClient` (`@bonsai/plugin-sdk/jev`): one method,
1955
+ * `classify({state, questions})`, in Bonsai's question and answer vocabulary
1956
+ * (yes/no is `bool` answering `probability`; instructions and criteria are
1957
+ * text; the state is a JSON object), rejecting with a classified
1958
+ * `JevCallError`. TypeSafe's `TypeSafeClient`, `SystemOneRequest`,
1959
+ * `SystemOneResult`, `Questions`, and the `NoulResponse`/`ChoiceResponse`/
1960
+ * `ScoreResponse` re-exports are gone, and the SDK no longer depends on
1961
+ * `@typesafe-ai/sdk`. `app.signals.observe` takes the same questions, answers
1962
+ * `invalid` for a state that is not a JSON object, and its reads type stored
1963
+ * answers as `KayAppSignalAnswer` (a `JevAnswer`, or a yes/no answer recorded
1964
+ * before 0.12.0 as `{type: "noul", noul}`).
1965
+ *
1966
+ * A clean break with no shim, and deliberately NOT a load refusal: every
1967
+ * earlier release stays in the retention list below. `withJev`'s contract was
1968
+ * always that `use` may fail and the fallback then runs, so a plugin compiled
1969
+ * against 0.11 that calls `jev.systemOne` throws inside `use` and runs its
1970
+ * fallback on this host. This fallback guarantee does not cover `signals.observe`:
1971
+ * old text/array states now return `invalid`; old object states with `noul`
1972
+ * questions can classify but receive `bool` answers, so reading `.noul` yields
1973
+ * undefined. Stored pre-0.12 answers retain `noul`. Retention allows activation,
1974
+ * not vocabulary compatibility: old plugins must migrate both surfaces.
1975
+ *
1976
+ * 0.12.1 adds `app.time` (`KayAppTime`): `snapshot()` returns the daemon's clock and the time
1977
+ * zone the user is in, as `{ nowMs, zone, zoneSource }`, where `zoneSource: "utc-fallback"` marks a
1978
+ * zone the host does not know. The member is always present and ungated, like `app.paths`.
1979
+ * Additive: a plugin compiled against 0.12.0 never reads it. A plugin that calls it declares
1980
+ * `^0.12.1`, so an older host refuses a directory or repository plugin at load instead of the
1981
+ * call failing. That check needs a host that knows its own version, and it never runs for a
1982
+ * bundled plugin, which ships with the SDK it calls.
1983
+ *
1984
+ * 0.12.2 adds the `ui-action` session event (`KayAppUiActionSessionEvent`), a fourth member of the
1985
+ * `KayAppSessionEvent` union: the daemon publishes it once per accepted answer to a card the agent
1986
+ * drew with `ui_render` (pressing Send on a drafted message, submitting a form), carrying the
1987
+ * projected entry's id and the answered call's id and no payload. A typed message still publishes
1988
+ * only `human-message`. Additive: a plugin compiled against 0.12.1 never subscribes to it, and
1989
+ * code that narrows the union by `type` meets one more member, as it must for any future one. A
1990
+ * plugin that subscribes to it declares `^0.12.2`, so an older host refuses a directory or
1991
+ * repository plugin at load instead of the subscription never firing. That check never runs for a
1992
+ * bundled plugin, which ships with the SDK it calls.
1993
+ *
1994
+ * 0.12.3 adds the `page` reference open kind (`{ kind: "page", pageId }` on a
1995
+ * `referencePresentations` entry), and lets a presentation name a `kay.app` URI module as well as a
1996
+ * `kay.agent` one. A plugin's own `scheme://` references then pill with its icon and the module's
1997
+ * `describe` title, and a click opens the plugin's own registered page with the reference URI as
1998
+ * the page's `objectId`. Additive: a `^0.12.2` plugin keeps loading. The value is new schema, so an
1999
+ * older host refuses the whole manifest at parse (`manifest-schema-invalid`), before any range
2000
+ * check runs. A plugin that declares it still declares `^0.12.3`, so the install-time version
2001
+ * checks name the mismatch instead of a schema error.
2002
+ *
2003
+ * 0.12.4 adds `app.repos` (`KayAppRepos`): `resolve(folder)` answers which git checkout encloses a
2004
+ * folder (repo root, primary checkout, common dir, remotes, origin), and `linkedWorktrees(commonDir)`
2005
+ * lists git's linked-worktree registry, both read by the host asynchronously under a time limit and
2006
+ * answering `unknown` rather than throwing. Always present and ungated, like `app.paths`. Additive:
2007
+ * a plugin compiled against 0.12.3 never reads it. A plugin that calls it declares `^0.12.4`, so an
2008
+ * older host refuses a directory or repository plugin at load instead of the call failing.
2009
+ *
2010
+ * 0.12.5 adds `userFiles` (`KayAppUserFiles`) on both `app` and the `kay.agent` api: stat, read,
2011
+ * list, walk, realpath, write, mkdir and rename in user folders, run by the host on its own worker
2012
+ * threads under a deadline and answering a typed result rather than throwing. Always present and
2013
+ * ungated, like `app.paths`. Additive: a plugin compiled against 0.12.4 never reads it. A plugin
2014
+ * that calls it declares `^0.12.5`, so an older host refuses a directory or repository plugin at
2015
+ * load instead of the call failing.
2016
+ *
2017
+ * 0.13.0 adds `@bonsai/plugin-sdk/fs`, Bonsai's own `node:fs/promises`: the same functions, arguments,
2018
+ * return types and errors, with every call run on the host's user-files workers under a deadline
2019
+ * (`ERR_KAY_FS_DEADLINE` and siblings when the host gives up or does not try), plus
2020
+ * `writeFileAtomic` and `withTimeout`. With no host installed it is Node's own module. It adds
2021
+ * `api.familyFolder` (`KayAgentFamilyFolder`), whose `path()` answers the plugin's folder in its
2022
+ * session family's Whiteboard, and makes it a required member of `KayAgentPluginApi`. It removes
2023
+ * the `kay.agent` api's `filesystem` broker, the `filesystem.read` / `filesystem.write`
2024
+ * permissions it was gated by, the `{ root: "filesystem", selector }` URI backing and the URI
2025
+ * module `verbs` that went with it: plugins use `@bonsai/plugin-sdk/fs`, `userFiles` or
2026
+ * `familyFolder` instead. No plugin used them. Stored grants naming the retired permissions are
2027
+ * ignored, not refused. For the api surface this is a clean break with no shim and deliberately
2028
+ * NOT a load refusal, like 0.12.0: every earlier release stays in the retention list, so a
2029
+ * plugin compiled against 0.12.x that reads `api.filesystem` gets `undefined` at the call. The
2030
+ * manifest is different: a manifest that still declares URI-module `verbs` or
2031
+ * `filesystemBacking: { root: "filesystem" }` fails to parse and is refused at load (no plugin
2032
+ * declared either). A plugin that imports
2033
+ * `@bonsai/plugin-sdk/fs` or calls `familyFolder` declares `^0.13.0`, so an older host refuses a
2034
+ * directory or repository plugin at load.
2035
+ *
2036
+ * 0.13.1 adds the signal engine to `@bonsai/plugin-sdk/signals`: `SignalDefinition`,
2037
+ * `createSignalEngine` and `signalAnswersPass` (a plugin declares its Jev signals as data and the
2038
+ * engine evaluates them, upstreams first, through `app.signals.observe`), plus `signalDigest`.
2039
+ * `observe` gains three optional input fields, `subject`, `after` and `reuse`, and an observation
2040
+ * and a read signal carry the stored `subject` and `upstreamId` back. Additive: a plugin compiled
2041
+ * against 0.13.0 never sends or reads them. A plugin that imports the engine declares `^0.13.1`,
2042
+ * so an older host refuses a directory or repository plugin at load.
2043
+ *
2044
+ * 0.13.2 adds `app.tools` (`KayAppTools`): `describe(sessionId, refs)` returns, for each tool name
2045
+ * or address a live session can use, the text the agent sees for it, where it comes from, and
2046
+ * whether it is one of Bonsai's own (`ownedByBonsai`). Checked per call against the new
2047
+ * `tools.describe` claim. It also adds the manifest's top-level `ownedByBonsai` flag, honoured only
2048
+ * for a plugin that ships with Bonsai. Additive: a plugin compiled against 0.13.1 never reads the
2049
+ * member. A plugin that calls it declares `^0.13.2`, so an older host refuses a directory or
2050
+ * repository plugin at load. The flag is new schema, so an older host refuses a manifest that sets
2051
+ * it at parse, like 0.12.3's page open kind.
2052
+ *
2053
+ * 0.13.3 adds `app.usage` (`KayAppUsage`, `createUnavailableUsage`): `uriActivity({ prefix })`
2054
+ * returns read and change activity for resources under one of the plugin's OWN registered URI
2055
+ * schemes, checked per call (any other prefix answers `refused`). It also adds
2056
+ * `KayAppAgentDefinition.maintains`, the URI schemes a registered agent definition's runs maintain;
2057
+ * reads by such a run and its session family are not counted. Additive: a plugin compiled against
2058
+ * 0.13.2 never reads the member or sets the field. A plugin that calls `app.usage` or declares
2059
+ * `maintains` declares `^0.13.3`, so an older host refuses a directory or repository plugin at
2060
+ * load; an older host's strict definition schema would refuse a definition that sets `maintains`.
2061
+ *
2062
+ * 0.13.4 caps reads through `@bonsai/plugin-sdk/fs`: a whole-file `readFile` (a file handle's too)
2063
+ * and a single `read` reject past 64 MiB with `EFBIG` instead of copying the bytes into the daemon.
2064
+ * No API changes: a plugin compiled against 0.13.3 runs unchanged unless it reads more than 64 MiB
2065
+ * in one call, and such a plugin reads in bounded chunks (a file handle's `read`,
2066
+ * `createReadStream`, `readLines`), which work on every 0.13 host. File calls sent to a host worker
2067
+ * that fail are also logged to the daemon log as `runtime.user-files.*` events.
2068
+ *
2069
+ * 0.13.5 loads a `kay.agent` or `kay.app` entrypoint's default export when the manifest's
2070
+ * `entrypoint.export` names none, the way Pi writes extensions; a module with no default export
2071
+ * still loads from a named `activate`. A plugin whose entrypoint has only a default
2072
+ * export declares `^0.13.5`, so an older host, which reads only `activate`, refuses it at load
2073
+ * instead of failing to find the export. It also renamed three published types with no aliases,
2074
+ * a break in the authoring types that shipped in this patch: `kay-app`'s `SessionTreeEntry`
2075
+ * became `TranscriptEntry`, and `transcript`'s `TranscriptEntry` and `TranscriptSourceEntry`
2076
+ * became `TranscriptEntryLike` and `TranscriptSourceEntryLike`.
2077
+ *
2078
+ * 0.13.6 publishes the pure contracts Bonsai's own plugins took from its internal libraries, so a
2079
+ * plugin needs less beside the SDK. A new `@bonsai/plugin-sdk/time` carries `Temporal` (the
2080
+ * host's own instance, like `z`), `canonicalZone`, `isValidZone` and `sameZone`, and the time
2081
+ * door's types. `kay-app` adds
2082
+ * the `JsonSchema` and `JsonValue` schemas, `PluginAgentDefinitionPermissionRule`,
2083
+ * `KAY_APP_DATA_SNAPSHOT_MAX_BYTES`, and the URI types `UriHelp`, `RawResource`, `UriPayload`,
2084
+ * `UriListParams`, `UriListResult`, `UriSearchParams` and `UriSearchResult`. `kay-agent` adds
2085
+ * `compileUriClaim`, `kay-agent/testing` adds `createTestClock`, and `transcript` adds the turn walk
2086
+ * (`turnSegments`), the run records and the work-block and work-headline helpers. Additive: a
2087
+ * plugin compiled against 0.13.5 never imports them. A plugin that imports one declares `^0.13.6`,
2088
+ * so an older host refuses a directory or repository plugin at load instead of the import failing.
2089
+ *
2090
+ * 0.13.7 adds four subpaths. `@bonsai/plugin-sdk/vendored-mcp` re-exports
2091
+ * `@bonsai/vendored-mcp-integration` (`createVendoredMcpUriModule` and its descriptor types; not
2092
+ * the MCP read-port types). `transcript-review` and `agent-conversation` re-export the session
2093
+ * folds Bonsai's own Sessions and Hindsight plugins share. `app-data` carries the app-data size
2094
+ * caps on an entry with no other import, for code a `kay.ui` page also loads. The protocol it
2095
+ * ships also carries three new capability-claim slugs (`mcp.host-server`, `prompt.resident`,
2096
+ * `skills.declared-source`). Additive: a plugin compiled against 0.13.6 never imports the new
2097
+ * subpaths, and its manifest parses unchanged. A plugin that imports one declares `^0.13.7`, so
2098
+ * an older host refuses a directory or repository plugin at load instead of the import failing.
2099
+ *
2100
+ * 0.13.8 takes the PATCH slot under the addition rule, as `api.withJev` did in 0.8.1: one new
2101
+ * member on the api a plugin RECEIVES, `api.systemOne` / `app.systemOne` (`@bonsai/plugin-sdk/
2102
+ * system-one`), the System One client for `decide` and `extract` on Jev, Clef, Clef Flash and
2103
+ * Clairic. It is non-optional for the same reason `withJev` is, and a host with no System One
2104
+ * binds a client that throws `not-served`. `withJev` stays for every compatible plugin. A
2105
+ * plugin that calls `systemOne` declares `^0.13.8`, so an older host refuses it at load instead
2106
+ * of the member being absent.
2107
+ *
2108
+ * 0.13.9 adds `@bonsai/plugin-sdk/zod`: the host's `z` on an entry with no other import, for
2109
+ * code a `kay.ui` page also loads (`kay-agent` exports the same `z`). Additive: a plugin compiled
2110
+ * against 0.13.8 never imports it. A plugin that imports it declares `^0.13.9`, so an older host
2111
+ * refuses a directory or repository plugin at load instead of the import failing.
2112
+ *
2113
+ * 0.13.10 adds two optional manifest fields. An `external-cli` auth scheme's `cli` says how the host
2114
+ * connects it (the binary, its probe and sign-in argv, the hints, the install command), which the
2115
+ * host read from its own tables before. An auth grant's `frontDoor` names the product a person
2116
+ * connects a shared identity through (`gmail` over `google.account`), with an optional file picker.
2117
+ * Additive: a manifest without them parses unchanged. A plugin that declares one declares
2118
+ * `^0.13.10`, so an older host refuses it at load with that reason rather than a schema error.
2119
+ *
2120
+ * 0.14.0 removes `withJev`: `api.withJev` on `kay.agent`, `app.withJev` on `kay.app`, the
2121
+ * `@bonsai/plugin-sdk/jev` subpath and every `Jev*` type it exported. A plugin uses `api.systemOne`
2122
+ * / `app.systemOne` (`@bonsai/plugin-sdk/system-one`) instead. The `jev.use` capability claim is
2123
+ * renamed `systemOne.use`, and stored grants are rewritten to the new slug. The signals subpath
2124
+ * types its own surface now: observe options by `KayAppSignalObserveOptions`, state by
2125
+ * `KayAppSignalState`, and questions and answers by `DecideQuestions` and `DecideAnswer`. For the
2126
+ * api surface this is a clean break with no shim and deliberately NOT a load refusal, like 0.13.0:
2127
+ * every earlier release stays in the retention list, so a plugin compiled against 0.13.x that
2128
+ * reads `api.withJev` gets `undefined` at the call, and one that imports a value from
2129
+ * `@bonsai/plugin-sdk/jev` fails at load. No plugin used either.
2130
+ *
2131
+ * 0.14.1 adds the owned-service `kay.app` auth list operation and `listAccounts`.
2132
+ * Existing resolve-only `has` callers retain account bounds and now probe metadata without
2133
+ * resolving credentials. Plugins using list declare `^0.14.1` so older hosts refuse at load.
2134
+ *
2135
+ * 0.15.0 replaces plugin-event publish arguments and requires resource URI declarations.
2136
+ * Pre-0.15 SDK contracts are no longer retained: their publishers cannot satisfy this contract.
2137
+ *
2138
+ * 0.15.1 adds plugin-event automation conditions and public event-identity run matches.
2139
+ * The host retains 0.15.0; plugins using the new condition declare ^0.15.1.
2140
+ *
2141
+ * 0.15.2 lets a plugin workflow start on the plugin's own events (a `plugin-event` trigger, with
2142
+ * the event handed to the run as `ctx.match`) and declare `concurrency`. The host retains 0.15.0
2143
+ * and 0.15.1; a plugin using either declares ^0.15.2, so an older host refuses it at load instead
2144
+ * of `define` throwing inside activation.
2145
+ *
2146
+ * 0.15.3 adds `owner: "user"` to `app.automations.create`, with the `spawn-session` effect it
2147
+ * allows: an automation the user owns, which outlives the calling session. Additive; plugins
2148
+ * using it declare ^0.15.3 so an older host, which would ignore the field and make the calling
2149
+ * session the owner, refuses them at load.
2150
+ *
2151
+ * 0.16.0 adds declared app-lifetime approval types and their brokered registration API.
2152
+ * Plugins using approval types declare ^0.16.0; the host retains the 0.15 contracts.
2153
+ *
2154
+ * 0.16.1 adds `api.log` on both targets: a logger whose lines land in Bonsai's own log under the
2155
+ * plugin's id. Additive; plugins calling it declare ^0.16.1 so an older host, which has no
2156
+ * `api.log`, refuses them at load instead of activation throwing.
2157
+ *
2158
+ * 0.16.2 adds `api.vendoredMcp` on `kay.agent`: a port to a vendored MCP server the plugin declares,
2159
+ * bound to that plugin, with its `VendoredMcpPort` / `VendoredMcpOutcome` types on
2160
+ * `@bonsai/plugin-sdk/vendored-mcp`. Additive; plugins calling it declare ^0.16.2 so an older host,
2161
+ * which has no `api.vendoredMcp`, refuses them at load instead of activation throwing.
2162
+ *
2163
+ * 0.16.3 adds `app.sessionEvents.subscribeSessionDeleted`: a notice for every deleted session, so
2164
+ * a plugin can delete what it derived from it. Additive; plugins calling it declare ^0.16.3.
2165
+ *
2166
+ * 0.17.0 consolidates `app.corpus` into the always-present `app.sessions`. Read methods retain
2167
+ * the `corpus.read` claim; control methods retain their own claims and are absent on read-only
2168
+ * hosts. The summary helper takes `sessions` and stored-session DTOs use session names. The host
2169
+ * no longer implements earlier runtime contracts, so declared 0.15/0.16 ranges are refused.
2170
+ *
2171
+ * 0.17.1 adds `app.skills.diff` and `app.skills.revision` under `skills.read`, `uncommitted` on a
2172
+ * history result, refs by app-inventory row id, and `app.skills.writeFile`, `install` and `delete`
2173
+ * under the new `skills.write` claim. Additive; plugins calling them declare ^0.17.1.
2174
+ *
2175
+ * 0.17.2 adds `app.account.activeOrganization()` (ungated) and `app.account.refreshBilling()`
2176
+ * (under the `account.assert` grant), and an optional `refresh()` on an app-data source definition.
2177
+ * Additive; plugins using them declare ^0.17.2.
2178
+ *
2179
+ * 0.17.3 adds `app.sealing` on `kay.app` (encrypt small values under a key only the plugin's id
2180
+ * can use; the daemon holds it) and `api.endpoints` on `kay.agent` (call an endpoint the plugin's
2181
+ * own `kay.app` part registered, by local id). Additive; plugins calling either declare ^0.17.3 so
2182
+ * an older host, which has neither member, refuses them at load instead of activation throwing.
2183
+ *
2184
+ * 0.17.4 adds the optional `app.sessions.readCost(sessionId)` (a stored session's spend, models,
2185
+ * and providers, under the same `corpus.read` grant as the other session reads). Additive.
2186
+ *
2187
+ * 0.17.5 adds `app.modelSelection.registerPolicy` on `kay.app`, a private method under the
2188
+ * `model-selection.register` claim (only plugins Bonsai ships). Additive; a host without it leaves
2189
+ * `app.modelSelection` undefined.
2190
+ *
2191
+ * 0.17.6 renames the stored-session read claim `corpus.read` to `sessions.read`, next to
2192
+ * `sessions.run`, `sessions.create` and `sessions.update`; stored grants are rewritten to the new
2193
+ * slug. The manifest's `contributes.corpusConsumers` becomes `contributes.sessionReaders` (kind
2194
+ * `sessionReader`), a clean break: no plugin outside this repo declares it.
2195
+ *
2196
+ * 0.18.0 adds the calls hindsight moved onto (#14533): `app.sessions.annotate` and
2197
+ * `app.sessions.compact` (claims `sessions.annotate`, `sessions.compact`), the session-state read,
2198
+ * `app.models.listTiers({ provider })`, `app.usage.skillInvocations`, an optional `cause` on
2199
+ * `app.models.complete` and `app.systemOne.decide`, `app.skills.registerSuggestionExplainer`, and
2200
+ * the private `app.soul` (claim `soul.write`). Additive; plugins calling them declare ^0.18.0.
2201
+ *
2202
+ * 0.18.1 adds `servedSimulators` on both targets (`KayServedSimulators`): the simulators a
2203
+ * simulating Bonsai daemon (evals, dev, tests) serves a plugin, keyed by adapter id. Optional and
2204
+ * absent unless such a daemon serves it, so no plugin needs it to load; additive, so it takes the
2205
+ * patch slot. A plugin need not declare a range to read it: an older host serves none, the same as
2206
+ * a production daemon, and code that reads it already runs without it. It also deletes the other
2207
+ * route a plugin could get a simulator by: a per-dispatch handle on a URI call's `ctx.auth`, and
2208
+ * the type that `@bonsai/plugin-sdk/kay-agent` exported for it. Only Slack read it. It entered the
2209
+ * source after 0.17.3's bump, and no SDK since 0.15.3 has been published, so no released contract
2210
+ * loses a member and the removal does not spend the minor slot.
2211
+ *
2212
+ * 0.18.2 adds the marketplace calls the kay plugin moved onto (#14530):
2213
+ * `app.skills.sourceContributors`, `app.skills.shareDestinations` and `app.skills.prepareShare`
2214
+ * under `skills.read`, `app.skills.setMarketplaceAdded` under `skills.write`, and two private
2215
+ * methods, `app.skills.confirmShare` (claim `skills.share`) and `app.plugins.setEnabled` (claim
2216
+ * `plugins.set-enabled`). Additive; plugins calling them declare ^0.18.2.
2217
+ *
2218
+ * 0.18.3 adds `app.systemPrompt.register` on `kay.app`, a private method under the
2219
+ * `system-prompt.register` claim (only plugins Bonsai ships): text a plugin adds to every chat's
2220
+ * system prompt, rendered by the daemon and reused across chats. Additive; a host without it leaves
2221
+ * `app.systemPrompt` undefined.
2222
+ *
2223
+ * 0.18.4 adds `api.compiler.bundleBrowser` on `kay.agent` (#14896): the host compiles
2224
+ * caller-supplied bytes with caller-owned import resolution, without filesystem or network
2225
+ * fallback. Additive and ungated; plugins calling it declare ^0.18.4.
2226
+ *
2227
+ * 0.19.0 makes the host resolve the credential of a tool or search provider that declares
2228
+ * `requiresAuth` before calling it, as it already did for URI verbs (#15102). The credential
2229
+ * arrives on the call as `ctx.credential` (`ResolvedCredential`, the one type all three share,
2230
+ * replacing `ResolvedAuth` and `UriResolvedCredential`); tools and search providers no longer
2231
+ * receive the `ctx.auth` resolver. `defineAuthedTool`, `withResolvedAuth` and
2232
+ * `withResolvedSearchProvider` keep their shapes and read the credential off the call. A plugin
2233
+ * built against an earlier SDK carries wrappers that ask `ctx.auth`, so the host no longer
2234
+ * implements earlier runtime contracts and declared 0.17/0.18 ranges are refused.
2235
+ *
2236
+ * 0.19.1 adds `app.memory` note operations and `app.skills.propose` for pending suggestions.
2237
+ *
2238
+ * 0.19.2 adds the optional `app.sessions.readPage` (one bounded page of a stored transcript, or a
2239
+ * typed reason there is none) and `app.sessions.listSessionPage` (a page of the session index, or
2240
+ * rows by id), both under `sessions.read`; `app.knowledgeSearch` on `kay.app` under the `kay.app`
2241
+ * `knowledgeSearch` grant; and re-exports the record-kind helpers (`storedTranscriptKindOf`,
2242
+ * `parseStoredTranscriptKindFilter`) the daemon's reader numbers records with. Additive and
2243
+ * optional, so it takes the patch slot; plugins calling them feature-detect.
2244
+ *
2245
+ * 0.20.0 removes the unused activation-free advertisement helpers and their types from
2246
+ * `kay-agent` (#15160). No plugin used them, so 0.19.x stays served rather than refused, as with
2247
+ * 0.14.0; a 0.19.x plugin that imported one would now fail at load.
2248
+ *
2249
+ * 0.20.1 deletes `preflight.acceptsPayloadlessWrite` from URI modules (#15164). A `write` call
2250
+ * with neither `content` nor `source` now reaches the module's `write` with `content: undefined`,
2251
+ * and the module decides: a route that takes no body (a folder create) proceeds, and one that
2252
+ * needs a body refuses, naming what is missing. Only gdrive and microsoft declared the member,
2253
+ * and no SDK since 0.15.3 has been published, so the removal does not spend the minor slot.
2254
+ *
2255
+ * 0.20.2 lets a `kay.agent` manifest describe a tool whole (#15152): `parameters` (and with it a
2256
+ * required `description`), an `authService`/`authScheme` binding, and a `permission` (kind, rule
2257
+ * key, and the string arguments that name its resources). The host builds the tool from that entry,
2258
+ * and code supplies only the call through `api.implementTool(localId, execute)`. A plugin that runs
2259
+ * in the plugin host must describe its tools this way, because the daemon never loads its code.
2260
+ * Additive for every other plugin, so it takes the patch slot; plugins describing a tool declare
2261
+ * ^0.20.2.
2262
+ *
2263
+ * 0.21.0 makes sign-in manifest data (#15151). The host builds every auth service and scheme from
2264
+ * the manifest's `auth.services`, which gains OAuth endpoints, a public `clientId`, api-key
2265
+ * `inputLabel`/`fields`/`setup`/`validates` and a service `summary`. `api.auth` keeps only the
2266
+ * functions: `registerValidator` and `registerAccountResolver` replace `advertiseService` and the
2267
+ * `declare{OAuthPkce,ApiKey,ExternalCli}Scheme` calls. 0.19.x and 0.20.x stay served, as with
2268
+ * 0.20.0: most plugins declare no sign-in in code and are unaffected. One that does stops working
2269
+ * until it is rebuilt against 0.21: a manifest `oauth2` scheme without the now-required endpoints
2270
+ * is refused at load, and an activation that calls a removed member throws, so the plugin loses
2271
+ * its tools and URI modules too.
2272
+ *
2273
+ * 0.21.1 lets a URI module's `read` return its index form on `RawResource.observation`, from the
2274
+ * same fetch as the content, and deletes what steered the old second read (#15163): `observes`
2275
+ * on URI modules, `format: "observation"` on the read context, and `owns` on knowledge sources.
2276
+ * A plugin that still declares `owns` or `observes` loads, and the member is ignored. One that
2277
+ * omits `owns` needs this host, since an older one requires it. No SDK since 0.15.3 has been
2278
+ * published, so the removals take the patch slot, as in 0.20.1. It also adds `knownResourcesView`,
2279
+ * which marks a list or search rendered from the known-resources ledger so the host does not
2280
+ * record it back.
2281
+ *
2282
+ * 0.21.2 adds same-plugin informational tooltip apps to reference presentations, matched by
2283
+ * canonical resource URI patterns, and context-only apps excluded from standalone navigation.
2284
+ * Plugins declaring either require ^0.21.2.
2285
+ *
2286
+ * 0.22.0 deletes URI-module members the daemon used to call in a plugin's code (#15150):
2287
+ * `authActions.classifyOperation` (sign-in actions come from `authActions.rules`), `preflight` (the
2288
+ * verb rejects a bad call when it runs), `permission`, and `toMarkdown` (a verb's result carries
2289
+ * its own `markdown`); `@bonsai/plugin-sdk/kay-agent` stops re-exporting
2290
+ * `UriOperationPreflightPolicy`. A `kay.app` module also loses `matches`, `normalize` and
2291
+ * `describe`: it routes, spells and links its addresses through its claims' `normalizeTo`, `title`
2292
+ * and `sourceUrl`. The host drops these members from a 0.20.x or 0.21.x module rather than calling
2293
+ * them, and a module already claims every scheme it declares, so both stay served.
2294
+ *
2295
+ * 0.22.1 renames `RawResource.observation` to `observations`, a list (#15168), so one read can
2296
+ * index several documents: a Gmail thread read indexes each of its messages. A module that still
2297
+ * returns `observation` loads, and its read is not indexed. No SDK since 0.15.3 has been
2298
+ * published, so the rename takes the patch slot, as in 0.21.1. Plugins that return observations
2299
+ * and declare a floor require ^0.22.1.
2300
+ *
2301
+ * 0.22.2 lets a converter decline a file its `matches` claimed (#15153): `convert` may resolve
2302
+ * `undefined`, and the read pipeline tries the next converter that claimed the file. A plugin
2303
+ * whose converters only convert is unaffected; one that declines requires ^0.22.2, since an older
2304
+ * host reads the result's `content`. Additive, so it takes the patch slot.
2305
+ *
2306
+ * 0.23.0 trims the message approval type (#15154): `prepare` returns a promise, so the host can
2307
+ * call it across a process boundary; `tighten` is gone (no plugin set it, and an unknown member
2308
+ * is ignored); `resolveResource` is optional, for a provider that keeps no saved draft. A 0.22
2309
+ * plugin's synchronous `prepare` is still read correctly, because the host awaits what it
2310
+ * returns, so 0.22.x stays served.
2311
+ *
2312
+ * 0.23.0 also deletes `definePoller`'s `resolveCredential` option (#15154): the helper asks
2313
+ * `app.backgroundAuth` itself, and `requiredScopes` on a background credential request becomes
2314
+ * optional. Omitted, the host asks for the first scope of the manifest's `background-job` grant
2315
+ * (`allowedScopes`) that the account holds, and answers `requires-auth` when it holds none. A
2316
+ * 0.22.x plugin that passes `resolveCredential` still loads; the option is ignored, so its poller
2317
+ * needs a `background-job` grant whose `allowedScopes` the host can choose from.
2318
+ *
2319
+ * 0.23.0 also deletes `timezone` from a cron schedule (#15394): every schedule, a workflow trigger's
2320
+ * and an automation's, runs in the computer's current time zone and follows it when it changes.
2321
+ * A `define` or create that still passes `timezone` is refused, so a 0.22.x plugin that pins a
2322
+ * cron zone stops loading its workflow until it drops the field; every other 0.22.x plugin is
2323
+ * unaffected and stays served. Plugins that declare a cron trigger declare ^0.23.0, since an
2324
+ * older host requires the zone.
2325
+ *
2326
+ * 0.24.0 lets the daemon build a hosted plugin's URI module from its manifest alone (#15141).
2327
+ * The module facts gain `verbs.searchable`; resolved modules carry `displayName` and
2328
+ * `authServiceId`. Asana and Figma use their services' single auth scheme.
2329
+ *
2330
+ * 0.25.0 unifies URI writes (#15402): `write(input, content, sources, ctx)` receives an
2331
+ * empty sources array for ordinary writes. Modules that accept files declare
2332
+ * `acceptsWriteSources: true` in their manifest. Earlier SDK contracts are no longer served.
2333
+ *
2334
+ * 0.26.0 folds `writeBytes` into `write` (#15433): a binary `source` copy reaches `write` as a
2335
+ * `Uint8Array` content, named and typed by `ctx.writeSource`, and only for a module that declares
2336
+ * `acceptsBytes: true` in its manifest. A module that still defines `writeBytes` never receives
2337
+ * bytes. Earlier SDK contracts are no longer served.
2338
+ *
2339
+ * 0.26.1 turns the revision check into a conditional `read` (#15423). `ctx.knownRevision` carries
2340
+ * the revision the session holds, and a module that has verified the source has not moved returns
2341
+ * `{ content: "", unchanged: true, metadata: { revision } }` with no body. The module's `revision`
2342
+ * member is gone (the host drops a leftover one), so is `fallback` and `locate` (the host's own
2343
+ * modules keep them), and so is the manifest's `filesystemBacking`, which no plugin declared.
2344
+ * Additive for a plugin that never used them. A plugin that answers `unchanged` declares ^0.26.1.
2345
+ *
2346
+ * 0.26.2 lets a hosted URI module describe its calls for the approval card (#15423): a manifest
2347
+ * URI module sets `describesOperations: true` when its code defines `describeOperation`, and the
2348
+ * daemon calls the plugin host for it. `amendOperation` is gone: the host applies an "Allow with
2349
+ * edits" answer itself, replacing top-level string properties of the payload, so a preview field
2350
+ * is editable only when the payload is an object with that key as a string. `labelResource` is
2351
+ * gone: a verb's result carries the transcript row's name as `label`. The SDK stops re-exporting
2352
+ * `UriOperationAmendment`, `UriResourceLabelRequest` and `UriPreviewEdit`. The host ignores a
2353
+ * leftover `amendOperation` or `labelResource`, so this is additive for a plugin that never sets
2354
+ * the flag; a plugin whose manifest sets `describesOperations` declares ^0.26.2.
2355
+ *
2356
+ * 0.26.3 gives a plugin's own sign-in back what #15151 left behind (#15195). Every `oauth2` sign-in a
2357
+ * plugin runs says where its account comes from: `account` is `"resolveAccountId"`,
2358
+ * `"resolveAccounts"` or, on a hosted (`confidential`) sign-in whose broker names the account,
2359
+ * `"sign-in"`, so each account a person signs in with is saved apart. `api.auth.registerAccountResolver`
2360
+ * registers the named function on any such scheme, its own client's included, and the SDK refuses a
2361
+ * plugin whose lookup and manifest disagree. An own-client (`pkce`) scheme may carry the
2362
+ * `clientSecret` that goes with its `clientId`. A plugin with an `oauth2` sign-in declares ^0.26.3.
2363
+ *
2364
+ * 0.27.0 makes a message approval card manifest data (#14574). `approvalTypes` declares the card's
2365
+ * facts and forms, and Bonsai draws it with the module's `describeOperation` and sends it with its
2366
+ * `write`. `app.approvals`, its `prepare`, `finalize` and `resolveResource` are gone, and a write can
2367
+ * refuse in the person's words with `UriProviderError.refusalMessage`. No plugin outside this repo
2368
+ * declared a card, so 0.26.3 stays served. A plugin that declares a card declares ^0.27.0.
2369
+ */
2370
+ declare const KAY_PLUGIN_SDK_VERSION: "0.27.0";
2371
+
2372
+ declare const KAY_PLUGIN_TARGET_NAMES: readonly ["kay.agent", "kay.app", "kay.ui"];
2373
+
2374
+ /** Browser compilation over caller-supplied bytes, without filesystem or network authority. */
2375
+ declare interface KayAgentCompiler {
2376
+ /** Rejects on compilation or source callback failure, and when the host composed no compiler. */
2377
+ bundleBrowser(request: KayBrowserBundleRequest, sources: KayBrowserSources): Promise<KayBrowserBundle>;
2378
+ }
2379
+
2380
+ /**
2381
+ * The plugin-facing `kay.agent` own-endpoint call: a plugin's agent part calls an endpoint its own
2382
+ * `kay.app` part registered. SDK 0.17.3; a plugin that calls it declares `compatibility.sdk`
2383
+ * `^0.19.0`.
2384
+ *
2385
+ * A plugin's two parts load as separate modules and share no memory, so this is how agent code
2386
+ * reaches state its app part keeps (a worker, a database). The manifest says which endpoints the
2387
+ * agent part may call: the `kay.app` target declares the endpoint with a `register` grant, and
2388
+ * `permissions.byTarget["kay.agent"].endpoints` lists it with `invoke`. No other plugin's endpoint
2389
+ * is nameable.
2390
+ *
2391
+ * An endpoint whose only `invoke` grant is the plugin's own `kay.agent` target is not reachable
2392
+ * from Bonsai's surfaces (its pages and runtime clients), so an action the agent takes after the
2393
+ * session's approval card cannot be taken around it.
2394
+ */
2395
+ /** Why an {@link KayAgentEndpoints.invoke} call produced no value. */
2396
+ declare type KayAgentEndpointFailureReason =
2397
+ /** The manifest grants this plugin's `kay.agent` target no `invoke` on this endpoint. */
2398
+ "not-declared"
2399
+ /** The plugin's `kay.app` part is not running, or registered no handler for it. */
2400
+ | "unavailable"
2401
+ /** The handler did not answer within the host's fixed deadline (10 seconds). It may still finish. */
2402
+ | "timed-out"
2403
+ /** The caller's `signal` aborted. The handler may still finish. */
2404
+ | "cancelled"
2405
+ /** The handler threw; `message` is its error's message. */
2406
+ | "failed"
2407
+ /** The request or the handler's response does not match the endpoint's declared schema. */
2408
+ | "invalid";
2409
+
2410
+ declare type KayAgentEndpointOutcome = {
2411
+ readonly ok: true;
2412
+ readonly value: unknown;
2413
+ } | {
2414
+ readonly ok: false;
2415
+ readonly reason: KayAgentEndpointFailureReason;
2416
+ readonly message: string;
2417
+ };
2418
+
2419
+ declare interface KayAgentEndpoints {
2420
+ /**
2421
+ * Call `endpoint`, the local id this plugin's manifest declares on its `kay.app` target. Never
2422
+ * rejects: every failure is an outcome. Nothing is queued: when the app part is not running the
2423
+ * answer is `unavailable` at once.
2424
+ */
2425
+ invoke(endpoint: string, payload: unknown, options?: {
2426
+ readonly signal?: AbortSignal;
2427
+ }): Promise<KayAgentEndpointOutcome>;
2428
+ }
2429
+
1641
2430
  /**
1642
2431
  * Publishes the plugin's declared events from agent code. See {@link KayAgentPluginApi.events}.
1643
2432
  */
@@ -1681,7 +2470,7 @@ declare interface KayAgentInteractionSurfaces {
1681
2470
  readonly desktop: InteractionSurface;
1682
2471
  }
1683
2472
 
1684
- /** One knowledge-index hit — a reference and within-list rank score, never a snippet. */
2473
+ /** One knowledge-index hit - a reference and within-list rank score, never a snippet. */
1685
2474
  declare interface KayAgentKnowledgeHit {
1686
2475
  readonly uri: string;
1687
2476
  /** Comparable only with other hits returned by this search call. */
@@ -1691,7 +2480,7 @@ declare interface KayAgentKnowledgeHit {
1691
2480
  /**
1692
2481
  * Query the daemon's shared knowledge index, scoped to this plugin's own declared `kay.agent`
1693
2482
  * schemes. Deny-by-default: `api.knowledgeSearch` is absent unless the manifest requests the
1694
- * `knowledgeSearch` grant AND the host effectively grants it — a plugin must feature-detect the
2483
+ * `knowledgeSearch` grant AND the host effectively grants it - a plugin must feature-detect the
1695
2484
  * capability. (It is WIRING, so absence is still the signal here, unlike the claim-checked
1696
2485
  * capabilities around it.) The host pre-scopes every call to the
1697
2486
  * plugin's OWN declared URI schemes; a caller-supplied `uriPrefixes` outside that scope is dropped
@@ -1707,7 +2496,7 @@ declare type KayAgentKnowledgeSearch = (query: string, opts?: {
1707
2496
  /**
1708
2497
  * One row of the daemon's known-resources ledger: a resource the host has
1709
2498
  * observed flowing through one of this plugin's own URI modules (or recorded
1710
- * through a host-side grant flow). Metadata facts, never content — content
2499
+ * through a host-side grant flow). Metadata facts, never content - content
1711
2500
  * understanding stays with the knowledge index.
1712
2501
  */
1713
2502
  declare interface KayAgentKnownResource {
@@ -1722,7 +2511,7 @@ declare interface KayAgentKnownResource {
1722
2511
  readonly seenVia: KayAgentKnownResourceSeenVia;
1723
2512
  /**
1724
2513
  * Durable grant provenance (`picked` for a Drive-picker grant). Unlike `seenVia`, a later
1725
- * ordinary sighting never erases it — the row permanently remembers it entered the corpus
2514
+ * ordinary sighting never erases it - the row permanently remembers it entered the corpus
1726
2515
  * through an explicit user grant.
1727
2516
  */
1728
2517
  readonly grantedVia?: string;
@@ -1741,12 +2530,12 @@ declare interface KayAgentKnownResource {
1741
2530
  * (the host-recorded memory that `contributes.uriModules[].knownResources`
1742
2531
  * opts a module's traffic into). Deny-by-default: `api.knownResources` is
1743
2532
  * absent unless the manifest requests the `knownResources` grant AND the host
1744
- * effectively grants it — feature-detect it exactly like
2533
+ * effectively grants it - feature-detect it exactly like
1745
2534
  * {@link KayAgentKnowledgeSearch}, the other WIRING capability. Every call is host-scoped to the plugin's
1746
2535
  * OWN declared module ids; there is no way to widen it. Read-only by design:
1747
2536
  * rows are created only by the host's recording wrap and host-side grant
1748
2537
  * writers, so a plugin can render its memory but never invent it. The ledger
1749
- * is a cache of CLAIMS, not an authority — a returned row proves the resource
2538
+ * is a cache of CLAIMS, not an authority - a returned row proves the resource
1750
2539
  * was once seen, never that it is still reachable.
1751
2540
  */
1752
2541
  declare interface KayAgentKnownResources {
@@ -1776,7 +2565,7 @@ declare interface KayAgentKnownResources {
1776
2565
  * How a known-resource row was MOST RECENTLY seen: one of the recording
1777
2566
  * wrap's verbs, or a host-side grant writer's `granted:<label>` (e.g. a
1778
2567
  * Drive picker completion writing `granted:picked`). The closed template
1779
- * union keeps the contract honest without enumerating grant labels — a
2568
+ * union keeps the contract honest without enumerating grant labels - a
1780
2569
  * plain-string widening here would silently admit junk provenance.
1781
2570
  */
1782
2571
  declare type KayAgentKnownResourceSeenVia = "read" | "list" | "search" | `granted:${string}`;
@@ -1785,7 +2574,7 @@ declare type KayAgentKnownResourceSeenVia = "read" | "list" | "search" | `grante
1785
2574
  * Claim-checked outbound HTTP. The handle is always present; authority is the CALL, not the handle.
1786
2575
  *
1787
2576
  * The signature is `fetch`'s on purpose: a plugin that already speaks `fetch` changes the object it
1788
- * calls, not the code around it. What differs is invisible from here — the host builds an exact
2577
+ * calls, not the code around it. What differs is invisible from here - the host builds an exact
1789
2578
  * `network.connect {connect}` claim from the live URL (and again from each redirect hop), checks it
1790
2579
  * against the user's grant ledger, and rejects with a {@link KayAgentCapabilityError} rather than
1791
2580
  * performing the request. There is no `allowedHosts` to read: a plugin cannot enumerate its own
@@ -1810,13 +2599,19 @@ declare interface KayAgentPluginApi {
1810
2599
  readonly knowledgeSearch?: KayAgentKnowledgeSearch;
1811
2600
  /** Absent unless the `knownResources` grant is requested and effectively granted. */
1812
2601
  readonly knownResources?: KayAgentKnownResources;
2602
+ /**
2603
+ * Optional: absent unless a simulating Bonsai daemon serves this plugin a simulator (SDK 0.18.1).
2604
+ * A production daemon never does. In this version only plugins the release carries are served;
2605
+ * any plugin may ship a `./simulator` later. See {@link KayServedSimulators}.
2606
+ */
2607
+ readonly servedSimulators?: KayServedSimulators;
1813
2608
  /**
1814
2609
  * Present when the host composes Whiteboard. Each operation is checked against its exact
1815
2610
  * `whiteboard.<operation> {scope}` claim; handle presence is not consent.
1816
2611
  */
1817
2612
  readonly whiteboard?: KayAgentWhiteboard;
1818
2613
  /**
1819
- * Always present; each request — and each redirect hop — is checked against
2614
+ * Always present; each request - and each redirect hop - is checked against
1820
2615
  * `network.connect {connect}` for the host it is about to reach.
1821
2616
  */
1822
2617
  readonly network: KayAgentNetwork;
@@ -1847,6 +2642,8 @@ declare interface KayAgentPluginApi {
1847
2642
  * (SDK 0.13.8).
1848
2643
  */
1849
2644
  readonly systemOne: SystemOneClient;
2645
+ /** Always present and ungated; compiles only caller-supplied bytes. SDK 0.18.4. */
2646
+ readonly compiler: KayAgentCompiler;
1850
2647
  /**
1851
2648
  * The daemon's clock and the time zone the user is in, read together on each `snapshot()` call.
1852
2649
  * Always present and ungated: it confers no authority, since a plugin runs in the daemon's
@@ -1869,18 +2666,50 @@ declare interface KayAgentPluginApi {
1869
2666
  */
1870
2667
  readonly events: KayAgentEvents;
1871
2668
  /**
1872
- * Register a tool (a named function the agent can call). Parallel to the kernel's `registerTool`.
1873
- * To auth-gate a tool, build the definition with {@link withResolvedAuth}: it stamps the
1874
- * `requiresAuth` binding onto the definition and resolves a live token from the kernel-injected
1875
- * `ctx.auth` before the body runs — the same wrapper the built-in service tools use. A definition
1876
- * with no `requiresAuth` is an ordinary always-on tool.
2669
+ * A logger whose lines land in Bonsai's own log under this plugin's id, filed on this
2670
+ * activation's session. Always present and ungated, like {@link time}. Use it instead of
2671
+ * `console`; see {@link KayPluginLog}.
2672
+ */
2673
+ readonly log: KayPluginLog;
2674
+ /**
2675
+ * Calls tools on the vendored MCP servers this plugin declares (`kay.app`
2676
+ * `contributes.mcpServers`), signed in through the plugin's own auth service. A port reaches
2677
+ * only this plugin's own server, and only while Bonsai hosts it for this plugin under its
2678
+ * `mcp.host-server` grant; it never reaches another plugin's server or one the user configured.
2679
+ * It calls any tool the server has, writes included. Always present; a host with no MCP host
2680
+ * answers each call `failed`. Types: `@bonsai/plugin-sdk/vendored-mcp` (SDK 0.16.2).
2681
+ */
2682
+ readonly vendoredMcp: KayAgentVendoredMcp;
2683
+ /**
2684
+ * Calls the endpoints this plugin's own `kay.app` part registered and the manifest grants this
2685
+ * target `invoke` on, by local id. Never another plugin's. Every failure is an outcome, never a
2686
+ * rejection; the host fixes a 10-second deadline. Always present; a host with no app part
2687
+ * answers each call `unavailable`. See {@link KayAgentEndpoints} (SDK 0.17.3).
2688
+ */
2689
+ readonly endpoints: KayAgentEndpoints;
2690
+ /**
2691
+ * Supply the `execute` of a tool kay-plugin.json describes (its entry declares `parameters`),
2692
+ * by the entry's `localId`. The host builds the rest of the tool - name, label, description,
2693
+ * parameters, auth binding and permission - from that entry. Build `execute` with
2694
+ * {@link toolExecute}. For a tool declaring `authService`, a session resolves the credential
2695
+ * onto `ctx.credential` before each call (for the account its `accountId` argument names, when
2696
+ * the tool declares one) and never calls `execute` without one; outside a session it may be
2697
+ * absent (SDK 0.20.2).
2698
+ */
2699
+ implementTool(localId: string, execute: KayAgentToolExecute): void;
2700
+ /**
2701
+ * Register a whole tool definition, for a declared tool whose entry has no `parameters` because
2702
+ * part of its policy is code. Such a plugin cannot run in the plugin host; prefer
2703
+ * {@link implementTool}. To auth-gate one, build the definition with {@link withResolvedAuth}
2704
+ * (or `defineAuthedTool`).
1877
2705
  */
1878
2706
  registerTool(definition: ToolDefinition): void;
1879
2707
  /**
1880
2708
  * Register a web search provider (a backend behind the single `web_search` tool). Parallel to the
1881
- * kernel's `registerSearchProvider`. An own-credential provider carries its `requiresAuth` binding —
1882
- * build it with {@link withResolvedSearchProvider}, which stamps the binding and resolves the token
1883
- * from `ctx.auth`. A provider without a binding reuses inference credentials or needs none.
2709
+ * kernel's `registerSearchProvider`. An own-credential provider carries its `requiresAuth` binding -
2710
+ * build it with {@link withResolvedSearchProvider}, which stamps the binding; the host resolves the
2711
+ * credential before each call and hands it to the body. A provider without a binding reuses
2712
+ * inference credentials or needs none.
1884
2713
  */
1885
2714
  registerSearchProvider(provider: SearchProvider): void;
1886
2715
  /**
@@ -1899,23 +2728,34 @@ declare interface KayAgentPluginApi {
1899
2728
  registerConverter(converter: ContentConverter): void;
1900
2729
  /**
1901
2730
  * Always present; the registration is checked against `tool-interception.register`. Register
1902
- * a tool-call interceptor — the neutral around-execution seam over EVERY tool call in the session
2731
+ * a tool-call interceptor - the neutral around-execution seam over EVERY tool call in the session
1903
2732
  * (any layer's tools, subagent sessions included): observe a call, delegate to the real tool via
1904
2733
  * `next()`, or return a substitute result so the real tool never runs. Materially higher
1905
2734
  * privilege than `registerTool` (which owns only its own tool), which is why the registration is
1906
- * a claim of its own. The permission gate still runs before execution — an interceptor can
2735
+ * a claim of its own. The permission gate still runs before execution - an interceptor can
1907
2736
  * substitute results, never widen what is callable.
1908
2737
  */
1909
2738
  interceptToolCall(interceptor: ToolCallInterceptor): void;
2739
+ /**
2740
+ * Sign-in. The plugin's manifest (`auth.services`) declares every service and scheme and the
2741
+ * facts the host shows and runs; plugin code registers only the functions a scheme needs.
2742
+ */
1910
2743
  readonly auth: {
1911
- advertiseService(descriptor: PluginServiceDescriptor): void;
1912
- declareOAuthPkceScheme(serviceId: string, scheme: PluginOAuthPkceScheme): void;
1913
- declareApiKeyScheme(serviceId: string, scheme: PluginApiKeyScheme): void;
1914
- declareExternalCliScheme(serviceId: string, scheme: PluginExternalCliScheme): void;
2744
+ /**
2745
+ * The check for an `api-key` scheme the manifest marks `validates: true`. `serviceId` and
2746
+ * `schemeId` are the manifest's global ids (`github.account`, `github.pat`).
2747
+ */
2748
+ registerValidator(serviceId: string, schemeId: string, validate: ValidatePluginApiKeyCredential): void;
2749
+ /**
2750
+ * The account lookup for an `oauth2` scheme whose manifest names it as where the account comes
2751
+ * from (`account: "resolveAccountId"` or `"resolveAccounts"`), registering that function only.
2752
+ * Refused on any other scheme.
2753
+ */
2754
+ registerAccountResolver(serviceId: string, schemeId: string, resolver: PluginAccountResolver): void;
1915
2755
  /**
1916
2756
  * Declare a delegated scheme (plugin-provided connect/refresh over opaque material) for a
1917
- * service. Mirrors the other three declarations; the host maps it onto the kernel's
1918
- * `DelegatedAuthScheme` and drives its `connect` from `service_connect`.
2757
+ * service. The host maps it onto the kernel's `DelegatedAuthScheme` and drives its `connect`
2758
+ * from `service_connect`.
1919
2759
  */
1920
2760
  declareDelegatedScheme(serviceId: string, scheme: PluginDelegatedScheme): void;
1921
2761
  /**
@@ -1935,7 +2775,7 @@ declare interface KayAgentPluginApi {
1935
2775
  * {@link KayAgentProcessRunResult.exitCode} always means the command itself failed, never that
1936
2776
  * permission did. Two DIFFERENT things reject, and a caller should handle both: a refusal rejects
1937
2777
  * with {@link KayAgentCapabilityError}, and cancelling through
1938
- * {@link KayAgentProcessRunRequest.signal} rejects with an `AbortError` carrying a fixed message —
2778
+ * {@link KayAgentProcessRunRequest.signal} rejects with an `AbortError` carrying a fixed message -
1939
2779
  * the host terminates the child and settles its output first, and deliberately does not echo back
1940
2780
  * the `reason` you aborted with. A user cancelling a run is not a crash. A timeout is NOT a
1941
2781
  * rejection: it resolves with exit code 124. The termination bound covers the DIRECT child only: a
@@ -1959,12 +2799,12 @@ declare interface KayAgentProcessRunRequest {
1959
2799
  readonly command: string;
1960
2800
  readonly argvClass: string;
1961
2801
  readonly args: readonly string[];
1962
- /** Abort the run; the host kills the DIRECT child and rejects — a forked descendant may outlive it (#6153). */
2802
+ /** Abort the run; the host kills the DIRECT child and rejects - a forked descendant may outlive it (#6153). */
1963
2803
  readonly signal?: AbortSignal;
1964
2804
  }
1965
2805
 
1966
2806
  /**
1967
- * A finished run. `stdout`/`stderr` are decoded text, and the host CAPS them — a truncation flag is
2807
+ * A finished run. `stdout`/`stderr` are decoded text, and the host CAPS them - a truncation flag is
1968
2808
  * set rather than the output silently ending, so a plugin parsing the stream can tell "the command
1969
2809
  * printed this" apart from "the command printed more than we kept".
1970
2810
  */
@@ -1976,6 +2816,28 @@ declare interface KayAgentProcessRunResult {
1976
2816
  readonly stderrTruncated?: boolean;
1977
2817
  }
1978
2818
 
2819
+ /** The `execute` a plugin supplies for a tool its manifest describes. */
2820
+ declare type KayAgentToolExecute = ToolDefinition["execute"];
2821
+
2822
+ /**
2823
+ * Calls tools on the plugin's own vendored MCP servers. See {@link KayAgentPluginApi.vendoredMcp}.
2824
+ */
2825
+ declare interface KayAgentVendoredMcp {
2826
+ /**
2827
+ * The port to `server`, a name this plugin declares in its `kay.app` target's
2828
+ * `contributes.mcpServers`. Throws when the plugin declares no server of that name. A declared
2829
+ * server that Bonsai does not host for this plugin still returns a port; each call then answers
2830
+ * `unknown-server`. Its message names the plugin that holds the name, or else lists the possible
2831
+ * reasons (no approved `mcp.host-server` grant, a sign-in the server cannot use, or a name that
2832
+ * a plugin Bonsai ships or another installed plugin also claims) and points at the plugin's load
2833
+ * diagnostic.
2834
+ *
2835
+ * A port reaches this plugin's own server only. To use another plugin's data, declare that
2836
+ * plugin in the manifest's `dependencies.plugins`; a later SDK surface reaches it.
2837
+ */
2838
+ port<TTool extends string = string>(server: string): VendoredMcpPort<TTool>;
2839
+ }
2840
+
1979
2841
  /**
1980
2842
  * Authenticated requests through the host's embedded-browser partition. The host confines every
1981
2843
  * call to the exact origin/path rows declared in the plugin manifest (segment-bounded), never
@@ -2094,7 +2956,7 @@ declare interface KayAgentWhiteboardUpdateInput {
2094
2956
  /**
2095
2957
  * `app.time` / `api.time`: host facts about time. Added to `kay.app` in SDK 0.12.1 and to
2096
2958
  * `kay.agent` with the calendar zone-of-record work: a plugin that calls it declares
2097
- * `compatibility.sdk` `^0.12.1`, so an older Bonsai refuses a directory or repository plugin at
2959
+ * `compatibility.sdk` `^0.19.0`, so an older Bonsai refuses a directory or repository plugin at
2098
2960
  * load instead of the call failing.
2099
2961
  */
2100
2962
  declare interface KayAppTime {
@@ -2104,9 +2966,7 @@ declare interface KayAppTime {
2104
2966
  * Every call asks the host again and returns a new object; nothing is cached. Call it where you
2105
2967
  * need the value (inside a tool, a handler or a workflow step), not inside `activate()`: a value
2106
2968
  * read there is as old as the activation, and the host can run a bundled plugin's `activate()`
2107
- * against a recording api that has no `time`, so a read there throws. The exception is a
2108
- * directory plugin that declares a workflow with a cron `timezone`: `workflows.define` is legal
2109
- * only during `activate()`, so it reads the zone there, and the schedule then keeps that zone.
2969
+ * against a recording api that has no `time`, so a read there throws.
2110
2970
  * Keep the result for as long as you use it, and not across a long wait (a sleep, a timer, a
2111
2971
  * queued run): the zone can change while you wait. On a daemon that runs on the user's machine,
2112
2972
  * a change of the process's `TZ` shows in the next call. A `TZ` that names a zone wins over the
@@ -2197,7 +3057,7 @@ declare interface KayAppUserFileListing {
2197
3057
  * File I/O in user folders, run by the host off the daemon's main thread. Every path is absolute.
2198
3058
  * No method rejects; each answers a {@link KayAppUserFilesResult}. This is not a sandbox: it does
2199
3059
  * not limit which paths a plugin may touch. Added in SDK 0.12.5: a plugin that calls it declares
2200
- * `compatibility.sdk` `^0.12.5`, so an older Bonsai refuses a directory or repository plugin at
3060
+ * `compatibility.sdk` `^0.19.0`, so an older Bonsai refuses a directory or repository plugin at
2201
3061
  * load instead of the call failing.
2202
3062
  */
2203
3063
  declare interface KayAppUserFiles {
@@ -2293,6 +3153,119 @@ declare interface KayAppUserFileWalkEntry {
2293
3153
  readonly kind: KayAppUserFileKind;
2294
3154
  }
2295
3155
 
3156
+ declare interface KayBrowserBundle {
3157
+ readonly outputs: readonly {
3158
+ readonly path: string;
3159
+ readonly text: string;
3160
+ }[];
3161
+ readonly warnings: readonly string[];
3162
+ }
3163
+
3164
+ declare interface KayBrowserBundleRequest {
3165
+ readonly entry: {
3166
+ readonly path: string;
3167
+ } | {
3168
+ readonly path: string;
3169
+ readonly contents: string;
3170
+ readonly loader: "js" | "css";
3171
+ };
3172
+ readonly target: string;
3173
+ readonly format: "iife" | "esm";
3174
+ readonly charset: "ascii" | "utf8";
3175
+ readonly minifyWhitespace: boolean;
3176
+ readonly legalComments: "none" | "inline";
3177
+ }
3178
+
3179
+ /** Import edges the host reports to a browser bundle's source resolver. */
3180
+ declare type KayBrowserImportKind = "entry-point" | "import-statement" | "require-call" | "dynamic-import" | "require-resolve" | "import-rule" | "composes-from" | "url-token";
3181
+
3182
+ /** All imports and bytes come from these callbacks; the host performs no fallback I/O. */
3183
+ declare interface KayBrowserSources {
3184
+ resolve(request: {
3185
+ readonly path: string;
3186
+ readonly importer: string;
3187
+ readonly kind: KayBrowserImportKind;
3188
+ }): Promise<{
3189
+ readonly path: string;
3190
+ readonly external?: boolean;
3191
+ readonly suffix?: string;
3192
+ }>;
3193
+ load(request: {
3194
+ readonly path: string;
3195
+ }): Promise<{
3196
+ readonly contents: string | Uint8Array;
3197
+ readonly loader: "js" | "css" | "json" | "dataurl";
3198
+ }>;
3199
+ }
3200
+
3201
+ /**
3202
+ * Each method writes one line. `name` is a stable event name (`sync-failed`), the same for every
3203
+ * line of one kind, so the line can be found by name; put what varies in `message` and
3204
+ * `attributes`. A call never throws, and it keeps working after the plugin is disabled.
3205
+ */
3206
+ declare interface KayPluginLog {
3207
+ debug(name: string, message: string, details?: KayPluginLogDetails): void;
3208
+ info(name: string, message: string, details?: KayPluginLogDetails): void;
3209
+ warn(name: string, message: string, details?: KayPluginLogDetails): void;
3210
+ error(name: string, message: string, details?: KayPluginLogDetails): void;
3211
+ /** A logger that adds these attributes to every line it writes, after the line's own. */
3212
+ child(attributes: KayPluginLogAttributes): KayPluginLog;
3213
+ }
3214
+
3215
+ /**
3216
+ * The plugin-facing log contract: a logger each plugin gets as `api.log`, whose lines land in
3217
+ * Bonsai's own log beside the daemon's.
3218
+ *
3219
+ * Ungated and always present, like `api.time`. It confers no authority: a line is written under the
3220
+ * plugin's own id, which the host stamps and the plugin cannot set, and a plugin can already print
3221
+ * to the console. The host records each line as `<pluginId>.<name>`, files it on a session's log
3222
+ * when it knows the session, and keeps an error's stack, so a built-in plugin's failure reaches
3223
+ * Error Tracking. Lines from a plugin the user added stay on the user's machine.
3224
+ *
3225
+ * This is a leaf module. It lives beside both target SDKs (rather than inside `kay-app`) so the
3226
+ * `kay.agent` SDK can expose the same logger without importing the `kay.app` surface.
3227
+ */
3228
+ /**
3229
+ * Metadata only: ids, closed values, counts. Never session content. The host drops any value that
3230
+ * is not a string, a boolean or a finite number.
3231
+ */
3232
+ declare type KayPluginLogAttributes = Readonly<Record<string, string | number | boolean>>;
3233
+
3234
+ declare interface KayPluginLogDetails {
3235
+ /** The error object. The host keeps its message, its stack and its `cause` chain. */
3236
+ readonly error?: unknown;
3237
+ /**
3238
+ * The session this line is about. Defaults to the session of the call the plugin is handling,
3239
+ * when the host knows it (a tool call or a URI read); the line then lands on that session's
3240
+ * `kay-log://events`. Pass it from an endpoint, a session-event handler or a timer. Work a call
3241
+ * starts (a timer, a subscription) keeps that call's session unless a line names another.
3242
+ */
3243
+ readonly sessionId?: string;
3244
+ readonly attributes?: KayPluginLogAttributes;
3245
+ }
3246
+
3247
+ declare const KayPluginProtocolVersion: z.ZodLiteral<"kay.plugin.v1">;
3248
+
3249
+ declare type KayPluginProtocolVersion = z.infer<typeof KayPluginProtocolVersion>;
3250
+
3251
+ /**
3252
+ * The simulators a simulating Bonsai daemon (evals, dev, tests) serves this plugin, keyed by the
3253
+ * adapter id its simulated URI connection rows name. The daemon builds each from the plugin's own
3254
+ * dev-only `./simulator` subpath; the plugin never imports its simulator.
3255
+ *
3256
+ * The member that carries this, `servedSimulators` on both plugin APIs, is optional and absent
3257
+ * unless a simulating daemon serves it. A production daemon never does, so treat absence as the
3258
+ * normal case. In this version the daemon serves it only to plugins the release carries; the seam
3259
+ * is not specific to them, and any plugin may ship a `./simulator` later.
3260
+ */
3261
+ declare interface KayServedSimulators {
3262
+ /**
3263
+ * What this plugin's simulator built for `adapterId`, or `undefined` when none was served for
3264
+ * that id. The shape is the plugin's own simulator contract; narrow it before use.
3265
+ */
3266
+ get(adapterId: string): unknown;
3267
+ }
3268
+
2296
3269
  /** Applies a KeyOf action to the given type. */
2297
3270
  declare function KeyOf<Type extends TSchema>(type: Type, options?: TSchemaOptions): TKeyOf_2<Type>;
2298
3271
 
@@ -2398,6 +3371,10 @@ declare function LiteralStringMapping(input: string): unknown;
2398
3371
 
2399
3372
  declare function LiteralTypeName<Value extends TLiteralValue>(value: Value): TLiteralTypeName<Value>;
2400
3373
 
3374
+ declare const LocalContributionId: z.ZodString;
3375
+
3376
+ declare type LocalContributionId = z.infer<typeof LocalContributionId>;
3377
+
2401
3378
  /** Applies a Lowercase action to the given type. */
2402
3379
  declare function Lowercase_2<Type extends TSchema>(type: Type, options?: TSchemaOptions): TLowercase<Type>;
2403
3380
 
@@ -2471,7 +3448,7 @@ declare type MidTurnCompactionRequest = {
2471
3448
  * Settles exactly once and never rejects, including abort and teardown paths.
2472
3449
  *
2473
3450
  * NEVER `await` this inside `execute`. The only thing that settles it is
2474
- * post-run compaction, and that cannot begin until this tool call returns —
3451
+ * post-run compaction, and that cannot begin until this tool call returns -
2475
3452
  * so awaiting it here hangs the run behind itself, which is the exact
2476
3453
  * deadlock this capability replaced. Attach a callback and return.
2477
3454
  */
@@ -2481,6 +3458,10 @@ declare type MidTurnCompactionRequest = {
2481
3458
  readonly reason: "already-pending" | "maintenance-in-flight";
2482
3459
  };
2483
3460
 
3461
+ declare const MimeTypeString: z.ZodString;
3462
+
3463
+ declare type MimeTypeString = z.infer<typeof MimeTypeString>;
3464
+
2484
3465
  /** Compatibility settings for the Mistral chat API. */
2485
3466
  declare interface MistralConversationsCompat extends Static<typeof MistralConversationsCompatSchema> {
2486
3467
  }
@@ -2516,7 +3497,7 @@ declare interface Model<TApi extends Api> extends BaseModel<TApi> {
2516
3497
  }
2517
3498
 
2518
3499
  /**
2519
- * The canonical model-facing content type — the single source of truth for what
3500
+ * The canonical model-facing content type - the single source of truth for what
2520
3501
  * a `read`/`finalize` boundary emits and what an {@link AgentToolResult.content}
2521
3502
  * carries (it IS the same `(TextContent | ImageContent)` union). When pi-ai later
2522
3503
  * adds audio, this one alias widens and every consumer follows.
@@ -2601,6 +3582,8 @@ declare const NeverPattern = "(?!)";
2601
3582
 
2602
3583
  declare const NewLine = "\n";
2603
3584
 
3585
+ declare const NonEmptyString: z.ZodString;
3586
+
2604
3587
  /** Applies a NonNullable action to the given type. */
2605
3588
  declare function NonNullable_2<Type extends TSchema>(type: Type, options?: TSchemaOptions): TNonNullable<Type>;
2606
3589
 
@@ -2622,33 +3605,12 @@ declare const NumberKey = "^-?(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?$";
2622
3605
 
2623
3606
  declare const NumberPattern = "-?(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?";
2624
3607
 
2625
- /**
2626
- * Who may supply the OAuth client for a scheme: Bonsai's embedded client, or one the user pastes in
2627
- * (BYOOC). An UNORDERED SET — list order carries no meaning (nothing reads it as a preference).
2628
- */
2629
- declare type OAuthClientSupplier = "kay" | "user";
2630
-
2631
3608
  /** What the provider hands back at the redirect URI after the user approves. */
2632
3609
  declare interface OAuthRedirectResult {
2633
3610
  readonly code: string;
2634
3611
  readonly state: string;
2635
3612
  }
2636
3613
 
2637
- /**
2638
- * The two client-supply axes, structured so the illegal cell is unrepresentable: a `confidential`
2639
- * exchange's secret may only ever be Bonsai's (held by the host's broker, never pasted by a
2640
- * customer), so `confidential` types `clientSuppliers` as `readonly ["kay"]` — `confidential ×
2641
- * user` is a compile-time impossibility in v1, not a runtime refusal. `pkce`'s `clientSuppliers`
2642
- * is a non-empty set; {@link createOAuthPkceAuthScheme} dedupes it and refuses empty.
2643
- */
2644
- declare type OAuthSchemeClientAxes = {
2645
- readonly exchange: "pkce";
2646
- readonly clientSuppliers: readonly OAuthClientSupplier[];
2647
- } | {
2648
- readonly exchange: "confidential";
2649
- readonly clientSuppliers: readonly ["kay"];
2650
- };
2651
-
2652
3614
  /** Creates an Object type. */
2653
3615
  declare function _Object_<Properties extends TProperties>(properties: Properties, options?: TObjectOptions): TObject<Properties>;
2654
3616
 
@@ -2667,6 +3629,79 @@ declare type ObjectLike_4 = Record<PropertyKey, any>;
2667
3629
  /** Extracts options from a TObject. */
2668
3630
  declare function ObjectOptions(type: TObject): TObjectOptions;
2669
3631
 
3632
+ /**
3633
+ * A source-native read of one URI, shaped for downstream indexing rather than
3634
+ * direct model consumption. A module's read returns it in
3635
+ * `RawResource.observations`, built from the same fetch as the content, once
3636
+ * per document it wants indexed; absence means "not indexed".
3637
+ *
3638
+ * Gone signal: the index retires a doc when a read throws `UriNotFoundError`
3639
+ * or an error whose `.status === 404`. A module whose vendor signals "gone"
3640
+ * differently (HTTP 410, a 200-body `{ok:false}`/`archived:true`, a
3641
+ * 403/404-ambiguous lost-access response) must translate that into one of
3642
+ * those two shapes itself; losing access to a resource counts as gone too.
3643
+ * A read that cannot build a complete observation (a secondary fetch failed)
3644
+ * returns none rather than a partial one.
3645
+ *
3646
+ * Account-qualified identity: a module whose read can resolve against more
3647
+ * than one connected account (the account selector is stripped before route
3648
+ * parsing, so two accounts reading the same opaque provider id would
3649
+ * otherwise collide on one doc key) must fold `ctx.auth.credential.accountId`
3650
+ * into `uri` - e.g. `gmail://@<accountId>/threads/<threadId>` - never the
3651
+ * user-renamable connection/selector label. `ctx.auth.credential` is the
3652
+ * reliable source of the resolved account at a `requiresAuth` module's
3653
+ * `read()`: it is always populated once auth resolution runs (an
3654
+ * `authContext`-style check already throws first when no credential
3655
+ * resolved). `ctx.connection` may ALSO be populated by dispatch - a
3656
+ * connection-required module receives it whenever the host has a tracked
3657
+ * connection for the account - so do not assume it is absent; a module that
3658
+ * wants the human-facing label rather than the account id reads
3659
+ * `ctx.connection?.displayName`.
3660
+ *
3661
+ * `accountId` is guaranteed stable only for the life of the stored credential
3662
+ * record, not necessarily across a disconnect/reconnect of the same
3663
+ * real-world provider account. A scheme that mints an opaque id at connect
3664
+ * time (the default for an api-key or delegated scheme, absent a
3665
+ * provider-derived override) gets a fresh id on every connect; a scheme that
3666
+ * instead derives the id from provider data (an oauth2-pkce scheme supplying
3667
+ * `resolveAccountId`, e.g. reading an OIDC `sub`) keeps the same id across
3668
+ * reconnect. A module on a scheme without a provider-stable id has two honest
3669
+ * choices: derive its own stable identity from provider data at read time
3670
+ * (call the provider's own account/"who am I" endpoint with the resolved
3671
+ * credential and fold THAT into `uri` instead of `accountId`), or
3672
+ * account-qualify with `accountId` knowing a disconnect/reconnect of the same
3673
+ * real-world account re-keys its documents under a new id rather than
3674
+ * updating them in place - nothing on the host side reconciles the old and
3675
+ * new keys.
3676
+ */
3677
+ declare interface ObservationMaterial {
3678
+ /** Canonical URI of the observed resource - may differ from the input URI. */
3679
+ readonly uri: string;
3680
+ /** Scheme-prefixed content type, e.g. `"github.pr"`, `"gmail.thread"`, `"wikipedia.article"`. */
3681
+ readonly kind: string;
3682
+ readonly title?: string;
3683
+ /** Source-native seams: one element per message/comment/section, in source order. */
3684
+ readonly text?: readonly string[];
3685
+ /** ISO-8601 creation time; provenance only - not persisted by the store yet. */
3686
+ readonly createdAt?: string;
3687
+ /** ISO-8601 last-update time; provenance only - not persisted by the store yet. */
3688
+ readonly updatedAt?: string;
3689
+ /** Source-native revision/version marker, when the source exposes one. */
3690
+ readonly version?: string;
3691
+ /**
3692
+ * How long this resource stays worth semantically searching, measured from
3693
+ * the LAST time it was observed - not from when it was first indexed. Every
3694
+ * observation of an unchanged resource pushes the deadline out again, so a
3695
+ * thread that keeps getting read keeps living and a quiet one ages out.
3696
+ *
3697
+ * Retention is opt-in per resource: absent means the index keeps the
3698
+ * resource until its source says it is gone. A route declares this only
3699
+ * when staleness is real for that shape - a chat thread or an inbox
3700
+ * conversation goes cold, a durable note the user wrote does not.
3701
+ */
3702
+ readonly retainForMs?: number;
3703
+ }
3704
+
2670
3705
  /** Applies a Omit action using the given types. */
2671
3706
  declare function Omit_2<Type extends TSchema, Indexer extends PropertyKey[]>(type: Type, indexer: readonly [...Indexer], options?: TSchemaOptions): TOmit<Type, TKeysToIndexer<Indexer>>;
2672
3707
 
@@ -2789,6 +3824,10 @@ declare const OptionalSemiColon: (input: string) => [unknown, string] | [];
2789
3824
 
2790
3825
  declare function OptionalSemiColonMapping(input: [unknown] | []): unknown;
2791
3826
 
3827
+ declare const PackageAssetPath: z.ZodString;
3828
+
3829
+ declare type PackageAssetPath = z.infer<typeof PackageAssetPath>;
3830
+
2792
3831
  /** Creates a Parameter type. */
2793
3832
  declare function Parameter<Name extends string, Extends extends TSchema, Equals extends TSchema>(name: Name, extends_: Extends, equals: Equals): TParameter<Name, Extends, Equals>;
2794
3833
 
@@ -3156,32 +4195,15 @@ declare function Pick_2<Type extends TSchema, Indexer extends TSchema>(type: Typ
3156
4195
  /** Creates a deferred Pick action. */
3157
4196
  declare function PickDeferred<Type extends TSchema, Indexer extends TSchema>(type: Type, indexer: Indexer, options?: TSchemaOptions): TPickDeferred<Type, Indexer>;
3158
4197
 
3159
- declare interface PluginApiKeyScheme {
3160
- readonly id: string;
3161
- /** Human-facing flow name; distinguish the key's purpose when sibling flows exist. */
3162
- readonly displayName: string;
3163
- /** What this flow unlocks and when to choose it over another. */
3164
- readonly agentHint?: PluginSchemeAgentHint;
3165
- /** What this flow unlocks, for the person: one plain sentence, no identifiers or URIs. */
3166
- readonly summary?: string;
3167
- readonly inputLabel: string;
3168
- /**
3169
- * Two or more labeled inputs for an irreducibly multi-part secret (e.g. a Cloudflare Access
3170
- * service token's client-id + client-secret pair). The connect prompt collects one value per
3171
- * field; handlers read them from `ctx.auth.credential.fields`, keyed by field id. Index 0 is
3172
- * the primary field (mirrored as `accessToken`). Absent means the classic single-secret prompt;
3173
- * when present, ids must be unique and non-empty and there must be at least two entries — the
3174
- * kernel rejects an invalid declaration at activation.
3175
- */
3176
- readonly fields?: readonly PluginApiKeySchemeField[];
3177
- readonly setup?: PluginApiKeySchemeSetup;
3178
- readonly validate?: ValidatePluginApiKeyCredential;
4198
+ /**
4199
+ * How a plugin learns which provider account a fresh OAuth token belongs to: one account, or every
4200
+ * account the grant reaches. Registered with `api.auth.registerAccountResolver`.
4201
+ */
4202
+ declare interface PluginAccountResolver {
4203
+ readonly resolveAccountId?: ResolvePluginAccountId;
4204
+ readonly resolveAccounts?: ResolvePluginAccounts;
3179
4205
  }
3180
4206
 
3181
- declare type PluginApiKeySchemeField = ApiKeyAuthSchemeField;
3182
-
3183
- declare type PluginApiKeySchemeSetup = ApiKeyAuthSchemeSetup;
3184
-
3185
4207
  /** The kinds of capability a plugin service can advertise (mirrors the host capability taxonomy). */
3186
4208
  declare type PluginCapabilityKind = "uri-module" | "tool" | "search-provider";
3187
4209
 
@@ -3198,12 +4220,12 @@ declare interface PluginDelegatedRevokeContext {
3198
4220
  }
3199
4221
 
3200
4222
  /**
3201
- * A protocol-agnostic scheme whose connect/refresh choreography the plugin provides — the host owns
4223
+ * A protocol-agnostic scheme whose connect/refresh choreography the plugin provides - the host owns
3202
4224
  * only vault persistence, gating, and single-flight refresh over the opaque material. Use this when
3203
4225
  * the auth dance is not a fixed OAuth-PKCE shape the host can drive itself (e.g. a runtime-discovered
3204
- * authorization server: 401 sniff → RFC 9728/8414 discovery → RFC 7591 dynamic client registration →
4226
+ * authorization server: 401 sniff -> RFC 9728/8414 discovery -> RFC 7591 dynamic client registration ->
3205
4227
  * PKCE). `connect` receives the host's browser-redirect capability (`ctx.redirectUri`/`ctx.authorize`)
3206
- * when one is configured, and both are absent when the host has none — the scheme decides whether it
4228
+ * when one is configured, and both are absent when the host has none - the scheme decides whether it
3207
4229
  * needs them and fails its connect with an actionable message if it does and they are missing.
3208
4230
  */
3209
4231
  declare interface PluginDelegatedScheme {
@@ -3253,83 +4275,18 @@ declare const PluginEventPublishInput: z.ZodObject<{
3253
4275
  poller: z.ZodOptional<z.ZodString>;
3254
4276
  runId: z.ZodOptional<z.ZodString>;
3255
4277
  }, z.core.$strict>>;
3256
- payload: z.ZodOptional<z.ZodType<JsonValue_2, unknown, z.core.$ZodTypeInternals<JsonValue_2, unknown>>>;
4278
+ payload: z.ZodOptional<z.ZodType<authoringCommonSchemas.JsonValue, unknown, z.core.$ZodTypeInternals<authoringCommonSchemas.JsonValue, unknown>>>;
3257
4279
  }, z.core.$strict>;
3258
4280
 
3259
4281
  declare type PluginEventPublishInput = z.infer<typeof PluginEventPublishInput>;
3260
4282
 
3261
- /**
3262
- * An external-CLI readiness scheme the plugin declares: a non-injectable marker for a
3263
- * host-probed local binary (e.g. `osascript`, `gh`). Connecting runs `binary probeArgs`
3264
- * through the host's bounded spawn — success mints a readiness record, never token
3265
- * material. Verb handlers gated on such a scheme receive `ctx.auth.externalCli`, a
3266
- * host-owned runner pinned to the declared binary; the plugin itself never spawns.
3267
- * The manifest twin must declare the binary under `permissions.byTarget["agent.harness"].process`.
3268
- */
3269
- declare interface PluginExternalCliScheme {
3270
- readonly id: string;
3271
- readonly displayName: string;
3272
- /** What this flow unlocks and when to choose it over another. */
3273
- readonly agentHint?: PluginSchemeAgentHint;
3274
- /** What this flow unlocks, for the person: one plain sentence, no identifiers or URIs. */
3275
- readonly summary?: string;
3276
- /** The local binary the host probes and runs (bare name resolved on PATH, or absolute). */
3277
- readonly binary: string;
3278
- /** Argv for the readiness probe; exit 0 means connected. */
3279
- readonly probeArgs: readonly string[];
3280
- /** Optional argv whose stdout is recorded as the CLI version on connect. */
3281
- readonly versionArgs?: readonly string[];
3282
- /** Probe/run timeout; the host default applies when absent. */
3283
- readonly timeoutMs?: number;
3284
- /** Actionable copy when the binary is missing (install path, platform requirement). */
3285
- readonly installHint: string;
3286
- /** Actionable copy when the probe fails (login step, OS permission grant). */
3287
- readonly loginHint: string;
3288
- }
4283
+ declare const PluginId: z.ZodString;
3289
4284
 
3290
- /**
3291
- * An OAuth2-PKCE scheme the plugin declares. The host owns acquisition, refresh, and broker
3292
- * routing; the plugin supplies only public metadata plus an optional account-id resolver.
3293
- *
3294
- * Intersects {@link PluginOAuthSchemeClientAxes} (BYOOC — bring-your-own-OAuth-client):
3295
- * `clientId`/`clientSecret` are optional and mean ONLY "the Kay-supplied embedded client" —
3296
- * present iff `exchange: "pkce"` and the host ships one. A `confidential` scheme never carries
3297
- * them; that secret lives with the host's broker, never with the plugin.
3298
- */
3299
- declare type PluginOAuthPkceScheme = PluginOAuthSchemeClientAxes & {
3300
- readonly id: string;
3301
- readonly displayName: string;
3302
- /** What this flow unlocks and when to choose it over another. */
3303
- readonly agentHint?: PluginSchemeAgentHint;
3304
- /** What this flow unlocks, for the person: one plain sentence, no identifiers or URIs. */
3305
- readonly summary?: string;
3306
- readonly authorizationUrl: string;
3307
- readonly tokenUrl: string;
3308
- /** The Bonsai-supplied embedded client id; omit for a `confidential` scheme or a `pkce` scheme
3309
- * the host ships no client for. */
3310
- readonly clientId?: string;
3311
- /**
3312
- * An embedded, **non-confidential** client secret for a broker-free PKCE scheme — the case where a
3313
- * desktop-app OAuth client requires `client_secret` at the token endpoint but the secret is public
3314
- * by design (e.g. Google installed-app clients). Omit for brokered schemes, where the confidential
3315
- * secret lives in the broker and never reaches the plugin. A scheme is broker-free purely by virtue
3316
- * of its `id` not being in the host's brokered-scheme map; supplying this never routes it anywhere.
3317
- */
3318
- readonly clientSecret?: string;
3319
- readonly scopes: readonly string[];
3320
- /** Extra params merged into the authorize query. */
3321
- readonly extraAuthorizeParams?: Readonly<Record<string, string>>;
3322
- readonly resolveAccountId?: ResolvePluginAccountId;
3323
- /**
3324
- * Enumerate every provider account a fresh OAuth grant powers. Present only for providers whose
3325
- * consent can grant multiple accounts; the host commits one account binding per result while
3326
- * keeping one shared token lifecycle.
3327
- */
3328
- readonly resolveAccounts?: ResolvePluginAccounts;
3329
- };
4285
+ declare type PluginId = z.infer<typeof PluginId>;
4286
+
4287
+ declare const PluginNamespace: z.ZodString;
3330
4288
 
3331
- /** BYOOC — the herd canonical client-axes union, aliased (never copied) for plugin authors. */
3332
- declare type PluginOAuthSchemeClientAxes = OAuthSchemeClientAxes;
4289
+ declare type PluginNamespace = z.infer<typeof PluginNamespace>;
3333
4290
 
3334
4291
  /** What one connection flow unlocks and when an agent should choose it; grants no authority. */
3335
4292
  declare type PluginSchemeAgentHint = string;
@@ -3341,7 +4298,7 @@ declare interface PluginServiceCapability {
3341
4298
  readonly summary: string;
3342
4299
  }
3343
4300
 
3344
- /** A service the plugin owns — advertised for discovery and used to gate auth-backed contributions. */
4301
+ /** A service the plugin owns - advertised for discovery and used to gate auth-backed contributions. */
3345
4302
  declare interface PluginServiceDescriptor {
3346
4303
  readonly id: string;
3347
4304
  readonly display: string;
@@ -3349,6 +4306,28 @@ declare interface PluginServiceDescriptor {
3349
4306
  readonly capabilities: readonly PluginServiceCapability[];
3350
4307
  }
3351
4308
 
4309
+ declare const PluginSourceClass: z.ZodEnum<{
4310
+ bundled: "bundled";
4311
+ "org-shared": "org-shared";
4312
+ "user-local": "user-local";
4313
+ "verified-marketplace": "verified-marketplace";
4314
+ freeform: "freeform";
4315
+ }>;
4316
+
4317
+ declare type PluginSourceClass = z.infer<typeof PluginSourceClass>;
4318
+
4319
+ declare const PluginTargetName: z.ZodEnum<{
4320
+ "kay.agent": "kay.agent";
4321
+ "kay.app": "kay.app";
4322
+ "kay.ui": "kay.ui";
4323
+ }>;
4324
+
4325
+ declare type PluginTargetName = z.infer<typeof PluginTargetName>;
4326
+
4327
+ declare const PluginToolName: z.ZodString;
4328
+
4329
+ declare type PluginToolName = z.infer<typeof PluginToolName>;
4330
+
3352
4331
  /**
3353
4332
  * What a run did to a URI. The words match the automation run wire's artifact actions. When one
3354
4333
  * run both creates and updates a URI, the reader reports `created`.
@@ -3357,7 +4336,7 @@ declare type ProducedResourceAction = "created" | "updated";
3357
4336
 
3358
4337
  /** One URI a tool call created or updated as a side effect. */
3359
4338
  declare interface ProducedResourceDeclaration {
3360
- /** A `scheme://…` URI or an absolute local file path, compared as an exact string. */
4339
+ /** A `scheme://...` URI or an absolute local file path, compared as an exact string. */
3361
4340
  readonly uri: string;
3362
4341
  readonly action: ProducedResourceAction;
3363
4342
  }
@@ -3454,7 +4433,7 @@ declare type ProviderId = KnownProvider | string;
3454
4433
  declare interface ProxiedToolCall {
3455
4434
  /** The registered tool the carrier will invoke. */
3456
4435
  readonly toolName: string;
3457
- /** The input that tool will be invoked with — what the gate must classify. */
4436
+ /** The input that tool will be invoked with - what the gate must classify. */
3458
4437
  readonly input: Record<string, unknown>;
3459
4438
  }
3460
4439
 
@@ -3464,6 +4443,28 @@ declare interface RawResource {
3464
4443
  readonly mimeType: string;
3465
4444
  readonly metadata?: RawResourceMetadata;
3466
4445
  readonly selector?: SelectorDisposition;
4446
+ /**
4447
+ * The indexable forms of this resource, built from the same fetch as
4448
+ * `content`: one per document the read wants indexed (a thread read offers
4449
+ * one per message). Absent or empty means nothing is indexed. The read tool
4450
+ * takes them off before the cache and the model; other host reads
4451
+ * (out-of-band host reads) return them untouched.
4452
+ */
4453
+ readonly observations?: readonly ObservationMaterial[];
4454
+ /** How long the host may cache this result; see {@link UriCachePolicy.ttlMs}. */
4455
+ readonly cachePolicy?: Pick<UriCachePolicy, "ttlMs">;
4456
+ /**
4457
+ * A short name for the resource this call touched, for the transcript row; absent shows the
4458
+ * address. Render-only: the host stamps it on the tool result's `details`, never in `content`.
4459
+ */
4460
+ readonly label?: UriResourceLabel;
4461
+ /**
4462
+ * Answer to a `read` called with `ctx.knownRevision`: the module checked the source's current
4463
+ * revision and it equals `knownRevision`, so `content` is empty and `metadata.revision` equals
4464
+ * `knownRevision`. Set it only when that check was made and matched; a module that cannot
4465
+ * check cheaply, or that found a different revision, returns the full resource without it.
4466
+ */
4467
+ readonly unchanged?: true;
3467
4468
  }
3468
4469
 
3469
4470
  declare interface RawResourceCacheControl {
@@ -3507,7 +4508,7 @@ declare interface RawResourceMetadata {
3507
4508
  readonly resourceIdentity?: RawResourceIdentity;
3508
4509
  /**
3509
4510
  * The resource's stable public address when `uri` reports something more
3510
- * specific than the address a consumer names it by — a retained revision
4511
+ * specific than the address a consumer names it by - a retained revision
3511
4512
  * (`skill://<id>/@revision/<version>`) served for a `skill://<source>/<name>`
3512
4513
  * read. Present only when the two differ. Consumers that attribute by name
3513
4514
  * (the read tool's `skillName` detail, and everything keyed off it) read
@@ -3582,6 +4583,29 @@ declare function Refine<Type extends TSchema, Value = Static<Type>>(type: Type,
3582
4583
  /** Applies a Refine check to the given type. */
3583
4584
  declare function RefineAdd<Type extends TSchema>(type: Type, refinement: TRefinement<Type>): TRefineAdd<Type>;
3584
4585
 
4586
+ /**
4587
+ * The web-session scope-confinement refinement, coined ONCE and shared by both
4588
+ * web-session boundaries: `loginUrl` and `probe.url` must each fall within a
4589
+ * declared `cookieDomains` entry. The manifest boundary
4590
+ * (`PluginWebSessionDeclaration`) enforces it because those URLs are
4591
+ * authenticated-navigation/request primitives a third-party manifest hands the
4592
+ * host; the resolved/wire boundary (`ResolvedPluginWebSession`) re-runs the SAME
4593
+ * check rather than trust it survived resolution (its parse is the surface's
4594
+ * only validation against a skewed daemon). Two copies of the check itself would
4595
+ * be one edit away from disagreeing across those hops.
4596
+ */
4597
+ declare function refineWebSessionScopeConfined(webSession: {
4598
+ readonly cookieDomains: readonly string[];
4599
+ readonly loginUrl: string;
4600
+ readonly probe: {
4601
+ readonly url: string;
4602
+ };
4603
+ }, ctx: z.RefinementCtx): void;
4604
+
4605
+ declare const RegistrableDomain: z.ZodString;
4606
+
4607
+ declare type RegistrableDomain = z.infer<typeof RegistrableDomain>;
4608
+
3585
4609
  /** Applies an RemoveImmutable action to a type. */
3586
4610
  declare function RemoveImmutable<Type extends TSchema>(type: Type, options?: TSchemaOptions): TRemoveImmutable<Type>;
3587
4611
 
@@ -3612,7 +4636,7 @@ declare function RequiredDeferred<Type extends TSchema>(type: Type, options?: TS
3612
4636
  declare type RequiredKeys<Properties extends TProperties, Result extends PropertyKey = keyof Omit<Properties, ReadonlyOptionalKeys<Properties> | ReadonlyKeys<Properties> | OptionalKeys<Properties>>> = Result;
3613
4637
 
3614
4638
  /**
3615
- * The capability⇄service auth binding. A registration carrying this is gated on `serviceId`'s
4639
+ * The capability<->service auth binding. A registration carrying this is gated on `serviceId`'s
3616
4640
  * connectivity; the runtime answers "is this capability authorized?" from this plus vault state.
3617
4641
  */
3618
4642
  declare interface RequiresAuth {
@@ -3620,7 +4644,7 @@ declare interface RequiresAuth {
3620
4644
  /**
3621
4645
  * Optional scheme preference. Absent means the binding is service-level: any injectable scheme
3622
4646
  * of the service satisfies it, and resolution picks each account's own backing scheme. Present,
3623
- * it names the scheme resolution tries first — an account connected under a sibling injectable
4647
+ * it names the scheme resolution tries first - an account connected under a sibling injectable
3624
4648
  * scheme still satisfies the binding and resolves against its own scheme. A non-injectable
3625
4649
  * capability (`external-cli`) MUST name its scheme: it is a scheme-exact island.
3626
4650
  */
@@ -3628,7 +4652,7 @@ declare interface RequiresAuth {
3628
4652
  /**
3629
4653
  * The scopes this capability needs to do its job. Threaded through `resolveToken` into the
3630
4654
  * vault load so a grant-enforcing vault (the daemon's authority-backed vault) can refuse a
3631
- * plugin whose granted scopes don't cover them (`scopesCovered`) — per call, per plugin. Absent
4655
+ * plugin whose granted scopes don't cover them (`scopesCovered`) - per call, per plugin. Absent
3632
4656
  * means the capability declares no scope requirement (the single-user local path never checks
3633
4657
  * scopes; it is a daemon per-plugin enforcement input). Also read by the scope-aware half of
3634
4658
  * `isBindingSatisfied` when the host supplies a granted-scopes reader.
@@ -3640,11 +4664,11 @@ declare interface RequiresAuth {
3640
4664
  */
3641
4665
  readonly scopeRequirement?: ScopeRequirement;
3642
4666
  /**
3643
- * The service id to NAME in connect guidance when this capability is gated — a host-composed
4667
+ * The service id to NAME in connect guidance when this capability is gated - a host-composed
3644
4668
  * FRONT DOOR whose `service_connect` grants exactly what this binding needs (e.g. Gmail's
3645
4669
  * modules resolve under the shared `google.account` credential but connect via the `gmail`
3646
4670
  * front door, which expands only Gmail's scopes onto it). Guidance only: credential resolution
3647
- * still keys on `(serviceId, schemeId)`. Absent, guidance names `serviceId` — which for a
4671
+ * still keys on `(serviceId, schemeId)`. Absent, guidance names `serviceId` - which for a
3648
4672
  * scoped binding on a shared multi-product credential would send the agent to a connect that
3649
4673
  * classifies resolved and no-ops, never granting the missing scopes.
3650
4674
  */
@@ -3652,22 +4676,997 @@ declare interface RequiresAuth {
3652
4676
  }
3653
4677
 
3654
4678
  /**
3655
- * What the resolver hands a tool body: a live token for a concrete account + identity.
3656
- * `accessToken` is `apiKey` for an api-key scheme or the (refreshed) bearer for oauth.
4679
+ * The credential the host resolved for one call to plugin code that declares `requiresAuth`: a URI
4680
+ * verb (`ctx.auth.credential`), a tool (`ctx.credential`) or a search provider (`ctx.credential`).
4681
+ * Plain data, so it crosses a process boundary with the call; plugin code never asks for one.
3657
4682
  */
3658
- declare interface ResolvedAuth {
4683
+ declare interface ResolvedCredential {
4684
+ /** Bearer for OAuth schemes, apiKey for api-key schemes. Host-resolved and refreshed. */
3659
4685
  readonly accessToken: string;
3660
- readonly account: AuthAccount;
3661
- readonly identityMode: IdentityMode;
4686
+ readonly accountId: string;
3662
4687
  readonly schemeId: string;
3663
4688
  readonly scopes?: readonly string[];
3664
4689
  /**
3665
- * Every value of a multi-field api-key credential, keyed by the scheme's field id;
3666
- * `accessToken` mirrors the primary (first) field. Absent for single-secret schemes.
4690
+ * Every value of a multi-field api-key credential, keyed by the scheme's declared field id
4691
+ * (`accessToken` mirrors the primary field). Absent for single-secret schemes.
3667
4692
  */
3668
4693
  readonly fields?: Readonly<Record<string, string>>;
3669
4694
  }
3670
4695
 
4696
+ declare const ResolvedPluginContractV1: z.ZodObject<{
4697
+ protocol: z.ZodLiteral<"kay.plugin.v1">;
4698
+ pluginId: z.ZodString;
4699
+ namespace: z.ZodString;
4700
+ contributions: z.ZodArray<z.ZodObject<{
4701
+ target: z.ZodEnum<{
4702
+ "kay.agent": "kay.agent";
4703
+ "kay.app": "kay.app";
4704
+ "kay.ui": "kay.ui";
4705
+ }>;
4706
+ kind: z.ZodEnum<{
4707
+ tool: "tool";
4708
+ resource: "resource";
4709
+ endpoint: "endpoint";
4710
+ storage: "storage";
4711
+ command: "command";
4712
+ uriModule: "uriModule";
4713
+ authService: "authService";
4714
+ app: "app";
4715
+ configSection: "configSection";
4716
+ skill: "skill";
4717
+ converter: "converter";
4718
+ artifactUriModule: "artifactUriModule";
4719
+ cliBinding: "cliBinding";
4720
+ searchProvider: "searchProvider";
4721
+ interactionDriver: "interactionDriver";
4722
+ entityResolver: "entityResolver";
4723
+ agentRenderer: "agentRenderer";
4724
+ eventDefinition: "eventDefinition";
4725
+ eventSubscription: "eventSubscription";
4726
+ appDataSource: "appDataSource";
4727
+ whiteboardType: "whiteboardType";
4728
+ approvalType: "approvalType";
4729
+ contextContributor: "contextContributor";
4730
+ transcriptionProvider: "transcriptionProvider";
4731
+ deviceDelegation: "deviceDelegation";
4732
+ sessionReader: "sessionReader";
4733
+ mcpServer: "mcpServer";
4734
+ uiCommand: "uiCommand";
4735
+ uiSlot: "uiSlot";
4736
+ settingsPanel: "settingsPanel";
4737
+ resultRenderer: "resultRenderer";
4738
+ referencePresentation: "referencePresentation";
4739
+ view: "view";
4740
+ theme: "theme";
4741
+ }>;
4742
+ localId: z.ZodString;
4743
+ globalId: z.ZodString;
4744
+ }, z.core.$strict>>;
4745
+ consumesAuthServices: z.ZodArray<z.ZodString>;
4746
+ explicitDependencies: z.ZodArray<z.ZodString>;
4747
+ authServices: z.ZodArray<z.ZodObject<{
4748
+ localId: z.ZodString;
4749
+ globalId: z.ZodString;
4750
+ displayName: z.ZodString;
4751
+ summary: z.ZodOptional<z.ZodString>;
4752
+ schemes: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodDiscriminatedUnion<[z.ZodObject<{
4753
+ exchange: z.ZodLiteral<"pkce">;
4754
+ clientSuppliers: z.ZodArray<z.ZodEnum<{
4755
+ user: "user";
4756
+ kay: "kay";
4757
+ }>>;
4758
+ clientId: z.ZodOptional<z.ZodString>;
4759
+ clientSecret: z.ZodOptional<z.ZodString>;
4760
+ account: z.ZodOptional<z.ZodEnum<{
4761
+ resolveAccountId: "resolveAccountId";
4762
+ resolveAccounts: "resolveAccounts";
4763
+ }>>;
4764
+ localId: z.ZodString;
4765
+ globalId: z.ZodString;
4766
+ kind: z.ZodLiteral<"oauth2">;
4767
+ scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
4768
+ authorizationUrl: z.ZodURL;
4769
+ tokenUrl: z.ZodURL;
4770
+ extraAuthorizeParams: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
4771
+ displayName: z.ZodOptional<z.ZodString>;
4772
+ agentHint: z.ZodOptional<z.ZodString>;
4773
+ summary: z.ZodOptional<z.ZodString>;
4774
+ provisioning: z.ZodOptional<z.ZodArray<z.ZodObject<{
4775
+ id: z.ZodString;
4776
+ displayName: z.ZodString;
4777
+ description: z.ZodString;
4778
+ remediationUrl: z.ZodOptional<z.ZodURL>;
4779
+ probe: z.ZodObject<{
4780
+ url: z.ZodURL;
4781
+ method: z.ZodEnum<{
4782
+ GET: "GET";
4783
+ }>;
4784
+ verdictStatuses: z.ZodArray<z.ZodNumber>;
4785
+ nonEmptyArrayAt: z.ZodOptional<z.ZodString>;
4786
+ }, z.core.$strict>;
4787
+ }, z.core.$strict>>>;
4788
+ }, z.core.$strict>, z.ZodObject<{
4789
+ exchange: z.ZodLiteral<"confidential">;
4790
+ clientSuppliers: z.ZodTuple<[z.ZodLiteral<"kay">], null>;
4791
+ account: z.ZodEnum<{
4792
+ resolveAccountId: "resolveAccountId";
4793
+ resolveAccounts: "resolveAccounts";
4794
+ "sign-in": "sign-in";
4795
+ }>;
4796
+ localId: z.ZodString;
4797
+ globalId: z.ZodString;
4798
+ kind: z.ZodLiteral<"oauth2">;
4799
+ scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
4800
+ authorizationUrl: z.ZodURL;
4801
+ tokenUrl: z.ZodURL;
4802
+ extraAuthorizeParams: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
4803
+ displayName: z.ZodOptional<z.ZodString>;
4804
+ agentHint: z.ZodOptional<z.ZodString>;
4805
+ summary: z.ZodOptional<z.ZodString>;
4806
+ provisioning: z.ZodOptional<z.ZodArray<z.ZodObject<{
4807
+ id: z.ZodString;
4808
+ displayName: z.ZodString;
4809
+ description: z.ZodString;
4810
+ remediationUrl: z.ZodOptional<z.ZodURL>;
4811
+ probe: z.ZodObject<{
4812
+ url: z.ZodURL;
4813
+ method: z.ZodEnum<{
4814
+ GET: "GET";
4815
+ }>;
4816
+ verdictStatuses: z.ZodArray<z.ZodNumber>;
4817
+ nonEmptyArrayAt: z.ZodOptional<z.ZodString>;
4818
+ }, z.core.$strict>;
4819
+ }, z.core.$strict>>>;
4820
+ }, z.core.$strict>], "exchange">, z.ZodObject<{
4821
+ localId: z.ZodString;
4822
+ globalId: z.ZodString;
4823
+ kind: z.ZodLiteral<"api-key">;
4824
+ scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
4825
+ inputLabel: z.ZodString;
4826
+ fields: z.ZodOptional<z.ZodArray<z.ZodObject<{
4827
+ id: z.ZodString;
4828
+ label: z.ZodString;
4829
+ }, z.core.$strict>>>;
4830
+ setup: z.ZodOptional<z.ZodObject<{
4831
+ instructions: z.ZodString;
4832
+ url: z.ZodURL;
4833
+ }, z.core.$strict>>;
4834
+ validates: z.ZodOptional<z.ZodLiteral<true>>;
4835
+ displayName: z.ZodOptional<z.ZodString>;
4836
+ agentHint: z.ZodOptional<z.ZodString>;
4837
+ summary: z.ZodOptional<z.ZodString>;
4838
+ provisioning: z.ZodOptional<z.ZodArray<z.ZodObject<{
4839
+ id: z.ZodString;
4840
+ displayName: z.ZodString;
4841
+ description: z.ZodString;
4842
+ remediationUrl: z.ZodOptional<z.ZodURL>;
4843
+ probe: z.ZodObject<{
4844
+ url: z.ZodURL;
4845
+ method: z.ZodEnum<{
4846
+ GET: "GET";
4847
+ }>;
4848
+ verdictStatuses: z.ZodArray<z.ZodNumber>;
4849
+ nonEmptyArrayAt: z.ZodOptional<z.ZodString>;
4850
+ }, z.core.$strict>;
4851
+ }, z.core.$strict>>>;
4852
+ }, z.core.$strict>, z.ZodObject<{
4853
+ localId: z.ZodString;
4854
+ globalId: z.ZodString;
4855
+ kind: z.ZodLiteral<"delegated">;
4856
+ scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
4857
+ displayName: z.ZodOptional<z.ZodString>;
4858
+ agentHint: z.ZodOptional<z.ZodString>;
4859
+ summary: z.ZodOptional<z.ZodString>;
4860
+ }, z.core.$strict>, z.ZodObject<{
4861
+ localId: z.ZodString;
4862
+ globalId: z.ZodString;
4863
+ kind: z.ZodLiteral<"external-cli">;
4864
+ scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
4865
+ cli: z.ZodOptional<z.ZodObject<{
4866
+ binary: z.ZodString;
4867
+ probe: z.ZodObject<{
4868
+ args: z.ZodArray<z.ZodString>;
4869
+ timeoutMs: z.ZodOptional<z.ZodNumber>;
4870
+ signedOutMarker: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
4871
+ }, z.core.$strict>;
4872
+ login: z.ZodOptional<z.ZodObject<{
4873
+ args: z.ZodArray<z.ZodString>;
4874
+ timeoutMs: z.ZodOptional<z.ZodNumber>;
4875
+ pasteCode: z.ZodOptional<z.ZodObject<{
4876
+ args: z.ZodArray<z.ZodString>;
4877
+ label: z.ZodString;
4878
+ }, z.core.$strict>>;
4879
+ }, z.core.$strict>>;
4880
+ install: z.ZodOptional<z.ZodObject<{
4881
+ command: z.ZodString;
4882
+ args: z.ZodArray<z.ZodString>;
4883
+ }, z.core.$strict>>;
4884
+ hints: z.ZodObject<{
4885
+ install: z.ZodString;
4886
+ login: z.ZodString;
4887
+ }, z.core.$strict>;
4888
+ }, z.core.$strict>>;
4889
+ displayName: z.ZodOptional<z.ZodString>;
4890
+ agentHint: z.ZodOptional<z.ZodString>;
4891
+ summary: z.ZodOptional<z.ZodString>;
4892
+ }, z.core.$strict>], "kind">>;
4893
+ purposes: z.ZodArray<z.ZodString>;
4894
+ webSession: z.ZodOptional<z.ZodObject<{
4895
+ importance: z.ZodEnum<{
4896
+ required: "required";
4897
+ recommended: "recommended";
4898
+ }>;
4899
+ loginUrl: z.ZodURL;
4900
+ cookieDomains: z.ZodArray<z.ZodString>;
4901
+ probe: z.ZodObject<{
4902
+ url: z.ZodURL;
4903
+ method: z.ZodEnum<{
4904
+ GET: "GET";
4905
+ POST: "POST";
4906
+ }>;
4907
+ signedInStatuses: z.ZodArray<z.ZodNumber>;
4908
+ }, z.core.$strict>;
4909
+ oauthVenue: z.ZodEnum<{
4910
+ external: "external";
4911
+ embedded: "embedded";
4912
+ }>;
4913
+ }, z.core.$strict>>;
4914
+ }, z.core.$strict>>;
4915
+ grants: z.ZodOptional<z.ZodObject<{
4916
+ byTarget: z.ZodObject<{
4917
+ "kay.agent": z.ZodOptional<z.ZodObject<{
4918
+ auth: z.ZodOptional<z.ZodArray<z.ZodObject<{
4919
+ operations: z.ZodArray<z.ZodEnum<{
4920
+ status: "status";
4921
+ list: "list";
4922
+ connect: "connect";
4923
+ disconnect: "disconnect";
4924
+ resolve: "resolve";
4925
+ }>>;
4926
+ purposes: z.ZodOptional<z.ZodArray<z.ZodString>>;
4927
+ allowedScopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
4928
+ requiredScopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
4929
+ connectScopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
4930
+ scopeRequirement: z.ZodOptional<z.ZodObject<{
4931
+ purpose: z.ZodString;
4932
+ alternatives: z.ZodArray<z.ZodObject<{
4933
+ allOf: z.ZodArray<z.ZodObject<{
4934
+ scope: z.ZodString;
4935
+ reason: z.ZodExactOptional<z.ZodString>;
4936
+ }, z.core.$strict>>;
4937
+ }, z.core.$strict>>;
4938
+ }, z.core.$strict>>;
4939
+ scopeDefinitions: z.ZodOptional<z.ZodArray<z.ZodObject<{
4940
+ id: z.ZodString;
4941
+ label: z.ZodString;
4942
+ description: z.ZodString;
4943
+ documentationUrl: z.ZodOptional<z.ZodURL>;
4944
+ }, z.core.$strict>>>;
4945
+ frontDoor: z.ZodOptional<z.ZodObject<{
4946
+ id: z.ZodString;
4947
+ displayName: z.ZodString;
4948
+ resourcePicker: z.ZodOptional<z.ZodObject<{
4949
+ effect: z.ZodEnum<{
4950
+ selection: "selection";
4951
+ "resource-grant": "resource-grant";
4952
+ }>;
4953
+ mimeTypes: z.ZodOptional<z.ZodArray<z.ZodString>>;
4954
+ successNote: z.ZodOptional<z.ZodString>;
4955
+ }, z.core.$strict>>;
4956
+ }, z.core.$strict>>;
4957
+ service: z.ZodString;
4958
+ schemes: z.ZodOptional<z.ZodArray<z.ZodString>>;
4959
+ accountSelectors: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
4960
+ kind: z.ZodLiteral<"active">;
4961
+ }, z.core.$strict>, z.ZodObject<{
4962
+ kind: z.ZodLiteral<"account-id">;
4963
+ accountId: z.ZodString;
4964
+ }, z.core.$strict>, z.ZodObject<{
4965
+ kind: z.ZodLiteral<"record-id">;
4966
+ recordId: z.ZodString;
4967
+ }, z.core.$strict>], "kind">>;
4968
+ }, z.core.$strict>>>;
4969
+ storage: z.ZodOptional<z.ZodArray<z.ZodObject<{
4970
+ kind: z.ZodEnum<{
4971
+ sqlite: "sqlite";
4972
+ dataDir: "dataDir";
4973
+ }>;
4974
+ operations: z.ZodArray<z.ZodEnum<{
4975
+ open: "open";
4976
+ read: "read";
4977
+ write: "write";
4978
+ }>>;
4979
+ }, z.core.$strict>>>;
4980
+ events: z.ZodOptional<z.ZodArray<z.ZodObject<{
4981
+ event: z.ZodString;
4982
+ operations: z.ZodArray<z.ZodEnum<{
4983
+ subscribe: "subscribe";
4984
+ publish: "publish";
4985
+ }>>;
4986
+ }, z.core.$strict>>>;
4987
+ endpoints: z.ZodOptional<z.ZodArray<z.ZodObject<{
4988
+ operations: z.ZodArray<z.ZodEnum<{
4989
+ register: "register";
4990
+ invoke: "invoke";
4991
+ }>>;
4992
+ endpoint: z.ZodString;
4993
+ }, z.core.$strict>>>;
4994
+ webSession: z.ZodOptional<z.ZodArray<z.ZodObject<{
4995
+ origin: z.ZodString;
4996
+ pathPrefixes: z.ZodArray<z.ZodString>;
4997
+ csrf: z.ZodOptional<z.ZodObject<{
4998
+ sourceUrl: z.ZodURL;
4999
+ selector: z.ZodString;
5000
+ attribute: z.ZodString;
5001
+ header: z.ZodString;
5002
+ bodyField: z.ZodOptional<z.ZodString>;
5003
+ }, z.core.$strict>>;
5004
+ }, z.core.$strict>>>;
5005
+ knowledgeSearch: z.ZodOptional<z.ZodArray<z.ZodObject<{
5006
+ scope: z.ZodLiteral<"own-schemes">;
5007
+ }, z.core.$strict>>>;
5008
+ knownResources: z.ZodOptional<z.ZodArray<z.ZodObject<{
5009
+ scope: z.ZodLiteral<"own-modules">;
5010
+ }, z.core.$strict>>>;
5011
+ }, z.core.$strict>>;
5012
+ "kay.app": z.ZodOptional<z.ZodObject<{
5013
+ auth: z.ZodOptional<z.ZodArray<z.ZodObject<{
5014
+ operations: z.ZodArray<z.ZodEnum<{
5015
+ status: "status";
5016
+ list: "list";
5017
+ connect: "connect";
5018
+ disconnect: "disconnect";
5019
+ resolve: "resolve";
5020
+ }>>;
5021
+ purposes: z.ZodOptional<z.ZodArray<z.ZodString>>;
5022
+ allowedScopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
5023
+ requiredScopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
5024
+ connectScopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
5025
+ scopeRequirement: z.ZodOptional<z.ZodObject<{
5026
+ purpose: z.ZodString;
5027
+ alternatives: z.ZodArray<z.ZodObject<{
5028
+ allOf: z.ZodArray<z.ZodObject<{
5029
+ scope: z.ZodString;
5030
+ reason: z.ZodExactOptional<z.ZodString>;
5031
+ }, z.core.$strict>>;
5032
+ }, z.core.$strict>>;
5033
+ }, z.core.$strict>>;
5034
+ scopeDefinitions: z.ZodOptional<z.ZodArray<z.ZodObject<{
5035
+ id: z.ZodString;
5036
+ label: z.ZodString;
5037
+ description: z.ZodString;
5038
+ documentationUrl: z.ZodOptional<z.ZodURL>;
5039
+ }, z.core.$strict>>>;
5040
+ frontDoor: z.ZodOptional<z.ZodObject<{
5041
+ id: z.ZodString;
5042
+ displayName: z.ZodString;
5043
+ resourcePicker: z.ZodOptional<z.ZodObject<{
5044
+ effect: z.ZodEnum<{
5045
+ selection: "selection";
5046
+ "resource-grant": "resource-grant";
5047
+ }>;
5048
+ mimeTypes: z.ZodOptional<z.ZodArray<z.ZodString>>;
5049
+ successNote: z.ZodOptional<z.ZodString>;
5050
+ }, z.core.$strict>>;
5051
+ }, z.core.$strict>>;
5052
+ service: z.ZodString;
5053
+ schemes: z.ZodOptional<z.ZodArray<z.ZodString>>;
5054
+ accountSelectors: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
5055
+ kind: z.ZodLiteral<"active">;
5056
+ }, z.core.$strict>, z.ZodObject<{
5057
+ kind: z.ZodLiteral<"account-id">;
5058
+ accountId: z.ZodString;
5059
+ }, z.core.$strict>, z.ZodObject<{
5060
+ kind: z.ZodLiteral<"record-id">;
5061
+ recordId: z.ZodString;
5062
+ }, z.core.$strict>], "kind">>;
5063
+ }, z.core.$strict>>>;
5064
+ storage: z.ZodOptional<z.ZodArray<z.ZodObject<{
5065
+ kind: z.ZodEnum<{
5066
+ sqlite: "sqlite";
5067
+ dataDir: "dataDir";
5068
+ }>;
5069
+ operations: z.ZodArray<z.ZodEnum<{
5070
+ open: "open";
5071
+ read: "read";
5072
+ write: "write";
5073
+ }>>;
5074
+ }, z.core.$strict>>>;
5075
+ events: z.ZodOptional<z.ZodArray<z.ZodObject<{
5076
+ event: z.ZodString;
5077
+ operations: z.ZodArray<z.ZodEnum<{
5078
+ subscribe: "subscribe";
5079
+ publish: "publish";
5080
+ }>>;
5081
+ }, z.core.$strict>>>;
5082
+ endpoints: z.ZodOptional<z.ZodArray<z.ZodObject<{
5083
+ operations: z.ZodArray<z.ZodEnum<{
5084
+ register: "register";
5085
+ invoke: "invoke";
5086
+ }>>;
5087
+ endpoint: z.ZodString;
5088
+ }, z.core.$strict>>>;
5089
+ webSession: z.ZodOptional<z.ZodArray<z.ZodObject<{
5090
+ origin: z.ZodString;
5091
+ pathPrefixes: z.ZodArray<z.ZodString>;
5092
+ csrf: z.ZodOptional<z.ZodObject<{
5093
+ sourceUrl: z.ZodURL;
5094
+ selector: z.ZodString;
5095
+ attribute: z.ZodString;
5096
+ header: z.ZodString;
5097
+ bodyField: z.ZodOptional<z.ZodString>;
5098
+ }, z.core.$strict>>;
5099
+ }, z.core.$strict>>>;
5100
+ knowledgeSearch: z.ZodOptional<z.ZodArray<z.ZodObject<{
5101
+ scope: z.ZodLiteral<"own-schemes">;
5102
+ }, z.core.$strict>>>;
5103
+ knownResources: z.ZodOptional<z.ZodArray<z.ZodObject<{
5104
+ scope: z.ZodLiteral<"own-modules">;
5105
+ }, z.core.$strict>>>;
5106
+ }, z.core.$strict>>;
5107
+ "kay.ui": z.ZodOptional<z.ZodObject<{
5108
+ auth: z.ZodOptional<z.ZodArray<z.ZodObject<{
5109
+ operations: z.ZodArray<z.ZodEnum<{
5110
+ status: "status";
5111
+ list: "list";
5112
+ connect: "connect";
5113
+ disconnect: "disconnect";
5114
+ resolve: "resolve";
5115
+ }>>;
5116
+ purposes: z.ZodOptional<z.ZodArray<z.ZodString>>;
5117
+ allowedScopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
5118
+ requiredScopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
5119
+ connectScopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
5120
+ scopeRequirement: z.ZodOptional<z.ZodObject<{
5121
+ purpose: z.ZodString;
5122
+ alternatives: z.ZodArray<z.ZodObject<{
5123
+ allOf: z.ZodArray<z.ZodObject<{
5124
+ scope: z.ZodString;
5125
+ reason: z.ZodExactOptional<z.ZodString>;
5126
+ }, z.core.$strict>>;
5127
+ }, z.core.$strict>>;
5128
+ }, z.core.$strict>>;
5129
+ scopeDefinitions: z.ZodOptional<z.ZodArray<z.ZodObject<{
5130
+ id: z.ZodString;
5131
+ label: z.ZodString;
5132
+ description: z.ZodString;
5133
+ documentationUrl: z.ZodOptional<z.ZodURL>;
5134
+ }, z.core.$strict>>>;
5135
+ frontDoor: z.ZodOptional<z.ZodObject<{
5136
+ id: z.ZodString;
5137
+ displayName: z.ZodString;
5138
+ resourcePicker: z.ZodOptional<z.ZodObject<{
5139
+ effect: z.ZodEnum<{
5140
+ selection: "selection";
5141
+ "resource-grant": "resource-grant";
5142
+ }>;
5143
+ mimeTypes: z.ZodOptional<z.ZodArray<z.ZodString>>;
5144
+ successNote: z.ZodOptional<z.ZodString>;
5145
+ }, z.core.$strict>>;
5146
+ }, z.core.$strict>>;
5147
+ service: z.ZodString;
5148
+ schemes: z.ZodOptional<z.ZodArray<z.ZodString>>;
5149
+ accountSelectors: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
5150
+ kind: z.ZodLiteral<"active">;
5151
+ }, z.core.$strict>, z.ZodObject<{
5152
+ kind: z.ZodLiteral<"account-id">;
5153
+ accountId: z.ZodString;
5154
+ }, z.core.$strict>, z.ZodObject<{
5155
+ kind: z.ZodLiteral<"record-id">;
5156
+ recordId: z.ZodString;
5157
+ }, z.core.$strict>], "kind">>;
5158
+ }, z.core.$strict>>>;
5159
+ storage: z.ZodOptional<z.ZodArray<z.ZodObject<{
5160
+ kind: z.ZodEnum<{
5161
+ sqlite: "sqlite";
5162
+ dataDir: "dataDir";
5163
+ }>;
5164
+ operations: z.ZodArray<z.ZodEnum<{
5165
+ open: "open";
5166
+ read: "read";
5167
+ write: "write";
5168
+ }>>;
5169
+ }, z.core.$strict>>>;
5170
+ events: z.ZodOptional<z.ZodArray<z.ZodObject<{
5171
+ event: z.ZodString;
5172
+ operations: z.ZodArray<z.ZodEnum<{
5173
+ subscribe: "subscribe";
5174
+ publish: "publish";
5175
+ }>>;
5176
+ }, z.core.$strict>>>;
5177
+ endpoints: z.ZodOptional<z.ZodArray<z.ZodObject<{
5178
+ operations: z.ZodArray<z.ZodEnum<{
5179
+ register: "register";
5180
+ invoke: "invoke";
5181
+ }>>;
5182
+ endpoint: z.ZodString;
5183
+ }, z.core.$strict>>>;
5184
+ webSession: z.ZodOptional<z.ZodArray<z.ZodObject<{
5185
+ origin: z.ZodString;
5186
+ pathPrefixes: z.ZodArray<z.ZodString>;
5187
+ csrf: z.ZodOptional<z.ZodObject<{
5188
+ sourceUrl: z.ZodURL;
5189
+ selector: z.ZodString;
5190
+ attribute: z.ZodString;
5191
+ header: z.ZodString;
5192
+ bodyField: z.ZodOptional<z.ZodString>;
5193
+ }, z.core.$strict>>;
5194
+ }, z.core.$strict>>>;
5195
+ knowledgeSearch: z.ZodOptional<z.ZodArray<z.ZodObject<{
5196
+ scope: z.ZodLiteral<"own-schemes">;
5197
+ }, z.core.$strict>>>;
5198
+ knownResources: z.ZodOptional<z.ZodArray<z.ZodObject<{
5199
+ scope: z.ZodLiteral<"own-modules">;
5200
+ }, z.core.$strict>>>;
5201
+ }, z.core.$strict>>;
5202
+ }, z.core.$strict>;
5203
+ }, z.core.$strict>>;
5204
+ kayAgentUriModules: z.ZodOptional<z.ZodArray<z.ZodObject<{
5205
+ claims: z.ZodExactOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
5206
+ kind: z.ZodLiteral<"scheme">;
5207
+ scheme: z.ZodString;
5208
+ }, z.core.$strict>, z.ZodObject<{
5209
+ kind: z.ZodLiteral<"uriPattern">;
5210
+ pattern: z.ZodObject<{
5211
+ protocol: z.ZodExactOptional<z.ZodString>;
5212
+ hostname: z.ZodExactOptional<z.ZodString>;
5213
+ pathname: z.ZodExactOptional<z.ZodString>;
5214
+ search: z.ZodExactOptional<z.ZodString>;
5215
+ }, z.core.$strict>;
5216
+ normalizeTo: z.ZodExactOptional<z.ZodString>;
5217
+ route: z.ZodExactOptional<z.ZodString>;
5218
+ sourceUrl: z.ZodExactOptional<z.ZodString>;
5219
+ title: z.ZodExactOptional<z.ZodString>;
5220
+ examples: z.ZodExactOptional<z.ZodArray<z.ZodString>>;
5221
+ }, z.core.$strict>, z.ZodObject<{
5222
+ kind: z.ZodLiteral<"urlPattern">;
5223
+ pattern: z.ZodObject<{
5224
+ protocol: z.ZodExactOptional<z.ZodString>;
5225
+ hostname: z.ZodExactOptional<z.ZodString>;
5226
+ pathname: z.ZodExactOptional<z.ZodString>;
5227
+ search: z.ZodExactOptional<z.ZodString>;
5228
+ }, z.core.$strict>;
5229
+ normalizeTo: z.ZodExactOptional<z.ZodString>;
5230
+ route: z.ZodExactOptional<z.ZodString>;
5231
+ examples: z.ZodExactOptional<z.ZodArray<z.ZodString>>;
5232
+ }, z.core.$strict>], "kind">>>;
5233
+ templates: z.ZodExactOptional<z.ZodArray<z.ZodObject<{
5234
+ uri: z.ZodString;
5235
+ description: z.ZodString;
5236
+ operations: z.ZodExactOptional<z.ZodArray<z.ZodEnum<{
5237
+ search: "search";
5238
+ delete: "delete";
5239
+ list: "list";
5240
+ read: "read";
5241
+ write: "write";
5242
+ help: "help";
5243
+ edit: "edit";
5244
+ }>>>;
5245
+ operationDocs: z.ZodExactOptional<z.ZodRecord<z.ZodEnum<{
5246
+ search: "search";
5247
+ delete: "delete";
5248
+ list: "list";
5249
+ read: "read";
5250
+ write: "write";
5251
+ help: "help";
5252
+ edit: "edit";
5253
+ }> & z.core.$partial, z.ZodString>>;
5254
+ operationDefaults: z.ZodExactOptional<z.ZodRecord<z.ZodEnum<{
5255
+ search: "search";
5256
+ delete: "delete";
5257
+ list: "list";
5258
+ read: "read";
5259
+ write: "write";
5260
+ help: "help";
5261
+ edit: "edit";
5262
+ }> & z.core.$partial, z.ZodEnum<{
5263
+ never: "never";
5264
+ allow: "allow";
5265
+ ask: "ask";
5266
+ }>>>;
5267
+ }, z.core.$strict>>>;
5268
+ verbs: z.ZodExactOptional<z.ZodObject<{
5269
+ readable: z.ZodBoolean;
5270
+ writable: z.ZodBoolean;
5271
+ editable: z.ZodBoolean;
5272
+ deletable: z.ZodExactOptional<z.ZodBoolean>;
5273
+ listable: z.ZodBoolean;
5274
+ searchable: z.ZodExactOptional<z.ZodBoolean>;
5275
+ }, z.core.$strict>>;
5276
+ verbDocs: z.ZodExactOptional<z.ZodObject<{
5277
+ read: z.ZodExactOptional<z.ZodString>;
5278
+ list: z.ZodExactOptional<z.ZodString>;
5279
+ search: z.ZodExactOptional<z.ZodString>;
5280
+ write: z.ZodExactOptional<z.ZodString>;
5281
+ edit: z.ZodExactOptional<z.ZodString>;
5282
+ delete: z.ZodExactOptional<z.ZodString>;
5283
+ }, z.core.$strict>>;
5284
+ permissionDefaults: z.ZodExactOptional<z.ZodObject<{
5285
+ read: z.ZodExactOptional<z.ZodEnum<{
5286
+ never: "never";
5287
+ allow: "allow";
5288
+ ask: "ask";
5289
+ }>>;
5290
+ write: z.ZodExactOptional<z.ZodEnum<{
5291
+ never: "never";
5292
+ allow: "allow";
5293
+ ask: "ask";
5294
+ }>>;
5295
+ edit: z.ZodExactOptional<z.ZodEnum<{
5296
+ never: "never";
5297
+ allow: "allow";
5298
+ ask: "ask";
5299
+ }>>;
5300
+ delete: z.ZodExactOptional<z.ZodEnum<{
5301
+ never: "never";
5302
+ allow: "allow";
5303
+ ask: "ask";
5304
+ }>>;
5305
+ }, z.core.$strict>>;
5306
+ authActions: z.ZodExactOptional<z.ZodObject<{
5307
+ actions: z.ZodRecord<z.ZodString, z.ZodObject<{
5308
+ purpose: z.ZodString;
5309
+ alternatives: z.ZodArray<z.ZodObject<{
5310
+ allOf: z.ZodArray<z.ZodObject<{
5311
+ scope: z.ZodString;
5312
+ reason: z.ZodExactOptional<z.ZodString>;
5313
+ }, z.core.$strict>>;
5314
+ }, z.core.$strict>>;
5315
+ }, z.core.$strict>>;
5316
+ rules: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
5317
+ action: z.ZodString;
5318
+ operations: z.ZodExactOptional<z.ZodArray<z.ZodEnum<{
5319
+ search: "search";
5320
+ delete: "delete";
5321
+ list: "list";
5322
+ read: "read";
5323
+ write: "write";
5324
+ help: "help";
5325
+ edit: "edit";
5326
+ }>>>;
5327
+ routes: z.ZodExactOptional<z.ZodArray<z.ZodString>>;
5328
+ query: z.ZodExactOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
5329
+ }, z.core.$strict>, z.ZodObject<{
5330
+ public: z.ZodLiteral<true>;
5331
+ operations: z.ZodExactOptional<z.ZodArray<z.ZodEnum<{
5332
+ search: "search";
5333
+ delete: "delete";
5334
+ list: "list";
5335
+ read: "read";
5336
+ write: "write";
5337
+ help: "help";
5338
+ edit: "edit";
5339
+ }>>>;
5340
+ routes: z.ZodExactOptional<z.ZodArray<z.ZodString>>;
5341
+ query: z.ZodExactOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
5342
+ }, z.core.$strict>]>>;
5343
+ }, z.core.$strict>>;
5344
+ requiresConnection: z.ZodExactOptional<z.ZodLiteral<true>>;
5345
+ acceptsSourceCopy: z.ZodExactOptional<z.ZodLiteral<false>>;
5346
+ acceptsWriteSources: z.ZodExactOptional<z.ZodLiteral<true>>;
5347
+ acceptsBytes: z.ZodExactOptional<z.ZodLiteral<true>>;
5348
+ ownsLineSelectors: z.ZodExactOptional<z.ZodLiteral<true>>;
5349
+ description: z.ZodExactOptional<z.ZodString>;
5350
+ agentHint: z.ZodExactOptional<z.ZodObject<{
5351
+ summary: z.ZodString;
5352
+ commonFlows: z.ZodExactOptional<z.ZodArray<z.ZodObject<{
5353
+ label: z.ZodString;
5354
+ when: z.ZodExactOptional<z.ZodString>;
5355
+ example: z.ZodString;
5356
+ }, z.core.$strict>>>;
5357
+ helpUri: z.ZodExactOptional<z.ZodString>;
5358
+ triggers: z.ZodExactOptional<z.ZodObject<{
5359
+ keywords: z.ZodExactOptional<z.ZodArray<z.ZodString>>;
5360
+ patterns: z.ZodExactOptional<z.ZodArray<z.ZodString>>;
5361
+ }, z.core.$strict>>;
5362
+ skills: z.ZodExactOptional<z.ZodArray<z.ZodString>>;
5363
+ }, z.core.$strict>>;
5364
+ localId: z.ZodString;
5365
+ globalId: z.ZodString;
5366
+ schemes: z.ZodArray<z.ZodString>;
5367
+ displayName: z.ZodOptional<z.ZodString>;
5368
+ authServiceId: z.ZodOptional<z.ZodString>;
5369
+ knownResources: z.ZodOptional<z.ZodLiteral<true>>;
5370
+ describesOperations: z.ZodOptional<z.ZodLiteral<true>>;
5371
+ }, z.core.$strict>>>;
5372
+ kayAgentArtifactUriModules: z.ZodOptional<z.ZodArray<z.ZodObject<{
5373
+ localId: z.ZodString;
5374
+ globalId: z.ZodString;
5375
+ scheme: z.ZodString;
5376
+ editable: z.ZodBoolean;
5377
+ listable: z.ZodBoolean;
5378
+ deletable: z.ZodBoolean;
5379
+ appendable: z.ZodBoolean;
5380
+ storageScope: z.ZodEnum<{
5381
+ session: "session";
5382
+ family: "family";
5383
+ }>;
5384
+ }, z.core.$strict>>>;
5385
+ kayAgentEntityResolvers: z.ZodOptional<z.ZodArray<z.ZodObject<{
5386
+ localId: z.ZodString;
5387
+ globalId: z.ZodString;
5388
+ displayName: z.ZodOptional<z.ZodString>;
5389
+ uriModule: z.ZodString;
5390
+ entityTypes: z.ZodArray<z.ZodString>;
5391
+ uriHint: z.ZodString;
5392
+ }, z.core.$strict>>>;
5393
+ kayAgentGitHostClaims: z.ZodOptional<z.ZodArray<z.ZodObject<{
5394
+ host: z.ZodString;
5395
+ authServiceId: z.ZodString;
5396
+ authSchemeIds: z.ZodArray<z.ZodString>;
5397
+ authServiceDisplayName: z.ZodString;
5398
+ basicAuthUser: z.ZodString;
5399
+ }, z.core.$strict>>>;
5400
+ kayAgentTools: z.ZodOptional<z.ZodArray<z.ZodObject<{
5401
+ displayName: z.ZodOptional<z.ZodString>;
5402
+ description: z.ZodOptional<z.ZodString>;
5403
+ parameters: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<authoringCommonSchemas.JsonValue, unknown, z.core.$ZodTypeInternals<authoringCommonSchemas.JsonValue, unknown>>>>;
5404
+ requiresAuth: z.ZodOptional<z.ZodObject<{
5405
+ serviceId: z.ZodString;
5406
+ schemeId: z.ZodOptional<z.ZodString>;
5407
+ }, z.core.$strict>>;
5408
+ permission: z.ZodOptional<z.ZodObject<{
5409
+ kind: z.ZodEnum<{
5410
+ read: "read";
5411
+ mutate: "mutate";
5412
+ destructive: "destructive";
5413
+ execute: "execute";
5414
+ }>;
5415
+ ruleKey: z.ZodOptional<z.ZodString>;
5416
+ resourceArgs: z.ZodOptional<z.ZodArray<z.ZodString>>;
5417
+ }, z.core.$strict>>;
5418
+ localId: z.ZodString;
5419
+ globalId: z.ZodString;
5420
+ toolName: z.ZodString;
5421
+ }, z.core.$strict>>>;
5422
+ kayAppTools: z.ZodOptional<z.ZodArray<z.ZodObject<{
5423
+ localId: z.ZodString;
5424
+ globalId: z.ZodString;
5425
+ toolName: z.ZodString;
5426
+ }, z.core.$strict>>>;
5427
+ kayAppApprovalTypes: z.ZodOptional<z.ZodArray<z.ZodObject<{
5428
+ kind: z.ZodLiteral<"message">;
5429
+ localId: z.ZodString;
5430
+ provider: z.ZodString;
5431
+ unknownMessage: z.ZodString;
5432
+ fields: z.ZodObject<{
5433
+ body: z.ZodObject<{
5434
+ key: z.ZodString;
5435
+ max: z.ZodNumber;
5436
+ }, z.core.$strict>;
5437
+ subject: z.ZodOptional<z.ZodObject<{
5438
+ key: z.ZodString;
5439
+ max: z.ZodNumber;
5440
+ }, z.core.$strict>>;
5441
+ }, z.core.$strict>;
5442
+ presentation: z.ZodObject<{
5443
+ showAccount: z.ZodBoolean;
5444
+ recipient: z.ZodEnum<{
5445
+ target: "target";
5446
+ person: "person";
5447
+ }>;
5448
+ }, z.core.$strict>;
5449
+ forms: z.ZodObject<{
5450
+ inline: z.ZodOptional<z.ZodObject<{
5451
+ uri: z.ZodUnion<readonly [z.ZodObject<{
5452
+ fixed: z.ZodString;
5453
+ }, z.core.$strict>, z.ZodObject<{
5454
+ value: z.ZodString;
5455
+ }, z.core.$strict>]>;
5456
+ requestFields: z.ZodOptional<z.ZodArray<z.ZodString>>;
5457
+ payload: z.ZodRecord<z.ZodString, z.ZodString>;
5458
+ fixed: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodBoolean]>>>;
5459
+ }, z.core.$strict>>;
5460
+ saved: z.ZodOptional<z.ZodObject<{
5461
+ uri: z.ZodUnion<readonly [z.ZodObject<{
5462
+ fixed: z.ZodString;
5463
+ }, z.core.$strict>, z.ZodObject<{
5464
+ value: z.ZodString;
5465
+ }, z.core.$strict>]>;
5466
+ requestFields: z.ZodOptional<z.ZodArray<z.ZodString>>;
5467
+ payload: z.ZodRecord<z.ZodString, z.ZodString>;
5468
+ fixed: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodBoolean]>>>;
5469
+ }, z.core.$strict>>;
5470
+ stored: z.ZodOptional<z.ZodObject<{
5471
+ uri: z.ZodUnion<readonly [z.ZodObject<{
5472
+ fixed: z.ZodString;
5473
+ }, z.core.$strict>, z.ZodObject<{
5474
+ value: z.ZodString;
5475
+ }, z.core.$strict>]>;
5476
+ requestFields: z.ZodOptional<z.ZodArray<z.ZodString>>;
5477
+ payload: z.ZodRecord<z.ZodString, z.ZodString>;
5478
+ fixed: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodBoolean]>>>;
5479
+ read: z.ZodObject<{
5480
+ revision: z.ZodString;
5481
+ body: z.ZodString;
5482
+ subject: z.ZodOptional<z.ZodString>;
5483
+ to: z.ZodOptional<z.ZodString>;
5484
+ cc: z.ZodOptional<z.ZodString>;
5485
+ bcc: z.ZodOptional<z.ZodString>;
5486
+ attachments: z.ZodOptional<z.ZodString>;
5487
+ }, z.core.$strict>;
5488
+ }, z.core.$strict>>;
5489
+ }, z.core.$strict>;
5490
+ display: z.ZodOptional<z.ZodObject<{
5491
+ bodyFormat: z.ZodOptional<z.ZodLiteral<"mrkdwn">>;
5492
+ replyField: z.ZodOptional<z.ZodString>;
5493
+ replyLabel: z.ZodOptional<z.ZodString>;
5494
+ facts: z.ZodOptional<z.ZodArray<z.ZodObject<{
5495
+ label: z.ZodString;
5496
+ field: z.ZodString;
5497
+ }, z.core.$strict>>>;
5498
+ }, z.core.$strict>>;
5499
+ globalId: z.ZodString;
5500
+ moduleId: z.ZodString;
5501
+ authService: z.ZodOptional<z.ZodString>;
5502
+ }, z.core.$strict>>>;
5503
+ kayAppDataSources: z.ZodOptional<z.ZodArray<z.ZodObject<{
5504
+ localId: z.ZodString;
5505
+ globalId: z.ZodString;
5506
+ scope: z.ZodEnum<{
5507
+ session: "session";
5508
+ runtime: "runtime";
5509
+ account: "account";
5510
+ }>;
5511
+ snapshot: z.ZodObject<{
5512
+ version: z.ZodNumber;
5513
+ schema: z.ZodRecord<z.ZodString, z.ZodUnknown>;
5514
+ }, z.core.$strict>;
5515
+ change: z.ZodObject<{
5516
+ version: z.ZodNumber;
5517
+ schema: z.ZodRecord<z.ZodString, z.ZodUnknown>;
5518
+ semantics: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
5519
+ kind: z.ZodLiteral<"incremental">;
5520
+ }, z.core.$strict>, z.ZodObject<{
5521
+ kind: z.ZodLiteral<"snapshot-replacement">;
5522
+ maxEncodedBytes: z.ZodNumber;
5523
+ rationale: z.ZodString;
5524
+ }, z.core.$strict>], "kind">>;
5525
+ }, z.core.$strict>;
5526
+ read: z.ZodOptional<z.ZodObject<{
5527
+ request: z.ZodObject<{
5528
+ version: z.ZodNumber;
5529
+ schema: z.ZodRecord<z.ZodString, z.ZodType<authoringCommonSchemas.JsonValue, unknown, z.core.$ZodTypeInternals<authoringCommonSchemas.JsonValue, unknown>>>;
5530
+ }, z.core.$strict>;
5531
+ result: z.ZodObject<{
5532
+ version: z.ZodNumber;
5533
+ schema: z.ZodRecord<z.ZodString, z.ZodType<authoringCommonSchemas.JsonValue, unknown, z.core.$ZodTypeInternals<authoringCommonSchemas.JsonValue, unknown>>>;
5534
+ }, z.core.$strict>;
5535
+ }, z.core.$strict>>;
5536
+ }, z.core.$strict>>>;
5537
+ kayAppWhiteboardTypes: z.ZodOptional<z.ZodArray<z.ZodObject<{
5538
+ localId: z.ZodString;
5539
+ globalId: z.ZodString;
5540
+ displayName: z.ZodString;
5541
+ schemaVersion: z.ZodNumber;
5542
+ storage: z.ZodDiscriminatedUnion<[z.ZodObject<{
5543
+ kind: z.ZodLiteral<"json">;
5544
+ }, z.core.$strict>, z.ZodObject<{
5545
+ kind: z.ZodLiteral<"payload">;
5546
+ }, z.core.$strict>, z.ZodObject<{
5547
+ kind: z.ZodLiteral<"markdown">;
5548
+ bodyField: z.ZodString;
5549
+ }, z.core.$strict>], "kind">;
5550
+ valueSchema: z.ZodRecord<z.ZodString, z.ZodType<authoringCommonSchemas.JsonValue, unknown, z.core.$ZodTypeInternals<authoringCommonSchemas.JsonValue, unknown>>>;
5551
+ presentation: z.ZodOptional<z.ZodObject<{
5552
+ app: z.ZodString;
5553
+ }, z.core.$strict>>;
5554
+ }, z.core.$strict>>>;
5555
+ kayAppMcpServers: z.ZodOptional<z.ZodArray<z.ZodObject<{
5556
+ name: z.ZodString;
5557
+ pluginId: z.ZodString;
5558
+ url: z.ZodString;
5559
+ auth: z.ZodEnum<{
5560
+ oauth: "oauth";
5561
+ "api-key": "api-key";
5562
+ none: "none";
5563
+ }>;
5564
+ authServiceId: z.ZodOptional<z.ZodString>;
5565
+ }, z.core.$strict>>>;
5566
+ kayAgentConverters: z.ZodOptional<z.ZodArray<z.ZodObject<{
5567
+ localId: z.ZodString;
5568
+ globalId: z.ZodString;
5569
+ description: z.ZodOptional<z.ZodString>;
5570
+ mimeTypes: z.ZodArray<z.ZodString>;
5571
+ extensions: z.ZodOptional<z.ZodArray<z.ZodString>>;
5572
+ }, z.core.$strict>>>;
5573
+ referencePresentations: z.ZodOptional<z.ZodArray<z.ZodObject<{
5574
+ localId: z.ZodString;
5575
+ globalId: z.ZodString;
5576
+ uriModule: z.ZodString;
5577
+ resourceKind: z.ZodString;
5578
+ open: z.ZodDiscriminatedUnion<[z.ZodObject<{
5579
+ kind: z.ZodLiteral<"working-document">;
5580
+ }, z.core.$strict>, z.ZodObject<{
5581
+ kind: z.ZodLiteral<"browser-pane">;
5582
+ }, z.core.$strict>, z.ZodObject<{
5583
+ kind: z.ZodLiteral<"page">;
5584
+ pageId: z.ZodString;
5585
+ }, z.core.$strict>], "kind">;
5586
+ variants: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
5587
+ resourceKind: z.ZodString;
5588
+ presentationPluginId: z.ZodOptional<z.ZodString>;
5589
+ }, z.core.$strict>>>;
5590
+ claims: z.ZodOptional<z.ZodArray<z.ZodObject<{
5591
+ kind: z.ZodLiteral<"urlPattern">;
5592
+ pattern: z.ZodObject<{
5593
+ hostname: z.ZodString;
5594
+ pathname: z.ZodOptional<z.ZodString>;
5595
+ search: z.ZodOptional<z.ZodString>;
5596
+ protocol: z.ZodEnum<{
5597
+ http: "http";
5598
+ https: "https";
5599
+ }>;
5600
+ }, z.core.$strict>;
5601
+ brandIcon: z.ZodOptional<z.ZodString>;
5602
+ }, z.core.$strict>>>;
5603
+ tooltip: z.ZodOptional<z.ZodObject<{
5604
+ app: z.ZodString;
5605
+ pattern: z.ZodObject<{
5606
+ protocol: z.ZodString;
5607
+ hostname: z.ZodString;
5608
+ pathname: z.ZodOptional<z.ZodString>;
5609
+ search: z.ZodOptional<z.ZodString>;
5610
+ }, z.core.$strict>;
5611
+ }, z.core.$strict>>;
5612
+ }, z.core.$strict>>>;
5613
+ kayUiApps: z.ZodOptional<z.ZodArray<z.ZodObject<{
5614
+ localId: z.ZodString;
5615
+ globalId: z.ZodString;
5616
+ displayName: z.ZodString;
5617
+ contextOnly: z.ZodOptional<z.ZodLiteral<true>>;
5618
+ activityRail: z.ZodOptional<z.ZodObject<{
5619
+ section: z.ZodOptional<z.ZodEnum<{
5620
+ primary: "primary";
5621
+ plugins: "plugins";
5622
+ }>>;
5623
+ order: z.ZodOptional<z.ZodNumber>;
5624
+ icon: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
5625
+ svg: z.ZodString;
5626
+ }, z.core.$strict>]>>;
5627
+ }, z.core.$strict>>;
5628
+ description: z.ZodOptional<z.ZodString>;
5629
+ icon: z.ZodOptional<z.ZodString>;
5630
+ runtime: z.ZodLiteral<"kay.react-app.v1">;
5631
+ sdk: z.ZodObject<{
5632
+ range: z.ZodString;
5633
+ }, z.core.$strict>;
5634
+ entrypoint: z.ZodObject<{
5635
+ module: z.ZodString;
5636
+ export: z.ZodOptional<z.ZodString>;
5637
+ }, z.core.$strict>;
5638
+ styles: z.ZodOptional<z.ZodArray<z.ZodString>>;
5639
+ assets: z.ZodOptional<z.ZodArray<z.ZodString>>;
5640
+ capabilities: z.ZodOptional<z.ZodObject<{
5641
+ endpoints: z.ZodOptional<z.ZodArray<z.ZodObject<{
5642
+ localId: z.ZodString;
5643
+ globalId: z.ZodString;
5644
+ }, z.core.$strict>>>;
5645
+ host: z.ZodOptional<z.ZodArray<z.ZodEnum<{
5646
+ "sessions.create": "sessions.create";
5647
+ "memory.read": "memory.read";
5648
+ "skills.read": "skills.read";
5649
+ "automations.run": "automations.run";
5650
+ "artifacts.read": "artifacts.read";
5651
+ "navigation.open-session": "navigation.open-session";
5652
+ "artifacts.preview": "artifacts.preview";
5653
+ "cost.read": "cost.read";
5654
+ "billing.read": "billing.read";
5655
+ "context.read": "context.read";
5656
+ "usage.read": "usage.read";
5657
+ "self-improvement.read": "self-improvement.read";
5658
+ "automations.read": "automations.read";
5659
+ "shared-artifacts.read": "shared-artifacts.read";
5660
+ "workspace.place-pane": "workspace.place-pane";
5661
+ "workspace.pane-header": "workspace.pane-header";
5662
+ "workspace.arrange": "workspace.arrange";
5663
+ }>>>;
5664
+ }, z.core.$strict>>;
5665
+ }, z.core.$strict>>>;
5666
+ }, z.core.$strict>;
5667
+
5668
+ declare type ResolvedPluginContractV1 = z.infer<typeof ResolvedPluginContractV1>;
5669
+
3671
5670
  declare type ResolveExternalCliFailureReason = "not-external-cli" | "no-connection" | "account-ambiguous" | "account-not-found" | "not-authorized" | "host-unavailable";
3672
5671
 
3673
5672
  declare type ResolveExternalCliResult = {
@@ -3683,7 +5682,7 @@ declare type ResolveExternalCliResult = {
3683
5682
 
3684
5683
  /**
3685
5684
  * Derive a stable provider account id (and optional label) from a freshly connected access token,
3686
- * plus — when known — who the account belongs to.
5685
+ * plus - when known - who the account belongs to.
3687
5686
  *
3688
5687
  * A resolver almost always calls the provider's profile endpoint to derive `accountId` at all, so
3689
5688
  * the identity fields are already in the response: return them rather than flattening the person
@@ -3706,7 +5705,7 @@ declare type ResolvePluginAccounts = (accessToken: string) => Promise<readonly {
3706
5705
  declare interface ResolveTokenFailure {
3707
5706
  readonly ok: false;
3708
5707
  readonly reason: ResolveTokenFailureReason;
3709
- /** Actionable text the wrapper surfaces verbatim to the agent. */
5708
+ /** Actionable text the host surfaces verbatim to the agent. */
3710
5709
  readonly message: string;
3711
5710
  /** When ambiguous, the candidate accounts so the agent can pick one. */
3712
5711
  readonly accounts?: readonly AuthAccount[];
@@ -3719,7 +5718,7 @@ declare type ResolveTokenResult = ResolveTokenSuccess | ResolveTokenFailure;
3719
5718
 
3720
5719
  declare interface ResolveTokenSuccess {
3721
5720
  readonly ok: true;
3722
- readonly auth: ResolvedAuth;
5721
+ readonly credential: ResolvedCredential;
3723
5722
  }
3724
5723
 
3725
5724
  /** Match remaining characters in the buffer until end. If no characters are in buffer, no match */
@@ -3735,7 +5734,7 @@ declare function ReturnType_2<Type extends TSchema>(type: Type, options?: TSchem
3735
5734
  declare function ReturnTypeDeferred<Type extends TSchema>(type: Type, options?: TSchemaOptions): TReturnTypeDeferred<Type>;
3736
5735
 
3737
5736
  /** Observed cause of a failed request or interrupted run. */
3738
- declare const RUN_FAILURE_REASONS: readonly ["auth", "cancelled", "content_blocked", "context_overflow", "invalid_request", "model_disabled", "model_unavailable", "network", "organization_unavailable", "overloaded", "quota_exhausted", "rate_limit", "runtime_interrupted", "safeguard_block", "seat_unpaid", "server_error", "sign_in_required", "stream_interrupted", "timeout", "unknown"];
5737
+ declare const RUN_FAILURE_REASONS: readonly ["account_unreachable", "auth", "cancelled", "content_blocked", "context_overflow", "final_output_missing", "invalid_request", "model_disabled", "model_unavailable", "network", "organization_unavailable", "overloaded", "quota_exhausted", "rate_limit", "runtime_interrupted", "safeguard_block", "seat_unpaid", "server_error", "sign_in_required", "stream_interrupted", "timeout", "unknown"];
3739
5738
 
3740
5739
  declare type RunFailureReason = (typeof RUN_FAILURE_REASONS)[number];
3741
5740
 
@@ -4161,7 +6160,7 @@ declare interface SearchParams {
4161
6160
  readonly query: string;
4162
6161
  /**
4163
6162
  * Pure time filter narrowing results to a window. Providers MUST treat this as
4164
- * a time filter only — never as a signal to change topic scope, content domain,
6163
+ * a time filter only - never as a signal to change topic scope, content domain,
4165
6164
  * or ranking (oh-my-pi's Tavily `topic=news` coupling silently dropped docs).
4166
6165
  * Providers without temporal filtering MUST ignore it silently.
4167
6166
  */
@@ -4175,7 +6174,7 @@ declare interface SearchParams {
4175
6174
  /**
4176
6175
  * A web search backend behind the single `web_search` tool. Directly analogous
4177
6176
  * to a `UriModule` behind `read`/`write`: registered through `ExtensionApi`,
4178
- * merged per session, dispatched by the registry. Stateless and shareable —
6177
+ * merged per session, dispatched by the registry. Stateless and shareable -
4179
6178
  * per-call context (the abort signal and the {@link SearchProviderContext}) is
4180
6179
  * threaded into `search` and `isAvailable`.
4181
6180
  */
@@ -4191,17 +6190,18 @@ declare abstract class SearchProvider {
4191
6190
  */
4192
6191
  abstract readonly providerId: string;
4193
6192
  /**
4194
- * The capability⇄scheme binding when this provider resolves its OWN credential through the
6193
+ * The capability<->scheme binding when this provider resolves its OWN credential through the
4195
6194
  * service-extension auth system (stamped by {@link withResolvedSearchProvider}). `undefined`
4196
- * for providers that reuse inference credentials (the builtins) or need no auth. The runner
4197
- * reads it to surface the provider in `auth_status` as gated-until-connected, parallel to a
4198
- * tool's or URI module's `requiresAuth`.
6195
+ * for providers that reuse inference credentials (the builtins) or need no auth. When set, the
6196
+ * host resolves the credential onto {@link SearchProviderContext.credential} before it asks or
6197
+ * calls the provider, and `auth_status` lists the provider as gated-until-connected, parallel to
6198
+ * a tool's or URI module's `requiresAuth`.
4199
6199
  */
4200
6200
  readonly requiresAuth?: RequiresAuth;
4201
6201
  /**
4202
- * Cheap availability check (typically: does a usable credential resolve?). An own-credential
4203
- * provider returns `false` until its auth scheme has a connected account, so the chain skips
4204
- * it gracefully — the gating counterpart to a tool/module's discoverable-but-disallowed state.
6202
+ * Cheap availability check. The host never asks a provider with `requiresAuth` whose credential
6203
+ * did not resolve: it is unavailable, so the chain skips it - the gating counterpart to a
6204
+ * tool/module's discoverable-but-disallowed state.
4205
6205
  */
4206
6206
  abstract isAvailable(ctx?: SearchProviderContext): Promise<boolean> | boolean;
4207
6207
  /** Run the search. Throw {@link SearchProviderError} on a provider failure. */
@@ -4210,15 +6210,16 @@ declare abstract class SearchProvider {
4210
6210
 
4211
6211
  /**
4212
6212
  * Per-call context threaded into a provider's {@link SearchProvider.isAvailable} and
4213
- * {@link SearchProvider.search}. Carries the execute-time auth surface — the SAME
4214
- * `ctx.auth` a tool or URI module receives — scoped to the provider's OWNING extension,
4215
- * so a provider that declares its own credential (an api-key/oauth scheme via the
4216
- * service-extension auth system) can resolve a token. `auth` is absent for builtins
4217
- * (no owning extension; they reuse inference credentials through the host model execution capability)
4218
- * and outside a live session.
6213
+ * {@link SearchProvider.search}.
4219
6214
  */
4220
6215
  declare interface SearchProviderContext {
4221
- readonly auth?: ExtensionAuthContext;
6216
+ /**
6217
+ * The credential the host resolved for a provider that declares
6218
+ * {@link SearchProvider.requiresAuth}, for the session-active account. The host neither asks
6219
+ * nor calls such a provider when none resolves. Absent for a provider without `requiresAuth`
6220
+ * (builtins reuse inference credentials through the host model execution capability).
6221
+ */
6222
+ readonly credential?: ResolvedCredential;
4222
6223
  }
4223
6224
 
4224
6225
  /** Registry id of a search provider, e.g. `builtin:anthropic`. Open-ended for extensions. */
@@ -4277,19 +6278,19 @@ declare type SelectorDisposition = {
4277
6278
  * rebuilds it on each `AgentSession.reroot` (`@herd/herd-agent`) (the only event that
4278
6279
  * moves `cwd`), then evaluates every tool's predicate against it exactly once per change.
4279
6280
  *
4280
- * **CLOSED-CONTEXT INVARIANT (load-bearing — do not violate when extending this type).** This object
4281
- * carries ONLY primary facts that are *independent of tool availability* — `cwd`, `repoRoot`, and the
6281
+ * **CLOSED-CONTEXT INVARIANT (load-bearing - do not violate when extending this type).** This object
6282
+ * carries ONLY primary facts that are *independent of tool availability* - `cwd`, `repoRoot`, and the
4282
6283
  * planned `mode`/`platform`. It MUST NEVER carry the tool list, the active/effective set, or anything
4283
6284
  * else derived from availability. If a predicate's input could depend on another predicate's output,
4284
6285
  * evaluation would have to reach a fixpoint and could cycle. Because the context is closed, the kernel
4285
6286
  * evaluates each predicate ONCE per context change (one pass, no fixpoint) and caches the result. Keep
4286
6287
  * every future field in this same closed class so the single-pass guarantee survives.
4287
6288
  *
4288
- * Predicates reading this MUST be **pure and synchronous** — same context in ⇒ same answer out, no I/O,
6289
+ * Predicates reading this MUST be **pure and synchronous** - same context in => same answer out, no I/O,
4289
6290
  * no side effects. The host resolves the VCS facts (`repoRoot`); the predicate only inspects them.
4290
6291
  */
4291
6292
  declare interface SessionContext {
4292
- /** The session's current working directory (the live, re-rootable cwd — not the launch dir). */
6293
+ /** The session's current working directory (the live, re-rootable cwd - not the launch dir). */
4293
6294
  readonly cwd: string;
4294
6295
  /**
4295
6296
  * The enclosing VCS repository root for {@link cwd}, or `null` when `cwd` is not inside a repo.
@@ -4299,6 +6300,10 @@ declare interface SessionContext {
4299
6300
  readonly repoRoot: string | null;
4300
6301
  }
4301
6302
 
6303
+ declare const SignedInStatusCode: z.ZodNumber;
6304
+
6305
+ declare type SignedInStatusCode = z.infer<typeof SignedInStatusCode>;
6306
+
4302
6307
  /** Matches from Start and End capturing everything in-between. Start and End are consumed. */
4303
6308
  declare function Span<Start extends string, End extends string, MultiLine extends boolean, Input extends string>(start: Start, end: End, multiLine: MultiLine, input: Input): TSpan<Start, End, MultiLine, Input>;
4304
6309
 
@@ -4411,12 +6416,25 @@ declare const StringPattern = ".*";
4411
6416
  /** Creates a Symbol type. */
4412
6417
  declare function Symbol_2(options?: TSchemaOptions): TSymbol;
4413
6418
 
6419
+ /** Structurally the plugin SDK's `KayAppSessionEventCause`: only the fields the host reads. */
6420
+ declare interface SystemOneCallCause {
6421
+ readonly kind?: "session-event" | "backfill";
6422
+ readonly handler: string;
6423
+ readonly sourceSessionId: string;
6424
+ }
6425
+
4414
6426
  declare interface SystemOneCallOptions {
4415
6427
  readonly signal?: AbortSignal;
4416
6428
  /** Bounds the whole call, retries included. */
4417
6429
  readonly timeoutMs?: number;
4418
6430
  /** What the call is for, carried to the host's usage accounting. Never sent to a provider. */
4419
6431
  readonly purpose?: string;
6432
+ /**
6433
+ * The session event a plugin's call answers, so the host charges the call to that session.
6434
+ * The host checks the plugin is handling that session's event right now. Never sent to a
6435
+ * provider.
6436
+ */
6437
+ readonly cause?: SystemOneCallCause;
4420
6438
  }
4421
6439
 
4422
6440
  declare interface SystemOneClient {
@@ -4870,6 +6888,13 @@ declare type TApplyReadonly<Readonly extends TModifierOperation, Type extends T.
4870
6888
 
4871
6889
  declare type TApplyReverse<Types extends TSchema[], Reversed extends boolean> = Reversed extends true ? TReverse<Types> : Types;
4872
6890
 
6891
+ declare const TargetEntrypoint: z.ZodObject<{
6892
+ module: z.ZodString;
6893
+ export: z.ZodOptional<z.ZodString>;
6894
+ }, z.core.$strict>;
6895
+
6896
+ declare type TargetEntrypoint = z.infer<typeof TargetEntrypoint>;
6897
+
4873
6898
  /** Represents an Array type. */
4874
6899
  declare interface TArray<Type extends TSchema = TSchema> extends TSchema {
4875
6900
  '~kind': 'Array';
@@ -6645,7 +8670,7 @@ declare type TOmitInstantiate<Context extends TProperties, State extends TState,
6645
8670
  * classification (the engine records the rejection on an unexplained failure),
6646
8671
  * and a stored record with one reads as none.
6647
8672
  */
6648
- declare const TOOL_CALL_FAILURE_CODES: readonly ["tool.invalid_input", "tool.blocked", "tool.cancelled", "tool.timeout", "tool.not_found", "tool.unavailable", "tool.execution_failed", "provider.http", "provider.api", "provider.transport", "uri.not_found", "uri.unsupported_operation", "uri.not_connected", "uri.auth_unavailable", "permission.denied", "edit.empty_edits", "edit.text_not_found", "edit.text_not_unique", "edit.empty_old_text", "edit.overlapping_edits", "edit.no_change"];
8673
+ declare const TOOL_CALL_FAILURE_CODES: readonly ["tool.invalid_input", "tool.blocked", "tool.cancelled", "tool.timeout", "tool.not_found", "tool.unavailable", "tool.execution_failed", "tool.auth_unavailable", "tool.replies_owed", "provider.http", "provider.api", "provider.transport", "uri.not_found", "uri.unsupported_operation", "uri.not_connected", "uri.auth_unavailable", "permission.denied", "edit.empty_edits", "edit.text_not_found", "edit.text_not_unique", "edit.empty_old_text", "edit.overlapping_edits", "edit.no_change"];
6649
8674
 
6650
8675
  /**
6651
8676
  * ---
@@ -6663,14 +8688,14 @@ declare type ToolActionKind = "read" | "mutate" | "destructive" | "execute";
6663
8688
  * A tool's declarative availability gate. `when` is the authoritative predicate the kernel evaluates
6664
8689
  * against the live {@link SessionContext} to decide whether the tool is offered to the model here;
6665
8690
  * `description` is the always-shown, human-readable "why" a UI renders next to a tool the predicate
6666
- * disables (e.g. greyed on the new-session page). The predicate runs in the main process only — a
8691
+ * disables (e.g. greyed on the new-session page). The predicate runs in the main process only - a
6667
8692
  * renderer receives just the resolved `available: boolean` plus this `description`.
6668
8693
  *
6669
8694
  * `when` MUST be pure and synchronous (see {@link SessionContext}); a throw is caught by the kernel,
6670
- * treated as "unavailable", and surfaced as a session diagnostic — it never crashes the tool sync.
8695
+ * treated as "unavailable", and surfaced as a session diagnostic - it never crashes the tool sync.
6671
8696
  */
6672
8697
  declare interface ToolAvailability {
6673
- /** Pure, synchronous gate. `true` ⇒ the tool may be offered in this context; `false` ⇒ withheld. */
8698
+ /** Pure, synchronous gate. `true` => the tool may be offered in this context; `false` => withheld. */
6674
8699
  when(ctx: SessionContext): boolean;
6675
8700
  /** Human-readable reason the tool is/isn't available, always shown in UI. */
6676
8701
  description: string;
@@ -6698,6 +8723,7 @@ declare const toolCallFailureCauseSchema: z.ZodObject<{
6698
8723
  "not-found": "not-found";
6699
8724
  permission: "permission";
6700
8725
  unavailable: "unavailable";
8726
+ waiting: "waiting";
6701
8727
  }>;
6702
8728
  retryable: z.ZodBoolean;
6703
8729
  action: z.ZodEnum<{
@@ -6706,6 +8732,7 @@ declare const toolCallFailureCauseSchema: z.ZodObject<{
6706
8732
  retry: "retry";
6707
8733
  "correct-input": "correct-input";
6708
8734
  connect: "connect";
8735
+ wait: "wait";
6709
8736
  }>;
6710
8737
  details: z.ZodOptional<z.ZodObject<{
6711
8738
  moduleId: z.ZodOptional<z.ZodString>;
@@ -6714,6 +8741,7 @@ declare const toolCallFailureCauseSchema: z.ZodObject<{
6714
8741
  uri: z.ZodOptional<z.ZodString>;
6715
8742
  path: z.ZodOptional<z.ZodString>;
6716
8743
  validationField: z.ZodOptional<z.ZodString>;
8744
+ validationRule: z.ZodOptional<z.ZodString>;
6717
8745
  errorName: z.ZodOptional<z.ZodString>;
6718
8746
  errorCode: z.ZodOptional<z.ZodString>;
6719
8747
  providerCode: z.ZodOptional<z.ZodString>;
@@ -6728,14 +8756,14 @@ declare type ToolCallFailureCode = (typeof TOOL_CALL_FAILURE_CODES)[number];
6728
8756
 
6729
8757
  /**
6730
8758
  * The neutral around-execution hook: return `next()`'s result (possibly transformed) to run the
6731
- * real tool, or return a result without calling `next()` to substitute one — the tool then never
8759
+ * real tool, or return a result without calling `next()` to substitute one - the tool then never
6732
8760
  * executes. Every downstream consumer (the model, the session log, result clamps, failure
6733
8761
  * attribution) sees whatever is returned exactly as if the tool produced it. Throwing surfaces to
6734
8762
  * the caller as a tool failure, classified like any other.
6735
8763
  *
6736
8764
  * Interceptors compose as middleware: each receives a `next` that runs the REST of the chain, the
6737
8765
  * innermost `next` being the tool itself. `next` may be called at most the caller's own logic
6738
- * demands (zero to short-circuit, once to delegate, more to retry) — the kernel does not police
8766
+ * demands (zero to short-circuit, once to delegate, more to retry) - the kernel does not police
6739
8767
  * arity.
6740
8768
  */
6741
8769
  declare type ToolCallInterceptor = (call: ToolCallInvocation, next: () => Promise<AgentToolResult<unknown>>) => Promise<AgentToolResult<unknown>>;
@@ -6744,7 +8772,7 @@ declare type ToolCallInterceptor = (call: ToolCallInvocation, next: () => Promis
6744
8772
  declare interface ToolCallInvocation {
6745
8773
  readonly toolCallId: string;
6746
8774
  readonly toolName: string;
6747
- /** The call's arguments, already through `prepareArguments` — the shape `execute` receives. */
8775
+ /** The call's arguments, already through `prepareArguments` - the shape `execute` receives. */
6748
8776
  readonly params: unknown;
6749
8777
  readonly signal: AbortSignal | undefined;
6750
8778
  /**
@@ -6763,7 +8791,7 @@ declare interface ToolCallInvocation {
6763
8791
 
6764
8792
  /**
6765
8793
  * The model the call's result is about to be shown to, as the session holds it at execution
6766
- * time: identity plus pi's `input` list — the SAME field pi's adapters read when they build the
8794
+ * time: identity plus pi's `input` list - the SAME field pi's adapters read when they build the
6767
8795
  * next request, so a capability policy keyed on it agrees with what the provider will accept.
6768
8796
  * Absent when the wrap was built without a resolver; a policy must then treat the capability
6769
8797
  * as unknown, not as absent.
@@ -6798,7 +8826,7 @@ declare type ToolCallPermissionVerdict = {
6798
8826
  * What a tool call ADDRESSES, resolved by the session before execution from facts it already
6799
8827
  * holds for auth scoping: a URI verb's matched module (and the extension that registered it), or
6800
8828
  * an extension-contributed tool's owner. `ownerExtensionId` is absent for builtin/app-owned
6801
- * modules and tools — the session owns those, no extension does. A host policy that keys on
8829
+ * modules and tools - the session owns those, no extension does. A host policy that keys on
6802
8830
  * "which integration is this call about" reads this instead of re-parsing `params`.
6803
8831
  */
6804
8832
  declare type ToolCallTarget = {
@@ -6816,15 +8844,15 @@ declare interface ToolContext {
6816
8844
  readonly cwd: string;
6817
8845
  readonly model: Model<any> | undefined;
6818
8846
  /**
6819
- * The execute-time auth resolver the SDK tool wrapper (`withResolvedAuth`) reads to resolve a
6820
- * live token for the active (or per-call-overridden) account. Present when the session is bound
6821
- * to an `ExtensionAuthRuntime` (`@herd/herd-agent`); absent in always-on contexts
6822
- * (the wrapper short-circuits with an actionable message when undefined).
8847
+ * The credential the host resolved for this call, for a tool that declares
8848
+ * {@link ToolDefinition.requiresAuth}: the account named by the call's `accountId` argument, else
8849
+ * the session-active one. The host does not call the tool when none resolves. Absent for a tool
8850
+ * without `requiresAuth`, and outside a live session.
6823
8851
  */
6824
- readonly auth?: ExtensionAuthContext;
8852
+ readonly credential?: ResolvedCredential;
6825
8853
  /**
6826
8854
  * Detached work whose result should re-enter the conversation as a new turn (each completion calls
6827
- * `nextTurn()` and appears in the Background tasks panel). Not for fire-and-forget side effects —
8855
+ * `nextTurn()` and appears in the Background tasks panel). Not for fire-and-forget side effects -
6828
8856
  * use `ExtensionContext.runEffect`. Absent when the host wires no background-task manager.
6829
8857
  */
6830
8858
  readonly backgroundTasks?: ExtensionBackgroundTasksApi;
@@ -6846,9 +8874,9 @@ declare interface ToolContext {
6846
8874
  /**
6847
8875
  * Re-root the session into `newCwd` mid-run, recomposing the cwd-scoped substrate (builtin tools,
6848
8876
  * the capability registry, the system-prompt project line) in place so subsequent tool calls operate
6849
- * there — the conversation continues uninterrupted. This is the agent self-reroot seam: the
8877
+ * there - the conversation continues uninterrupted. This is the agent self-reroot seam: the
6850
8878
  * motivating caller is an app tool (e.g. `isolate_worktree`) that does its git ops then calls
6851
- * `ctx.reroot(worktreePath)` from inside its own `execute`. Safe mid-run — it never gates on idle.
8879
+ * `ctx.reroot(worktreePath)` from inside its own `execute`. Safe mid-run - it never gates on idle.
6852
8880
  * Present only with a live session (absent in session-less inventory/standalone contexts, like
6853
8881
  * {@link auth}). `reason` labels the transition for observability (e.g. `"worktree-isolation"`).
6854
8882
  */
@@ -6889,12 +8917,12 @@ declare interface ToolDefinition<TParams extends ToolParametersWire = ToolParame
6889
8917
  executionMode?: ToolExecutionMode;
6890
8918
  /**
6891
8919
  * How long a single execution may legitimately stay silent (#3785).
6892
- * - `"fast"` (the default when omitted): the execution is bounded — if it
8920
+ * - `"fast"` (the default when omitted): the execution is bounded - if it
6893
8921
  * neither settles nor loses the abort race within the fast-tool deadline
6894
8922
  * (120s), the kernel fails the call with a timeout error the model can
6895
8923
  * react to. Right for local reads/writes and short network calls, which
6896
8924
  * finish in seconds or are stuck.
6897
- * - `"long"`: no deadline — a build under a shell, a parent parked on a
8925
+ * - `"long"`: no deadline - a build under a shell, a parent parked on a
6898
8926
  * child task. The abort race still applies: a user Stop always wins,
6899
8927
  * whether or not the tool honors its `signal`.
6900
8928
  * Declare `"long"` only when unbounded silent execution is genuinely part
@@ -6911,29 +8939,29 @@ declare interface ToolDefinition<TParams extends ToolParametersWire = ToolParame
6911
8939
  */
6912
8940
  replaySafe?: true;
6913
8941
  /**
6914
- * Optional capability⇄scheme binding. When present this tool is auth-gated: discoverable when
6915
- * unauthed, callable once the binding is satisfied. The SDK's `withResolvedAuth`
6916
- * stamps this; absent means an ordinary always-on tool (additive — nothing changes for existing
6917
- * tools that omit it).
8942
+ * Optional capability<->scheme binding. When present this tool is auth-gated: discoverable when
8943
+ * unauthed, callable once the binding is satisfied, and the host resolves its credential onto
8944
+ * {@link ToolContext.credential} before each call. The SDK's `withResolvedAuth` stamps this; absent
8945
+ * means an ordinary always-on tool.
6918
8946
  */
6919
8947
  requiresAuth?: RequiresAuth;
6920
8948
  /**
6921
8949
  * Optional declarative availability gate ({@link ToolAvailability}). When present, the kernel
6922
8950
  * evaluates `availability.when` against the live {@link SessionContext} once per context change
6923
8951
  * (session start + each reroot) and withholds the tool from the model-visible set wherever it
6924
- * returns `false`. Backward-compatible: **absent ⇒ always available**. Orthogonal to
6925
- * mode-disallowed sets and to auth/permission gates — availability answers only "does this tool
8952
+ * returns `false`. Backward-compatible: **absent => always available**. Orthogonal to
8953
+ * mode-disallowed sets and to auth/permission gates - availability answers only "does this tool
6926
8954
  * apply in this context", and composes with the others at the same chokepoint.
6927
8955
  */
6928
8956
  availability?: ToolAvailability;
6929
8957
  /**
6930
8958
  * Optional declarative permission classification ({@link ToolPermissionHint}). Consulted by
6931
8959
  * the permission gate ONLY for tools the classifier does not otherwise recognize (extension/app
6932
- * tools), letting a tool relax the fail-closed `execute` fallback (a pure staging tool → `read`),
8960
+ * tools), letting a tool relax the fail-closed `execute` fallback (a pure staging tool -> `read`),
6933
8961
  * declare its provider `scheme`, derive the `resources` a call touches (a browser
6934
8962
  * navigation's target origin) so per-provider and per-origin rules can gate it.
6935
8963
  * Because it lives on the definition it is
6936
- * provenance-bound. Backward-compatible: **absent ⇒ the classifier's default (`execute`, no
8964
+ * provenance-bound. Backward-compatible: **absent => the classifier's default (`execute`, no
6937
8965
  * scheme)**.
6938
8966
  */
6939
8967
  permission?: ToolPermissionHint;
@@ -6987,7 +9015,7 @@ declare type ToolParametersWire = unknown;
6987
9015
  * definition (the same shape of author-declared, kernel-read fact as `requiresAuth` and
6988
9016
  * `availability`). Consulted ONLY when the classifier does not otherwise recognize the tool
6989
9017
  * (never overrides `read`/`bash`/URI builtins), so a tool can relax the fail-closed
6990
- * `execute` fallback (e.g. a pure staging tool → `read`) or scope itself for per-provider and
9018
+ * `execute` fallback (e.g. a pure staging tool -> `read`) or scope itself for per-provider and
6991
9019
  * per-origin rules. Because it lives on the registered definition, it is provenance-bound: a
6992
9020
  * tool named the same as another carries its OWN hint, never inherits a first-party one.
6993
9021
  *
@@ -6996,7 +9024,7 @@ declare type ToolParametersWire = unknown;
6996
9024
  * touch protected config must NOT declare `read`. Bonsai's embedded-experience tools never touch
6997
9025
  * `configDir`, so this is safe for them. `read` is also what every capability surface reports as
6998
9026
  * "read-only" (Bonsai's Permissions page groups and defaults on it), so it is a claim about what the
6999
- * tool DOES — never a way to buy silence. A tool that should raise no ask on its own account
9027
+ * tool DOES - never a way to buy silence. A tool that should raise no ask on its own account
7000
9028
  * declares {@link ToolPermissionHint.quiet} and keeps its honest `kind`.
7001
9029
  */
7002
9030
  declare interface ToolPermissionHint {
@@ -7013,8 +9041,8 @@ declare interface ToolPermissionHint {
7013
9041
  readonly ruleKey?: string;
7014
9042
  /**
7015
9043
  * Overrides the ask rail's default human-response window for THIS tool's asks, in ms.
7016
- * A UX window declaration, not authority: it cannot loosen or tighten what is asked —
7017
- * kind/ruleKey/scheme/rules/mode all decide that exactly as they would without it —
9044
+ * A UX window declaration, not authority: it cannot loosen or tighten what is asked -
9045
+ * kind/ruleKey/scheme/rules/mode all decide that exactly as they would without it -
7018
9046
  * only how long the prompt waits before it lapses unanswered (`expired`, which the gate
7019
9047
  * already treats as `unanswered`, never `denied`). Bounded use case: a suggestion-shaped
7020
9048
  * tool whose silence means "continue" (e.g. `suggest_compaction`'s 15s ask, chosen to
@@ -7025,26 +9053,26 @@ declare interface ToolPermissionHint {
7025
9053
  /**
7026
9054
  * Derives the resources a call touches from its validated input (e.g. the target origin of
7027
9055
  * a browser navigation). Pure and total; a throw is treated as "no resources" and the call
7028
- * falls back to the plain classification (fail-closed — never crashes the gate).
9056
+ * falls back to the plain classification (fail-closed - never crashes the gate).
7029
9057
  */
7030
9058
  readonly deriveResources?: (input: Record<string, unknown>) => readonly string[];
7031
9059
  /**
7032
9060
  * Derives a call's classification (`kind`/`ruleKey`/`scheme`) from its validated input, where
7033
9061
  * the static fields above fix them for every call. This is the generalization of
7034
- * {@link deriveResources} (input → resources) to the rule-matching triple, and of the kernel's
9062
+ * {@link deriveResources} (input -> resources) to the rule-matching triple, and of the kernel's
7035
9063
  * built-in `deriveBashRuleKey` (a bash call's argv sharpens its key) to an author-declared tool.
7036
9064
  *
7037
9065
  * Returns a partial: each present field OVERRIDES the static hint for this call; each absent
7038
9066
  * field (or a wholly `undefined` return) falls back to the static hint, then the fail-closed
7039
9067
  * default. Pure and total; a throw is treated as "no refinement" and the call falls back to the
7040
- * static hint (fail-closed — never crashes the gate).
9068
+ * static hint (fail-closed - never crashes the gate).
7041
9069
  *
7042
9070
  * It grants no authority the static fields don't already grant: it computes the same
7043
9071
  * kind/ruleKey/scheme the tool could hard-code, per call rather than once. `kind` here matters
7044
9072
  * because the same tool can read on one input and execute on another, which a static `kind`
7045
9073
  * cannot express.
7046
9074
  *
7047
- * Exemplar — Bonsai's `mcp` proxy tool, one tool spanning every server: `search`/`describe` derive
9075
+ * Exemplar - Bonsai's `mcp` proxy tool, one tool spanning every server: `search`/`describe` derive
7048
9076
  * `{ kind: "read" }` (metadata lookups), while `call` derives
7049
9077
  * `{ kind: "execute", ruleKey: "mcp:<server>::<tool>", scheme: "<server>" }`, so a
7050
9078
  * `{ scheme: "<server>" }` rule gates a whole server and a `{ ruleKey: "mcp:<server>::<tool>" }`
@@ -7061,7 +9089,7 @@ declare interface ToolPermissionHint {
7061
9089
  * deriver is a pure function of its own input and cannot see the target's hint, its service
7062
9090
  * scheme, or the kernel's own recognition of names like `bash` and the URI verbs. Resolution
7063
9091
  * re-enters classification under the target's identity, so a proxied call matches EXACTLY the
7064
- * rules its direct form would — same kind, same ruleKey, same scheme.
9092
+ * rules its direct form would - same kind, same ruleKey, same scheme.
7065
9093
  *
7066
9094
  * A hop ADDS the target's rules; it never SUBTRACTS the carrier's. The carrier's own
7067
9095
  * classification rides along (`ToolActionPreflight.carrier`) and the controller takes the
@@ -7071,22 +9099,22 @@ declare interface ToolPermissionHint {
7071
9099
  * alone could not.
7072
9100
  *
7073
9101
  * Not consulted at all when the CARRIER is a tool the kernel classifies itself (`bash`, the URI
7074
- * verbs, the read tools) — the same invariant that governs the rest of this hint. A proxy may
9102
+ * verbs, the read tools) - the same invariant that governs the rest of this hint. A proxy may
7075
9103
  * still freely TARGET one of them.
7076
9104
  *
7077
9105
  * Pure and total. EVERY abnormal outcome falls back to the carrier's own classification, never
7078
9106
  * to an intermediate link: a throw, a malformed return, a blank target name, a non-object input,
7079
9107
  * a cycle, or a chain longer than 4 hops. (Falling back to an intermediate would itself be a
7080
- * bypass — a crafted 5-link chain could present hop 4's benign classification for a call whose
9108
+ * bypass - a crafted 5-link chain could present hop 4's benign classification for a call whose
7081
9109
  * real target is `bash rm -rf /`.) Only a chain terminating normally, at a tool declaring no
7082
9110
  * further proxy, hops at all.
7083
9111
  *
7084
- * "Fail-closed" here means the carrier's own classification applies — the identity the call
7085
- * really had — not that the result is always stricter than the target's. How much gate is left
9112
+ * "Fail-closed" here means the carrier's own classification applies - the identity the call
9113
+ * really had - not that the result is always stricter than the target's. How much gate is left
7086
9114
  * on such a call is exactly how much the CARRIER carries: an `execute` carrier is stricter than
7087
9115
  * a `read` target and equal to a `mutate`/`destructive` one outside allow mode, while a
7088
9116
  * {@link quiet} carrier (Bonsai's own `call_tool`) contributes no mode default at all, so the
7089
- * fallback leaves nothing but the carrier's rules and the protected-path deny — and the carrier
9117
+ * fallback leaves nothing but the carrier's rules and the protected-path deny - and the carrier
7090
9118
  * names no path, so that deny has nothing to fire on. This is why a carrier must refuse a target
7091
9119
  * that is itself a carrier: no chain long or circular enough to reach the fallback can be built,
7092
9120
  * which is the only thing that keeps the fallback from being toothless. Fail-closed is a
@@ -7097,24 +9125,24 @@ declare interface ToolPermissionHint {
7097
9125
  * Declares that this tool's identity contributes its RULES to the gate but not its MODE
7098
9126
  * DEFAULT. A rule about it still applies in full (a deny denies, an ask asks, an allow
7099
9127
  * allows) and the protected-path hard-deny still fires; what is withheld is the verdict the
7100
- * MODE would reach from `kind` alone — default/ask mode's "anything but a read asks".
9128
+ * MODE would reach from `kind` alone - default/ask mode's "anything but a read asks".
7101
9129
  *
7102
9130
  * It is a statement about this identity's CONTRIBUTION, never about what the call does.
7103
9131
  * `kind` stays the honest declaration of the strongest effect a call can have, and a quiet
7104
- * tool declares it exactly as loudly as a noisy one — which is the whole point: buying
9132
+ * tool declares it exactly as loudly as a noisy one - which is the whole point: buying
7105
9133
  * silence with `kind: "read"` instead moves the call below the protected-path hard-deny and
7106
9134
  * reports the tool as read-only on every capability surface.
7107
9135
  *
7108
9136
  * It exists for a PROXY CARRIER ({@link deriveProxiedCall}), and is honest only for a tool
7109
9137
  * whose only effect is invoking the target the gate is already classifying beside it: the
7110
9138
  * target's kind, rules, resources and the protected-path deny all still decide, so a proxied
7111
- * call is gated exactly like the direct one — no more, and no ask the direct call would never
9139
+ * call is gated exactly like the direct one - no more, and no ask the direct call would never
7112
9140
  * have raised. Bonsai's `call_tool` declares `{ kind: "execute", quiet: true }` (owner ruling,
7113
9141
  * 2026-08-18): honest about everything it can reach, silent on its own account.
7114
9142
  *
7115
9143
  * Quiet is not ungated, but it IS nearly all the gate a lone carrier has. On a call that
7116
9144
  * classifies as the carrier because no hop resolved (a cycle, an over-long chain), a quiet
7117
- * carrier leaves only its own rules — see {@link deriveProxiedCall}'s fail-closed paragraph
9145
+ * carrier leaves only its own rules - see {@link deriveProxiedCall}'s fail-closed paragraph
7118
9146
  * for why a carrier must therefore refuse a carrier as a target.
7119
9147
  */
7120
9148
  readonly quiet?: boolean;
@@ -8317,32 +10345,43 @@ declare interface UriAgentHint {
8317
10345
  readonly triggers?: UriHintTriggers;
8318
10346
  /**
8319
10347
  * Skill invocation names (flat `localId`s, e.g. `"gmail-email-triage"`) that hold this module's
8320
- * deeper workflow judgment — the name a `read skill://<name>` dispatch resolves, not a display
10348
+ * deeper workflow judgment - the name a `read skill://<name>` dispatch resolves, not a display
8321
10349
  * title or a path. Point here only at skills that actually exist in the composed skill roster;
8322
10350
  * a dangling name sends the agent to a `skill://` read for nothing.
8323
10351
  */
8324
10352
  readonly skills?: readonly string[];
8325
10353
  }
8326
10354
 
8327
- declare type UriAuthActionClassification = {
8328
- readonly kind: "action";
8329
- readonly actionId: string;
8330
- } | {
8331
- readonly kind: "public";
8332
- };
8333
-
8334
10355
  /**
8335
- * Finite authorization actions plus the pure route classifier that selects one before dispatch.
8336
- * An exception, an unknown action id, or `undefined` classification fails closed in the host.
10356
+ * Finite authorization actions plus the rules that select one before dispatch. A call no rule
10357
+ * matches, or a rule naming an action that is not in `actions`, fails closed in the host.
8337
10358
  */
8338
10359
  declare interface UriAuthActionPolicy {
8339
10360
  readonly actions: Readonly<Record<string, ScopeRequirement>>;
8340
- classifyOperation(request: {
8341
- readonly operation: UriOperation;
8342
- readonly uri: string;
8343
- }): UriAuthActionClassification | undefined;
10361
+ /** Absent matches no call, so every call fails closed. */
10362
+ readonly rules?: readonly UriAuthActionRule[];
8344
10363
  }
8345
10364
 
10365
+ /**
10366
+ * One row of a module's sign-in action rules: which calls need which action. A row matches a call
10367
+ * when every condition it names holds; a condition it leaves out matches anything. The first
10368
+ * matching row decides, so a row with no conditions at the end means "everything else".
10369
+ */
10370
+ declare type UriAuthActionRule = {
10371
+ /** The verbs this row covers. */
10372
+ readonly operations?: readonly UriOperation[];
10373
+ /** The claim `route` ids this row covers, matched against the call's address. */
10374
+ readonly routes?: readonly string[];
10375
+ /** Query parameters the address must carry with exactly these values (`{ permanent: "true" }`). */
10376
+ readonly query?: Readonly<Record<string, string>>;
10377
+ } & ({
10378
+ /** The {@link UriAuthActionPolicy.actions} entry the call needs. */
10379
+ readonly action: string;
10380
+ } | {
10381
+ /** The call needs no credential. */
10382
+ readonly public: true;
10383
+ });
10384
+
8346
10385
  declare interface UriAuthRef {
8347
10386
  readonly serviceId: string;
8348
10387
  readonly schemeId: string;
@@ -8364,7 +10403,7 @@ declare interface UriAuthRequirement {
8364
10403
  */
8365
10404
  readonly requiredScopes?: readonly string[];
8366
10405
  /**
8367
- * The service id connect guidance should NAME when this module is gated — a host-composed
10406
+ * The service id connect guidance should NAME when this module is gated - a host-composed
8368
10407
  * front door whose connect grants exactly this module's scopes (e.g. `gmail` expanding onto
8369
10408
  * the shared `google.account` credential). Guidance only; resolution keys on
8370
10409
  * `(serviceId, schemeId)`. Absent, guidance names `serviceId`.
@@ -8410,6 +10449,21 @@ declare type UriCachePolicyResolver = (operation: UriOperation, cacheUri: string
8410
10449
 
8411
10450
  declare type UriClaim = UriSchemeClaim | UriPatternClaim | UrlPatternClaim;
8412
10451
 
10452
+ /**
10453
+ * A URL with `:name` placeholders for the claim's captures. Each capture is escaped for where it
10454
+ * lands: lowercased in the host, one path segment (a `:name*` capture keeps its `/`), or a query
10455
+ * or fragment value. `{transform(...)}` runs one named, built-in transform over the text inside
10456
+ * it, captures pasted in unescaped, and escapes the output for where it lands:
10457
+ *
10458
+ * - `base64`: unpadded base64 of the UTF-8 text (`{base64(:id :calendar)}`).
10459
+ * - `slackTimestamp`: a Slack archive message token as the API's timestamp
10460
+ * (`p1783350000000100` becomes `1783350000.000100`).
10461
+ *
10462
+ * A transform that cannot read its input fills nothing. A claim whose `normalizeTo` fills nothing
10463
+ * does not match; a `sourceUrl` that fills nothing paints no link.
10464
+ */
10465
+ declare type UriClaimTemplate = string;
10466
+
8413
10467
  declare interface UriCommonFlow {
8414
10468
  readonly label: string;
8415
10469
  readonly when?: string;
@@ -8459,41 +10513,28 @@ declare interface UriExample {
8459
10513
  readonly operation?: UriOperation;
8460
10514
  }
8461
10515
 
8462
- declare interface UriExtensionModule extends Omit<UriModule, "verbs"> {
10516
+ /**
10517
+ * A plugin's URI module. Its claims route, spell and describe its addresses, so it has no
10518
+ * `matches`, `normalize` or `describe`. It also has no `fallback` (a plugin's addresses are always
10519
+ * claimed) and no `locate` (a plugin has no file on disk for the daemon to open).
10520
+ */
10521
+ declare interface UriExtensionModule extends Omit<UriModule, "verbs" | "normalize" | "matches" | "describe" | "fallback" | "locate"> {
8463
10522
  readonly verbs: UriVerbSupport;
8464
10523
  /** Human-facing per-verb effect docs; see {@link UriVerbDocs}. */
8465
10524
  readonly verbDocs?: UriVerbDocs;
8466
10525
  /**
8467
10526
  * Plugin-declared default permission per verb group. A verb group set to `"ask"`
8468
- * compiles into a defaults-level ask rule — the user is prompted by default but can
10527
+ * compiles into a defaults-level ask rule - the user is prompted by default but can
8469
10528
  * override with an explicit allow. Undeclared = `"allow"` (fail-open).
8470
10529
  * See {@link UriPermissionDefaults}.
8471
10530
  */
8472
10531
  readonly permissionDefaults?: UriPermissionDefaults;
8473
10532
  /** Requires a resolved URI connection before any verb handler runs. */
8474
10533
  readonly requiresConnection?: boolean;
8475
- /** Pure route-aware permission facts; see {@link UriExtensionOperationPermissionPolicy}. */
8476
- readonly permission?: UriExtensionOperationPermissionPolicy;
8477
10534
  /** False rejects generic write-tool `source` copies before source fetch. */
8478
10535
  readonly acceptsSourceCopy?: boolean;
8479
10536
  }
8480
10537
 
8481
- declare interface UriExtensionOperationPermissionPolicy {
8482
- /**
8483
- * Classify one canonical route, purely. `write`/`edit`/`delete` may only be made stricter
8484
- * than the verb default; `help`/`read`/`list`/`search` must stay `"read"` (a `ruleKey` is
8485
- * allowed), because the kernel reruns a crash-interrupted read without asking again. Any
8486
- * other answer, or a throw, fails the call closed.
8487
- */
8488
- classifyOperation(request: {
8489
- readonly operation: UriOperation;
8490
- readonly uri: string;
8491
- }): {
8492
- readonly kind: "read" | "mutate" | "destructive" | "execute";
8493
- readonly ruleKey?: string;
8494
- } | undefined;
8495
- }
8496
-
8497
10538
  declare interface UriExternalCliRunner {
8498
10539
  readonly run: (request: UriExternalCliRunRequest) => Promise<UriExternalCliRunResult>;
8499
10540
  }
@@ -8528,6 +10569,8 @@ declare interface UriHelp {
8528
10569
  * than text the module's author wrote. Absent: the module's own text.
8529
10570
  */
8530
10571
  readonly thirdPartyContent?: true;
10572
+ /** The module's own markdown for this result, shown instead of the host's default rendering. */
10573
+ readonly markdown?: string;
8531
10574
  }
8532
10575
 
8533
10576
  declare interface UriHintTriggers {
@@ -8567,6 +10610,12 @@ declare interface UriListResult {
8567
10610
  readonly items: readonly UriListItem[];
8568
10611
  readonly nextCursor?: string;
8569
10612
  readonly metadata?: UriListMetadata;
10613
+ /** How long the host may cache this result; see {@link UriCachePolicy.ttlMs}. */
10614
+ readonly cachePolicy?: Pick<UriCachePolicy, "ttlMs">;
10615
+ /** The module's own markdown for this result, shown instead of the host's default rendering. */
10616
+ readonly markdown?: string;
10617
+ /** The touched resource's name for the transcript row, as on `RawResource.label`. */
10618
+ readonly label?: UriResourceLabel;
8570
10619
  }
8571
10620
 
8572
10621
  declare type UriLocateContext = Pick<UriResolveContext, "cwd" | "signal" | "connection" | "sessionId" | "paths"> & {
@@ -8584,31 +10633,13 @@ declare type UriLocateResult = {
8584
10633
  readonly kind: "not-disk-backed";
8585
10634
  };
8586
10635
 
8587
- declare type UriMarkdownRenderInput = {
8588
- readonly operation: "help";
8589
- readonly uri: string;
8590
- readonly result: UriHelp;
8591
- } | {
8592
- readonly operation: "list";
8593
- readonly uri: string;
8594
- readonly result: UriListResult;
8595
- } | {
8596
- readonly operation: "search";
8597
- readonly uri: string;
8598
- readonly result: UriSearchResult;
8599
- } | {
8600
- readonly operation: Extract<UriOperation, "write" | "edit" | "delete">;
8601
- readonly uri: string;
8602
- readonly result: UriMutationResult;
8603
- };
8604
-
8605
10636
  declare interface UriModule {
8606
10637
  readonly id: string;
8607
10638
  /**
8608
10639
  * Explicit human-readable name for catalog/display purposes (the plugin
8609
10640
  * manifest's `contributes.uriModules[].displayName`, threaded through by
8610
- * hand since there is no automatic manifest→runtime-module composition
8611
- * step). Falls back to a mechanical id-derived title when absent — see
10641
+ * hand since there is no automatic manifest->runtime-module composition
10642
+ * step). Falls back to a mechanical id-derived title when absent - see
8612
10643
  * `uriCatalogTitle`.
8613
10644
  */
8614
10645
  readonly title?: string;
@@ -8628,14 +10659,26 @@ declare interface UriModule {
8628
10659
  * calls `parseLineSelector` itself and reports what it did through `RawResource.selector`.
8629
10660
  */
8630
10661
  readonly ownsLineSelectors?: boolean;
10662
+ /** Opt in to host-resolved supplementary sources; absent means unsupported. */
10663
+ readonly acceptsWriteSources?: boolean;
10664
+ /**
10665
+ * Opt in to raw bytes as `write`'s content; absent means text and JSON only. The `write`
10666
+ * tool's `source` copy leg is the only producer: a provider's binary resource (an attachment,
10667
+ * an image, a PDF) reaches a module that declares this as a `Uint8Array`, never decoded into
10668
+ * the model's context, and a binary copy to any other module is refused before it runs.
10669
+ */
10670
+ readonly acceptsBytes?: boolean;
8631
10671
  readonly claims?: readonly UriClaim[];
10672
+ /**
10673
+ * The routes the module's scheme-root `help` lists, as data, so a host can list them without
10674
+ * calling `help`.
10675
+ */
10676
+ readonly templates?: readonly UriTemplate[];
8632
10677
  /** Migration-only prompt summary until structured help/catalog coverage replaces prose. */
8633
10678
  readonly description?: string;
8634
10679
  readonly agentHint?: UriAgentHint;
8635
10680
  readonly requiresAuth?: UriAuthRequirement;
8636
10681
  readonly authActions?: UriAuthActionPolicy;
8637
- /** Pure route/payload validation applied before a consequential permission ask. */
8638
- readonly preflight?: UriOperationPreflightPolicy;
8639
10682
  /**
8640
10683
  * Structured facts for approval surfaces, or `undefined` when unavailable.
8641
10684
  * A one-line description must name the whole consequence; `preview` instead
@@ -8645,120 +10688,46 @@ declare interface UriModule {
8645
10688
  * of covered payload fields and query parameters. Unknown fields cost the summary.
8646
10689
  * The host owns framing, the whole-quote fit (no elision) and display-safety admission.
8647
10690
  *
8648
- * Unlike preflight, this hook is async and may do I/O. Resolve names through `ctx`,
10691
+ * This hook is async and may do I/O. Resolve names through `ctx`,
8649
10692
  * the same dispatch context used by execution, never an ambient or cached account. A name
8650
10693
  * the module resolved under that account may be cached for a bounded time, keyed by that
8651
10694
  * account's identity and never answered to another account or after a failed lookup.
8652
- * The host calls it once before raising the ask, enforces the short `ctx.signal`
8653
- * deadline and discards late answers. A throw yields no summary and a module-attributed
8654
- * diagnostic; declining costs a click into the app, never an under-described approval.
8655
- */
8656
- describeOperation?(request: {
8657
- readonly operation: UriOperation;
8658
- readonly uri: string;
8659
- readonly payload: unknown;
8660
- }, ctx: UriResolveContext): Promise<UriOperationDescription | undefined>;
8661
- /**
8662
- * Rebuild a call from the person's "Allow with edits" answer: the same payload
8663
- * {@link describeOperation} was given, with the values the person typed into the preview's
8664
- * `editable` fields put in their place. Implement it beside any preview that marks a field
8665
- * `editable`; without it the host drops every editable marker from that module's previews, so
8666
- * a field is never offered for editing that cannot be honoured.
8667
- *
8668
- * Pure and fast: it must not send, write or otherwise act, and it should not do I/O (it gets
8669
- * the dispatch context `ctx` only so a name can be resolved the way `describeOperation` does).
8670
- * Return the COMPLETE amended payload in the shape the module's own handler reads. Validate it
8671
- * with the handler's own schema, so an amended call is exactly as valid as one the model made.
8672
- * Decline by returning `undefined` or throwing; either denies the call with nothing done.
8673
- *
8674
- * The host calls it once, after the person allowed the call, never for a denial, and only for
8675
- * a `write` whose payload this module described. The kernel passes the `edits` through
8676
- * unchanged. Bonsai's daemon has already refused, before the ask settled, a key that is not an
8677
- * `editable` field of the preview it showed, a repeated key, a blank value and a value past the
8678
- * field's `maxLength`, but another host may not, so refuse each of those here yourself (return
8679
- * `undefined`).
10695
+ * The host calls it once before raising the ask and waits for the answer, with no deadline;
10696
+ * `ctx.signal` fires when the host stops waiting (the session closes, or a caller gives up),
10697
+ * and a late answer is discarded. A throw yields no
10698
+ * summary and a module-attributed diagnostic; declining costs a click into the app, never an
10699
+ * under-described approval.
8680
10700
  *
8681
- * The host then holds the amended call to what the person was shown, in two steps, and runs it
8682
- * only if both pass. It classifies the amended call again and requires the same tool, rule key,
8683
- * kind, resources, scheme and target address, so an edit cannot reach a different route. It then
8684
- * calls {@link describeOperation} on the amended call and requires that preview to read exactly
8685
- * as the one the person saw, apart from the values of the fields they edited: the same title, the
8686
- * same fields in the same order, each with the same label, key, `editable` marker and
10701
+ * "Allow with edits": a field marked `editable` may be rewritten by the person on the card.
10702
+ * The host rebuilds the call itself (see the field's `editable`), then holds the rebuilt call to
10703
+ * what the person was shown, in two steps, and runs it only if both pass. It classifies the
10704
+ * rebuilt call again and requires the same tool, rule key, kind, resources, scheme and target
10705
+ * address. It then calls this hook on the rebuilt call and requires that preview to read exactly
10706
+ * as the one the person saw, apart from the values of the fields they edited: the same title,
10707
+ * the same fields in the same order, each with the same label, key, `editable` marker and
8687
10708
  * `maxLength`, and every read-only field with the same value. Anything else refuses the call
8688
- * with nothing done: a mismatch, and also a describer that is missing, declines, throws or
8689
- * overruns its deadline. The `description` line is not compared.
8690
- *
8691
- * So rebuild from the original payload and change only the fields you offered. A recipient, a
8692
- * thread or an attachment list that an amendment changed is caught by the second step, but only
8693
- * where the preview shows it: put whatever says where a call goes, or what it does beyond its
10709
+ * with nothing done: a mismatch, and also an answer of `undefined` or a throw. The `description`
10710
+ * line is not compared. So put whatever says where a call goes, or what it does beyond its
8694
10711
  * editable fields, in the preview's `title` or a field, never only in its `description`, and
8695
10712
  * keep recipients, destinations and thread bindings out of `editable` fields.
8696
10713
  */
8697
- amendOperation?(request: {
10714
+ describeOperation?(request: {
8698
10715
  readonly operation: UriOperation;
8699
10716
  readonly uri: string;
8700
10717
  readonly payload: unknown;
8701
- readonly edits: readonly UriPreviewEdit[];
8702
- }, ctx: UriResolveContext): Promise<UriOperationAmendment | undefined>;
8703
- /**
8704
- * A short, render-only name for the resource a settled call on `request.uri` touched, which the
8705
- * host stamps on the tool result's `details` so a transcript row can name it where it would
8706
- * otherwise print the address (`#lane-analytics` and `thread`, not a channel id). Answer
8707
- * `undefined` for any address you cannot honestly name.
8708
- *
8709
- * Called once per successful URI verb call, AFTER the verb handler has returned, with the same
8710
- * dispatch context. Resolve names through `ctx` and nothing else, and prefer a cache your own
8711
- * verb handlers warm, keyed by the executing account: a name one account saw is never answered
8712
- * to another, and a failed, blank or aborted lookup is never cached. The host bounds the wait
8713
- * (a finished result is held at most a quarter of a second), gives `ctx.signal` a hard deadline,
8714
- * and drops a late, thrown or refused answer without failing the call; a throw is reported as a
8715
- * module-attributed diagnostic. The label is a label, never an identity: the address remains the
8716
- * click target, hover text and accessible name. It is UI-only, so it never enters the tool
8717
- * result's content and no telemetry reads it.
8718
- *
8719
- * Unlike `describeOperation` this is not an approval surface: it carries no consequence, no
8720
- * quote and no coverage claim, and nothing may gate a permission on it.
8721
- */
8722
- labelResource?(request: UriResourceLabelRequest, ctx: UriResolveContext): Promise<UriResourceLabel | undefined>;
8723
- /**
8724
- * Per-resource observability: does a `format: "observation"` read of THIS
8725
- * uri render source-native material ({@link UriResolveContext.format})?
8726
- * Route-parse only — cheap, side-effect-free, no I/O, no auth (the same
8727
- * discipline as `matches`); a throw is treated as `false`. Returning true
8728
- * is the resource's contract that its observation read returns an
8729
- * observation render and that failures under that format throw typed,
8730
- * status-bearing errors rather than resolving a friendly fallback page.
8731
- * The kernel stamps the answer onto the resource's access events, which is
8732
- * what ambient index consumers replay on — so "PRs are observable" is
8733
- * declared here, route by route, never module-wide. Absent means no read
8734
- * of this module is observable. A vendor's own gone-vocabulary (HTTP 410,
8735
- * a 200-body "ok:false"/"archived:true"/"status:cancelled", or a
8736
- * 403/404-ambiguous lost-access response) is this module's job to
8737
- * translate into `UriNotFoundError` or a `status: 404` error under the
8738
- * observation format — the fold that retires a doc never learns vendor
8739
- * vocabulary (see `ObservationMaterial`'s doc comment).
8740
- */
8741
- observes?(uri: string): boolean;
8742
- /**
8743
- * Head-only revision probe: the resource's CURRENT source-native revision
8744
- * without fetching its body, or `undefined` when that cannot be known
8745
- * cheaply. The host calls it before a repeat `read` of an address the
8746
- * session already holds, with `ctx.expectedRevision` set to the revision
8747
- * that read reported (`RawResourceMetadata.revision`); a value equal to it
8748
- * means "unchanged" and the fetch is skipped, anything else falls through
8749
- * to the ordinary read. A module whose read revision embeds more than the
8750
- * head can know (a content digest beside a stat stamp) may answer relative
8751
- * to `expectedRevision` — return it when the cheap part matches, `undefined`
8752
- * when it does not — but must never return a value it has not verified.
8753
- * `undefined` is always safe: it costs one fetch, never a wrong answer.
8754
- * Must be cheaper than the read (a metadata request, a `stat`); a throw is
8755
- * treated as `undefined`.
8756
- */
8757
- revision?(uri: string, ctx: UriResolveContext): Promise<string | undefined>;
10718
+ }, ctx: UriResolveContext): Promise<UriOperationDescription | undefined>;
8758
10719
  readonly getCachePolicy?: UriCachePolicyResolver;
8759
- /** Retained matching escape hatch; future dispatch should prefer compiled claims. */
8760
- matches(input: string, ctx: UriResolveContext): boolean;
10720
+ /**
10721
+ * Code matching, for the host's own modules whose addresses no claim can describe (a bare file
10722
+ * path). A plugin module has none; it routes through its `claims` alone.
10723
+ */
10724
+ matches?(input: string, ctx: UriResolveContext): boolean;
10725
+ /** The official spelling, for the host's own modules; a plugin's comes from its claims' `normalizeTo`. */
8761
10726
  normalize?(input: string, ctx: UriResolveContext): UriNormalizeResult | undefined;
10727
+ /**
10728
+ * The pill's title and link, for the host's own modules only; a plugin module has none, and its
10729
+ * pill comes from its claims' `title` and `sourceUrl`.
10730
+ */
8762
10731
  describe?(input: string, ctx: UriDescribeContext): UriResourceDescription | undefined;
8763
10732
  locate?(input: string, ctx: UriLocateContext): Promise<UriLocateResult>;
8764
10733
  /**
@@ -8771,33 +10740,21 @@ declare interface UriModule {
8771
10740
  read(input: string, ctx: UriResolveContext): Promise<RawResource>;
8772
10741
  /** Observes only; see {@link read}. */
8773
10742
  help?(input: string, ctx: UriResolveContext): Promise<UriHelp>;
8774
- write?(input: string, content: UriPayload, ctx: UriResolveContext): Promise<UriMutationResult | void>;
8775
- /** Opt-in structured write with one or more host-resolved resources delivered beside the content. */
8776
- writeWithSources?(input: string, content: UriPayload, sources: readonly UriWriteSource[], ctx: UriResolveContext): Promise<UriMutationResult | void>;
8777
- /**
8778
- * Opt-in byte sink: write RAW BYTES to this address, no UTF-8 round trip.
8779
- * `UriPayload` is text/JSON by contract, so a module that can store bytes
8780
- * declares it here instead of stretching `write`. The only caller today is
8781
- * the `write` tool's `source` copy leg, which is how a provider's binary
8782
- * resource — a Gmail attachment, an image, a PDF, a zip — reaches a
8783
- * byte-capable destination without ever being decoded into the model's
8784
- * context. A module that omits it is text-only, and a binary copy targeting
8785
- * it is refused with an error naming a byte-capable destination.
8786
- *
8787
- * `source` describes what the bytes are: a filesystem-backed sink can ignore
8788
- * it (the target path already carries the name), while a remote provider
8789
- * sink needs it to name and type the stored file. It sits before `ctx` so a
8790
- * forwarding wrapper that fails to thread it is a compile error, not a
8791
- * silent drop.
10743
+ /**
10744
+ * `sources` is empty for ordinary writes; populated only with `acceptsWriteSources: true`.
10745
+ * `content` is a `Uint8Array` only with `acceptsBytes: true`, and then `ctx.writeSource`
10746
+ * names and types it. It is `undefined` when the call carried neither `content` nor `source`.
10747
+ * The module decides what that means: a route that takes no body (a folder
10748
+ * create) proceeds, and a route that needs one refuses with an error naming
10749
+ * what is missing. Never treat it as empty content.
8792
10750
  */
8793
- writeBytes?(input: string, bytes: Uint8Array, source: UriSourceDescriptor, ctx: UriResolveContext): Promise<UriMutationResult | void>;
10751
+ write?(input: string, content: UriPayload | Uint8Array | undefined, sources: readonly UriWriteSource[], ctx: UriResolveContext): Promise<UriMutationResult | void>;
8794
10752
  edit?(input: string, patch: UriPayload, ctx: UriResolveContext): Promise<UriMutationResult>;
8795
10753
  /** Observes only; see {@link read}. */
8796
10754
  list?(input: string, params: UriListParams, ctx: UriResolveContext): Promise<UriListResult>;
8797
10755
  /** Observes only; see {@link read}. */
8798
10756
  search?(input: string, params: UriSearchParams, ctx: UriResolveContext): Promise<UriSearchResult>;
8799
10757
  delete?(input: string, ctx: UriResolveContext): Promise<UriMutationResult>;
8800
- toMarkdown?(input: UriMarkdownRenderInput, ctx: UriResolveContext): string | undefined;
8801
10758
  }
8802
10759
 
8803
10760
  /** Authoritative lifecycle facts for a successful record-like URI mutation. */
@@ -8823,6 +10780,12 @@ declare interface UriMutationResult {
8823
10780
  readonly receipt?: UriMutationReceipt;
8824
10781
  /** Opaque source-native revision after this successful mutation. */
8825
10782
  readonly revision?: string;
10783
+ /** Cached reads this mutation made stale; see {@link UriCachePolicy.invalidate}. */
10784
+ readonly cachePolicy?: Pick<UriCachePolicy, "invalidate">;
10785
+ /** The module's own markdown for this result, shown instead of the host's default rendering. */
10786
+ readonly markdown?: string;
10787
+ /** The touched resource's name for the transcript row, as on `RawResource.label`. */
10788
+ readonly label?: UriResourceLabel;
8826
10789
  }
8827
10790
 
8828
10791
  declare interface UriNodeCapability {
@@ -8843,11 +10806,6 @@ declare interface UriNormalizeResult {
8843
10806
 
8844
10807
  declare type UriOperation = "help" | "read" | "write" | "edit" | "list" | "search" | "delete";
8845
10808
 
8846
- /** The call {@link UriModule.amendOperation} rebuilt: the whole payload, in the shape the module reads. */
8847
- declare interface UriOperationAmendment {
8848
- readonly payload: unknown;
8849
- }
8850
-
8851
10809
  declare interface UriOperationDescription {
8852
10810
  /** Static verb phrase authored by the module. Never interpolated from input. */
8853
10811
  readonly action: string;
@@ -8870,9 +10828,11 @@ declare interface UriOperationDescription {
8870
10828
  */
8871
10829
  readonly key?: string;
8872
10830
  /**
8873
- * `true` offers this field to the person for editing on the approval card. Offer it only
8874
- * when the module implements {@link UriModule.amendOperation} for this call and can honour
8875
- * any value within `maxLength`; the host drops the offer otherwise. Absent means read-only.
10831
+ * `true` offers this field to the person for editing on the approval card. The host applies
10832
+ * an edit itself: it copies the payload and replaces the value of the top-level string
10833
+ * property named `key`. So offer a field only when the payload is an object, `key` is one
10834
+ * of its string properties, and the module would send any value within `maxLength` as it
10835
+ * sends the model's; the host drops the offer otherwise. Absent means read-only.
8876
10836
  */
8877
10837
  readonly editable?: true;
8878
10838
  /** Longest edited value, in UTF-16 code units. Meaningful only with `editable`. */
@@ -8890,56 +10850,6 @@ declare interface UriOperationDescription {
8890
10850
  };
8891
10851
  }
8892
10852
 
8893
- /**
8894
- * Pure, route-aware validation that runs before permission policy can surface an ask.
8895
- *
8896
- * This is deliberately narrower than execution: it receives only the canonical URI,
8897
- * operation, and operation payload, performs no I/O, and returns a user-actionable
8898
- * rejection for calls that the module already knows cannot succeed. The handler must
8899
- * still validate again when it executes because approval is not an authority boundary.
8900
- */
8901
- declare interface UriOperationPreflightPolicy {
8902
- /**
8903
- * The rejection half. Optional since kay#7684: a module whose only preflight
8904
- * fact is affirmative (`acceptsPayloadlessWrite`) must not have to stub a
8905
- * validator that never rejects.
8906
- */
8907
- validateOperation?(request: {
8908
- readonly operation: UriOperation;
8909
- readonly uri: string;
8910
- readonly payload: unknown;
8911
- }): string | undefined;
8912
- /**
8913
- * Route-level affirmative: may a `write` to this URI carry NO payload at all
8914
- * — neither `content` nor `source`? (The canonical case is folder creation,
8915
- * e.g. `?type=folder`.) The write tool's generic shape rule requires exactly
8916
- * one payload form; a route answers `true` here when a payloadless write is
8917
- * meaningful FOR THAT ROUTE, and the rule then admits the call.
8918
- *
8919
- * This exists because an empty body is not always sendable: on some
8920
- * model/provider paths a top-level empty-string argument (`content: ""`)
8921
- * never reaches the host — the key arrives absent, indistinguishable from an
8922
- * omitted argument (kay#7684). A contract that can only be invoked with an
8923
- * empty string is unreachable on those paths, so a route whose write is
8924
- * meaningful with no body must declare it and let the caller omit the
8925
- * payload instead.
8926
- *
8927
- * Pure and side-effect-free like {@link validateOperation}: route-parse
8928
- * only, no I/O. A throw NEVER admits the write, but the two consult paths
8929
- * disagree on purpose about what happens next: pre-ask (permission
8930
- * resolution, which must never crash the gate) answers no and records a
8931
- * module-attributed diagnostic; at execute time the write tool asks only
8932
- * when the call genuinely carries no payload, and a throw there is the
8933
- * module's own bug surfacing as the call's error — louder than a misleading
8934
- * \"provide exactly one of content or source\" the model could never
8935
- * satisfy. Absent means no route of this module accepts a payloadless
8936
- * write.
8937
- */
8938
- acceptsPayloadlessWrite?(request: {
8939
- readonly uri: string;
8940
- }): boolean;
8941
- }
8942
-
8943
10853
  declare interface UriParameter {
8944
10854
  readonly name: string;
8945
10855
  readonly in: "uri" | "query" | "selector";
@@ -8949,29 +10859,60 @@ declare interface UriParameter {
8949
10859
  readonly examples?: readonly unknown[];
8950
10860
  }
8951
10861
 
10862
+ /**
10863
+ * A claim on a module's own custom-scheme addresses. The pattern matches with or without an
10864
+ * account prefix: `gcal://@work/events/x` is matched as `gcal://events/x`, and the prefix is put
10865
+ * back on the official spelling, so one claim covers both spellings.
10866
+ */
8952
10867
  declare interface UriPatternClaim {
8953
10868
  readonly kind: "uriPattern";
8954
10869
  readonly pattern: UriPatternInit;
8955
10870
  /**
8956
- * Canonical spelling rebuilt from the captures. When the template keeps the
8957
- * input's scheme (the module's own addressing), the input's query string is
10871
+ * Canonical spelling rebuilt from the captures (see {@link UriClaimTemplate}). When the template
10872
+ * keeps the input's scheme (the module's own addressing), the input's query string is
8958
10873
  * carried over verbatim so a route flag such as `?permanent=true` survives
8959
10874
  * canonicalization (kay#7859); a template that re-targets to another scheme
8960
10875
  * (a projection to a web link) drops it, as does a pattern that consumed the
8961
10876
  * query itself or a template that spells its own.
8962
10877
  */
8963
- readonly normalizeTo?: string;
10878
+ readonly normalizeTo?: UriClaimTemplate;
10879
+ /**
10880
+ * Names the route this claim matches, so data keyed by route (a module's sign-in action rules)
10881
+ * can say which addresses it means. Several claims may name the same route.
10882
+ */
10883
+ readonly route?: string;
10884
+ /**
10885
+ * The web page a matched address opens, filled from the captures (see
10886
+ * {@link UriClaimTemplate}). The host matches an address's official spelling and paints its
10887
+ * reference with the source URL of the first matching claim that declares one.
10888
+ */
10889
+ readonly sourceUrl?: UriClaimTemplate;
10890
+ /**
10891
+ * The name a matched address's reference shows: literal text, with each `:name` replaced by
10892
+ * that capture as decoded (`"Flow :flow"`, or a fixed `"BFS"`). The first matching claim that
10893
+ * declares one names the address.
10894
+ */
10895
+ readonly title?: string;
8964
10896
  readonly examples?: readonly string[];
8965
10897
  }
8966
10898
 
8967
10899
  declare interface UriPatternInit {
8968
10900
  readonly protocol?: string;
10901
+ /**
10902
+ * Dot-delimited host pattern. A pattern that is one capture (`:owner`) takes the whole host,
10903
+ * dots included, as a `github://some.org/repo` owner must.
10904
+ */
8969
10905
  readonly hostname?: string;
8970
10906
  /**
8971
10907
  * Slash-delimited path pattern. A final capture may use `:name*` to consume
8972
- * the remaining path segments, preserving `/` in the captured value.
10908
+ * the remaining path segments, preserving `/` in the captured value. Unless the pattern itself
10909
+ * ends in `/`, an input path ending in one `/` matches as if the slash were absent, so
10910
+ * `threads/t1/` is `threads/t1` (captures and official spelling included) and a lone `/` after a
10911
+ * host is the empty path; a doubled `//` is never dropped, nor the root path of an address with
10912
+ * no host (`bfs:///`).
8973
10913
  */
8974
10914
  readonly pathname?: string;
10915
+ /** `&`-delimited query pattern; `""` matches only an address with no query. */
8975
10916
  readonly search?: string;
8976
10917
  }
8977
10918
 
@@ -8990,7 +10931,7 @@ declare interface UriPayloadContract {
8990
10931
 
8991
10932
  /**
8992
10933
  * The three-state permission vocabulary a plugin declares for its default permissions.
8993
- * Maps to `PermissionRule.effect`: `allow` → allow, `ask` → ask, `never` → deny.
10934
+ * Maps to `PermissionRule.effect`: `allow` -> allow, `ask` -> ask, `never` -> deny.
8994
10935
  */
8995
10936
  declare type UriPermissionDefault = "allow" | "ask" | "never";
8996
10937
 
@@ -9008,19 +10949,6 @@ declare interface UriPermissionDefaults {
9008
10949
  readonly delete?: UriPermissionDefault;
9009
10950
  }
9010
10951
 
9011
- /**
9012
- * One change a person made to an `editable` field of a call's action preview ("Allow with
9013
- * edits"): the field's `key` and the value they want it to hold. Values are message content, so
9014
- * a module must not log or persist them.
9015
- */
9016
- declare interface UriPreviewEdit {
9017
- readonly key: string;
9018
- readonly value: string;
9019
- }
9020
-
9021
- /** The read shape a caller may request via {@link UriResolveContext.format}. */
9022
- declare type UriReadFormat = "observation";
9023
-
9024
10952
  declare interface UriResolveContext {
9025
10953
  readonly cwd: string;
9026
10954
  readonly signal?: AbortSignal;
@@ -9029,8 +10957,8 @@ declare interface UriResolveContext {
9029
10957
  readonly auth?: UriResolvedAuth;
9030
10958
  /**
9031
10959
  * Id of the session dispatching this call, stamped by the host at the dispatch site.
9032
- * It never originates from anything the caller can influence — no verb argument, no write
9033
- * body — so a module may treat it as trustworthy caller identity and stamp it onto writes.
10960
+ * It never originates from anything the caller can influence - no verb argument, no write
10961
+ * body - so a module may treat it as trustworthy caller identity and stamp it onto writes.
9034
10962
  *
9035
10963
  * Absent when no session owns the dispatch: registry matching and permission pre-checks
9036
10964
  * resolve a URI outside any verb call.
@@ -9038,14 +10966,14 @@ declare interface UriResolveContext {
9038
10966
  readonly sessionId?: string;
9039
10967
  /**
9040
10968
  * WHO the dispatching session acts as, stamped by the host at the same dispatch site as
9041
- * {@link UriResolveContext.sessionId} and just as un-influenceable by the caller — so a module
10969
+ * {@link UriResolveContext.sessionId} and just as un-influenceable by the caller - so a module
9042
10970
  * writing to a store it owns can record the actor without the agent being able to choose one.
9043
10971
  *
9044
10972
  * Free text minted by the host's own runtime (Bonsai's form is `user`, `subagent`,
9045
10973
  * `system/<surface>`, `followup/<surface>`) rather than a closed union: the surface half is the
9046
10974
  * host's vocabulary, and a second enumeration of it here would drift from the first.
9047
10975
  *
9048
- * Absent whenever the host has nothing to say — no session owns the dispatch, or the session
10976
+ * Absent whenever the host has nothing to say - no session owns the dispatch, or the session
9049
10977
  * predates the host recording an origin. A module must then omit the actor rather than assume
9050
10978
  * one; an invented actor written into a durable artifact can never be walked back.
9051
10979
  */
@@ -9061,7 +10989,7 @@ declare interface UriResolveContext {
9061
10989
  readonly origin: "model" | "host";
9062
10990
  /**
9063
10991
  * The daemon-assigned id of the run driving this invocation, when the host's own execution
9064
- * frame carried one. Absent means the frame carried none — never a reason to guess one: a
10992
+ * frame carried one. Absent means the frame carried none - never a reason to guess one: a
9065
10993
  * module recording this onto a durable artifact must treat absence as unresolved provenance,
9066
10994
  * not as "no run was active".
9067
10995
  */
@@ -9070,39 +10998,33 @@ declare interface UriResolveContext {
9070
10998
  readonly toolName?: string;
9071
10999
  };
9072
11000
  /**
9073
- * An OPAQUE, host-captured context for the mutation this dispatch is about to make —
11001
+ * An OPAQUE, host-captured context for the mutation this dispatch is about to make -
9074
11002
  * the artifact-provenance counterpart of `sessionId`/`actor`, and stamped at the same
9075
11003
  * un-influenceable dispatch site.
9076
11004
  *
9077
11005
  * The host composes it from facts a caller cannot supply: which session is acting, the
9078
11006
  * run driving it, the tool invocation, and whatever the host resolved about how that
9079
- * session came to exist. The kernel treats it as an uninterpreted JSON value — it never
11007
+ * session came to exist. The kernel treats it as an uninterpreted JSON value - it never
9080
11008
  * reads a field, only checks that the value is lossless JSON before it crosses the
9081
- * dispatch boundary — so this layer stays ignorant of any one product's provenance
11009
+ * dispatch boundary - so this layer stays ignorant of any one product's provenance
9082
11010
  * semantics. A module that owns a durable artifact carries it to its store and validates
9083
11011
  * it against its OWN schema at the point it persists, where the target revision is known.
9084
11012
  *
9085
11013
  * Absent means the host captured nothing for this dispatch (a read, a host with no
9086
- * capture resolver, or a capture that failed) — never a claim that there was nothing to
11014
+ * capture resolver, or a capture that failed) - never a claim that there was nothing to
9087
11015
  * capture. Present only on mutating dispatches (`write`/`edit`/`delete`); reads never pay
9088
11016
  * for it.
9089
11017
  */
9090
11018
  readonly captureContext?: Readonly<Record<string, unknown>>;
9091
11019
  /**
9092
- * Requested read shape. A module may ignore this and return its normal read; honoring
9093
- * it means returning an `ObservationMaterial` via `observationResource(...)` instead.
9094
- * Opt-in only — there is no advertisement surface or capability flag.
9095
- */
9096
- readonly format?: UriReadFormat;
9097
- /**
9098
- * Host-provided writable data root for the OWNING extension of the module handling this call —
11020
+ * Host-provided writable data root for the OWNING extension of the module handling this call -
9099
11021
  * structurally identical to the per-extension `paths` a tool/handler context already receives, so
9100
11022
  * a module authored against both surfaces reads `ctx.paths?.dataDir` uniformly. Lets a URI module
9101
11023
  * own durable local state (a JSON store, a small file tree) instead of the host constructing and
9102
11024
  * injecting it. Host-populated after dispatch selects a module and keyed to that module's owner;
9103
11025
  * always absent during matching, and absent for modules with no owning extension (builtins) or a
9104
11026
  * host that wires no per-module data dir. Unlike a tool context, the host only NAMES this path for
9105
- * a URI module and does NOT pre-create the directory — create it on first write and tolerate its
11027
+ * a URI module and does NOT pre-create the directory - create it on first write and tolerate its
9106
11028
  * absence on read.
9107
11029
  */
9108
11030
  readonly paths?: {
@@ -9117,6 +11039,15 @@ declare interface UriResolveContext {
9117
11039
  * proceeds as before.
9118
11040
  */
9119
11041
  readonly expectedRevision?: string;
11042
+ /**
11043
+ * The revision this session already holds for the address a `read` is about to fetch: the
11044
+ * `RawResourceMetadata.revision` its last read reported. Set only on a repeat `read`, never
11045
+ * on a mutation (`expectedRevision` is the mutation witness). A module with a cheap
11046
+ * current-revision check (a metadata request, a `stat`) may compare first and, when it has
11047
+ * verified the two are equal, answer {@link RawResource.unchanged} with no body. A module
11048
+ * with no such check ignores it and reads in full, which is always correct.
11049
+ */
11050
+ readonly knownRevision?: string;
9120
11051
  /** Host marks a mediated session that enforces its private revision witness ledger. */
9121
11052
  readonly requiresRevisionWitness?: boolean;
9122
11053
  /** Host-derived descriptor for a top-level copied resource; absent for inline writes. */
@@ -9126,26 +11057,13 @@ declare interface UriResolveContext {
9126
11057
  declare interface UriResolvedAuth {
9127
11058
  readonly connection?: UriConnection;
9128
11059
  /** Present only for verb handlers of a module declaring `requiresAuth`; absent during matching. */
9129
- readonly credential?: UriResolvedCredential;
11060
+ readonly credential?: ResolvedCredential;
9130
11061
  /** Present for handlers gated by a non-injectable external-CLI readiness scheme. */
9131
11062
  readonly externalCli?: UriExternalCliRunner;
9132
11063
  /** Opaque host metadata; not a credential channel. */
9133
11064
  readonly metadata?: Record<string, unknown>;
9134
11065
  }
9135
11066
 
9136
- declare interface UriResolvedCredential {
9137
- /** Bearer for OAuth schemes, apiKey for api-key schemes. Host-resolved and refreshed. */
9138
- readonly accessToken: string;
9139
- readonly accountId: string;
9140
- readonly schemeId: string;
9141
- readonly scopes?: readonly string[];
9142
- /**
9143
- * Every value of a multi-field api-key credential, keyed by the scheme's declared field id
9144
- * (`accessToken` mirrors the primary field). Absent for single-secret schemes.
9145
- */
9146
- readonly fields?: Readonly<Record<string, string>>;
9147
- }
9148
-
9149
11067
  declare interface UriResourceDescription {
9150
11068
  readonly uri: string;
9151
11069
  /** Absent when the caller should retain its existing label. */
@@ -9165,12 +11083,9 @@ declare interface UriResourceLabel {
9165
11083
  readonly section?: string;
9166
11084
  }
9167
11085
 
9168
- /** The call a module is asked to label. */
9169
- declare interface UriResourceLabelRequest {
9170
- readonly operation: UriOperation;
9171
- /** The dispatch address: selector-stripped, the exact form the module's verb handler received. */
9172
- readonly uri: string;
9173
- }
11086
+ declare const UriScheme: z.ZodString;
11087
+
11088
+ declare type UriScheme = z.infer<typeof UriScheme>;
9174
11089
 
9175
11090
  declare interface UriSchemeClaim {
9176
11091
  readonly kind: "scheme";
@@ -9205,15 +11120,21 @@ declare interface UriSearchResult {
9205
11120
  * so the caller knows the matches may be partial.
9206
11121
  */
9207
11122
  readonly metadata?: UriListMetadata;
11123
+ /** How long the host may cache this result; see {@link UriCachePolicy.ttlMs}. */
11124
+ readonly cachePolicy?: Pick<UriCachePolicy, "ttlMs">;
11125
+ /** The module's own markdown for this result, shown instead of the host's default rendering. */
11126
+ readonly markdown?: string;
11127
+ /** The touched resource's name for the transcript row, as on `RawResource.label`. */
11128
+ readonly label?: UriResourceLabel;
9208
11129
  }
9209
11130
 
9210
11131
  /**
9211
11132
  * What a copied resource IS, minus its bytes: the identity half of a mediated
9212
11133
  * source. The host derives it once (filename inferred from the source address,
9213
11134
  * `mimeType` carried from the source module's own `RawResource.mimeType`) and
9214
- * delivers it on both byte-bearing write hooks — inside each `UriWriteSource`,
9215
- * and as the standalone third argument to `writeBytes` — so a remote sink can
9216
- * name and type what it stores without re-deriving either from raw bytes.
11135
+ * delivers it inside each `UriWriteSource`, and on `ctx.writeSource` for a
11136
+ * `source` copy - so a remote sink can name and type what it stores without
11137
+ * re-deriving either from raw bytes.
9217
11138
  */
9218
11139
  declare interface UriSourceDescriptor {
9219
11140
  readonly uri: string;
@@ -9228,11 +11149,11 @@ declare interface UriTemplate {
9228
11149
  /**
9229
11150
  * Per-operation effect docs for this route, keyed by operation. A route
9230
11151
  * whose shared {@link description} spans several verbs ("Read, edit, or
9231
- * trash a thread") is ambiguous for any surface that groups by verb — a
11152
+ * trash a thread") is ambiguous for any surface that groups by verb - a
9232
11153
  * permission view must not describe `read` with a sentence that mentions
9233
11154
  * trashing. Each entry says what THAT operation concretely does at THIS
9234
11155
  * route; operations without an entry fall back to the shared description.
9235
- * Additive and optional — existing templates are unaffected.
11156
+ * Additive and optional - existing templates are unaffected.
9236
11157
  */
9237
11158
  readonly operationDocs?: Partial<Record<UriOperation, string>>;
9238
11159
  /**
@@ -9272,13 +11193,13 @@ declare interface UriValidationMessage {
9272
11193
 
9273
11194
  /**
9274
11195
  * Author-declared, human-facing documentation of what each supported verb
9275
- * CONCRETELY does against the provider — the capability half of a module's
11196
+ * CONCRETELY does against the provider - the capability half of a module's
9276
11197
  * boolean verb-support declaration. Written for a permission/capability
9277
11198
  * surface ("what am I allowing?"), not for the model: one plain sentence per
9278
11199
  * verb naming the real-world effect ("Sends mail, creates/updates drafts,
9279
11200
  * applies label changes"), never wire mechanics or URI shapes. Verbs the
9280
11201
  * module does not support are omitted; at runtime a supported verb with no
9281
- * entry simply renders undocumented (fail-open metadata) — but for a plugin's
11202
+ * entry simply renders undocumented (fail-open metadata) - but for a plugin's
9282
11203
  * `kay.agent` URI modules, `auditPluginDisclosure` (`@bonsai/plugin-sdk/
9283
11204
  * disclosure`) enforces coverage of every supported verb at authoring/load
9284
11205
  * time.
@@ -9286,7 +11207,7 @@ declare interface UriValidationMessage {
9286
11207
  * Lives here in the protocol layer (beside {@link UriTemplate.operationDocs},
9287
11208
  * its per-route sibling) so both `@herd/uri-extensions`' `UriExtensionModule`
9288
11209
  * and herd-agent's kernel `UriModule` can carry it without inverting the
9289
- * `@herd/uri` ← `@herd/uri-extensions` dependency.
11210
+ * `@herd/uri` <- `@herd/uri-extensions` dependency.
9290
11211
  */
9291
11212
  declare interface UriVerbDocs {
9292
11213
  /** What a `read` of this address space returns (also covers `help`). */
@@ -9309,6 +11230,7 @@ declare interface UriVerbSupport {
9309
11230
  readonly editable: boolean;
9310
11231
  readonly deletable?: boolean;
9311
11232
  readonly listable: boolean;
11233
+ readonly searchable?: boolean;
9312
11234
  }
9313
11235
 
9314
11236
  /** A mediated resource supplied beside structured write content without entering model context. */
@@ -9316,10 +11238,15 @@ declare interface UriWriteSource extends UriSourceDescriptor {
9316
11238
  readonly content: string | Uint8Array;
9317
11239
  }
9318
11240
 
11241
+ /** {@link hostWithinDomain} over a URL's hostname; an unparseable URL is never within. */
11242
+ declare function urlHostWithinDomain(url: string, domain: string): boolean;
11243
+
11244
+ /** A claim on a public web link (`http` or `https`), usually folded onto the module's own scheme. */
9319
11245
  declare interface UrlPatternClaim {
9320
11246
  readonly kind: "urlPattern";
9321
11247
  readonly pattern: UriPatternInit;
9322
- readonly normalizeTo?: string;
11248
+ readonly normalizeTo?: UriClaimTemplate;
11249
+ readonly route?: string;
9323
11250
  readonly examples?: readonly string[];
9324
11251
  }
9325
11252
 
@@ -9366,6 +11293,66 @@ declare interface ValidateApiKeyCredentialResult {
9366
11293
 
9367
11294
  declare type ValidatePluginApiKeyCredential = ValidateApiKeyCredential;
9368
11295
 
11296
+ /**
11297
+ * ---
11298
+ * responsibility: The one interface through which a vendored-MCP plugin's code calls a tool on its
11299
+ * own vendored MCP server, so every read-through plugin and the daemon that implements the port
11300
+ * agree on the same shape by construction.
11301
+ * owns:
11302
+ * - {@link VendoredMcpPort} - what a plugin's URI module and tools call.
11303
+ * - {@link VendoredMcpOutcome} - the typed result a plugin decodes, including every failure it
11304
+ * must surface to the agent rather than swallow.
11305
+ * does_not_own:
11306
+ * - The implementation. A plugin never dials MCP itself: it takes the port from
11307
+ * `api.vendoredMcp.port(server)` (`@bonsai/plugin-sdk/kay-agent`), which the daemon binds to the
11308
+ * plugin's own hosted server over its MCP host. Plugin source stays host-free, and a plugin
11309
+ * under test substitutes a fake port.
11310
+ * - Which tool names exist. `TTool` is the plugin's own union of the vendor tools it calls; the
11311
+ * port is generic so a typo in a tool name fails typecheck inside the plugin.
11312
+ * ---
11313
+ */
11314
+ /**
11315
+ * Why a call failed, as the plugin must tell the agent. `needs-auth` carries the exact service to
11316
+ * reconnect (`serviceId`) so a plugin can name it in its error instead of returning an empty
11317
+ * result; today's plugins name their statically declared `requiresAuth` service instead, which is
11318
+ * the same service for a single-service plugin. `unknown-server` and `unknown-tool` are wiring
11319
+ * faults (a server Bonsai does not host for this plugin, or a tool name the server does not have)
11320
+ * and stay loud for the same reason: an unreachable host must never decode as "no data".
11321
+ */
11322
+ declare type VendoredMcpFailureReason = "needs-auth" | "unknown-server" | "unknown-tool" | "failed";
11323
+
11324
+ declare type VendoredMcpOutcome =
11325
+ /**
11326
+ * `value` is the tool's `structuredContent` when it sent one, else its text content parsed as
11327
+ * JSON, else that text as a string: a vendor tool that answers in prose (a transcript, a
11328
+ * markdown summary) is a result, not a failure. A route that needs a record rejects a string
11329
+ * itself, with its own message.
11330
+ */
11331
+ {
11332
+ readonly ok: true;
11333
+ readonly value: unknown;
11334
+ } | {
11335
+ readonly ok: false;
11336
+ readonly reason: VendoredMcpFailureReason;
11337
+ readonly message: string;
11338
+ /** Exact reconnect target supplied by the MCP host for an auth failure. */
11339
+ readonly serviceId?: string;
11340
+ };
11341
+
11342
+ /**
11343
+ * One vendored MCP server, as the plugin that declares it calls it. `invoke` calls any tool the
11344
+ * server has, whether it reads or writes. The port checks no permission of its own: a call is as
11345
+ * permitted as the plugin tool or URI verb that makes it.
11346
+ */
11347
+ declare interface VendoredMcpPort<TTool extends string = string> {
11348
+ invoke(input: {
11349
+ /** The session's working directory; the host resolves the server binding per cwd. */
11350
+ readonly cwd: string;
11351
+ readonly tool: TTool;
11352
+ readonly args: Readonly<Record<string, unknown>>;
11353
+ }): Promise<VendoredMcpOutcome>;
11354
+ }
11355
+
9369
11356
  /** Creates a Void type. */
9370
11357
  declare function Void(options?: TSchemaOptions): TVoid;
9371
11358
 
@@ -9400,8 +11387,8 @@ declare const WhiteboardEntryInfo: z.ZodObject<{
9400
11387
  authorSessionId: z.ZodNullable<z.ZodString>;
9401
11388
  }, z.core.$strict>>;
9402
11389
  state: z.ZodEnum<{
9403
- available: "available";
9404
11390
  unavailable: "unavailable";
11391
+ available: "available";
9405
11392
  "unsupported-version": "unsupported-version";
9406
11393
  invalid: "invalid";
9407
11394
  }>;
@@ -9422,8 +11409,8 @@ declare const WhiteboardEntryInspection: z.ZodObject<{
9422
11409
  authorSessionId: z.ZodNullable<z.ZodString>;
9423
11410
  }, z.core.$strict>>;
9424
11411
  state: z.ZodEnum<{
9425
- available: "available";
9426
11412
  unavailable: "unavailable";
11413
+ available: "available";
9427
11414
  "unsupported-version": "unsupported-version";
9428
11415
  invalid: "invalid";
9429
11416
  }>;