@yaklabs-ai/plugin-sdk 0.55.0 → 0.55.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.55.0"
16
+ "@bonsai/plugin-sdk": "npm:@yaklabs-ai/plugin-sdk@^0.55.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.55.0" },
65
+ "compatibility": { "sdk": "^0.55.1" },
66
66
  "targets": {
67
67
  "kay": {
68
68
  "agent": {
@@ -153,7 +153,7 @@ naming both versions, instead of loading it and finding no `activate`.
153
153
  | `@bonsai/plugin-sdk/system-one` | The types and error class for `api.systemOne` / `app.systemOne`, from 0.13.8 |
154
154
  | `@bonsai/plugin-sdk/zod` | `z` (the host's in the daemon), on an entry with no other import, from 0.13.9 |
155
155
 
156
- A plugin that imports these subpaths declares the current supported SDK range (`^0.55.0`).
156
+ A plugin that imports these subpaths declares the current supported SDK range (`^0.55.1`).
157
157
  The rows record when each subpath appeared, not retained runtime compatibility. `vendored-mcp` builds the plugin's URI module (its link cards and help); hosting the
158
158
  vendor's MCP server itself is a separate host decision: Bonsai hosts it once a person approves
159
159
  the plugin's `mcp.host-server` grant for that server's name and URL. A server that needs an OAuth
@@ -161,7 +161,7 @@ sign-in names one of the plugin's auth services in `authService`; that service m
161
161
  one `delegated` scheme, which Bonsai uses to sign the person in to the server. Bonsai declares that
162
162
  scheme at runtime; the plugin's code must not declare it again. From 0.16.2 a plugin's code can also
163
163
  call the server's tools through `api.vendoredMcp.port(<server>)`, typed by this subpath's
164
- `VendoredMcpPort` and `VendoredMcpOutcome` (declare `^0.55.0`).
164
+ `VendoredMcpPort` and `VendoredMcpOutcome` (declare `^0.55.1`).
165
165
 
166
166
  From 0.13.10 the manifest schema carries two facts Bonsai reads for its own plugins only; another
167
167
  plugin's are ignored, with a load diagnostic. An `external-cli` auth scheme's `cli` says how Bonsai
@@ -243,7 +243,7 @@ Provider schemas remain authoritative; declaring a dependency grants no authorit
243
243
  through `app.uri`, parse returned Markdown in the consuming plugin, and retain the read's
244
244
  revision (or `contentDigest` from `/uri`) for edits. The old `memory.read` and `memory.write`
245
245
  grants do not authorize the replacement scheme-and-verb calls. Contracts before 0.49.0 are
246
- refused; migrate and declare `^0.55.0`. The current host also serves the 0.49.0 resource contract.
246
+ refused; migrate and declare `^0.55.1`. The current host also serves the 0.49.0 resource contract.
247
247
 
248
248
  ## What this package is, and is not, at runtime
249
249
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "package": "@yaklabs-ai/plugin-sdk",
4
- "version": "0.55.0",
4
+ "version": "0.55.1",
5
5
  "target": "npm",
6
6
  "firstPartyLicense": "MIT",
7
7
  "bundled": [
@@ -2676,8 +2676,12 @@ declare const KAY_PLUGIN_PROTOCOL_VERSION: "kay.plugin.v1";
2676
2676
  *
2677
2677
  * 0.55.0 carries managed MCP calls over resource writes in both daemon and plugin-host code.
2678
2678
  * Existing agent and background MCP call shapes remain supported.
2679
+ *
2680
+ * 0.55.1 adds canonical path resources on declared tool permissions, asynchronous display-only
2681
+ * tool previews with cancellation, app-scoped availability snapshots and app-target output
2682
+ * artifact usage declarations. A plugin using these declares ^0.55.1.
2679
2683
  */
2680
- declare const KAY_PLUGIN_SDK_VERSION: "0.55.0";
2684
+ declare const KAY_PLUGIN_SDK_VERSION: "0.55.1";
2681
2685
 
2682
2686
  declare const KAY_PLUGIN_TARGET_NAMES: readonly ["kay.agent", "kay.app", "kay.ui"];
2683
2687
 
@@ -8374,9 +8378,10 @@ declare interface ToolPermissionHint {
8374
8378
  * labelled facts. Render-only: never matched against a rule, never one-tap approval grounds.
8375
8379
  * The tool says what its input claims, so the gate shows it as the tool's claim, not as the
8376
8380
  * daemon's attestation. The host admits only display-safe text; a throw, a blank title or an
8377
- * unsafe string costs the description and the call is asked about as before.
8381
+ * unsafe string costs the description and the call is asked about as before. A promise is
8382
+ * bounded by the host description timeout; forward its optional cancellation signal to reads.
8378
8383
  */
8379
- readonly describePreview?: (input: Record<string, unknown>) => ToolPreviewDescription | undefined;
8384
+ readonly describePreview?: (input: Record<string, unknown>, signal?: AbortSignal) => ToolPreviewDescription | undefined | Promise<ToolPreviewDescription | undefined>;
8380
8385
  readonly kind?: ToolActionKind;
8381
8386
  readonly scheme?: string;
8382
8387
  readonly ruleKey?: string;
@@ -817,7 +817,7 @@ declare interface DerivedToolClassification {
817
817
  * `execute`: name, parameters, auth binding and permission all come from the manifest, as in a
818
818
  * session.
819
819
  */
820
- export declare function describedToolForTest(contract: ResolvedPluginContractV1, localId: string, execute: KayAgentToolExecute): ToolDefinition;
820
+ export declare function describedToolForTest(contract: ResolvedPluginContractV1, localId: string, execute: KayAgentToolExecute, environment?: ToolPermissionEnvironment): ToolDefinition;
821
821
 
822
822
  declare const Digit: TDigit;
823
823
 
@@ -2730,8 +2730,12 @@ declare const KAY_PLUGIN_PROTOCOL_VERSION: "kay.plugin.v1";
2730
2730
  *
2731
2731
  * 0.55.0 carries managed MCP calls over resource writes in both daemon and plugin-host code.
2732
2732
  * Existing agent and background MCP call shapes remain supported.
2733
+ *
2734
+ * 0.55.1 adds canonical path resources on declared tool permissions, asynchronous display-only
2735
+ * tool previews with cancellation, app-scoped availability snapshots and app-target output
2736
+ * artifact usage declarations. A plugin using these declares ^0.55.1.
2733
2737
  */
2734
- declare const KAY_PLUGIN_SDK_VERSION: "0.55.0";
2738
+ declare const KAY_PLUGIN_SDK_VERSION: "0.55.1";
2735
2739
 
2736
2740
  declare const KAY_PLUGIN_TARGET_NAMES: readonly ["kay.agent", "kay.app", "kay.ui"];
2737
2741
 
@@ -5137,9 +5141,9 @@ declare const ResolvedPluginContractV1: z.ZodObject<{
5137
5141
  resource: "resource";
5138
5142
  storage: "storage";
5139
5143
  uriModule: "uriModule";
5144
+ app: "app";
5140
5145
  authService: "authService";
5141
5146
  command: "command";
5142
- app: "app";
5143
5147
  skill: "skill";
5144
5148
  converter: "converter";
5145
5149
  artifactUriModule: "artifactUriModule";
@@ -5913,6 +5917,7 @@ declare const ResolvedPluginContractV1: z.ZodObject<{
5913
5917
  displayName: z.ZodOptional<z.ZodString>;
5914
5918
  authServiceId: z.ZodOptional<z.ZodString>;
5915
5919
  authSchemeId: z.ZodOptional<z.ZodString>;
5920
+ requiredScopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
5916
5921
  knownResources: z.ZodOptional<z.ZodLiteral<true>>;
5917
5922
  describesOperations: z.ZodOptional<z.ZodLiteral<true>>;
5918
5923
  looksUpWebLinks: z.ZodOptional<z.ZodLiteral<true>>;
@@ -5971,6 +5976,9 @@ declare const ResolvedPluginContractV1: z.ZodObject<{
5971
5976
  resourcePrefix: z.ZodOptional<z.ZodString>;
5972
5977
  resourceArgs: z.ZodOptional<z.ZodArray<z.ZodString>>;
5973
5978
  resourceTrim: z.ZodOptional<z.ZodLiteral<true>>;
5979
+ resourcePathNormalization: z.ZodOptional<z.ZodObject<{
5980
+ preserveUriSchemes: z.ZodOptional<z.ZodArray<z.ZodString>>;
5981
+ }, z.core.$strict>>;
5974
5982
  defaultPermission: z.ZodOptional<z.ZodEnum<{
5975
5983
  never: "never";
5976
5984
  allow: "allow";
@@ -5997,6 +6005,209 @@ declare const ResolvedPluginContractV1: z.ZodObject<{
5997
6005
  globalId: z.ZodString;
5998
6006
  toolName: z.ZodString;
5999
6007
  }, z.core.$strict>>>;
6008
+ kayAppArtifacts: z.ZodOptional<z.ZodObject<{
6009
+ outputs: z.ZodLiteral<true>;
6010
+ }, z.core.$strict>>;
6011
+ kayAppUriModules: z.ZodOptional<z.ZodArray<z.ZodObject<{
6012
+ revisionBacked: z.ZodOptional<z.ZodLiteral<true>>;
6013
+ mailCalibrationSource: z.ZodOptional<z.ZodLiteral<true>>;
6014
+ screenActions: z.ZodExactOptional<z.ZodObject<{
6015
+ scheme: z.ZodString;
6016
+ hosts: z.ZodArray<z.ZodString>;
6017
+ paths: z.ZodOptional<z.ZodArray<z.ZodString>>;
6018
+ apps: z.ZodArray<z.ZodString>;
6019
+ options: z.ZodRecord<z.ZodString, z.ZodDiscriminatedUnion<[z.ZodObject<{
6020
+ kind: z.ZodLiteral<"exact">;
6021
+ description: z.ZodString;
6022
+ verb: z.ZodEnum<{
6023
+ read: "read";
6024
+ write: "write";
6025
+ edit: "edit";
6026
+ delete: "delete";
6027
+ }>;
6028
+ uri: z.ZodString;
6029
+ }, z.core.$strict>, z.ZodObject<{
6030
+ kind: z.ZodLiteral<"catch-all">;
6031
+ description: z.ZodString;
6032
+ verb: z.ZodEnum<{
6033
+ read: "read";
6034
+ write: "write";
6035
+ edit: "edit";
6036
+ delete: "delete";
6037
+ }>;
6038
+ }, z.core.$strict>], "kind">>;
6039
+ }, z.core.$strict>>;
6040
+ claims: z.ZodExactOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
6041
+ kind: z.ZodLiteral<"scheme">;
6042
+ scheme: z.ZodString;
6043
+ }, z.core.$strict>, z.ZodObject<{
6044
+ kind: z.ZodLiteral<"uriPattern">;
6045
+ pattern: z.ZodObject<{
6046
+ protocol: z.ZodExactOptional<z.ZodString>;
6047
+ hostname: z.ZodExactOptional<z.ZodString>;
6048
+ pathname: z.ZodExactOptional<z.ZodString>;
6049
+ search: z.ZodExactOptional<z.ZodString>;
6050
+ }, z.core.$strict>;
6051
+ normalizeTo: z.ZodExactOptional<z.ZodString>;
6052
+ route: z.ZodExactOptional<z.ZodString>;
6053
+ sourceUrl: z.ZodExactOptional<z.ZodString>;
6054
+ title: z.ZodExactOptional<z.ZodString>;
6055
+ examples: z.ZodExactOptional<z.ZodArray<z.ZodString>>;
6056
+ }, z.core.$strict>, z.ZodObject<{
6057
+ kind: z.ZodLiteral<"urlPattern">;
6058
+ pattern: z.ZodObject<{
6059
+ protocol: z.ZodExactOptional<z.ZodString>;
6060
+ hostname: z.ZodExactOptional<z.ZodString>;
6061
+ pathname: z.ZodExactOptional<z.ZodString>;
6062
+ search: z.ZodExactOptional<z.ZodString>;
6063
+ }, z.core.$strict>;
6064
+ normalizeTo: z.ZodExactOptional<z.ZodString>;
6065
+ route: z.ZodExactOptional<z.ZodString>;
6066
+ examples: z.ZodExactOptional<z.ZodArray<z.ZodString>>;
6067
+ }, z.core.$strict>], "kind">>>;
6068
+ templates: z.ZodExactOptional<z.ZodArray<z.ZodObject<{
6069
+ uri: z.ZodString;
6070
+ description: z.ZodString;
6071
+ operations: z.ZodExactOptional<z.ZodArray<z.ZodEnum<{
6072
+ search: "search";
6073
+ read: "read";
6074
+ list: "list";
6075
+ write: "write";
6076
+ edit: "edit";
6077
+ delete: "delete";
6078
+ help: "help";
6079
+ }>>>;
6080
+ operationDocs: z.ZodExactOptional<z.ZodRecord<z.ZodEnum<{
6081
+ search: "search";
6082
+ read: "read";
6083
+ list: "list";
6084
+ write: "write";
6085
+ edit: "edit";
6086
+ delete: "delete";
6087
+ help: "help";
6088
+ }> & z.core.$partial, z.ZodString>>;
6089
+ operationDefaults: z.ZodExactOptional<z.ZodRecord<z.ZodEnum<{
6090
+ search: "search";
6091
+ read: "read";
6092
+ list: "list";
6093
+ write: "write";
6094
+ edit: "edit";
6095
+ delete: "delete";
6096
+ help: "help";
6097
+ }> & z.core.$partial, z.ZodEnum<{
6098
+ never: "never";
6099
+ allow: "allow";
6100
+ ask: "ask";
6101
+ }>>>;
6102
+ }, z.core.$strict>>>;
6103
+ verbs: z.ZodExactOptional<z.ZodObject<{
6104
+ readable: z.ZodBoolean;
6105
+ writable: z.ZodBoolean;
6106
+ editable: z.ZodBoolean;
6107
+ deletable: z.ZodExactOptional<z.ZodBoolean>;
6108
+ listable: z.ZodBoolean;
6109
+ searchable: z.ZodExactOptional<z.ZodBoolean>;
6110
+ }, z.core.$strict>>;
6111
+ verbDocs: z.ZodExactOptional<z.ZodObject<{
6112
+ read: z.ZodExactOptional<z.ZodString>;
6113
+ list: z.ZodExactOptional<z.ZodString>;
6114
+ search: z.ZodExactOptional<z.ZodString>;
6115
+ write: z.ZodExactOptional<z.ZodString>;
6116
+ edit: z.ZodExactOptional<z.ZodString>;
6117
+ delete: z.ZodExactOptional<z.ZodString>;
6118
+ }, z.core.$strict>>;
6119
+ permissionDefaults: z.ZodExactOptional<z.ZodObject<{
6120
+ read: z.ZodExactOptional<z.ZodEnum<{
6121
+ never: "never";
6122
+ allow: "allow";
6123
+ ask: "ask";
6124
+ }>>;
6125
+ write: z.ZodExactOptional<z.ZodEnum<{
6126
+ never: "never";
6127
+ allow: "allow";
6128
+ ask: "ask";
6129
+ }>>;
6130
+ edit: z.ZodExactOptional<z.ZodEnum<{
6131
+ never: "never";
6132
+ allow: "allow";
6133
+ ask: "ask";
6134
+ }>>;
6135
+ delete: z.ZodExactOptional<z.ZodEnum<{
6136
+ never: "never";
6137
+ allow: "allow";
6138
+ ask: "ask";
6139
+ }>>;
6140
+ }, z.core.$strict>>;
6141
+ authActions: z.ZodExactOptional<z.ZodObject<{
6142
+ actions: z.ZodRecord<z.ZodString, z.ZodObject<{
6143
+ purpose: z.ZodString;
6144
+ alternatives: z.ZodArray<z.ZodObject<{
6145
+ allOf: z.ZodArray<z.ZodObject<{
6146
+ scope: z.ZodString;
6147
+ reason: z.ZodExactOptional<z.ZodString>;
6148
+ }, z.core.$strict>>;
6149
+ }, z.core.$strict>>;
6150
+ }, z.core.$strict>>;
6151
+ rules: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
6152
+ action: z.ZodString;
6153
+ operations: z.ZodExactOptional<z.ZodArray<z.ZodEnum<{
6154
+ search: "search";
6155
+ read: "read";
6156
+ list: "list";
6157
+ write: "write";
6158
+ edit: "edit";
6159
+ delete: "delete";
6160
+ help: "help";
6161
+ }>>>;
6162
+ routes: z.ZodExactOptional<z.ZodArray<z.ZodString>>;
6163
+ query: z.ZodExactOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
6164
+ }, z.core.$strict>, z.ZodObject<{
6165
+ public: z.ZodLiteral<true>;
6166
+ operations: z.ZodExactOptional<z.ZodArray<z.ZodEnum<{
6167
+ search: "search";
6168
+ read: "read";
6169
+ list: "list";
6170
+ write: "write";
6171
+ edit: "edit";
6172
+ delete: "delete";
6173
+ help: "help";
6174
+ }>>>;
6175
+ routes: z.ZodExactOptional<z.ZodArray<z.ZodString>>;
6176
+ query: z.ZodExactOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
6177
+ }, z.core.$strict>]>>;
6178
+ }, z.core.$strict>>;
6179
+ requiresConnection: z.ZodExactOptional<z.ZodLiteral<true>>;
6180
+ acceptsSourceCopy: z.ZodExactOptional<z.ZodLiteral<false>>;
6181
+ acceptsWriteSources: z.ZodExactOptional<z.ZodLiteral<true>>;
6182
+ acceptsBytes: z.ZodExactOptional<z.ZodLiteral<true>>;
6183
+ ownsLineSelectors: z.ZodExactOptional<z.ZodLiteral<true>>;
6184
+ description: z.ZodExactOptional<z.ZodString>;
6185
+ agentHint: z.ZodExactOptional<z.ZodObject<{
6186
+ summary: z.ZodString;
6187
+ commonFlows: z.ZodExactOptional<z.ZodArray<z.ZodObject<{
6188
+ label: z.ZodString;
6189
+ when: z.ZodExactOptional<z.ZodString>;
6190
+ example: z.ZodString;
6191
+ }, z.core.$strict>>>;
6192
+ helpUri: z.ZodExactOptional<z.ZodString>;
6193
+ triggers: z.ZodExactOptional<z.ZodObject<{
6194
+ keywords: z.ZodExactOptional<z.ZodArray<z.ZodString>>;
6195
+ patterns: z.ZodExactOptional<z.ZodArray<z.ZodString>>;
6196
+ }, z.core.$strict>>;
6197
+ skills: z.ZodExactOptional<z.ZodArray<z.ZodString>>;
6198
+ }, z.core.$strict>>;
6199
+ localId: z.ZodString;
6200
+ adapterId: z.ZodOptional<z.ZodString>;
6201
+ globalId: z.ZodString;
6202
+ schemes: z.ZodArray<z.ZodString>;
6203
+ displayName: z.ZodOptional<z.ZodString>;
6204
+ authServiceId: z.ZodOptional<z.ZodString>;
6205
+ authSchemeId: z.ZodOptional<z.ZodString>;
6206
+ requiredScopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
6207
+ knownResources: z.ZodOptional<z.ZodLiteral<true>>;
6208
+ describesOperations: z.ZodOptional<z.ZodLiteral<true>>;
6209
+ looksUpWebLinks: z.ZodOptional<z.ZodLiteral<true>>;
6210
+ }, z.core.$strict>>>;
6000
6211
  kayAppTools: z.ZodOptional<z.ZodArray<z.ZodObject<{
6001
6212
  description: z.ZodOptional<z.ZodString>;
6002
6213
  toolName: z.ZodString;
@@ -6021,6 +6232,9 @@ declare const ResolvedPluginContractV1: z.ZodObject<{
6021
6232
  resourcePrefix: z.ZodOptional<z.ZodString>;
6022
6233
  resourceArgs: z.ZodOptional<z.ZodArray<z.ZodString>>;
6023
6234
  resourceTrim: z.ZodOptional<z.ZodLiteral<true>>;
6235
+ resourcePathNormalization: z.ZodOptional<z.ZodObject<{
6236
+ preserveUriSchemes: z.ZodOptional<z.ZodArray<z.ZodString>>;
6237
+ }, z.core.$strict>>;
6024
6238
  defaultPermission: z.ZodOptional<z.ZodEnum<{
6025
6239
  never: "never";
6026
6240
  allow: "allow";
@@ -6044,6 +6258,9 @@ declare const ResolvedPluginContractV1: z.ZodObject<{
6044
6258
  }, z.core.$strict>>>;
6045
6259
  }, z.core.$strict>>;
6046
6260
  globalId: z.ZodString;
6261
+ availability: z.ZodOptional<z.ZodObject<{
6262
+ scope: z.ZodLiteral<"app">;
6263
+ }, z.core.$strict>>;
6047
6264
  }, z.core.$strict>>>;
6048
6265
  kayAppApprovalTypes: z.ZodOptional<z.ZodArray<z.ZodObject<{
6049
6266
  kind: z.ZodLiteral<"message">;
@@ -6404,6 +6621,7 @@ declare const ResolvedPluginContractV1: z.ZodObject<{
6404
6621
  "connect-flows.read": "connect-flows.read";
6405
6622
  "connect-flows.dismiss": "connect-flows.dismiss";
6406
6623
  "support.report": "support.report";
6624
+ "report-evidence.read": "report-evidence.read";
6407
6625
  "navigation.open-page": "navigation.open-page";
6408
6626
  "sessions.create": "sessions.create";
6409
6627
  "models.complete": "models.complete";
@@ -9756,6 +9974,11 @@ declare interface ToolExecutionPolicyDefaults {
9756
9974
  */
9757
9975
  declare type ToolParametersWire = unknown;
9758
9976
 
9977
+ /** Explicit host environment used to expand manifest permission paths. */
9978
+ declare interface ToolPermissionEnvironment {
9979
+ readonly homeDirectory: string;
9980
+ }
9981
+
9759
9982
  /**
9760
9983
  * A tool's own declaration of how a call to it should classify, supplied on the tool
9761
9984
  * definition (the same shape of author-declared, kernel-read fact as `requiresAuth` and
@@ -9779,9 +10002,10 @@ declare interface ToolPermissionHint {
9779
10002
  * labelled facts. Render-only: never matched against a rule, never one-tap approval grounds.
9780
10003
  * The tool says what its input claims, so the gate shows it as the tool's claim, not as the
9781
10004
  * daemon's attestation. The host admits only display-safe text; a throw, a blank title or an
9782
- * unsafe string costs the description and the call is asked about as before.
10005
+ * unsafe string costs the description and the call is asked about as before. A promise is
10006
+ * bounded by the host description timeout; forward its optional cancellation signal to reads.
9783
10007
  */
9784
- readonly describePreview?: (input: Record<string, unknown>) => ToolPreviewDescription | undefined;
10008
+ readonly describePreview?: (input: Record<string, unknown>, signal?: AbortSignal) => ToolPreviewDescription | undefined | Promise<ToolPreviewDescription | undefined>;
9785
10009
  readonly kind?: ToolActionKind;
9786
10010
  readonly scheme?: string;
9787
10011
  readonly ruleKey?: string;
@@ -123,8 +123,12 @@ function createKayPluginLog(write, bound = {}) {
123
123
  }
124
124
 
125
125
  // packages/plugin-sdk/dist/kay-agent/declared-tool.js
126
- function declaredToolPermission(permission) {
127
- const { kind, ruleKey, resourceArgs, scheme, resourcePrefix, resourceTrim, defaultPermission, classificationRules } = permission;
126
+ import { isAbsolute, join, normalize, resolve } from "node:path";
127
+ function declaredToolPermission(permission, environment) {
128
+ const { kind, ruleKey, resourceArgs, scheme, resourcePrefix, resourceTrim, resourcePathNormalization, defaultPermission, classificationRules } = permission;
129
+ if (resourcePathNormalization !== void 0 && environment === void 0) {
130
+ throw new Error("Path-normalized tool resources require a home directory.");
131
+ }
128
132
  return {
129
133
  kind,
130
134
  ...scheme === void 0 ? {} : { scheme },
@@ -145,14 +149,22 @@ function declaredToolPermission(permission) {
145
149
  ...resourceArgs === void 0 ? {} : {
146
150
  deriveResources: (input) => resourceArgs.flatMap((arg) => {
147
151
  const value = input[arg];
148
- return typeof value === "string" ? [
149
- `${resourcePrefix ?? ""}${resourceTrim === true ? value.trim() : value}`
150
- ] : [];
152
+ if (typeof value !== "string")
153
+ return [];
154
+ let resource = resourceTrim === true ? value.trim() : value;
155
+ if (resourcePathNormalization !== void 0 && environment !== void 0) {
156
+ const preserved = resourcePathNormalization.preserveUriSchemes?.some((preservedScheme) => resource.toLowerCase().startsWith(`${preservedScheme.toLowerCase()}://`)) ?? false;
157
+ if (!preserved) {
158
+ const expanded = resource === "~" ? environment.homeDirectory : resource.startsWith("~/") ? join(environment.homeDirectory, resource.slice(2)) : resource;
159
+ resource = isAbsolute(expanded) ? resolve(expanded) : normalize(expanded);
160
+ }
161
+ }
162
+ return [`${resourcePrefix ?? ""}${resource}`];
151
163
  })
152
164
  }
153
165
  };
154
166
  }
155
- function declaredToolDefinition(tool, execute) {
167
+ function declaredToolDefinition(tool, execute, environment) {
156
168
  const { parameters, description, requiresAuth, permission } = tool;
157
169
  if (parameters === void 0 || description === void 0) {
158
170
  throw new Error(`Tool '${tool.toolName}' declares no parameters in kay-plugin.json, so its definition comes from code.`);
@@ -171,7 +183,7 @@ function declaredToolDefinition(tool, execute) {
171
183
  ...requiresAuth.schemeId === void 0 ? {} : { schemeId: requiresAuth.schemeId }
172
184
  }
173
185
  },
174
- ...permission === void 0 ? {} : { permission: declaredToolPermission(permission) },
186
+ ...permission === void 0 ? {} : { permission: declaredToolPermission(permission, environment) },
175
187
  execute
176
188
  };
177
189
  }
@@ -405,12 +417,12 @@ function defaultTestToolContext() {
405
417
  async function invokeToolForTest(tool, params, ctx = defaultTestToolContext()) {
406
418
  return tool.execute("test-call", params, void 0, void 0, ctx);
407
419
  }
408
- function describedToolForTest(contract, localId, execute) {
420
+ function describedToolForTest(contract, localId, execute, environment) {
409
421
  const tool = contract.kayAgentTools?.find((declared) => declared.localId === localId);
410
422
  if (tool === void 0) {
411
423
  throw new Error(`The contract declares no kay.agent tool '${localId}'.`);
412
424
  }
413
- return declaredToolDefinition(tool, execute);
425
+ return declaredToolDefinition(tool, execute, environment);
414
426
  }
415
427
  function producedResourcesForTest(result) {
416
428
  const recorded = recordProducedResources(result.details).details;
@@ -3084,8 +3084,12 @@ declare const KAY_PLUGIN_PROTOCOL_VERSION: "kay.plugin.v1";
3084
3084
  *
3085
3085
  * 0.55.0 carries managed MCP calls over resource writes in both daemon and plugin-host code.
3086
3086
  * Existing agent and background MCP call shapes remain supported.
3087
+ *
3088
+ * 0.55.1 adds canonical path resources on declared tool permissions, asynchronous display-only
3089
+ * tool previews with cancellation, app-scoped availability snapshots and app-target output
3090
+ * artifact usage declarations. A plugin using these declares ^0.55.1.
3087
3091
  */
3088
- declare const KAY_PLUGIN_SDK_VERSION: "0.55.0";
3092
+ declare const KAY_PLUGIN_SDK_VERSION: "0.55.1";
3089
3093
 
3090
3094
  declare const KAY_PLUGIN_TARGET_NAMES: readonly ["kay.agent", "kay.app", "kay.ui"];
3091
3095
 
@@ -9805,9 +9809,10 @@ declare interface ToolPermissionHint {
9805
9809
  * labelled facts. Render-only: never matched against a rule, never one-tap approval grounds.
9806
9810
  * The tool says what its input claims, so the gate shows it as the tool's claim, not as the
9807
9811
  * daemon's attestation. The host admits only display-safe text; a throw, a blank title or an
9808
- * unsafe string costs the description and the call is asked about as before.
9812
+ * unsafe string costs the description and the call is asked about as before. A promise is
9813
+ * bounded by the host description timeout; forward its optional cancellation signal to reads.
9809
9814
  */
9810
- readonly describePreview?: (input: Record<string, unknown>) => ToolPreviewDescription | undefined;
9815
+ readonly describePreview?: (input: Record<string, unknown>, signal?: AbortSignal) => ToolPreviewDescription | undefined | Promise<ToolPreviewDescription | undefined>;
9811
9816
  readonly kind?: ToolActionKind;
9812
9817
  readonly scheme?: string;
9813
9818
  readonly ruleKey?: string;
package/dist/kay-app.d.ts CHANGED
@@ -153,6 +153,80 @@ declare const AgentRuntimeAutomationFactSource: z.ZodEnum<{
153
153
 
154
154
  declare type AgentRuntimeAutomationFactSource = z.infer<typeof AgentRuntimeAutomationFactSource>;
155
155
 
156
+ /**
157
+ * The failure record the automation lane mints for a failure it observed itself (domain
158
+ * `automation`). A producer passes `AgentRuntimeAutomationFailureCode`, so an undeclared code
159
+ * fails to compile; the reader takes any `automation.` code, so a stored run still reads after
160
+ * a code is renamed.
161
+ */
162
+ declare type AgentRuntimeAutomationFailure<Code extends string = string> = FailureOccurrence<AgentRuntimeAutomationFailureCause, Code, "automation">;
163
+
164
+ declare const AgentRuntimeAutomationFailure: z.ZodType<AgentRuntimeAutomationFailure>;
165
+
166
+ /**
167
+ * The cause on a failure the automation lane observes itself: the closed facts the daemon saw,
168
+ * keyed by the same `kind` as its `AutomationFailureCause`, plus the engine's own
169
+ * ({@link AgentRuntimeAutomationEngineFailureCause}). No message, stderr, URI or path: these
170
+ * records are exported with the run's log rows. A script's stderr tail stays on the outcome's
171
+ * `message`.
172
+ */
173
+ declare const AgentRuntimeAutomationFailureCause: z.ZodDiscriminatedUnion<[z.ZodObject<{
174
+ kind: z.ZodLiteral<"effect_threw">;
175
+ }, z.core.$strict>, z.ZodObject<{
176
+ kind: z.ZodLiteral<"effect_unsupported">;
177
+ }, z.core.$strict>, z.ZodObject<{
178
+ kind: z.ZodLiteral<"switched_off_across_restart">;
179
+ }, z.core.$strict>, z.ZodObject<{
180
+ kind: z.ZodLiteral<"probe_failed">;
181
+ consecutiveFailures: z.ZodNumber;
182
+ retired: z.ZodBoolean;
183
+ }, z.core.$strict>, z.ZodObject<{
184
+ kind: z.ZodLiteral<"run_start_failed">;
185
+ }, z.core.$strict>, z.ZodObject<{
186
+ kind: z.ZodLiteral<"plugin_revision_moving">;
187
+ }, z.core.$strict>, z.ZodObject<{
188
+ kind: z.ZodLiteral<"owner_unsupported">;
189
+ }, z.core.$strict>, z.ZodObject<{
190
+ kind: z.ZodLiteral<"turn_target_missing">;
191
+ }, z.core.$strict>, z.ZodObject<{
192
+ kind: z.ZodLiteral<"target_missing">;
193
+ }, z.core.$strict>, z.ZodObject<{
194
+ kind: z.ZodLiteral<"declaration_gone">;
195
+ }, z.core.$strict>, z.ZodObject<{
196
+ kind: z.ZodLiteral<"turn_delivery_failed">;
197
+ }, z.core.$strict>, z.ZodObject<{
198
+ kind: z.ZodLiteral<"handler_failed">;
199
+ }, z.core.$strict>, z.ZodObject<{
200
+ kind: z.ZodLiteral<"network_unreachable">;
201
+ }, z.core.$strict>, z.ZodObject<{
202
+ kind: z.ZodLiteral<"script_timed_out">;
203
+ }, z.core.$strict>, z.ZodObject<{
204
+ kind: z.ZodLiteral<"script_cwd_unset">;
205
+ }, z.core.$strict>, z.ZodObject<{
206
+ kind: z.ZodLiteral<"script_result_invalid">;
207
+ }, z.core.$strict>, z.ZodObject<{
208
+ kind: z.ZodLiteral<"script_failed">;
209
+ }, z.core.$strict>, z.ZodObject<{
210
+ kind: z.ZodLiteral<"turn_failed">;
211
+ }, z.core.$strict>, z.ZodObject<{
212
+ kind: z.ZodLiteral<"workflow_failed">;
213
+ }, z.core.$strict>, z.ZodObject<{
214
+ kind: z.ZodLiteral<"surface_unavailable">;
215
+ why: z.ZodEnum<{
216
+ starting: "starting";
217
+ script_unreadable: "script_unreadable";
218
+ }>;
219
+ }, z.core.$strict>, z.ZodObject<{
220
+ kind: z.ZodLiteral<"script_exited">;
221
+ signal: z.ZodNullable<z.ZodString>;
222
+ }, z.core.$strict>, z.ZodObject<{
223
+ kind: z.ZodLiteral<"script_process_error">;
224
+ errorCode: z.ZodOptional<z.ZodString>;
225
+ cwdExists: z.ZodBoolean;
226
+ }, z.core.$strict>], "kind">;
227
+
228
+ declare type AgentRuntimeAutomationFailureCause = z.infer<typeof AgentRuntimeAutomationFailureCause>;
229
+
156
230
  /** One automation run's provenance detail (RFC Release 2). */
157
231
  declare const AgentRuntimeAutomationRunDetail: z.ZodObject<{
158
232
  run: z.ZodObject<{
@@ -324,7 +398,7 @@ declare const AgentRuntimeAutomationRunDetail: z.ZodObject<{
324
398
  retryable: z.ZodBoolean;
325
399
  retryAfterMs: z.ZodOptional<z.ZodNumber>;
326
400
  }, z.core.$strict>>;
327
- failure: z.ZodOptional<z.ZodType<RunFailureOccurrence<string, string>, unknown, z.core.$ZodTypeInternals<RunFailureOccurrence<string, string>, unknown>>>;
401
+ failure: z.ZodOptional<z.ZodUnion<readonly [z.ZodType<RunFailureOccurrence<string, string>, unknown, z.core.$ZodTypeInternals<RunFailureOccurrence<string, string>, unknown>>, z.ZodType<AgentRuntimeAutomationFailure<string>, unknown, z.core.$ZodTypeInternals<AgentRuntimeAutomationFailure<string>, unknown>>]>>;
328
402
  sessionId: z.ZodOptional<z.ZodString>;
329
403
  retryAtMs: z.ZodOptional<z.ZodNumber>;
330
404
  tries: z.ZodOptional<z.ZodNumber>;
@@ -2511,7 +2585,7 @@ declare interface Decision<Q extends DecideQuestions = DecideQuestions> {
2511
2585
  }
2512
2586
 
2513
2587
  /** Builds an app tool from manifest facts, retaining its execution, availability and preview callbacks. */
2514
- export declare function declaredAppToolDefinition(tool: ToolContribution, implementation: KayAppToolImplementation): KayAppToolDefinition;
2588
+ export declare function declaredAppToolDefinition(tool: ToolContribution, implementation: KayAppToolImplementation, environment?: ToolPermissionEnvironment): KayAppToolDefinition;
2515
2589
 
2516
2590
  /** Createsa uni-directional Codec with Decode only. The Decode function is called on Value.Decode */
2517
2591
  declare function Decode<Type extends TSchema, Callback extends TDecodeCallback<StaticDecode<Type>, unknown>>(type: Type, callback: Callback): TCodec<Type, ReturnType<Callback>>;
@@ -4312,8 +4386,12 @@ declare const KAY_PLUGIN_PROTOCOL_VERSION: "kay.plugin.v1";
4312
4386
  *
4313
4387
  * 0.55.0 carries managed MCP calls over resource writes in both daemon and plugin-host code.
4314
4388
  * Existing agent and background MCP call shapes remain supported.
4389
+ *
4390
+ * 0.55.1 adds canonical path resources on declared tool permissions, asynchronous display-only
4391
+ * tool previews with cancellation, app-scoped availability snapshots and app-target output
4392
+ * artifact usage declarations. A plugin using these declares ^0.55.1.
4315
4393
  */
4316
- declare const KAY_PLUGIN_SDK_VERSION: "0.55.0";
4394
+ declare const KAY_PLUGIN_SDK_VERSION: "0.55.1";
4317
4395
 
4318
4396
  declare const KAY_PLUGIN_TARGET_NAMES: readonly ["kay.agent", "kay.app", "kay.ui"];
4319
4397
 
@@ -15928,6 +16006,9 @@ export declare const ToolContribution: z.ZodObject<{
15928
16006
  resourcePrefix: z.ZodOptional<z.ZodString>;
15929
16007
  resourceArgs: z.ZodOptional<z.ZodArray<z.ZodString>>;
15930
16008
  resourceTrim: z.ZodOptional<z.ZodLiteral<true>>;
16009
+ resourcePathNormalization: z.ZodOptional<z.ZodObject<{
16010
+ preserveUriSchemes: z.ZodOptional<z.ZodArray<z.ZodString>>;
16011
+ }, z.core.$strict>>;
15931
16012
  defaultPermission: z.ZodOptional<z.ZodEnum<{
15932
16013
  never: "never";
15933
16014
  allow: "allow";
@@ -15950,6 +16031,9 @@ export declare const ToolContribution: z.ZodObject<{
15950
16031
  ruleKey: z.ZodOptional<z.ZodString>;
15951
16032
  }, z.core.$strict>>>;
15952
16033
  }, z.core.$strict>>;
16034
+ availability: z.ZodOptional<z.ZodObject<{
16035
+ scope: z.ZodLiteral<"app">;
16036
+ }, z.core.$strict>>;
15953
16037
  localId: z.ZodString;
15954
16038
  toolName: z.ZodString;
15955
16039
  displayName: z.ZodOptional<z.ZodString>;
@@ -16076,6 +16160,11 @@ declare interface ToolExecutionPolicyDefaults {
16076
16160
  */
16077
16161
  export declare type ToolParametersWire = unknown;
16078
16162
 
16163
+ /** Explicit host environment used to expand manifest permission paths. */
16164
+ export declare interface ToolPermissionEnvironment {
16165
+ readonly homeDirectory: string;
16166
+ }
16167
+
16079
16168
  /**
16080
16169
  * A tool's own declaration of how a call to it should classify, supplied on the tool
16081
16170
  * definition (the same shape of author-declared, kernel-read fact as `requiresAuth` and
@@ -16099,9 +16188,10 @@ export declare interface ToolPermissionHint {
16099
16188
  * labelled facts. Render-only: never matched against a rule, never one-tap approval grounds.
16100
16189
  * The tool says what its input claims, so the gate shows it as the tool's claim, not as the
16101
16190
  * daemon's attestation. The host admits only display-safe text; a throw, a blank title or an
16102
- * unsafe string costs the description and the call is asked about as before.
16191
+ * unsafe string costs the description and the call is asked about as before. A promise is
16192
+ * bounded by the host description timeout; forward its optional cancellation signal to reads.
16103
16193
  */
16104
- readonly describePreview?: (input: Record<string, unknown>) => ToolPreviewDescription | undefined;
16194
+ readonly describePreview?: (input: Record<string, unknown>, signal?: AbortSignal) => ToolPreviewDescription | undefined | Promise<ToolPreviewDescription | undefined>;
16105
16195
  readonly kind?: ToolActionKind;
16106
16196
  readonly scheme?: string;
16107
16197
  readonly ruleKey?: string;
package/dist/kay-app.js CHANGED
@@ -1007,8 +1007,12 @@ function refusedCountOf(error) {
1007
1007
  }
1008
1008
 
1009
1009
  // packages/plugin-sdk/dist/kay-agent/declared-tool.js
1010
- function declaredToolPermission(permission) {
1011
- const { kind, ruleKey, resourceArgs, scheme, resourcePrefix, resourceTrim, defaultPermission, classificationRules } = permission;
1010
+ import { isAbsolute, join, normalize, resolve } from "node:path";
1011
+ function declaredToolPermission(permission, environment) {
1012
+ const { kind, ruleKey, resourceArgs, scheme, resourcePrefix, resourceTrim, resourcePathNormalization, defaultPermission, classificationRules } = permission;
1013
+ if (resourcePathNormalization !== void 0 && environment === void 0) {
1014
+ throw new Error("Path-normalized tool resources require a home directory.");
1015
+ }
1012
1016
  return {
1013
1017
  kind,
1014
1018
  ...scheme === void 0 ? {} : { scheme },
@@ -1029,16 +1033,24 @@ function declaredToolPermission(permission) {
1029
1033
  ...resourceArgs === void 0 ? {} : {
1030
1034
  deriveResources: (input) => resourceArgs.flatMap((arg) => {
1031
1035
  const value = input[arg];
1032
- return typeof value === "string" ? [
1033
- `${resourcePrefix ?? ""}${resourceTrim === true ? value.trim() : value}`
1034
- ] : [];
1036
+ if (typeof value !== "string")
1037
+ return [];
1038
+ let resource = resourceTrim === true ? value.trim() : value;
1039
+ if (resourcePathNormalization !== void 0 && environment !== void 0) {
1040
+ const preserved = resourcePathNormalization.preserveUriSchemes?.some((preservedScheme) => resource.toLowerCase().startsWith(`${preservedScheme.toLowerCase()}://`)) ?? false;
1041
+ if (!preserved) {
1042
+ const expanded = resource === "~" ? environment.homeDirectory : resource.startsWith("~/") ? join(environment.homeDirectory, resource.slice(2)) : resource;
1043
+ resource = isAbsolute(expanded) ? resolve(expanded) : normalize(expanded);
1044
+ }
1045
+ }
1046
+ return [`${resourcePrefix ?? ""}${resource}`];
1035
1047
  })
1036
1048
  }
1037
1049
  };
1038
1050
  }
1039
1051
 
1040
1052
  // packages/plugin-sdk/dist/kay-app/declared-tool.js
1041
- function declaredAppToolDefinition(tool, implementation) {
1053
+ function declaredAppToolDefinition(tool, implementation, environment) {
1042
1054
  if (tool.parameters === void 0 || tool.description === void 0) {
1043
1055
  throw new Error(`Tool '${tool.toolName}' declares no parameters or description.`);
1044
1056
  }
@@ -1053,7 +1065,7 @@ function declaredAppToolDefinition(tool, implementation) {
1053
1065
  ...tool.promptGuidelines === void 0 ? {} : { promptGuidelines: tool.promptGuidelines },
1054
1066
  ...tool.permission === void 0 ? {} : {
1055
1067
  permission: {
1056
- ...declaredToolPermission(tool.permission),
1068
+ ...declaredToolPermission(tool.permission, environment),
1057
1069
  ...preview?.describePreview === void 0 ? {} : { describePreview: preview.describePreview }
1058
1070
  }
1059
1071
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yaklabs-ai/plugin-sdk",
3
- "version": "0.55.0",
3
+ "version": "0.55.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",