@yaklabs-ai/plugin-sdk 0.12.4 → 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.
package/dist/kay-app.d.ts CHANGED
@@ -2729,6 +2729,13 @@ export declare interface KayAppPluginApi {
2729
2729
  * which blocks the daemon; see {@link KayAppRepos}.
2730
2730
  */
2731
2731
  readonly repos: KayAppRepos;
2732
+ /**
2733
+ * File I/O in user folders (stat, read, list, walk, realpath, write, mkdir, rename), run by the
2734
+ * host on its own worker threads under a deadline and answered as a typed result. Always present
2735
+ * and ungated, like {@link paths}. Use it instead of `node:fs`, whose sync calls block the
2736
+ * daemon; see {@link KayAppUserFiles}.
2737
+ */
2738
+ readonly userFiles: KayAppUserFiles;
2732
2739
  /**
2733
2740
  * Read/arrange access to the live desktop workspace. Present whenever the host has a workspace
2734
2741
  * (a headless daemon may not); absence is a host fact, never a grant signal. Reading the snapshot
@@ -4224,6 +4231,135 @@ export declare interface KayAppUiActionSessionEvent extends KayAppSessionEventBa
4224
4231
  readonly toolCallId: string;
4225
4232
  }
4226
4233
 
4234
+ export declare interface KayAppUserFileEntry {
4235
+ readonly name: string;
4236
+ /** From the directory entry itself: a symlink is reported as `symlink`, never followed. */
4237
+ readonly kind: KayAppUserFileKind;
4238
+ }
4239
+
4240
+ /**
4241
+ * The plugin-facing user-files contract: file I/O in folders the user owns, done by the host on
4242
+ * its own worker threads.
4243
+ *
4244
+ * Ungated and always present, like `app.paths`. It confers no authority: a plugin runs in the
4245
+ * daemon's process and can call `node:fs` itself. What the door adds is where the work runs. A
4246
+ * `node:fs` sync call blocks the daemon's event loop for as long as the path takes to answer,
4247
+ * which under a macOS-protected folder or on a drive that stopped answering can be a very long
4248
+ * time (kay#11575); an async one holds a thread of the pool the whole daemon shares. The host runs
4249
+ * each request on a dedicated worker, gives it a deadline, and answers a typed result instead of
4250
+ * throwing.
4251
+ *
4252
+ * This is a leaf module. It lives beside both target SDKs, like `time.ts`, so the `kay.agent` SDK
4253
+ * exposes the same door without importing the `kay.app` surface.
4254
+ */
4255
+ export declare type KayAppUserFileKind = "file" | "directory" | "symlink" | "other";
4256
+
4257
+ export declare interface KayAppUserFileListing {
4258
+ readonly entries: readonly KayAppUserFileEntry[];
4259
+ /** True when the directory had more entries than `maxEntries`; the rest were not read. */
4260
+ readonly entryLimitReached: boolean;
4261
+ }
4262
+
4263
+ /**
4264
+ * File I/O in user folders, run by the host off the daemon's main thread. Every path is absolute.
4265
+ * No method rejects; each answers a {@link KayAppUserFilesResult}. This is not a sandbox: it does
4266
+ * not limit which paths a plugin may touch. Added in SDK 0.12.5: a plugin that calls it declares
4267
+ * `compatibility.sdk` `^0.12.5`, so an older Bonsai refuses a directory or repository plugin at
4268
+ * load instead of the call failing.
4269
+ */
4270
+ export declare interface KayAppUserFiles {
4271
+ /** Follows symlinks. */
4272
+ stat(path: string, options?: KayAppUserFilesCallOptions): Promise<KayAppUserFilesResult<KayAppUserFileStat>>;
4273
+ /** UTF-8. */
4274
+ readText(path: string, options?: KayAppUserFilesReadTextOptions): Promise<KayAppUserFilesResult<string>>;
4275
+ list(path: string, options?: KayAppUserFilesListOptions): Promise<KayAppUserFilesResult<KayAppUserFileListing>>;
4276
+ /** Depth-first below `path`; symlinks are reported, never followed. */
4277
+ walk(path: string, options?: KayAppUserFilesWalkOptions): Promise<KayAppUserFilesResult<KayAppUserFileWalk>>;
4278
+ /** The path with every symlink resolved. */
4279
+ realpath(path: string, options?: KayAppUserFilesCallOptions): Promise<KayAppUserFilesResult<string>>;
4280
+ /**
4281
+ * Creates or replaces a UTF-8 file, not atomically. After `timeout` or `aborted` the write may
4282
+ * still happen.
4283
+ */
4284
+ writeText(path: string, content: string, options?: KayAppUserFilesCallOptions): Promise<KayAppUserFilesResult<null>>;
4285
+ /** Creates the directory and any missing parents; succeeds when it already exists. */
4286
+ mkdir(path: string, options?: KayAppUserFilesCallOptions): Promise<KayAppUserFilesResult<null>>;
4287
+ rename(from: string, to: string, options?: KayAppUserFilesCallOptions): Promise<KayAppUserFilesResult<null>>;
4288
+ }
4289
+
4290
+ export declare interface KayAppUserFilesCallOptions {
4291
+ /** Deadline in milliseconds from the call, waiting included. Default 5000, at most 60000. */
4292
+ readonly timeoutMs?: number;
4293
+ readonly signal?: AbortSignal;
4294
+ }
4295
+
4296
+ export declare interface KayAppUserFilesListOptions extends KayAppUserFilesCallOptions {
4297
+ /** Default 5000, at most 50000. */
4298
+ readonly maxEntries?: number;
4299
+ }
4300
+
4301
+ export declare interface KayAppUserFilesReadTextOptions extends KayAppUserFilesCallOptions {
4302
+ /** A larger file answers `error` with code `EFBIG`. Default 8 MiB, at most 64 MiB. */
4303
+ readonly maxBytes?: number;
4304
+ }
4305
+
4306
+ /**
4307
+ * Every answer. `missing`: nothing exists at the path (ENOENT). `timeout`: no answer from the path
4308
+ * in time. Its `reason` is `deadline` (this request ran out of time), `cooling-down` (a request at
4309
+ * or above this path timed out recently, so the host did not try) or `saturated` (the host's
4310
+ * workers are stuck on other paths, so it did not try). `aborted`: the caller's signal fired.
4311
+ * `error`: anything else, with the Node error `code` when there is one (`EACCES`, `EISDIR`,
4312
+ * `EFBIG` for a file over `maxBytes`, `EINVAL` for a relative path).
4313
+ */
4314
+ export declare type KayAppUserFilesResult<T> = {
4315
+ readonly kind: "ok";
4316
+ readonly value: T;
4317
+ } | {
4318
+ readonly kind: "missing";
4319
+ } | {
4320
+ readonly kind: "timeout";
4321
+ readonly reason: "deadline" | "cooling-down" | "saturated";
4322
+ readonly detail: string;
4323
+ } | {
4324
+ readonly kind: "aborted";
4325
+ } | {
4326
+ readonly kind: "error";
4327
+ readonly code?: string;
4328
+ readonly detail: string;
4329
+ };
4330
+
4331
+ export declare interface KayAppUserFileStat {
4332
+ /** What the path is after following symlinks; never `symlink`. */
4333
+ readonly kind: "file" | "directory" | "other";
4334
+ /** Bytes. */
4335
+ readonly size: number;
4336
+ /** Milliseconds since the Unix epoch. */
4337
+ readonly modifiedAtMs: number;
4338
+ }
4339
+
4340
+ export declare interface KayAppUserFilesWalkOptions extends KayAppUserFilesCallOptions {
4341
+ /** Default 10000, at most 100000. */
4342
+ readonly maxEntries?: number;
4343
+ /** Deepest level reported; the root's children are depth 1. Default 16, at most 64. */
4344
+ readonly maxDepth?: number;
4345
+ /** Report and descend into dot-prefixed entries. Default true. */
4346
+ readonly includeHidden?: boolean;
4347
+ }
4348
+
4349
+ export declare interface KayAppUserFileWalk {
4350
+ readonly entries: readonly KayAppUserFileWalkEntry[];
4351
+ /** True when the walk stopped at `maxEntries`. */
4352
+ readonly entryLimitReached: boolean;
4353
+ /** True when a directory at `maxDepth` was reported but not descended into. */
4354
+ readonly depthLimitReached: boolean;
4355
+ }
4356
+
4357
+ export declare interface KayAppUserFileWalkEntry {
4358
+ /** Path segments below the walk's root. */
4359
+ readonly segments: readonly string[];
4360
+ readonly kind: KayAppUserFileKind;
4361
+ }
4362
+
4227
4363
  export declare interface KayAppWhiteboard {
4228
4364
  /**
4229
4365
  * Binds read-only Whiteboard access to the exact context issued to this plugin's session source.
@@ -6360,8 +6496,6 @@ export declare interface UriModule {
6360
6496
  readonly permissionDefaults?: UriPermissionDefaults;
6361
6497
  /** Requires a resolved URI connection before any verb handler runs. */
6362
6498
  readonly requiresConnection?: boolean;
6363
- /** Host-only marker: dispatch mutations as native file operations after locate finalization. */
6364
- readonly hostNativeFileMutations?: true;
6365
6499
  /**
6366
6500
  * This module refuses a whole-content overwrite of an address the dispatching
6367
6501
  * session has never read or written, when content is already stored there
@@ -6373,7 +6507,7 @@ export declare interface UriModule {
6373
6507
  * A module without the flag never receives the marked dispatch and behaves
6374
6508
  * exactly as before. Enforcement depth past this floor — refusing a write to
6375
6509
  * content that CHANGED since the read — stays the module's own call:
6376
- * `builtin:local-file` and host-native projections enforce both halves; the
6510
+ * `builtin:local-file` enforces both halves; the
6377
6511
  * artifact factory enforces the floor and leaves change detection to its
6378
6512
  * `edit` anchor. A module declaring this flag obligates itself to one more
6379
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.4",
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"