@yaklabs-ai/plugin-sdk 0.41.0 → 0.42.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -13,7 +13,7 @@ it under the name your plugin code actually imports:
13
13
  ```json
14
14
  {
15
15
  "dependencies": {
16
- "@bonsai/plugin-sdk": "npm:@yaklabs-ai/plugin-sdk@^0.41.0"
16
+ "@bonsai/plugin-sdk": "npm:@yaklabs-ai/plugin-sdk@^0.42.1"
17
17
  }
18
18
  }
19
19
  ```
@@ -62,7 +62,7 @@ Every tool the entrypoint registers is declared in the manifest too:
62
62
  "description": "Greets people by name.",
63
63
  "version": "0.1.0",
64
64
  "namespace": "widgets",
65
- "compatibility": { "sdk": "^0.41.0" },
65
+ "compatibility": { "sdk": "^0.42.1" },
66
66
  "targets": {
67
67
  "kay": {
68
68
  "agent": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "package": "@yaklabs-ai/plugin-sdk",
4
- "version": "0.41.0",
4
+ "version": "0.42.1",
5
5
  "target": "npm",
6
6
  "firstPartyLicense": "MIT",
7
7
  "bundled": [
@@ -2417,8 +2417,15 @@ declare const KAY_PLUGIN_PROTOCOL_VERSION: "kay.plugin.v1";
2417
2417
  *
2418
2418
  * 0.41.0 adds app.mcp.callTool for background calls to a plugin's own manifest-declared MCP
2419
2419
  * servers, using Bonsai's managed connection without a session or working directory (#16172).
2420
+ *
2421
+ * 0.42.0 hands background work the shared ResolvedCredential in auth.credential. Workflow
2422
+ * accounts carry auth resolution outcomes, and Poller callbacks receive only the credential.
2423
+ * Older SDK ranges are refused because their background success shape is no longer served.
2424
+ *
2425
+ * 0.42.1 adds current-session tool lifetimes and invocation-bound artifact reads/new outputs,
2426
+ * plus described-tool execution, guidance and permission resource metadata.
2420
2427
  */
2421
- declare const KAY_PLUGIN_SDK_VERSION: "0.41.0";
2428
+ declare const KAY_PLUGIN_SDK_VERSION: "0.42.1";
2422
2429
 
2423
2430
  declare const KAY_PLUGIN_TARGET_NAMES: readonly ["kay.agent", "kay.app", "kay.ui"];
2424
2431
 
@@ -2867,8 +2874,42 @@ declare interface KayAgentProcessRunResult {
2867
2874
  readonly stderrTruncated?: boolean;
2868
2875
  }
2869
2876
 
2877
+ /** A loaded session's volatile lifetime. Reopening a released session gets a fresh key. */
2878
+ declare interface KayAgentSession {
2879
+ readonly key: string;
2880
+ /** Registers synchronous cleanup, invoked once on release. Returns an unregister function. */
2881
+ onDispose(disposer: () => void): () => void;
2882
+ /** Valid only while this tool call is active. */
2883
+ readonly artifacts: KayAgentSessionArtifacts;
2884
+ }
2885
+
2886
+ /** Metadata returned by a current-session artifact operation; no filesystem authority. */
2887
+ declare interface KayAgentSessionArtifact {
2888
+ readonly uri: string;
2889
+ readonly name: string;
2890
+ readonly mimeType?: string;
2891
+ }
2892
+
2893
+ /** Current-session file access, authorized at each call; never retained between tool calls. */
2894
+ declare interface KayAgentSessionArtifacts {
2895
+ readBytes(input: {
2896
+ readonly uri: string;
2897
+ readonly maxBytes?: number;
2898
+ }): Promise<KayAgentSessionArtifact & {
2899
+ readonly bytes: Uint8Array;
2900
+ }>;
2901
+ publishNew(input: {
2902
+ readonly name: string;
2903
+ readonly bytes: Uint8Array;
2904
+ }): Promise<KayAgentSessionArtifact>;
2905
+ }
2906
+
2907
+ declare type KayAgentToolContext = Parameters<ToolDefinition["execute"]>[4] & {
2908
+ readonly session?: KayAgentSession;
2909
+ };
2910
+
2870
2911
  /** The `execute` a plugin supplies for a tool its manifest describes. */
2871
- declare type KayAgentToolExecute = ToolDefinition["execute"];
2912
+ declare type KayAgentToolExecute = (toolCallId: string, params: Parameters<ToolDefinition["execute"]>[1], signal: AbortSignal | undefined, onUpdate: Parameters<ToolDefinition["execute"]>[3], ctx: KayAgentToolContext) => ReturnType<ToolDefinition["execute"]>;
2872
2913
 
2873
2914
  /**
2874
2915
  * Calls tools on the plugin's own vendored MCP servers. See {@link KayAgentPluginApi.vendoredMcp}.
@@ -3085,13 +3126,14 @@ declare interface KayAppUserFileEntry {
3085
3126
  * The plugin-facing user-files contract: file I/O in folders the user owns, done by the host on
3086
3127
  * its own worker threads.
3087
3128
  *
3088
- * Ungated and always present, like `app.paths`. It confers no authority: a plugin runs in the
3089
- * daemon's process and can call `node:fs` itself. What the door adds is where the work runs. A
3090
- * `node:fs` sync call blocks the daemon's event loop for as long as the path takes to answer,
3091
- * which under a macOS-protected folder or on a drive that stopped answering can be a very long
3092
- * time (kay#11575); an async one holds a thread of the pool the whole daemon shares. The host runs
3093
- * each request on a dedicated worker, gives it a deadline, and answers a typed result instead of
3094
- * throwing.
3129
+ * Ungated and always present, like `app.paths`. It confers no authority: the process a plugin
3130
+ * runs in, the daemon or the plugin host, could call `node:fs` itself. What the door adds is where
3131
+ * the work runs. A `node:fs` sync call blocks that process's event loop for as long as the path
3132
+ * takes to answer, which under a macOS-protected folder or on a drive that stopped answering can
3133
+ * be a very long time (kay#11575); an async one holds a thread of the pool the whole process
3134
+ * shares. The daemon's user-files service runs each request on a dedicated worker, gives it a
3135
+ * deadline, and answers a typed result instead of throwing. A plugin in the plugin host reaches
3136
+ * the same service: each call is sent to the daemon and answered from there.
3095
3137
  *
3096
3138
  * This is a leaf module. It lives beside both target SDKs, like `time.ts`, so the `kay.agent` SDK
3097
3139
  * exposes the same door without importing the `kay.app` surface.
@@ -3132,7 +3174,12 @@ declare interface KayAppUserFiles {
3132
3174
  }
3133
3175
 
3134
3176
  declare interface KayAppUserFilesCallOptions {
3135
- /** Deadline in milliseconds from the call, waiting included. Default 5000, at most 60000. */
3177
+ /**
3178
+ * Deadline in milliseconds, waiting included. Default 5000, at most 60000. It starts when the
3179
+ * daemon's user-files service receives the request: from the call in the daemon, or, for a
3180
+ * plugin in the plugin host, once the request has crossed to the daemon. A daemon that never
3181
+ * reads the request leaves the call waiting until the host's connection to it is closed.
3182
+ */
3136
3183
  readonly timeoutMs?: number;
3137
3184
  readonly signal?: AbortSignal;
3138
3185
  }
@@ -1629,7 +1629,7 @@ declare class InvalidLiteralValue extends Error {
1629
1629
  * `ctx` (with a `credential` for an auth-gated tool) to exercise anything beyond the
1630
1630
  * happy-path default.
1631
1631
  */
1632
- export declare function invokeToolForTest<TDetails = unknown>(tool: ToolDefinition<any, TDetails>, params: Record<string, unknown>, ctx?: ToolContext): Promise<AgentToolResult<TDetails>>;
1632
+ export declare function invokeToolForTest<TDetails = unknown>(tool: ToolDefinition<any, TDetails>, params: Record<string, unknown>, ctx?: KayAgentToolContext): Promise<AgentToolResult<TDetails>>;
1633
1633
 
1634
1634
  /** Returns true if the given value is a TAny. */
1635
1635
  declare function IsAny(value: unknown): value is TAny;
@@ -2471,8 +2471,15 @@ declare const KAY_PLUGIN_PROTOCOL_VERSION: "kay.plugin.v1";
2471
2471
  *
2472
2472
  * 0.41.0 adds app.mcp.callTool for background calls to a plugin's own manifest-declared MCP
2473
2473
  * servers, using Bonsai's managed connection without a session or working directory (#16172).
2474
+ *
2475
+ * 0.42.0 hands background work the shared ResolvedCredential in auth.credential. Workflow
2476
+ * accounts carry auth resolution outcomes, and Poller callbacks receive only the credential.
2477
+ * Older SDK ranges are refused because their background success shape is no longer served.
2478
+ *
2479
+ * 0.42.1 adds current-session tool lifetimes and invocation-bound artifact reads/new outputs,
2480
+ * plus described-tool execution, guidance and permission resource metadata.
2474
2481
  */
2475
- declare const KAY_PLUGIN_SDK_VERSION: "0.41.0";
2482
+ declare const KAY_PLUGIN_SDK_VERSION: "0.42.1";
2476
2483
 
2477
2484
  declare const KAY_PLUGIN_TARGET_NAMES: readonly ["kay.agent", "kay.app", "kay.ui"];
2478
2485
 
@@ -2918,8 +2925,42 @@ declare interface KayAgentProcessRunResult {
2918
2925
  readonly stderrTruncated?: boolean;
2919
2926
  }
2920
2927
 
2928
+ /** A loaded session's volatile lifetime. Reopening a released session gets a fresh key. */
2929
+ declare interface KayAgentSession {
2930
+ readonly key: string;
2931
+ /** Registers synchronous cleanup, invoked once on release. Returns an unregister function. */
2932
+ onDispose(disposer: () => void): () => void;
2933
+ /** Valid only while this tool call is active. */
2934
+ readonly artifacts: KayAgentSessionArtifacts;
2935
+ }
2936
+
2937
+ /** Metadata returned by a current-session artifact operation; no filesystem authority. */
2938
+ declare interface KayAgentSessionArtifact {
2939
+ readonly uri: string;
2940
+ readonly name: string;
2941
+ readonly mimeType?: string;
2942
+ }
2943
+
2944
+ /** Current-session file access, authorized at each call; never retained between tool calls. */
2945
+ declare interface KayAgentSessionArtifacts {
2946
+ readBytes(input: {
2947
+ readonly uri: string;
2948
+ readonly maxBytes?: number;
2949
+ }): Promise<KayAgentSessionArtifact & {
2950
+ readonly bytes: Uint8Array;
2951
+ }>;
2952
+ publishNew(input: {
2953
+ readonly name: string;
2954
+ readonly bytes: Uint8Array;
2955
+ }): Promise<KayAgentSessionArtifact>;
2956
+ }
2957
+
2958
+ declare type KayAgentToolContext = Parameters<ToolDefinition["execute"]>[4] & {
2959
+ readonly session?: KayAgentSession;
2960
+ };
2961
+
2921
2962
  /** The `execute` a plugin supplies for a tool its manifest describes. */
2922
- declare type KayAgentToolExecute = ToolDefinition["execute"];
2963
+ declare type KayAgentToolExecute = (toolCallId: string, params: Parameters<ToolDefinition["execute"]>[1], signal: AbortSignal | undefined, onUpdate: Parameters<ToolDefinition["execute"]>[3], ctx: KayAgentToolContext) => ReturnType<ToolDefinition["execute"]>;
2923
2964
 
2924
2965
  /**
2925
2966
  * Calls tools on the plugin's own vendored MCP servers. See {@link KayAgentPluginApi.vendoredMcp}.
@@ -3136,13 +3177,14 @@ declare interface KayAppUserFileEntry {
3136
3177
  * The plugin-facing user-files contract: file I/O in folders the user owns, done by the host on
3137
3178
  * its own worker threads.
3138
3179
  *
3139
- * Ungated and always present, like `app.paths`. It confers no authority: a plugin runs in the
3140
- * daemon's process and can call `node:fs` itself. What the door adds is where the work runs. A
3141
- * `node:fs` sync call blocks the daemon's event loop for as long as the path takes to answer,
3142
- * which under a macOS-protected folder or on a drive that stopped answering can be a very long
3143
- * time (kay#11575); an async one holds a thread of the pool the whole daemon shares. The host runs
3144
- * each request on a dedicated worker, gives it a deadline, and answers a typed result instead of
3145
- * throwing.
3180
+ * Ungated and always present, like `app.paths`. It confers no authority: the process a plugin
3181
+ * runs in, the daemon or the plugin host, could call `node:fs` itself. What the door adds is where
3182
+ * the work runs. A `node:fs` sync call blocks that process's event loop for as long as the path
3183
+ * takes to answer, which under a macOS-protected folder or on a drive that stopped answering can
3184
+ * be a very long time (kay#11575); an async one holds a thread of the pool the whole process
3185
+ * shares. The daemon's user-files service runs each request on a dedicated worker, gives it a
3186
+ * deadline, and answers a typed result instead of throwing. A plugin in the plugin host reaches
3187
+ * the same service: each call is sent to the daemon and answered from there.
3146
3188
  *
3147
3189
  * This is a leaf module. It lives beside both target SDKs, like `time.ts`, so the `kay.agent` SDK
3148
3190
  * exposes the same door without importing the `kay.app` surface.
@@ -3183,7 +3225,12 @@ declare interface KayAppUserFiles {
3183
3225
  }
3184
3226
 
3185
3227
  declare interface KayAppUserFilesCallOptions {
3186
- /** Deadline in milliseconds from the call, waiting included. Default 5000, at most 60000. */
3228
+ /**
3229
+ * Deadline in milliseconds, waiting included. Default 5000, at most 60000. It starts when the
3230
+ * daemon's user-files service receives the request: from the call in the daemon, or, for a
3231
+ * plugin in the plugin host, once the request has crossed to the daemon. A daemon that never
3232
+ * reads the request leaves the call waiting until the host's connection to it is closed.
3233
+ */
3187
3234
  readonly timeoutMs?: number;
3188
3235
  readonly signal?: AbortSignal;
3189
3236
  }
@@ -5495,6 +5542,12 @@ declare const ResolvedPluginContractV1: z.ZodObject<{
5495
5542
  displayName: z.ZodOptional<z.ZodString>;
5496
5543
  description: z.ZodOptional<z.ZodString>;
5497
5544
  parameters: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<authoringCommonSchemas.JsonValue, unknown, z.core.$ZodTypeInternals<authoringCommonSchemas.JsonValue, unknown>>>>;
5545
+ executionMode: z.ZodOptional<z.ZodEnum<{
5546
+ sequential: "sequential";
5547
+ parallel: "parallel";
5548
+ }>>;
5549
+ promptSnippet: z.ZodOptional<z.ZodString>;
5550
+ promptGuidelines: z.ZodOptional<z.ZodArray<z.ZodString>>;
5498
5551
  requiresAuth: z.ZodOptional<z.ZodObject<{
5499
5552
  serviceId: z.ZodString;
5500
5553
  schemeId: z.ZodOptional<z.ZodString>;
@@ -5507,6 +5560,8 @@ declare const ResolvedPluginContractV1: z.ZodObject<{
5507
5560
  execute: "execute";
5508
5561
  }>;
5509
5562
  ruleKey: z.ZodOptional<z.ZodString>;
5563
+ scheme: z.ZodOptional<z.ZodString>;
5564
+ resourcePrefix: z.ZodOptional<z.ZodString>;
5510
5565
  resourceArgs: z.ZodOptional<z.ZodArray<z.ZodString>>;
5511
5566
  }, z.core.$strict>>;
5512
5567
  localId: z.ZodString;
@@ -5796,6 +5851,7 @@ declare const ResolvedPluginContractV1: z.ZodObject<{
5796
5851
  "artifacts.read": "artifacts.read";
5797
5852
  "artifacts.preview": "artifacts.preview";
5798
5853
  "markdown.document-view": "markdown.document-view";
5854
+ "references.open": "references.open";
5799
5855
  "billing.read": "billing.read";
5800
5856
  "automations.read": "automations.read";
5801
5857
  "automations.run": "automations.run";
@@ -124,14 +124,15 @@ function createKayPluginLog(write, bound = {}) {
124
124
 
125
125
  // packages/plugin-sdk/dist/kay-agent/declared-tool.js
126
126
  function permissionHint(permission) {
127
- const { kind, ruleKey, resourceArgs } = permission;
127
+ const { kind, ruleKey, resourceArgs, scheme, resourcePrefix } = permission;
128
128
  return {
129
129
  kind,
130
+ ...scheme === void 0 ? {} : { scheme },
130
131
  ...ruleKey === void 0 ? {} : { ruleKey },
131
132
  ...resourceArgs === void 0 ? {} : {
132
133
  deriveResources: (input) => resourceArgs.flatMap((arg) => {
133
134
  const value = input[arg];
134
- return typeof value === "string" ? [value] : [];
135
+ return typeof value === "string" ? [`${resourcePrefix ?? ""}${value}`] : [];
135
136
  })
136
137
  }
137
138
  };
@@ -146,6 +147,9 @@ function declaredToolDefinition(tool, execute) {
146
147
  label: tool.displayName ?? tool.toolName,
147
148
  description,
148
149
  parameters,
150
+ ...tool.executionMode === void 0 ? {} : { executionMode: tool.executionMode },
151
+ ...tool.promptSnippet === void 0 ? {} : { promptSnippet: tool.promptSnippet },
152
+ ...tool.promptGuidelines === void 0 ? {} : { promptGuidelines: tool.promptGuidelines },
149
153
  ...requiresAuth === void 0 ? {} : {
150
154
  requiresAuth: {
151
155
  serviceId: requiresAuth.serviceId,
@@ -2746,8 +2746,15 @@ declare const KAY_PLUGIN_PROTOCOL_VERSION: "kay.plugin.v1";
2746
2746
  *
2747
2747
  * 0.41.0 adds app.mcp.callTool for background calls to a plugin's own manifest-declared MCP
2748
2748
  * servers, using Bonsai's managed connection without a session or working directory (#16172).
2749
+ *
2750
+ * 0.42.0 hands background work the shared ResolvedCredential in auth.credential. Workflow
2751
+ * accounts carry auth resolution outcomes, and Poller callbacks receive only the credential.
2752
+ * Older SDK ranges are refused because their background success shape is no longer served.
2753
+ *
2754
+ * 0.42.1 adds current-session tool lifetimes and invocation-bound artifact reads/new outputs,
2755
+ * plus described-tool execution, guidance and permission resource metadata.
2749
2756
  */
2750
- declare const KAY_PLUGIN_SDK_VERSION: "0.41.0";
2757
+ declare const KAY_PLUGIN_SDK_VERSION: "0.42.1";
2751
2758
 
2752
2759
  declare const KAY_PLUGIN_TARGET_NAMES: readonly ["kay.agent", "kay.app", "kay.ui"];
2753
2760
 
@@ -3225,8 +3232,42 @@ export declare interface KayAgentProcessRunResult {
3225
3232
  readonly stderrTruncated?: boolean;
3226
3233
  }
3227
3234
 
3235
+ /** A loaded session's volatile lifetime. Reopening a released session gets a fresh key. */
3236
+ export declare interface KayAgentSession {
3237
+ readonly key: string;
3238
+ /** Registers synchronous cleanup, invoked once on release. Returns an unregister function. */
3239
+ onDispose(disposer: () => void): () => void;
3240
+ /** Valid only while this tool call is active. */
3241
+ readonly artifacts: KayAgentSessionArtifacts;
3242
+ }
3243
+
3244
+ /** Metadata returned by a current-session artifact operation; no filesystem authority. */
3245
+ export declare interface KayAgentSessionArtifact {
3246
+ readonly uri: string;
3247
+ readonly name: string;
3248
+ readonly mimeType?: string;
3249
+ }
3250
+
3251
+ /** Current-session file access, authorized at each call; never retained between tool calls. */
3252
+ export declare interface KayAgentSessionArtifacts {
3253
+ readBytes(input: {
3254
+ readonly uri: string;
3255
+ readonly maxBytes?: number;
3256
+ }): Promise<KayAgentSessionArtifact & {
3257
+ readonly bytes: Uint8Array;
3258
+ }>;
3259
+ publishNew(input: {
3260
+ readonly name: string;
3261
+ readonly bytes: Uint8Array;
3262
+ }): Promise<KayAgentSessionArtifact>;
3263
+ }
3264
+
3265
+ export declare type KayAgentToolContext = Parameters<ToolDefinition["execute"]>[4] & {
3266
+ readonly session?: KayAgentSession;
3267
+ };
3268
+
3228
3269
  /** The `execute` a plugin supplies for a tool its manifest describes. */
3229
- export declare type KayAgentToolExecute = ToolDefinition["execute"];
3270
+ export declare type KayAgentToolExecute = (toolCallId: string, params: Parameters<ToolDefinition["execute"]>[1], signal: AbortSignal | undefined, onUpdate: Parameters<ToolDefinition["execute"]>[3], ctx: KayAgentToolContext) => ReturnType<ToolDefinition["execute"]>;
3230
3271
 
3231
3272
  /**
3232
3273
  * The facts a plugin declares about a URI module in its manifest (`contributes.uriModules[]`), so
@@ -3461,13 +3502,14 @@ export declare interface KayAppUserFileEntry {
3461
3502
  * The plugin-facing user-files contract: file I/O in folders the user owns, done by the host on
3462
3503
  * its own worker threads.
3463
3504
  *
3464
- * Ungated and always present, like `app.paths`. It confers no authority: a plugin runs in the
3465
- * daemon's process and can call `node:fs` itself. What the door adds is where the work runs. A
3466
- * `node:fs` sync call blocks the daemon's event loop for as long as the path takes to answer,
3467
- * which under a macOS-protected folder or on a drive that stopped answering can be a very long
3468
- * time (kay#11575); an async one holds a thread of the pool the whole daemon shares. The host runs
3469
- * each request on a dedicated worker, gives it a deadline, and answers a typed result instead of
3470
- * throwing.
3505
+ * Ungated and always present, like `app.paths`. It confers no authority: the process a plugin
3506
+ * runs in, the daemon or the plugin host, could call `node:fs` itself. What the door adds is where
3507
+ * the work runs. A `node:fs` sync call blocks that process's event loop for as long as the path
3508
+ * takes to answer, which under a macOS-protected folder or on a drive that stopped answering can
3509
+ * be a very long time (kay#11575); an async one holds a thread of the pool the whole process
3510
+ * shares. The daemon's user-files service runs each request on a dedicated worker, gives it a
3511
+ * deadline, and answers a typed result instead of throwing. A plugin in the plugin host reaches
3512
+ * the same service: each call is sent to the daemon and answered from there.
3471
3513
  *
3472
3514
  * This is a leaf module. It lives beside both target SDKs, like `time.ts`, so the `kay.agent` SDK
3473
3515
  * exposes the same door without importing the `kay.app` surface.
@@ -3508,7 +3550,12 @@ export declare interface KayAppUserFiles {
3508
3550
  }
3509
3551
 
3510
3552
  export declare interface KayAppUserFilesCallOptions {
3511
- /** Deadline in milliseconds from the call, waiting included. Default 5000, at most 60000. */
3553
+ /**
3554
+ * Deadline in milliseconds, waiting included. Default 5000, at most 60000. It starts when the
3555
+ * daemon's user-files service receives the request: from the call in the daemon, or, for a
3556
+ * plugin in the plugin host, once the request has crossed to the daemon. A daemon that never
3557
+ * reads the request leaves the call waiting until the host's connection to it is closed.
3558
+ */
3512
3559
  readonly timeoutMs?: number;
3513
3560
  readonly signal?: AbortSignal;
3514
3561
  }
@@ -5129,6 +5176,21 @@ declare const PluginCapabilityRefusalV1: z.ZodObject<{
5129
5176
  envelope: z.ZodObject<{
5130
5177
  source: z.ZodString;
5131
5178
  }, z.core.$strict>;
5179
+ }, z.core.$strict>, z.ZodObject<{
5180
+ target: z.ZodLiteral<"kay.agent">;
5181
+ slug: z.ZodLiteral<"session-artifacts.read">;
5182
+ envelope: z.ZodObject<{
5183
+ kind: z.ZodEnum<{
5184
+ output: "output";
5185
+ upload: "upload";
5186
+ }>;
5187
+ }, z.core.$strict>;
5188
+ }, z.core.$strict>, z.ZodObject<{
5189
+ target: z.ZodLiteral<"kay.agent">;
5190
+ slug: z.ZodLiteral<"session-artifacts.create">;
5191
+ envelope: z.ZodObject<{
5192
+ kind: z.ZodLiteral<"output">;
5193
+ }, z.core.$strict>;
5132
5194
  }, z.core.$strict>, z.ZodObject<{
5133
5195
  target: z.ZodLiteral<"kay.app">;
5134
5196
  slug: z.ZodLiteral<"artifacts.read">;
@@ -5473,7 +5535,7 @@ declare const PluginTargetName: z.ZodEnum<{
5473
5535
  declare type PluginTargetName = z.infer<typeof PluginTargetName>;
5474
5536
 
5475
5537
  export declare type PluginToolDefinition<TParams extends ToolParametersWire = ToolParametersWire, TDetails = unknown> = Omit<ToolDefinition<TParams, TDetails>, "execute"> & {
5476
- readonly execute: (toolCallId: string, params: ToolExecutionAwareParams<InferToolInput<TParams>>, signal: AbortSignal | undefined, onUpdate: AgentToolUpdateCallback<TDetails> | undefined, ctx: ToolContext) => Promise<AgentToolResult<TDetails>>;
5538
+ readonly execute: (toolCallId: string, params: ToolExecutionAwareParams<InferToolInput<TParams>>, signal: AbortSignal | undefined, onUpdate: AgentToolUpdateCallback<TDetails> | undefined, ctx: KayAgentToolContext) => Promise<AgentToolResult<TDetails>>;
5477
5539
  };
5478
5540
 
5479
5541
  declare const PluginToolName: z.ZodString;
@@ -9200,7 +9262,7 @@ export declare interface ToolDefinition<TParams extends ToolParametersWire = Too
9200
9262
  * The `execute` of a described tool for {@link KayAgentPluginApi.implementTool}: `body` receives
9201
9263
  * the call's arguments parsed by `schema`, the schema the manifest's `parameters` came from.
9202
9264
  */
9203
- export declare function toolExecute<TSchema extends z_2.ZodType>(schema: TSchema, body: (toolCallId: string, input: z_2.output<TSchema>, signal: AbortSignal | undefined, onUpdate: AgentToolUpdateCallback<unknown> | undefined, ctx: ToolContext) => Promise<AgentToolResult<unknown>>): KayAgentToolExecute;
9265
+ export declare function toolExecute<TSchema extends z_2.ZodType>(schema: TSchema, body: (toolCallId: string, input: z_2.output<TSchema>, signal: AbortSignal | undefined, onUpdate: AgentToolUpdateCallback<unknown> | undefined, ctx: KayAgentToolContext) => Promise<AgentToolResult<unknown>>): KayAgentToolExecute;
9204
9266
 
9205
9267
  /** Runtime execute input shape that always allows reserved execution directives. */
9206
9268
  export declare type ToolExecutionAwareParams<T> = T & {
package/dist/kay-app.d.ts CHANGED
@@ -2722,8 +2722,15 @@ declare const KAY_PLUGIN_PROTOCOL_VERSION: "kay.plugin.v1";
2722
2722
  *
2723
2723
  * 0.41.0 adds app.mcp.callTool for background calls to a plugin's own manifest-declared MCP
2724
2724
  * servers, using Bonsai's managed connection without a session or working directory (#16172).
2725
+ *
2726
+ * 0.42.0 hands background work the shared ResolvedCredential in auth.credential. Workflow
2727
+ * accounts carry auth resolution outcomes, and Poller callbacks receive only the credential.
2728
+ * Older SDK ranges are refused because their background success shape is no longer served.
2729
+ *
2730
+ * 0.42.1 adds current-session tool lifetimes and invocation-bound artifact reads/new outputs,
2731
+ * plus described-tool execution, guidance and permission resource metadata.
2725
2732
  */
2726
- declare const KAY_PLUGIN_SDK_VERSION: "0.41.0";
2733
+ declare const KAY_PLUGIN_SDK_VERSION: "0.42.1";
2727
2734
 
2728
2735
  declare const KAY_PLUGIN_TARGET_NAMES: readonly ["kay.agent", "kay.app", "kay.ui"];
2729
2736
 
@@ -3932,7 +3939,7 @@ export declare interface KayAppAutomationUriChangeCondition {
3932
3939
 
3933
3940
  /** Exact-account credential resolution for a plugin's durable background jobs. */
3934
3941
  export declare interface KayAppBackgroundAuth {
3935
- resolveCredential(request: KayAppBackgroundCredentialRequest): Promise<KayAppBackgroundCredentialResult>;
3942
+ resolveCredential(request: KayAppBackgroundCredentialRequest): Promise<KayAppCredentialResolution>;
3936
3943
  }
3937
3944
 
3938
3945
  /** A credential request for durable background work bound to one known account. */
@@ -3948,21 +3955,6 @@ export declare interface KayAppBackgroundCredentialRequest {
3948
3955
  readonly jobId: string;
3949
3956
  }
3950
3957
 
3951
- /** The non-secret outcome of a durable background credential lookup. */
3952
- export declare type KayAppBackgroundCredentialResult = {
3953
- readonly status: "resolved";
3954
- readonly accessToken: string;
3955
- readonly accountId: string;
3956
- readonly scopes: readonly string[];
3957
- } | {
3958
- readonly status: "missing";
3959
- readonly reason: string;
3960
- } | {
3961
- readonly status: "requires-auth";
3962
- readonly reason: string;
3963
- readonly requiredScopes?: readonly string[];
3964
- };
3965
-
3966
3958
  /**
3967
3959
  * The `kay.app` system-prompt contract (`app.systemPrompt`): text a plugin adds to every chat's
3968
3960
  * system prompt, rendered by the daemon from a few facts about the chat and reused across chats.
@@ -4114,6 +4106,19 @@ export declare class KayAppCredentialRejectedError extends Error {
4114
4106
  readonly name = "KayAppCredentialRejectedError";
4115
4107
  }
4116
4108
 
4109
+ /** A credential for this call, or an account failure with no secret material. Never persist it. */
4110
+ export declare type KayAppCredentialResolution = {
4111
+ readonly status: "resolved";
4112
+ readonly credential: ResolvedCredential;
4113
+ } | {
4114
+ readonly status: "missing";
4115
+ readonly reason: string;
4116
+ } | {
4117
+ readonly status: "requires-auth";
4118
+ readonly reason: string;
4119
+ readonly requiredScopes?: readonly string[];
4120
+ };
4121
+
4117
4122
  export declare interface KayAppData {
4118
4123
  /**
4119
4124
  * Register the live definition behind one declared source. At most one registration per source
@@ -4359,18 +4364,17 @@ export declare interface KayAppDynamicContextSearchOptions {
4359
4364
  } | undefined;
4360
4365
  }
4361
4366
 
4362
- /**
4363
- * The app-wide endpoint bus. A plugin registers named handlers a consuming surface can invoke; the
4364
- * host routes invocations (e.g. Bonsai Desktop forwards the renderer's frame-gated call to the daemon,
4365
- * where the endpoint is single-homed). The corpus is NEVER reachable here - only what the plugin
4366
- * explicitly exposes. Both `payload` and the handler's return ride strict JSON on the wire.
4367
- */
4367
+ /** Per-invocation authority prepared from the endpoint's manifest declaration. */
4368
+ export declare interface KayAppEndpointContext {
4369
+ readonly credentials: readonly KayAppResolvedCredential[];
4370
+ readonly signal: AbortSignal;
4371
+ /** Record only a scheme from this call's credentials after its provider operation succeeds. */
4372
+ reportWorked(schemeId: string): void;
4373
+ }
4374
+
4375
+ /** The app-wide endpoint bus; payloads and returned values must be JSON. */
4368
4376
  export declare interface KayAppEndpoints {
4369
- /**
4370
- * Register a handler under `name`. Names are app-wide (open bus); a duplicate name is rejected by
4371
- * the host registry.
4372
- */
4373
- register(name: string, handler: (payload: unknown) => unknown | Promise<unknown>): void;
4377
+ register(name: string, handler: (payload: unknown, context: KayAppEndpointContext) => unknown | Promise<unknown>): void;
4374
4378
  }
4375
4379
 
4376
4380
  /**
@@ -5407,9 +5411,7 @@ export declare interface KayAppPollerOptions<Cursor extends JsonValue> {
5407
5411
  readonly poll: (input: {
5408
5412
  readonly account: KayAppAccountSummary;
5409
5413
  readonly cursor: Cursor | undefined;
5410
- readonly credential: Extract<KayAppBackgroundCredentialResult, {
5411
- readonly status: "resolved";
5412
- }>;
5414
+ readonly credential: ResolvedCredential;
5413
5415
  readonly runId: string;
5414
5416
  }) => Promise<KayAppPollResult<Cursor>>;
5415
5417
  }
@@ -5564,50 +5566,7 @@ export declare interface KayAppResolveCredentialRequest {
5564
5566
  readonly purpose: string;
5565
5567
  }
5566
5568
 
5567
- /**
5568
- * ---
5569
- * responsibility: The plugin-facing credential surface of the `kay.app` target SDK. A daemon-hosted
5570
- * plugin lists account metadata or resolves credentials for an owned or consumed auth service
5571
- * under explicit grants. Credential material is read where the work happens.
5572
- * owns:
5573
- * - {@link KayAppAuth}, {@link KayAppResolvedCredential}.
5574
- * does_not_own:
5575
- * - Acquisition, storage, refresh, or revocation. Those are the credential authority's, reached
5576
- * through the host. A plugin can only ask for material it is granted, for a purpose it declared.
5577
- * ---
5578
- *
5579
- * ## Deny-by-default
5580
- *
5581
- * `KayAppPluginApi.auth` is **present only for plugins the host grants** (`auth.operations`
5582
- * containing `"list"` or `"resolve"` in `permissions.byTarget["kay.app"]`, against an owned or consumed
5583
- * service) and `undefined` otherwise - an ungranted plugin cannot even reference the capability.
5584
- * This mirrors `KayAppPluginApi.sessions`, and it is the rule for every capability behind a grant:
5585
- * never hand a plugin an object whose grant is decorative.
5586
- *
5587
- * ## Secrets do not leave this object
5588
- *
5589
- * A resolved credential is live secret material. Never log it, never echo it into an error message,
5590
- * never put it in an event payload, never return it from an endpoint handler, and never accept it
5591
- * as a URI or config value. Read it, use it in the outbound request, drop it.
5592
- */
5593
- /**
5594
- * Live credential material for one account of one auth scheme.
5595
- *
5596
- * Shaped to match the kernel's `ResolvedCredential` so a plugin that already reads
5597
- * `ctx.auth.credential` in a URI verb reads the same thing here.
5598
- */
5599
- export declare interface KayAppResolvedCredential {
5600
- /** Bearer for OAuth schemes, the api key for api-key schemes. Host-resolved and refreshed. */
5601
- readonly accessToken: string;
5602
- readonly accountId: string;
5603
- readonly schemeId: string;
5604
- readonly scopes?: readonly string[];
5605
- /**
5606
- * Every value of a multi-field api-key credential, keyed by the scheme's declared field id
5607
- * (`accessToken` mirrors the primary field). Absent for single-secret schemes.
5608
- */
5609
- readonly fields?: Readonly<Record<string, string>>;
5610
- }
5569
+ export declare type KayAppResolvedCredential = ResolvedCredential;
5611
5570
 
5612
5571
  /** Hard limits on the routes a `tier` or `model` selection may use. */
5613
5572
  export declare interface KayAppRouteConstraints {
@@ -7970,13 +7929,14 @@ export declare interface KayAppUserFileEntry {
7970
7929
  * The plugin-facing user-files contract: file I/O in folders the user owns, done by the host on
7971
7930
  * its own worker threads.
7972
7931
  *
7973
- * Ungated and always present, like `app.paths`. It confers no authority: a plugin runs in the
7974
- * daemon's process and can call `node:fs` itself. What the door adds is where the work runs. A
7975
- * `node:fs` sync call blocks the daemon's event loop for as long as the path takes to answer,
7976
- * which under a macOS-protected folder or on a drive that stopped answering can be a very long
7977
- * time (kay#11575); an async one holds a thread of the pool the whole daemon shares. The host runs
7978
- * each request on a dedicated worker, gives it a deadline, and answers a typed result instead of
7979
- * throwing.
7932
+ * Ungated and always present, like `app.paths`. It confers no authority: the process a plugin
7933
+ * runs in, the daemon or the plugin host, could call `node:fs` itself. What the door adds is where
7934
+ * the work runs. A `node:fs` sync call blocks that process's event loop for as long as the path
7935
+ * takes to answer, which under a macOS-protected folder or on a drive that stopped answering can
7936
+ * be a very long time (kay#11575); an async one holds a thread of the pool the whole process
7937
+ * shares. The daemon's user-files service runs each request on a dedicated worker, gives it a
7938
+ * deadline, and answers a typed result instead of throwing. A plugin in the plugin host reaches
7939
+ * the same service: each call is sent to the daemon and answered from there.
7980
7940
  *
7981
7941
  * This is a leaf module. It lives beside both target SDKs, like `time.ts`, so the `kay.agent` SDK
7982
7942
  * exposes the same door without importing the `kay.app` surface.
@@ -8017,7 +7977,12 @@ export declare interface KayAppUserFiles {
8017
7977
  }
8018
7978
 
8019
7979
  export declare interface KayAppUserFilesCallOptions {
8020
- /** Deadline in milliseconds from the call, waiting included. Default 5000, at most 60000. */
7980
+ /**
7981
+ * Deadline in milliseconds, waiting included. Default 5000, at most 60000. It starts when the
7982
+ * daemon's user-files service receives the request: from the call in the daemon, or, for a
7983
+ * plugin in the plugin host, once the request has crossed to the daemon. A daemon that never
7984
+ * reads the request leaves the call waiting until the host's connection to it is closed.
7985
+ */
8021
7986
  readonly timeoutMs?: number;
8022
7987
  readonly signal?: AbortSignal;
8023
7988
  }
@@ -8145,7 +8110,7 @@ export declare interface KayAppWhiteboardTypes {
8145
8110
  */
8146
8111
  export declare interface KayAppWorkflowAccount {
8147
8112
  readonly account: KayAppAccountSummary;
8148
- readonly credential: KayAppBackgroundCredentialResult;
8113
+ readonly auth: KayAppCredentialResolution;
8149
8114
  }
8150
8115
 
8151
8116
  /**
@@ -10314,7 +10279,7 @@ export declare function requireWriteContent(payload: UriPayload | Uint8Array | u
10314
10279
  * verb (`ctx.auth.credential`), a tool (`ctx.credential`) or a search provider (`ctx.credential`).
10315
10280
  * Plain data, so it crosses a process boundary with the call; plugin code never asks for one.
10316
10281
  */
10317
- declare interface ResolvedCredential {
10282
+ export declare interface ResolvedCredential {
10318
10283
  /** Bearer for OAuth schemes, apiKey for api-key schemes. Host-resolved and refreshed. */
10319
10284
  readonly accessToken: string;
10320
10285
  readonly accountId: string;
@@ -16963,6 +16928,9 @@ declare const WithElementList_0: (input: string, result?: unknown[]) => [unknown
16963
16928
 
16964
16929
  declare function WithElementListMapping(input: [unknown, unknown, unknown] | []): unknown;
16965
16930
 
16931
+ /** Try the call's credentials in order; only credential rejection advances to the next. */
16932
+ export declare function withEndpointCredential<T>(context: KayAppEndpointContext, use: (credential: KayAppResolvedCredential) => Promise<T>): Promise<T>;
16933
+
16966
16934
  declare function WithMapping(input: [unknown, unknown] | []): unknown;
16967
16935
 
16968
16936
  declare const WithNull: (input: string) => [unknown, string] | [];
package/dist/kay-app.js CHANGED
@@ -599,11 +599,6 @@ function payload(name, schema, options = {}) {
599
599
  };
600
600
  }
601
601
 
602
- // packages/plugin-sdk/dist/kay-app/account.js
603
- function isRetryable(result) {
604
- return result.status === "not-ready";
605
- }
606
-
607
602
  // packages/plugin-sdk/dist/kay-app/auth.js
608
603
  var KayAppCredentialRejectedError = class extends Error {
609
604
  name = "KayAppCredentialRejectedError";
@@ -626,6 +621,32 @@ async function withCredential(auth, request, use) {
626
621
  throw rejection ?? new Error(`No credential is resolvable for '${request.serviceId}'.`);
627
622
  }
628
623
 
624
+ // packages/plugin-sdk/dist/kay-app/endpoints.js
625
+ async function withEndpointCredential(context, use) {
626
+ let rejection;
627
+ for (const credential of context.credentials) {
628
+ context.signal.throwIfAborted();
629
+ try {
630
+ const result = await use(credential);
631
+ try {
632
+ context.reportWorked(credential.schemeId);
633
+ } catch {
634
+ }
635
+ return result;
636
+ } catch (error) {
637
+ if (!(error instanceof KayAppCredentialRejectedError))
638
+ throw error;
639
+ rejection = error;
640
+ }
641
+ }
642
+ throw rejection ?? new Error("No credential is resolvable for this endpoint.");
643
+ }
644
+
645
+ // packages/plugin-sdk/dist/kay-app/account.js
646
+ function isRetryable(result) {
647
+ return result.status === "not-ready";
648
+ }
649
+
629
650
  // packages/plugin-sdk/dist/kay-app/automations.js
630
651
  var KAY_APP_AUTOMATION_CONDITION_KINDS = [
631
652
  "time",
@@ -715,7 +736,7 @@ function definePoller(app, localId, options) {
715
736
  let skipped = 0;
716
737
  let failed = 0;
717
738
  let refused = 0;
718
- for (const { account, credential } of accounts) {
739
+ for (const { account, auth } of accounts) {
719
740
  const saved = previous.find((entry) => entry.schemeId === account.schemeId && entry.accountId === account.accountId);
720
741
  const name = `${account.schemeId}/${account.accountId}`;
721
742
  const keepSaved = (summary) => {
@@ -723,9 +744,9 @@ function definePoller(app, localId, options) {
723
744
  next.push(saved);
724
745
  details.push(`${name}: ${summary}`);
725
746
  };
726
- if (credential.status !== "resolved") {
747
+ if (auth.status !== "resolved") {
727
748
  skipped++;
728
- keepSaved(credential.status === "requires-auth" ? "Sign-in or required scope missing" : "Credential missing");
749
+ keepSaved(auth.status === "requires-auth" ? "Sign-in or required scope missing" : "Credential missing");
729
750
  continue;
730
751
  }
731
752
  let result;
@@ -733,7 +754,7 @@ function definePoller(app, localId, options) {
733
754
  result = await options.poll({
734
755
  account,
735
756
  cursor: structuredClone(saved?.cursor),
736
- credential,
757
+ credential: auth.credential,
737
758
  runId
738
759
  });
739
760
  } catch {
@@ -964,5 +985,6 @@ export {
964
985
  transcriptMessageText,
965
986
  transcriptMessageTexts,
966
987
  transcriptRoleLabel,
967
- withCredential
988
+ withCredential,
989
+ withEndpointCredential
968
990
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yaklabs-ai/plugin-sdk",
3
- "version": "0.41.0",
3
+ "version": "0.42.1",
4
4
  "description": "The Kay plugin SDK — types and helpers for authoring a Kay directory plugin.",
5
5
  "author": "YakLabs",
6
6
  "type": "module",