@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/README.md +1 -1
- package/THIRD-PARTY-INVENTORY.json +1 -1
- package/dist/disclosure.d.ts +146 -51
- package/dist/disclosure.js +14 -13
- package/dist/fs.d.ts +156 -0
- package/dist/fs.js +895 -0
- package/dist/kay-agent-testing.d.ts +147 -52
- package/dist/kay-agent-testing.js +23 -12
- package/dist/kay-agent.d.ts +149 -90
- package/dist/kay-agent.js +0 -11
- package/dist/kay-app.d.ts +137 -3
- package/package.json +5 -1
|
@@ -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, "
|
|
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
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
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
|
-
|
|
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. */
|
|
@@ -1167,6 +1126,13 @@ declare interface KayAgentPluginApi {
|
|
|
1167
1126
|
* the same zone-of-record port the session stamp uses; see {@link KayAppTime.snapshot}.
|
|
1168
1127
|
*/
|
|
1169
1128
|
readonly time: KayAppTime;
|
|
1129
|
+
/**
|
|
1130
|
+
* File I/O in user folders, run by the host on its own worker threads under a deadline and
|
|
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
|
|
1133
|
+
* {@link KayAppUserFiles}.
|
|
1134
|
+
*/
|
|
1135
|
+
readonly userFiles: KayAppUserFiles;
|
|
1170
1136
|
/**
|
|
1171
1137
|
* Publish the plugin's declared events, for example so a default notification rule can tell the
|
|
1172
1138
|
* user what the agent just did. Always present, like {@link withJev}: there is nothing to
|
|
@@ -1471,6 +1437,135 @@ declare interface KayAppTimeSnapshot {
|
|
|
1471
1437
|
readonly zoneSource: "host" | "utc-fallback";
|
|
1472
1438
|
}
|
|
1473
1439
|
|
|
1440
|
+
declare interface KayAppUserFileEntry {
|
|
1441
|
+
readonly name: string;
|
|
1442
|
+
/** From the directory entry itself: a symlink is reported as `symlink`, never followed. */
|
|
1443
|
+
readonly kind: KayAppUserFileKind;
|
|
1444
|
+
}
|
|
1445
|
+
|
|
1446
|
+
/**
|
|
1447
|
+
* The plugin-facing user-files contract: file I/O in folders the user owns, done by the host on
|
|
1448
|
+
* its own worker threads.
|
|
1449
|
+
*
|
|
1450
|
+
* Ungated and always present, like `app.paths`. It confers no authority: a plugin runs in the
|
|
1451
|
+
* daemon's process and can call `node:fs` itself. What the door adds is where the work runs. A
|
|
1452
|
+
* `node:fs` sync call blocks the daemon's event loop for as long as the path takes to answer,
|
|
1453
|
+
* which under a macOS-protected folder or on a drive that stopped answering can be a very long
|
|
1454
|
+
* time (kay#11575); an async one holds a thread of the pool the whole daemon shares. The host runs
|
|
1455
|
+
* each request on a dedicated worker, gives it a deadline, and answers a typed result instead of
|
|
1456
|
+
* throwing.
|
|
1457
|
+
*
|
|
1458
|
+
* This is a leaf module. It lives beside both target SDKs, like `time.ts`, so the `kay.agent` SDK
|
|
1459
|
+
* exposes the same door without importing the `kay.app` surface.
|
|
1460
|
+
*/
|
|
1461
|
+
declare type KayAppUserFileKind = "file" | "directory" | "symlink" | "other";
|
|
1462
|
+
|
|
1463
|
+
declare interface KayAppUserFileListing {
|
|
1464
|
+
readonly entries: readonly KayAppUserFileEntry[];
|
|
1465
|
+
/** True when the directory had more entries than `maxEntries`; the rest were not read. */
|
|
1466
|
+
readonly entryLimitReached: boolean;
|
|
1467
|
+
}
|
|
1468
|
+
|
|
1469
|
+
/**
|
|
1470
|
+
* File I/O in user folders, run by the host off the daemon's main thread. Every path is absolute.
|
|
1471
|
+
* No method rejects; each answers a {@link KayAppUserFilesResult}. This is not a sandbox: it does
|
|
1472
|
+
* not limit which paths a plugin may touch. Added in SDK 0.12.5: a plugin that calls it declares
|
|
1473
|
+
* `compatibility.sdk` `^0.12.5`, so an older Bonsai refuses a directory or repository plugin at
|
|
1474
|
+
* load instead of the call failing.
|
|
1475
|
+
*/
|
|
1476
|
+
declare interface KayAppUserFiles {
|
|
1477
|
+
/** Follows symlinks. */
|
|
1478
|
+
stat(path: string, options?: KayAppUserFilesCallOptions): Promise<KayAppUserFilesResult<KayAppUserFileStat>>;
|
|
1479
|
+
/** UTF-8. */
|
|
1480
|
+
readText(path: string, options?: KayAppUserFilesReadTextOptions): Promise<KayAppUserFilesResult<string>>;
|
|
1481
|
+
list(path: string, options?: KayAppUserFilesListOptions): Promise<KayAppUserFilesResult<KayAppUserFileListing>>;
|
|
1482
|
+
/** Depth-first below `path`; symlinks are reported, never followed. */
|
|
1483
|
+
walk(path: string, options?: KayAppUserFilesWalkOptions): Promise<KayAppUserFilesResult<KayAppUserFileWalk>>;
|
|
1484
|
+
/** The path with every symlink resolved. */
|
|
1485
|
+
realpath(path: string, options?: KayAppUserFilesCallOptions): Promise<KayAppUserFilesResult<string>>;
|
|
1486
|
+
/**
|
|
1487
|
+
* Creates or replaces a UTF-8 file, not atomically. After `timeout` or `aborted` the write may
|
|
1488
|
+
* still happen.
|
|
1489
|
+
*/
|
|
1490
|
+
writeText(path: string, content: string, options?: KayAppUserFilesCallOptions): Promise<KayAppUserFilesResult<null>>;
|
|
1491
|
+
/** Creates the directory and any missing parents; succeeds when it already exists. */
|
|
1492
|
+
mkdir(path: string, options?: KayAppUserFilesCallOptions): Promise<KayAppUserFilesResult<null>>;
|
|
1493
|
+
rename(from: string, to: string, options?: KayAppUserFilesCallOptions): Promise<KayAppUserFilesResult<null>>;
|
|
1494
|
+
}
|
|
1495
|
+
|
|
1496
|
+
declare interface KayAppUserFilesCallOptions {
|
|
1497
|
+
/** Deadline in milliseconds from the call, waiting included. Default 5000, at most 60000. */
|
|
1498
|
+
readonly timeoutMs?: number;
|
|
1499
|
+
readonly signal?: AbortSignal;
|
|
1500
|
+
}
|
|
1501
|
+
|
|
1502
|
+
declare interface KayAppUserFilesListOptions extends KayAppUserFilesCallOptions {
|
|
1503
|
+
/** Default 5000, at most 50000. */
|
|
1504
|
+
readonly maxEntries?: number;
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1507
|
+
declare interface KayAppUserFilesReadTextOptions extends KayAppUserFilesCallOptions {
|
|
1508
|
+
/** A larger file answers `error` with code `EFBIG`. Default 8 MiB, at most 64 MiB. */
|
|
1509
|
+
readonly maxBytes?: number;
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1512
|
+
/**
|
|
1513
|
+
* Every answer. `missing`: nothing exists at the path (ENOENT). `timeout`: no answer from the path
|
|
1514
|
+
* in time. Its `reason` is `deadline` (this request ran out of time), `cooling-down` (a request at
|
|
1515
|
+
* or above this path timed out recently, so the host did not try) or `saturated` (the host's
|
|
1516
|
+
* workers are stuck on other paths, so it did not try). `aborted`: the caller's signal fired.
|
|
1517
|
+
* `error`: anything else, with the Node error `code` when there is one (`EACCES`, `EISDIR`,
|
|
1518
|
+
* `EFBIG` for a file over `maxBytes`, `EINVAL` for a relative path).
|
|
1519
|
+
*/
|
|
1520
|
+
declare type KayAppUserFilesResult<T> = {
|
|
1521
|
+
readonly kind: "ok";
|
|
1522
|
+
readonly value: T;
|
|
1523
|
+
} | {
|
|
1524
|
+
readonly kind: "missing";
|
|
1525
|
+
} | {
|
|
1526
|
+
readonly kind: "timeout";
|
|
1527
|
+
readonly reason: "deadline" | "cooling-down" | "saturated";
|
|
1528
|
+
readonly detail: string;
|
|
1529
|
+
} | {
|
|
1530
|
+
readonly kind: "aborted";
|
|
1531
|
+
} | {
|
|
1532
|
+
readonly kind: "error";
|
|
1533
|
+
readonly code?: string;
|
|
1534
|
+
readonly detail: string;
|
|
1535
|
+
};
|
|
1536
|
+
|
|
1537
|
+
declare interface KayAppUserFileStat {
|
|
1538
|
+
/** What the path is after following symlinks; never `symlink`. */
|
|
1539
|
+
readonly kind: "file" | "directory" | "other";
|
|
1540
|
+
/** Bytes. */
|
|
1541
|
+
readonly size: number;
|
|
1542
|
+
/** Milliseconds since the Unix epoch. */
|
|
1543
|
+
readonly modifiedAtMs: number;
|
|
1544
|
+
}
|
|
1545
|
+
|
|
1546
|
+
declare interface KayAppUserFilesWalkOptions extends KayAppUserFilesCallOptions {
|
|
1547
|
+
/** Default 10000, at most 100000. */
|
|
1548
|
+
readonly maxEntries?: number;
|
|
1549
|
+
/** Deepest level reported; the root's children are depth 1. Default 16, at most 64. */
|
|
1550
|
+
readonly maxDepth?: number;
|
|
1551
|
+
/** Report and descend into dot-prefixed entries. Default true. */
|
|
1552
|
+
readonly includeHidden?: boolean;
|
|
1553
|
+
}
|
|
1554
|
+
|
|
1555
|
+
declare interface KayAppUserFileWalk {
|
|
1556
|
+
readonly entries: readonly KayAppUserFileWalkEntry[];
|
|
1557
|
+
/** True when the walk stopped at `maxEntries`. */
|
|
1558
|
+
readonly entryLimitReached: boolean;
|
|
1559
|
+
/** True when a directory at `maxDepth` was reported but not descended into. */
|
|
1560
|
+
readonly depthLimitReached: boolean;
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
declare interface KayAppUserFileWalkEntry {
|
|
1564
|
+
/** Path segments below the walk's root. */
|
|
1565
|
+
readonly segments: readonly string[];
|
|
1566
|
+
readonly kind: KayAppUserFileKind;
|
|
1567
|
+
}
|
|
1568
|
+
|
|
1474
1569
|
declare type KnownApi = "openai-completions" | "mistral-conversations" | "openai-responses" | "azure-openai-responses" | "openai-codex-responses" | "anthropic-messages" | "bedrock-converse-stream" | "google-generative-ai" | "google-vertex" | "pi-messages";
|
|
1475
1570
|
|
|
1476
1571
|
declare type KnownProvider = "amazon-bedrock" | "ant-ling" | "anthropic" | "google" | "google-vertex" | "openai" | "azure-openai-responses" | "openai-codex" | "radius" | "typesafe" | "nvidia" | "deepseek" | "github-copilot" | "xai" | "groq" | "cerebras" | "openrouter" | "vercel-ai-gateway" | "zai" | "zai-coding-cn" | "mistral" | "minimax" | "minimax-cn" | "moonshotai" | "moonshotai-cn" | "huggingface" | "fireworks" | "together" | "baseten" | "opencode" | "opencode-go" | "kimi-coding" | "meta" | "cloudflare-workers-ai" | "cloudflare-ai-gateway" | "qwen-token-plan" | "qwen-token-plan-cn" | "qwen-token-plan-individual" | "xiaomi" | "xiaomi-token-plan-cn" | "xiaomi-token-plan-ams" | "xiaomi-token-plan-sgp";
|
|
@@ -135,19 +135,18 @@ var UNWIRED_SURFACE = {
|
|
|
135
135
|
screenshot: NOT_WIRED,
|
|
136
136
|
open: NOT_WIRED
|
|
137
137
|
};
|
|
138
|
+
var USER_FILE_METHODS = [
|
|
139
|
+
"stat",
|
|
140
|
+
"readText",
|
|
141
|
+
"list",
|
|
142
|
+
"walk",
|
|
143
|
+
"realpath",
|
|
144
|
+
"writeText",
|
|
145
|
+
"mkdir",
|
|
146
|
+
"rename"
|
|
147
|
+
];
|
|
138
148
|
function fauxKayAgentCapabilities() {
|
|
139
149
|
return {
|
|
140
|
-
filesystem: {
|
|
141
|
-
readText: unwired("filesystem.readText"),
|
|
142
|
-
writeText: unwired("filesystem.writeText"),
|
|
143
|
-
readBytes: unwired("filesystem.readBytes"),
|
|
144
|
-
writeBytes: unwired("filesystem.writeBytes"),
|
|
145
|
-
mkdir: unwired("filesystem.mkdir"),
|
|
146
|
-
readDir: unwired("filesystem.readDir"),
|
|
147
|
-
stat: unwired("filesystem.stat"),
|
|
148
|
-
rename: unwired("filesystem.rename"),
|
|
149
|
-
realpath: unwired("filesystem.realpath")
|
|
150
|
-
},
|
|
151
150
|
network: { fetch: unwired("network.fetch") },
|
|
152
151
|
webSession: {
|
|
153
152
|
request: unwired("webSession.request"),
|
|
@@ -191,7 +190,19 @@ function fauxKayAgentCapabilities() {
|
|
|
191
190
|
// zone-of-record path overrides this handle after the spread.
|
|
192
191
|
time: {
|
|
193
192
|
snapshot: () => ({ nowMs: 0, zone: "UTC", zoneSource: "utc-fallback" })
|
|
194
|
-
}
|
|
193
|
+
},
|
|
194
|
+
// Answers every call `error` naming itself, keeping the real contract's promise never to
|
|
195
|
+
// reject. A test that exercises a plugin's file I/O overrides this handle after the spread.
|
|
196
|
+
userFiles: Object.fromEntries(USER_FILE_METHODS.map((name) => [
|
|
197
|
+
name,
|
|
198
|
+
async () => ({
|
|
199
|
+
kind: "error",
|
|
200
|
+
detail: `userFiles.${name} is not wired in this test double`
|
|
201
|
+
})
|
|
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 }
|
|
195
206
|
};
|
|
196
207
|
}
|
|
197
208
|
function defaultTestToolContext() {
|
package/dist/kay-agent.d.ts
CHANGED
|
@@ -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
|
-
*
|
|
1349
|
-
*
|
|
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
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
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
|
-
|
|
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. */
|
|
@@ -1628,6 +1571,13 @@ export declare interface KayAgentPluginApi {
|
|
|
1628
1571
|
* the same zone-of-record port the session stamp uses; see {@link KayAppTime.snapshot}.
|
|
1629
1572
|
*/
|
|
1630
1573
|
readonly time: KayAppTime;
|
|
1574
|
+
/**
|
|
1575
|
+
* File I/O in user folders, run by the host on its own worker threads under a deadline and
|
|
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
|
|
1578
|
+
* {@link KayAppUserFiles}.
|
|
1579
|
+
*/
|
|
1580
|
+
readonly userFiles: KayAppUserFiles;
|
|
1631
1581
|
/**
|
|
1632
1582
|
* Publish the plugin's declared events, for example so a default notification rule can tell the
|
|
1633
1583
|
* user what the agent just did. Always present, like {@link withJev}: there is nothing to
|
|
@@ -1946,6 +1896,135 @@ declare interface KayAppTimeSnapshot {
|
|
|
1946
1896
|
readonly zoneSource: "host" | "utc-fallback";
|
|
1947
1897
|
}
|
|
1948
1898
|
|
|
1899
|
+
export declare interface KayAppUserFileEntry {
|
|
1900
|
+
readonly name: string;
|
|
1901
|
+
/** From the directory entry itself: a symlink is reported as `symlink`, never followed. */
|
|
1902
|
+
readonly kind: KayAppUserFileKind;
|
|
1903
|
+
}
|
|
1904
|
+
|
|
1905
|
+
/**
|
|
1906
|
+
* The plugin-facing user-files contract: file I/O in folders the user owns, done by the host on
|
|
1907
|
+
* its own worker threads.
|
|
1908
|
+
*
|
|
1909
|
+
* Ungated and always present, like `app.paths`. It confers no authority: a plugin runs in the
|
|
1910
|
+
* daemon's process and can call `node:fs` itself. What the door adds is where the work runs. A
|
|
1911
|
+
* `node:fs` sync call blocks the daemon's event loop for as long as the path takes to answer,
|
|
1912
|
+
* which under a macOS-protected folder or on a drive that stopped answering can be a very long
|
|
1913
|
+
* time (kay#11575); an async one holds a thread of the pool the whole daemon shares. The host runs
|
|
1914
|
+
* each request on a dedicated worker, gives it a deadline, and answers a typed result instead of
|
|
1915
|
+
* throwing.
|
|
1916
|
+
*
|
|
1917
|
+
* This is a leaf module. It lives beside both target SDKs, like `time.ts`, so the `kay.agent` SDK
|
|
1918
|
+
* exposes the same door without importing the `kay.app` surface.
|
|
1919
|
+
*/
|
|
1920
|
+
export declare type KayAppUserFileKind = "file" | "directory" | "symlink" | "other";
|
|
1921
|
+
|
|
1922
|
+
export declare interface KayAppUserFileListing {
|
|
1923
|
+
readonly entries: readonly KayAppUserFileEntry[];
|
|
1924
|
+
/** True when the directory had more entries than `maxEntries`; the rest were not read. */
|
|
1925
|
+
readonly entryLimitReached: boolean;
|
|
1926
|
+
}
|
|
1927
|
+
|
|
1928
|
+
/**
|
|
1929
|
+
* File I/O in user folders, run by the host off the daemon's main thread. Every path is absolute.
|
|
1930
|
+
* No method rejects; each answers a {@link KayAppUserFilesResult}. This is not a sandbox: it does
|
|
1931
|
+
* not limit which paths a plugin may touch. Added in SDK 0.12.5: a plugin that calls it declares
|
|
1932
|
+
* `compatibility.sdk` `^0.12.5`, so an older Bonsai refuses a directory or repository plugin at
|
|
1933
|
+
* load instead of the call failing.
|
|
1934
|
+
*/
|
|
1935
|
+
export declare interface KayAppUserFiles {
|
|
1936
|
+
/** Follows symlinks. */
|
|
1937
|
+
stat(path: string, options?: KayAppUserFilesCallOptions): Promise<KayAppUserFilesResult<KayAppUserFileStat>>;
|
|
1938
|
+
/** UTF-8. */
|
|
1939
|
+
readText(path: string, options?: KayAppUserFilesReadTextOptions): Promise<KayAppUserFilesResult<string>>;
|
|
1940
|
+
list(path: string, options?: KayAppUserFilesListOptions): Promise<KayAppUserFilesResult<KayAppUserFileListing>>;
|
|
1941
|
+
/** Depth-first below `path`; symlinks are reported, never followed. */
|
|
1942
|
+
walk(path: string, options?: KayAppUserFilesWalkOptions): Promise<KayAppUserFilesResult<KayAppUserFileWalk>>;
|
|
1943
|
+
/** The path with every symlink resolved. */
|
|
1944
|
+
realpath(path: string, options?: KayAppUserFilesCallOptions): Promise<KayAppUserFilesResult<string>>;
|
|
1945
|
+
/**
|
|
1946
|
+
* Creates or replaces a UTF-8 file, not atomically. After `timeout` or `aborted` the write may
|
|
1947
|
+
* still happen.
|
|
1948
|
+
*/
|
|
1949
|
+
writeText(path: string, content: string, options?: KayAppUserFilesCallOptions): Promise<KayAppUserFilesResult<null>>;
|
|
1950
|
+
/** Creates the directory and any missing parents; succeeds when it already exists. */
|
|
1951
|
+
mkdir(path: string, options?: KayAppUserFilesCallOptions): Promise<KayAppUserFilesResult<null>>;
|
|
1952
|
+
rename(from: string, to: string, options?: KayAppUserFilesCallOptions): Promise<KayAppUserFilesResult<null>>;
|
|
1953
|
+
}
|
|
1954
|
+
|
|
1955
|
+
export declare interface KayAppUserFilesCallOptions {
|
|
1956
|
+
/** Deadline in milliseconds from the call, waiting included. Default 5000, at most 60000. */
|
|
1957
|
+
readonly timeoutMs?: number;
|
|
1958
|
+
readonly signal?: AbortSignal;
|
|
1959
|
+
}
|
|
1960
|
+
|
|
1961
|
+
export declare interface KayAppUserFilesListOptions extends KayAppUserFilesCallOptions {
|
|
1962
|
+
/** Default 5000, at most 50000. */
|
|
1963
|
+
readonly maxEntries?: number;
|
|
1964
|
+
}
|
|
1965
|
+
|
|
1966
|
+
export declare interface KayAppUserFilesReadTextOptions extends KayAppUserFilesCallOptions {
|
|
1967
|
+
/** A larger file answers `error` with code `EFBIG`. Default 8 MiB, at most 64 MiB. */
|
|
1968
|
+
readonly maxBytes?: number;
|
|
1969
|
+
}
|
|
1970
|
+
|
|
1971
|
+
/**
|
|
1972
|
+
* Every answer. `missing`: nothing exists at the path (ENOENT). `timeout`: no answer from the path
|
|
1973
|
+
* in time. Its `reason` is `deadline` (this request ran out of time), `cooling-down` (a request at
|
|
1974
|
+
* or above this path timed out recently, so the host did not try) or `saturated` (the host's
|
|
1975
|
+
* workers are stuck on other paths, so it did not try). `aborted`: the caller's signal fired.
|
|
1976
|
+
* `error`: anything else, with the Node error `code` when there is one (`EACCES`, `EISDIR`,
|
|
1977
|
+
* `EFBIG` for a file over `maxBytes`, `EINVAL` for a relative path).
|
|
1978
|
+
*/
|
|
1979
|
+
export declare type KayAppUserFilesResult<T> = {
|
|
1980
|
+
readonly kind: "ok";
|
|
1981
|
+
readonly value: T;
|
|
1982
|
+
} | {
|
|
1983
|
+
readonly kind: "missing";
|
|
1984
|
+
} | {
|
|
1985
|
+
readonly kind: "timeout";
|
|
1986
|
+
readonly reason: "deadline" | "cooling-down" | "saturated";
|
|
1987
|
+
readonly detail: string;
|
|
1988
|
+
} | {
|
|
1989
|
+
readonly kind: "aborted";
|
|
1990
|
+
} | {
|
|
1991
|
+
readonly kind: "error";
|
|
1992
|
+
readonly code?: string;
|
|
1993
|
+
readonly detail: string;
|
|
1994
|
+
};
|
|
1995
|
+
|
|
1996
|
+
export declare interface KayAppUserFileStat {
|
|
1997
|
+
/** What the path is after following symlinks; never `symlink`. */
|
|
1998
|
+
readonly kind: "file" | "directory" | "other";
|
|
1999
|
+
/** Bytes. */
|
|
2000
|
+
readonly size: number;
|
|
2001
|
+
/** Milliseconds since the Unix epoch. */
|
|
2002
|
+
readonly modifiedAtMs: number;
|
|
2003
|
+
}
|
|
2004
|
+
|
|
2005
|
+
export declare interface KayAppUserFilesWalkOptions extends KayAppUserFilesCallOptions {
|
|
2006
|
+
/** Default 10000, at most 100000. */
|
|
2007
|
+
readonly maxEntries?: number;
|
|
2008
|
+
/** Deepest level reported; the root's children are depth 1. Default 16, at most 64. */
|
|
2009
|
+
readonly maxDepth?: number;
|
|
2010
|
+
/** Report and descend into dot-prefixed entries. Default true. */
|
|
2011
|
+
readonly includeHidden?: boolean;
|
|
2012
|
+
}
|
|
2013
|
+
|
|
2014
|
+
export declare interface KayAppUserFileWalk {
|
|
2015
|
+
readonly entries: readonly KayAppUserFileWalkEntry[];
|
|
2016
|
+
/** True when the walk stopped at `maxEntries`. */
|
|
2017
|
+
readonly entryLimitReached: boolean;
|
|
2018
|
+
/** True when a directory at `maxDepth` was reported but not descended into. */
|
|
2019
|
+
readonly depthLimitReached: boolean;
|
|
2020
|
+
}
|
|
2021
|
+
|
|
2022
|
+
export declare interface KayAppUserFileWalkEntry {
|
|
2023
|
+
/** Path segments below the walk's root. */
|
|
2024
|
+
readonly segments: readonly string[];
|
|
2025
|
+
readonly kind: KayAppUserFileKind;
|
|
2026
|
+
}
|
|
2027
|
+
|
|
1949
2028
|
declare const KayPluginManifestV1: z.ZodObject<{
|
|
1950
2029
|
protocol: z.ZodLiteral<"kay.plugin.v1">;
|
|
1951
2030
|
id: z.ZodString;
|
|
@@ -1981,16 +2060,8 @@ declare const KayPluginManifestV1: z.ZodObject<{
|
|
|
1981
2060
|
localId: z.ZodString;
|
|
1982
2061
|
schemes: z.ZodArray<z.ZodString>;
|
|
1983
2062
|
displayName: z.ZodOptional<z.ZodString>;
|
|
1984
|
-
filesystemBacking: z.ZodOptional<z.
|
|
2063
|
+
filesystemBacking: z.ZodOptional<z.ZodObject<{
|
|
1985
2064
|
root: z.ZodLiteral<"dataDir">;
|
|
1986
|
-
}, z.core.$strict>, z.ZodObject<{
|
|
1987
|
-
root: z.ZodLiteral<"filesystem">;
|
|
1988
|
-
selector: z.ZodString;
|
|
1989
|
-
}, z.core.$strict>], "root">>;
|
|
1990
|
-
verbs: z.ZodOptional<z.ZodObject<{
|
|
1991
|
-
writable: z.ZodOptional<z.ZodBoolean>;
|
|
1992
|
-
editable: z.ZodOptional<z.ZodBoolean>;
|
|
1993
|
-
deletable: z.ZodOptional<z.ZodBoolean>;
|
|
1994
2065
|
}, z.core.$strict>>;
|
|
1995
2066
|
authService: z.ZodOptional<z.ZodString>;
|
|
1996
2067
|
knownResources: z.ZodOptional<z.ZodLiteral<true>>;
|
|
@@ -3332,18 +3403,6 @@ declare const PluginCapabilityRefusalV1: z.ZodObject<{
|
|
|
3332
3403
|
origin: z.ZodString;
|
|
3333
3404
|
pathPrefix: z.ZodString;
|
|
3334
3405
|
}, z.core.$strict>;
|
|
3335
|
-
}, z.core.$strict>, z.ZodObject<{
|
|
3336
|
-
target: z.ZodLiteral<"kay.agent">;
|
|
3337
|
-
slug: z.ZodLiteral<"filesystem.read">;
|
|
3338
|
-
envelope: z.ZodObject<{
|
|
3339
|
-
root: z.ZodString;
|
|
3340
|
-
}, z.core.$strict>;
|
|
3341
|
-
}, z.core.$strict>, z.ZodObject<{
|
|
3342
|
-
target: z.ZodLiteral<"kay.agent">;
|
|
3343
|
-
slug: z.ZodLiteral<"filesystem.write">;
|
|
3344
|
-
envelope: z.ZodObject<{
|
|
3345
|
-
root: z.ZodString;
|
|
3346
|
-
}, z.core.$strict>;
|
|
3347
3406
|
}, z.core.$strict>, z.ZodObject<{
|
|
3348
3407
|
target: z.ZodLiteral<"kay.agent">;
|
|
3349
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,
|