@yaklabs-ai/plugin-sdk 0.12.5 → 0.13.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.
@@ -531,7 +531,7 @@ declare interface ExtensionPaths {
531
531
  export declare function fauxAuthContext(overrides?: Partial<ExtensionAuthContext>): ExtensionAuthContext;
532
532
 
533
533
  /** The capability handles a `KayAgentPluginApi` always carries — authority is decided per call. */
534
- export declare type FauxKayAgentCapabilities = Pick<KayAgentPluginApi, "filesystem" | "network" | "webSession" | "process" | "whiteboard" | "interaction" | "interceptToolCall" | "withJev" | "events" | "time" | "userFiles">;
534
+ export declare type FauxKayAgentCapabilities = Pick<KayAgentPluginApi, "network" | "webSession" | "process" | "whiteboard" | "interaction" | "interceptToolCall" | "withJev" | "events" | "time" | "userFiles" | "familyFolder">;
535
535
 
536
536
  export declare function fauxKayAgentCapabilities(): FauxKayAgentCapabilities;
537
537
 
@@ -925,52 +925,14 @@ declare interface KayAgentEvents {
925
925
  publish(localId: string, payload: unknown): void;
926
926
  }
927
927
 
928
- /**
929
- * Claim-checked filesystem operations. Paths are root-relative; canonical host paths never cross
930
- * the seam. Writes are atomic: readers see the old file or the new one, never a partial write. A
931
- * replace keeps the file's mode but makes a new file, so owner and extended attributes are not
932
- * carried over. On a volume without hard links an exclusive create can briefly show an empty file.
933
- */
934
- declare interface KayAgentFilesystem {
935
- readText(location: KayAgentFilesystemLocation): Promise<string>;
936
- writeText(location: KayAgentFilesystemLocation, content: string, options?: KayAgentFilesystemWriteOptions): Promise<void>;
937
- /** The whole file, or the requested window of it. */
938
- readBytes(location: KayAgentFilesystemLocation, range?: KayAgentFilesystemByteRange): Promise<Uint8Array>;
939
- writeBytes(location: KayAgentFilesystemLocation, bytes: Uint8Array, options?: KayAgentFilesystemWriteOptions): Promise<void>;
940
- mkdir(location: KayAgentFilesystemLocation): Promise<void>;
941
- readDir(location: KayAgentFilesystemLocation): Promise<readonly KayAgentFilesystemEntry[]>;
942
- stat(location: KayAgentFilesystemLocation): Promise<KayAgentFilesystemStat>;
943
- rename(from: KayAgentFilesystemLocation, to: KayAgentFilesystemLocation): Promise<void>;
944
- /** Returns the canonical path relative to the selected grant root. */
945
- realpath(location: KayAgentFilesystemLocation): Promise<string>;
946
- }
947
-
948
- /** A byte window of a file; `maxBytes` is capped by the host. */
949
- declare interface KayAgentFilesystemByteRange {
950
- readonly offset: number;
951
- readonly maxBytes: number;
952
- }
953
-
954
- declare interface KayAgentFilesystemEntry {
955
- readonly name: string;
956
- readonly kind: "file" | "directory" | "symlink" | "other";
957
- }
958
-
959
- declare interface KayAgentFilesystemLocation {
960
- /** Exact `root` selector the host bound for this target, plus a path relative to it. */
961
- readonly root: string;
962
- readonly path: string;
963
- }
964
-
965
- declare interface KayAgentFilesystemStat {
966
- readonly kind: "file" | "directory" | "other";
967
- readonly size: number;
968
- readonly modifiedAtMs: number;
969
- }
970
-
971
- declare interface KayAgentFilesystemWriteOptions {
972
- /** Fail with `already_exists` instead of replacing a file already at the location. */
973
- readonly exclusive?: boolean;
928
+ /** This plugin's folder in the session family's shared Whiteboard. */
929
+ declare interface KayAgentFamilyFolder {
930
+ /**
931
+ * The folder's absolute path, created on first use. The plugin that owns the Whiteboard gets
932
+ * the whole family folder; every other plugin gets its own `plugins/<plugin-id>/` inside it.
933
+ * Undefined outside a session.
934
+ */
935
+ path(): Promise<string | undefined>;
974
936
  }
975
937
 
976
938
  declare interface KayAgentInteractionSurfaces {
@@ -1112,11 +1074,8 @@ declare interface KayAgentPluginApi {
1112
1074
  /** Register a whole URI module (a scheme handler that owns its address space, e.g. `drive://`). */
1113
1075
  registerModule(module: UriExtensionModule): void;
1114
1076
  };
1115
- /**
1116
- * Always present; each call is checked against `filesystem.read {root}` / `filesystem.write
1117
- * {root}` for the root it touches, and against the host's binding for that root.
1118
- */
1119
- readonly filesystem: KayAgentFilesystem;
1077
+ /** This plugin's folder in the session family's shared Whiteboard, created on first use. Undefined outside a session. */
1078
+ readonly familyFolder: KayAgentFamilyFolder;
1120
1079
  /** Absent unless the `knowledgeSearch` grant is requested and effectively granted. */
1121
1080
  readonly knowledgeSearch?: KayAgentKnowledgeSearch;
1122
1081
  /** Absent unless the `knownResources` grant is requested and effectively granted. */
@@ -1169,9 +1128,8 @@ declare interface KayAgentPluginApi {
1169
1128
  readonly time: KayAppTime;
1170
1129
  /**
1171
1130
  * File I/O in user folders, run by the host on its own worker threads under a deadline and
1172
- * answered as a typed result. Always present and ungated: unlike {@link filesystem} it takes
1173
- * absolute paths and checks no grant, because it adds no authority a plugin's `node:fs` does not
1174
- * already have. What it adds is that a slow or unresponsive folder never blocks the daemon. See
1131
+ * answered as a typed result. Always present and ungated: it takes absolute paths and checks no
1132
+ * grant, because it adds no authority a plugin's `node:fs` does not already have. What it adds is that a slow or unresponsive folder never blocks the daemon. See
1175
1133
  * {@link KayAppUserFiles}.
1176
1134
  */
1177
1135
  readonly userFiles: KayAppUserFiles;
@@ -147,17 +147,6 @@ var USER_FILE_METHODS = [
147
147
  ];
148
148
  function fauxKayAgentCapabilities() {
149
149
  return {
150
- filesystem: {
151
- readText: unwired("filesystem.readText"),
152
- writeText: unwired("filesystem.writeText"),
153
- readBytes: unwired("filesystem.readBytes"),
154
- writeBytes: unwired("filesystem.writeBytes"),
155
- mkdir: unwired("filesystem.mkdir"),
156
- readDir: unwired("filesystem.readDir"),
157
- stat: unwired("filesystem.stat"),
158
- rename: unwired("filesystem.rename"),
159
- realpath: unwired("filesystem.realpath")
160
- },
161
150
  network: { fetch: unwired("network.fetch") },
162
151
  webSession: {
163
152
  request: unwired("webSession.request"),
@@ -210,7 +199,10 @@ function fauxKayAgentCapabilities() {
210
199
  kind: "error",
211
200
  detail: `userFiles.${name} is not wired in this test double`
212
201
  })
213
- ]))
202
+ ])),
203
+ // A test double runs outside any session, so it has no family folder — the same answer the
204
+ // real capability gives. A test that exercises one overrides this handle after the spread.
205
+ familyFolder: { path: async () => void 0 }
214
206
  };
215
207
  }
216
208
  function defaultTestToolContext() {
@@ -1273,14 +1273,6 @@ declare type JsonValue_3 = string | number | boolean | null | JsonValue_3[] | {
1273
1273
 
1274
1274
  declare const JsonValue_3: z.ZodType<JsonValue_3>;
1275
1275
 
1276
- /**
1277
- * The root selector the host binds to the session family's shared Whiteboard folder. The plugin
1278
- * that owns the Whiteboard gets the whole folder; every other plugin gets its own
1279
- * `plugins/<plugin-id>/` folder inside it. Calls on it are claims on
1280
- * `filesystem.read`/`filesystem.write` with this `root`, decided like any other.
1281
- */
1282
- export declare const KAY_FAMILY_WHITEBOARD_FILESYSTEM_ROOT = "family-whiteboard";
1283
-
1284
1276
  /** A plugin's Kay agent activation — receives only the brokered {@link KayAgentPluginApi}. */
1285
1277
  export declare type KayAgentActivate = (api: KayAgentPluginApi) => void;
1286
1278
 
@@ -1345,9 +1337,8 @@ export declare interface KayAgentAdvertisementAuthApi {
1345
1337
  * `grant-read-failed` means Kay could not read its own consent store and refused rather than
1346
1338
  * assume — the second is not something a grant prompt fixes.
1347
1339
  *
1348
- * Structurally parallel to {@link KayAgentFilesystemError}: broker handles are declaration-gated,
1349
- * so presence does not imply a current grant or concrete binding. This error says which ordered
1350
- * policy layer refused one specific call.
1340
+ * Broker handles are always present, so presence does not imply a current grant or concrete
1341
+ * binding. This error says which ordered policy layer refused one specific call.
1351
1342
  */
1352
1343
  export declare class KayAgentCapabilityError extends Error {
1353
1344
  readonly refusal: PluginCapabilityRefusalV1;
@@ -1371,59 +1362,14 @@ export declare interface KayAgentEvents {
1371
1362
  publish(localId: string, payload: unknown): void;
1372
1363
  }
1373
1364
 
1374
- /**
1375
- * Claim-checked filesystem operations. Paths are root-relative; canonical host paths never cross
1376
- * the seam. Writes are atomic: readers see the old file or the new one, never a partial write. A
1377
- * replace keeps the file's mode but makes a new file, so owner and extended attributes are not
1378
- * carried over. On a volume without hard links an exclusive create can briefly show an empty file.
1379
- */
1380
- export declare interface KayAgentFilesystem {
1381
- readText(location: KayAgentFilesystemLocation): Promise<string>;
1382
- writeText(location: KayAgentFilesystemLocation, content: string, options?: KayAgentFilesystemWriteOptions): Promise<void>;
1383
- /** The whole file, or the requested window of it. */
1384
- readBytes(location: KayAgentFilesystemLocation, range?: KayAgentFilesystemByteRange): Promise<Uint8Array>;
1385
- writeBytes(location: KayAgentFilesystemLocation, bytes: Uint8Array, options?: KayAgentFilesystemWriteOptions): Promise<void>;
1386
- mkdir(location: KayAgentFilesystemLocation): Promise<void>;
1387
- readDir(location: KayAgentFilesystemLocation): Promise<readonly KayAgentFilesystemEntry[]>;
1388
- stat(location: KayAgentFilesystemLocation): Promise<KayAgentFilesystemStat>;
1389
- rename(from: KayAgentFilesystemLocation, to: KayAgentFilesystemLocation): Promise<void>;
1390
- /** Returns the canonical path relative to the selected grant root. */
1391
- realpath(location: KayAgentFilesystemLocation): Promise<string>;
1392
- }
1393
-
1394
- /** A byte window of a file; `maxBytes` is capped by the host. */
1395
- export declare interface KayAgentFilesystemByteRange {
1396
- readonly offset: number;
1397
- readonly maxBytes: number;
1398
- }
1399
-
1400
- export declare interface KayAgentFilesystemEntry {
1401
- readonly name: string;
1402
- readonly kind: "file" | "directory" | "symlink" | "other";
1403
- }
1404
-
1405
- export declare class KayAgentFilesystemError extends Error {
1406
- readonly code: KayAgentFilesystemErrorCode;
1407
- constructor(code: KayAgentFilesystemErrorCode, message: string);
1408
- }
1409
-
1410
- export declare type KayAgentFilesystemErrorCode = "denied" | "invalid_path" | "not_found" | "already_exists" | "not_directory" | "is_directory" | "io_error";
1411
-
1412
- export declare interface KayAgentFilesystemLocation {
1413
- /** Exact `root` selector the host bound for this target, plus a path relative to it. */
1414
- readonly root: string;
1415
- readonly path: string;
1416
- }
1417
-
1418
- export declare interface KayAgentFilesystemStat {
1419
- readonly kind: "file" | "directory" | "other";
1420
- readonly size: number;
1421
- readonly modifiedAtMs: number;
1422
- }
1423
-
1424
- export declare interface KayAgentFilesystemWriteOptions {
1425
- /** Fail with `already_exists` instead of replacing a file already at the location. */
1426
- readonly exclusive?: boolean;
1365
+ /** This plugin's folder in the session family's shared Whiteboard. */
1366
+ export declare interface KayAgentFamilyFolder {
1367
+ /**
1368
+ * The folder's absolute path, created on first use. The plugin that owns the Whiteboard gets
1369
+ * the whole family folder; every other plugin gets its own `plugins/<plugin-id>/` inside it.
1370
+ * Undefined outside a session.
1371
+ */
1372
+ path(): Promise<string | undefined>;
1427
1373
  }
1428
1374
 
1429
1375
  /**
@@ -1573,11 +1519,8 @@ export declare interface KayAgentPluginApi {
1573
1519
  /** Register a whole URI module (a scheme handler that owns its address space, e.g. `drive://`). */
1574
1520
  registerModule(module: UriExtensionModule): void;
1575
1521
  };
1576
- /**
1577
- * Always present; each call is checked against `filesystem.read {root}` / `filesystem.write
1578
- * {root}` for the root it touches, and against the host's binding for that root.
1579
- */
1580
- readonly filesystem: KayAgentFilesystem;
1522
+ /** This plugin's folder in the session family's shared Whiteboard, created on first use. Undefined outside a session. */
1523
+ readonly familyFolder: KayAgentFamilyFolder;
1581
1524
  /** Absent unless the `knowledgeSearch` grant is requested and effectively granted. */
1582
1525
  readonly knowledgeSearch?: KayAgentKnowledgeSearch;
1583
1526
  /** Absent unless the `knownResources` grant is requested and effectively granted. */
@@ -1630,9 +1573,8 @@ export declare interface KayAgentPluginApi {
1630
1573
  readonly time: KayAppTime;
1631
1574
  /**
1632
1575
  * File I/O in user folders, run by the host on its own worker threads under a deadline and
1633
- * answered as a typed result. Always present and ungated: unlike {@link filesystem} it takes
1634
- * absolute paths and checks no grant, because it adds no authority a plugin's `node:fs` does not
1635
- * already have. What it adds is that a slow or unresponsive folder never blocks the daemon. See
1576
+ * answered as a typed result. Always present and ungated: it takes absolute paths and checks no
1577
+ * grant, because it adds no authority a plugin's `node:fs` does not already have. What it adds is that a slow or unresponsive folder never blocks the daemon. See
1636
1578
  * {@link KayAppUserFiles}.
1637
1579
  */
1638
1580
  readonly userFiles: KayAppUserFiles;
@@ -2118,16 +2060,8 @@ declare const KayPluginManifestV1: z.ZodObject<{
2118
2060
  localId: z.ZodString;
2119
2061
  schemes: z.ZodArray<z.ZodString>;
2120
2062
  displayName: z.ZodOptional<z.ZodString>;
2121
- filesystemBacking: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
2063
+ filesystemBacking: z.ZodOptional<z.ZodObject<{
2122
2064
  root: z.ZodLiteral<"dataDir">;
2123
- }, z.core.$strict>, z.ZodObject<{
2124
- root: z.ZodLiteral<"filesystem">;
2125
- selector: z.ZodString;
2126
- }, z.core.$strict>], "root">>;
2127
- verbs: z.ZodOptional<z.ZodObject<{
2128
- writable: z.ZodOptional<z.ZodBoolean>;
2129
- editable: z.ZodOptional<z.ZodBoolean>;
2130
- deletable: z.ZodOptional<z.ZodBoolean>;
2131
2065
  }, z.core.$strict>>;
2132
2066
  authService: z.ZodOptional<z.ZodString>;
2133
2067
  knownResources: z.ZodOptional<z.ZodLiteral<true>>;
@@ -3469,18 +3403,6 @@ declare const PluginCapabilityRefusalV1: z.ZodObject<{
3469
3403
  origin: z.ZodString;
3470
3404
  pathPrefix: z.ZodString;
3471
3405
  }, z.core.$strict>;
3472
- }, z.core.$strict>, z.ZodObject<{
3473
- target: z.ZodLiteral<"kay.agent">;
3474
- slug: z.ZodLiteral<"filesystem.read">;
3475
- envelope: z.ZodObject<{
3476
- root: z.ZodString;
3477
- }, z.core.$strict>;
3478
- }, z.core.$strict>, z.ZodObject<{
3479
- target: z.ZodLiteral<"kay.agent">;
3480
- slug: z.ZodLiteral<"filesystem.write">;
3481
- envelope: z.ZodObject<{
3482
- root: z.ZodString;
3483
- }, z.core.$strict>;
3484
3406
  }, z.core.$strict>, z.ZodObject<{
3485
3407
  target: z.ZodLiteral<"kay.agent">;
3486
3408
  slug: z.ZodLiteral<"process.spawn">;
package/dist/kay-agent.js CHANGED
@@ -1374,15 +1374,6 @@ var DelegatedRefreshRejectedError = class extends Error {
1374
1374
  function isDelegatedRefreshRejected(error) {
1375
1375
  return typeof error === "object" && error !== null && error[DELEGATED_REFRESH_REJECTED] === true;
1376
1376
  }
1377
- var KayAgentFilesystemError = class extends Error {
1378
- code;
1379
- constructor(code, message) {
1380
- super(message);
1381
- this.name = "KayAgentFilesystemError";
1382
- this.code = code;
1383
- }
1384
- };
1385
- var KAY_FAMILY_WHITEBOARD_FILESYSTEM_ROOT = "family-whiteboard";
1386
1377
  var KayAgentCapabilityError = class extends Error {
1387
1378
  refusal;
1388
1379
  constructor(refusal, message) {
@@ -1405,9 +1396,7 @@ export {
1405
1396
  DelegatedRefreshRejectedError,
1406
1397
  INTERACTION_CREDENTIAL_GUARD,
1407
1398
  JevCallError,
1408
- KAY_FAMILY_WHITEBOARD_FILESYSTEM_ROOT,
1409
1399
  KayAgentCapabilityError,
1410
- KayAgentFilesystemError,
1411
1400
  KayAgentWebSessionError,
1412
1401
  OBSERVATION_MIME,
1413
1402
  PluginApiError,
package/dist/kay-app.d.ts CHANGED
@@ -6496,8 +6496,6 @@ export declare interface UriModule {
6496
6496
  readonly permissionDefaults?: UriPermissionDefaults;
6497
6497
  /** Requires a resolved URI connection before any verb handler runs. */
6498
6498
  readonly requiresConnection?: boolean;
6499
- /** Host-only marker: dispatch mutations as native file operations after locate finalization. */
6500
- readonly hostNativeFileMutations?: true;
6501
6499
  /**
6502
6500
  * This module refuses a whole-content overwrite of an address the dispatching
6503
6501
  * session has never read or written, when content is already stored there
@@ -6509,7 +6507,7 @@ export declare interface UriModule {
6509
6507
  * A module without the flag never receives the marked dispatch and behaves
6510
6508
  * exactly as before. Enforcement depth past this floor — refusing a write to
6511
6509
  * content that CHANGED since the read — stays the module's own call:
6512
- * `builtin:local-file` and host-native projections enforce both halves; the
6510
+ * `builtin:local-file` enforces both halves; the
6513
6511
  * artifact factory enforces the floor and leaves change detection to its
6514
6512
  * `edit` anchor. A module declaring this flag obligates itself to one more
6515
6513
  * thing: every revision its mutations report must be a value its own reads
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yaklabs-ai/plugin-sdk",
3
- "version": "0.12.5",
3
+ "version": "0.13.0",
4
4
  "description": "The Kay plugin SDK — types and helpers for authoring a Kay directory plugin.",
5
5
  "author": "YakLabs",
6
6
  "type": "module",
@@ -17,6 +17,10 @@
17
17
  "types": "./dist/kay-app.d.ts",
18
18
  "default": "./dist/kay-app.js"
19
19
  },
20
+ "./fs": {
21
+ "types": "./dist/fs.d.ts",
22
+ "default": "./dist/fs.js"
23
+ },
20
24
  "./kay-agent/testing": {
21
25
  "types": "./dist/kay-agent-testing.d.ts",
22
26
  "default": "./dist/kay-agent-testing.js"