@yaklabs-ai/plugin-sdk 0.12.4 → 0.12.5
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 +137 -0
- package/dist/disclosure.js +11 -0
- package/dist/kay-agent-testing.d.ts +138 -1
- package/dist/kay-agent-testing.js +20 -1
- package/dist/kay-agent.d.ts +137 -0
- package/dist/kay-app.d.ts +136 -0
- package/package.json +1 -1
package/README.md
CHANGED
package/dist/disclosure.d.ts
CHANGED
|
@@ -1266,6 +1266,14 @@ declare interface KayAgentPluginApi {
|
|
|
1266
1266
|
* the same zone-of-record port the session stamp uses; see {@link KayAppTime.snapshot}.
|
|
1267
1267
|
*/
|
|
1268
1268
|
readonly time: KayAppTime;
|
|
1269
|
+
/**
|
|
1270
|
+
* File I/O in user folders, run by the host on its own worker threads under a deadline and
|
|
1271
|
+
* answered as a typed result. Always present and ungated: unlike {@link filesystem} it takes
|
|
1272
|
+
* absolute paths and checks no grant, because it adds no authority a plugin's `node:fs` does not
|
|
1273
|
+
* already have. What it adds is that a slow or unresponsive folder never blocks the daemon. See
|
|
1274
|
+
* {@link KayAppUserFiles}.
|
|
1275
|
+
*/
|
|
1276
|
+
readonly userFiles: KayAppUserFiles;
|
|
1269
1277
|
/**
|
|
1270
1278
|
* Publish the plugin's declared events, for example so a default notification rule can tell the
|
|
1271
1279
|
* user what the agent just did. Always present, like {@link withJev}: there is nothing to
|
|
@@ -1570,6 +1578,135 @@ declare interface KayAppTimeSnapshot {
|
|
|
1570
1578
|
readonly zoneSource: "host" | "utc-fallback";
|
|
1571
1579
|
}
|
|
1572
1580
|
|
|
1581
|
+
declare interface KayAppUserFileEntry {
|
|
1582
|
+
readonly name: string;
|
|
1583
|
+
/** From the directory entry itself: a symlink is reported as `symlink`, never followed. */
|
|
1584
|
+
readonly kind: KayAppUserFileKind;
|
|
1585
|
+
}
|
|
1586
|
+
|
|
1587
|
+
/**
|
|
1588
|
+
* The plugin-facing user-files contract: file I/O in folders the user owns, done by the host on
|
|
1589
|
+
* its own worker threads.
|
|
1590
|
+
*
|
|
1591
|
+
* Ungated and always present, like `app.paths`. It confers no authority: a plugin runs in the
|
|
1592
|
+
* daemon's process and can call `node:fs` itself. What the door adds is where the work runs. A
|
|
1593
|
+
* `node:fs` sync call blocks the daemon's event loop for as long as the path takes to answer,
|
|
1594
|
+
* which under a macOS-protected folder or on a drive that stopped answering can be a very long
|
|
1595
|
+
* time (kay#11575); an async one holds a thread of the pool the whole daemon shares. The host runs
|
|
1596
|
+
* each request on a dedicated worker, gives it a deadline, and answers a typed result instead of
|
|
1597
|
+
* throwing.
|
|
1598
|
+
*
|
|
1599
|
+
* This is a leaf module. It lives beside both target SDKs, like `time.ts`, so the `kay.agent` SDK
|
|
1600
|
+
* exposes the same door without importing the `kay.app` surface.
|
|
1601
|
+
*/
|
|
1602
|
+
declare type KayAppUserFileKind = "file" | "directory" | "symlink" | "other";
|
|
1603
|
+
|
|
1604
|
+
declare interface KayAppUserFileListing {
|
|
1605
|
+
readonly entries: readonly KayAppUserFileEntry[];
|
|
1606
|
+
/** True when the directory had more entries than `maxEntries`; the rest were not read. */
|
|
1607
|
+
readonly entryLimitReached: boolean;
|
|
1608
|
+
}
|
|
1609
|
+
|
|
1610
|
+
/**
|
|
1611
|
+
* File I/O in user folders, run by the host off the daemon's main thread. Every path is absolute.
|
|
1612
|
+
* No method rejects; each answers a {@link KayAppUserFilesResult}. This is not a sandbox: it does
|
|
1613
|
+
* not limit which paths a plugin may touch. Added in SDK 0.12.5: a plugin that calls it declares
|
|
1614
|
+
* `compatibility.sdk` `^0.12.5`, so an older Bonsai refuses a directory or repository plugin at
|
|
1615
|
+
* load instead of the call failing.
|
|
1616
|
+
*/
|
|
1617
|
+
declare interface KayAppUserFiles {
|
|
1618
|
+
/** Follows symlinks. */
|
|
1619
|
+
stat(path: string, options?: KayAppUserFilesCallOptions): Promise<KayAppUserFilesResult<KayAppUserFileStat>>;
|
|
1620
|
+
/** UTF-8. */
|
|
1621
|
+
readText(path: string, options?: KayAppUserFilesReadTextOptions): Promise<KayAppUserFilesResult<string>>;
|
|
1622
|
+
list(path: string, options?: KayAppUserFilesListOptions): Promise<KayAppUserFilesResult<KayAppUserFileListing>>;
|
|
1623
|
+
/** Depth-first below `path`; symlinks are reported, never followed. */
|
|
1624
|
+
walk(path: string, options?: KayAppUserFilesWalkOptions): Promise<KayAppUserFilesResult<KayAppUserFileWalk>>;
|
|
1625
|
+
/** The path with every symlink resolved. */
|
|
1626
|
+
realpath(path: string, options?: KayAppUserFilesCallOptions): Promise<KayAppUserFilesResult<string>>;
|
|
1627
|
+
/**
|
|
1628
|
+
* Creates or replaces a UTF-8 file, not atomically. After `timeout` or `aborted` the write may
|
|
1629
|
+
* still happen.
|
|
1630
|
+
*/
|
|
1631
|
+
writeText(path: string, content: string, options?: KayAppUserFilesCallOptions): Promise<KayAppUserFilesResult<null>>;
|
|
1632
|
+
/** Creates the directory and any missing parents; succeeds when it already exists. */
|
|
1633
|
+
mkdir(path: string, options?: KayAppUserFilesCallOptions): Promise<KayAppUserFilesResult<null>>;
|
|
1634
|
+
rename(from: string, to: string, options?: KayAppUserFilesCallOptions): Promise<KayAppUserFilesResult<null>>;
|
|
1635
|
+
}
|
|
1636
|
+
|
|
1637
|
+
declare interface KayAppUserFilesCallOptions {
|
|
1638
|
+
/** Deadline in milliseconds from the call, waiting included. Default 5000, at most 60000. */
|
|
1639
|
+
readonly timeoutMs?: number;
|
|
1640
|
+
readonly signal?: AbortSignal;
|
|
1641
|
+
}
|
|
1642
|
+
|
|
1643
|
+
declare interface KayAppUserFilesListOptions extends KayAppUserFilesCallOptions {
|
|
1644
|
+
/** Default 5000, at most 50000. */
|
|
1645
|
+
readonly maxEntries?: number;
|
|
1646
|
+
}
|
|
1647
|
+
|
|
1648
|
+
declare interface KayAppUserFilesReadTextOptions extends KayAppUserFilesCallOptions {
|
|
1649
|
+
/** A larger file answers `error` with code `EFBIG`. Default 8 MiB, at most 64 MiB. */
|
|
1650
|
+
readonly maxBytes?: number;
|
|
1651
|
+
}
|
|
1652
|
+
|
|
1653
|
+
/**
|
|
1654
|
+
* Every answer. `missing`: nothing exists at the path (ENOENT). `timeout`: no answer from the path
|
|
1655
|
+
* in time. Its `reason` is `deadline` (this request ran out of time), `cooling-down` (a request at
|
|
1656
|
+
* or above this path timed out recently, so the host did not try) or `saturated` (the host's
|
|
1657
|
+
* workers are stuck on other paths, so it did not try). `aborted`: the caller's signal fired.
|
|
1658
|
+
* `error`: anything else, with the Node error `code` when there is one (`EACCES`, `EISDIR`,
|
|
1659
|
+
* `EFBIG` for a file over `maxBytes`, `EINVAL` for a relative path).
|
|
1660
|
+
*/
|
|
1661
|
+
declare type KayAppUserFilesResult<T> = {
|
|
1662
|
+
readonly kind: "ok";
|
|
1663
|
+
readonly value: T;
|
|
1664
|
+
} | {
|
|
1665
|
+
readonly kind: "missing";
|
|
1666
|
+
} | {
|
|
1667
|
+
readonly kind: "timeout";
|
|
1668
|
+
readonly reason: "deadline" | "cooling-down" | "saturated";
|
|
1669
|
+
readonly detail: string;
|
|
1670
|
+
} | {
|
|
1671
|
+
readonly kind: "aborted";
|
|
1672
|
+
} | {
|
|
1673
|
+
readonly kind: "error";
|
|
1674
|
+
readonly code?: string;
|
|
1675
|
+
readonly detail: string;
|
|
1676
|
+
};
|
|
1677
|
+
|
|
1678
|
+
declare interface KayAppUserFileStat {
|
|
1679
|
+
/** What the path is after following symlinks; never `symlink`. */
|
|
1680
|
+
readonly kind: "file" | "directory" | "other";
|
|
1681
|
+
/** Bytes. */
|
|
1682
|
+
readonly size: number;
|
|
1683
|
+
/** Milliseconds since the Unix epoch. */
|
|
1684
|
+
readonly modifiedAtMs: number;
|
|
1685
|
+
}
|
|
1686
|
+
|
|
1687
|
+
declare interface KayAppUserFilesWalkOptions extends KayAppUserFilesCallOptions {
|
|
1688
|
+
/** Default 10000, at most 100000. */
|
|
1689
|
+
readonly maxEntries?: number;
|
|
1690
|
+
/** Deepest level reported; the root's children are depth 1. Default 16, at most 64. */
|
|
1691
|
+
readonly maxDepth?: number;
|
|
1692
|
+
/** Report and descend into dot-prefixed entries. Default true. */
|
|
1693
|
+
readonly includeHidden?: boolean;
|
|
1694
|
+
}
|
|
1695
|
+
|
|
1696
|
+
declare interface KayAppUserFileWalk {
|
|
1697
|
+
readonly entries: readonly KayAppUserFileWalkEntry[];
|
|
1698
|
+
/** True when the walk stopped at `maxEntries`. */
|
|
1699
|
+
readonly entryLimitReached: boolean;
|
|
1700
|
+
/** True when a directory at `maxDepth` was reported but not descended into. */
|
|
1701
|
+
readonly depthLimitReached: boolean;
|
|
1702
|
+
}
|
|
1703
|
+
|
|
1704
|
+
declare interface KayAppUserFileWalkEntry {
|
|
1705
|
+
/** Path segments below the walk's root. */
|
|
1706
|
+
readonly segments: readonly string[];
|
|
1707
|
+
readonly kind: KayAppUserFileKind;
|
|
1708
|
+
}
|
|
1709
|
+
|
|
1573
1710
|
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";
|
|
1574
1711
|
|
|
1575
1712
|
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";
|
package/dist/disclosure.js
CHANGED
|
@@ -824,6 +824,17 @@ function createKayAgentProbeCapabilityHandles() {
|
|
|
824
824
|
// real capability keeps for a zone the host cannot read.
|
|
825
825
|
time: {
|
|
826
826
|
snapshot: () => ({ nowMs: 0, zone: "UTC", zoneSource: "utc-fallback" })
|
|
827
|
+
},
|
|
828
|
+
// Inert like the filesystem broker: a probe must never touch the user's disk.
|
|
829
|
+
userFiles: {
|
|
830
|
+
stat: inertResult,
|
|
831
|
+
readText: inertResult,
|
|
832
|
+
list: inertResult,
|
|
833
|
+
walk: inertResult,
|
|
834
|
+
realpath: inertResult,
|
|
835
|
+
writeText: inertResult,
|
|
836
|
+
mkdir: inertResult,
|
|
837
|
+
rename: inertResult
|
|
827
838
|
}
|
|
828
839
|
};
|
|
829
840
|
}
|
|
@@ -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">;
|
|
534
|
+
export declare type FauxKayAgentCapabilities = Pick<KayAgentPluginApi, "filesystem" | "network" | "webSession" | "process" | "whiteboard" | "interaction" | "interceptToolCall" | "withJev" | "events" | "time" | "userFiles">;
|
|
535
535
|
|
|
536
536
|
export declare function fauxKayAgentCapabilities(): FauxKayAgentCapabilities;
|
|
537
537
|
|
|
@@ -1167,6 +1167,14 @@ declare interface KayAgentPluginApi {
|
|
|
1167
1167
|
* the same zone-of-record port the session stamp uses; see {@link KayAppTime.snapshot}.
|
|
1168
1168
|
*/
|
|
1169
1169
|
readonly time: KayAppTime;
|
|
1170
|
+
/**
|
|
1171
|
+
* 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
|
|
1175
|
+
* {@link KayAppUserFiles}.
|
|
1176
|
+
*/
|
|
1177
|
+
readonly userFiles: KayAppUserFiles;
|
|
1170
1178
|
/**
|
|
1171
1179
|
* Publish the plugin's declared events, for example so a default notification rule can tell the
|
|
1172
1180
|
* user what the agent just did. Always present, like {@link withJev}: there is nothing to
|
|
@@ -1471,6 +1479,135 @@ declare interface KayAppTimeSnapshot {
|
|
|
1471
1479
|
readonly zoneSource: "host" | "utc-fallback";
|
|
1472
1480
|
}
|
|
1473
1481
|
|
|
1482
|
+
declare interface KayAppUserFileEntry {
|
|
1483
|
+
readonly name: string;
|
|
1484
|
+
/** From the directory entry itself: a symlink is reported as `symlink`, never followed. */
|
|
1485
|
+
readonly kind: KayAppUserFileKind;
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1488
|
+
/**
|
|
1489
|
+
* The plugin-facing user-files contract: file I/O in folders the user owns, done by the host on
|
|
1490
|
+
* its own worker threads.
|
|
1491
|
+
*
|
|
1492
|
+
* Ungated and always present, like `app.paths`. It confers no authority: a plugin runs in the
|
|
1493
|
+
* daemon's process and can call `node:fs` itself. What the door adds is where the work runs. A
|
|
1494
|
+
* `node:fs` sync call blocks the daemon's event loop for as long as the path takes to answer,
|
|
1495
|
+
* which under a macOS-protected folder or on a drive that stopped answering can be a very long
|
|
1496
|
+
* time (kay#11575); an async one holds a thread of the pool the whole daemon shares. The host runs
|
|
1497
|
+
* each request on a dedicated worker, gives it a deadline, and answers a typed result instead of
|
|
1498
|
+
* throwing.
|
|
1499
|
+
*
|
|
1500
|
+
* This is a leaf module. It lives beside both target SDKs, like `time.ts`, so the `kay.agent` SDK
|
|
1501
|
+
* exposes the same door without importing the `kay.app` surface.
|
|
1502
|
+
*/
|
|
1503
|
+
declare type KayAppUserFileKind = "file" | "directory" | "symlink" | "other";
|
|
1504
|
+
|
|
1505
|
+
declare interface KayAppUserFileListing {
|
|
1506
|
+
readonly entries: readonly KayAppUserFileEntry[];
|
|
1507
|
+
/** True when the directory had more entries than `maxEntries`; the rest were not read. */
|
|
1508
|
+
readonly entryLimitReached: boolean;
|
|
1509
|
+
}
|
|
1510
|
+
|
|
1511
|
+
/**
|
|
1512
|
+
* File I/O in user folders, run by the host off the daemon's main thread. Every path is absolute.
|
|
1513
|
+
* No method rejects; each answers a {@link KayAppUserFilesResult}. This is not a sandbox: it does
|
|
1514
|
+
* not limit which paths a plugin may touch. Added in SDK 0.12.5: a plugin that calls it declares
|
|
1515
|
+
* `compatibility.sdk` `^0.12.5`, so an older Bonsai refuses a directory or repository plugin at
|
|
1516
|
+
* load instead of the call failing.
|
|
1517
|
+
*/
|
|
1518
|
+
declare interface KayAppUserFiles {
|
|
1519
|
+
/** Follows symlinks. */
|
|
1520
|
+
stat(path: string, options?: KayAppUserFilesCallOptions): Promise<KayAppUserFilesResult<KayAppUserFileStat>>;
|
|
1521
|
+
/** UTF-8. */
|
|
1522
|
+
readText(path: string, options?: KayAppUserFilesReadTextOptions): Promise<KayAppUserFilesResult<string>>;
|
|
1523
|
+
list(path: string, options?: KayAppUserFilesListOptions): Promise<KayAppUserFilesResult<KayAppUserFileListing>>;
|
|
1524
|
+
/** Depth-first below `path`; symlinks are reported, never followed. */
|
|
1525
|
+
walk(path: string, options?: KayAppUserFilesWalkOptions): Promise<KayAppUserFilesResult<KayAppUserFileWalk>>;
|
|
1526
|
+
/** The path with every symlink resolved. */
|
|
1527
|
+
realpath(path: string, options?: KayAppUserFilesCallOptions): Promise<KayAppUserFilesResult<string>>;
|
|
1528
|
+
/**
|
|
1529
|
+
* Creates or replaces a UTF-8 file, not atomically. After `timeout` or `aborted` the write may
|
|
1530
|
+
* still happen.
|
|
1531
|
+
*/
|
|
1532
|
+
writeText(path: string, content: string, options?: KayAppUserFilesCallOptions): Promise<KayAppUserFilesResult<null>>;
|
|
1533
|
+
/** Creates the directory and any missing parents; succeeds when it already exists. */
|
|
1534
|
+
mkdir(path: string, options?: KayAppUserFilesCallOptions): Promise<KayAppUserFilesResult<null>>;
|
|
1535
|
+
rename(from: string, to: string, options?: KayAppUserFilesCallOptions): Promise<KayAppUserFilesResult<null>>;
|
|
1536
|
+
}
|
|
1537
|
+
|
|
1538
|
+
declare interface KayAppUserFilesCallOptions {
|
|
1539
|
+
/** Deadline in milliseconds from the call, waiting included. Default 5000, at most 60000. */
|
|
1540
|
+
readonly timeoutMs?: number;
|
|
1541
|
+
readonly signal?: AbortSignal;
|
|
1542
|
+
}
|
|
1543
|
+
|
|
1544
|
+
declare interface KayAppUserFilesListOptions extends KayAppUserFilesCallOptions {
|
|
1545
|
+
/** Default 5000, at most 50000. */
|
|
1546
|
+
readonly maxEntries?: number;
|
|
1547
|
+
}
|
|
1548
|
+
|
|
1549
|
+
declare interface KayAppUserFilesReadTextOptions extends KayAppUserFilesCallOptions {
|
|
1550
|
+
/** A larger file answers `error` with code `EFBIG`. Default 8 MiB, at most 64 MiB. */
|
|
1551
|
+
readonly maxBytes?: number;
|
|
1552
|
+
}
|
|
1553
|
+
|
|
1554
|
+
/**
|
|
1555
|
+
* Every answer. `missing`: nothing exists at the path (ENOENT). `timeout`: no answer from the path
|
|
1556
|
+
* in time. Its `reason` is `deadline` (this request ran out of time), `cooling-down` (a request at
|
|
1557
|
+
* or above this path timed out recently, so the host did not try) or `saturated` (the host's
|
|
1558
|
+
* workers are stuck on other paths, so it did not try). `aborted`: the caller's signal fired.
|
|
1559
|
+
* `error`: anything else, with the Node error `code` when there is one (`EACCES`, `EISDIR`,
|
|
1560
|
+
* `EFBIG` for a file over `maxBytes`, `EINVAL` for a relative path).
|
|
1561
|
+
*/
|
|
1562
|
+
declare type KayAppUserFilesResult<T> = {
|
|
1563
|
+
readonly kind: "ok";
|
|
1564
|
+
readonly value: T;
|
|
1565
|
+
} | {
|
|
1566
|
+
readonly kind: "missing";
|
|
1567
|
+
} | {
|
|
1568
|
+
readonly kind: "timeout";
|
|
1569
|
+
readonly reason: "deadline" | "cooling-down" | "saturated";
|
|
1570
|
+
readonly detail: string;
|
|
1571
|
+
} | {
|
|
1572
|
+
readonly kind: "aborted";
|
|
1573
|
+
} | {
|
|
1574
|
+
readonly kind: "error";
|
|
1575
|
+
readonly code?: string;
|
|
1576
|
+
readonly detail: string;
|
|
1577
|
+
};
|
|
1578
|
+
|
|
1579
|
+
declare interface KayAppUserFileStat {
|
|
1580
|
+
/** What the path is after following symlinks; never `symlink`. */
|
|
1581
|
+
readonly kind: "file" | "directory" | "other";
|
|
1582
|
+
/** Bytes. */
|
|
1583
|
+
readonly size: number;
|
|
1584
|
+
/** Milliseconds since the Unix epoch. */
|
|
1585
|
+
readonly modifiedAtMs: number;
|
|
1586
|
+
}
|
|
1587
|
+
|
|
1588
|
+
declare interface KayAppUserFilesWalkOptions extends KayAppUserFilesCallOptions {
|
|
1589
|
+
/** Default 10000, at most 100000. */
|
|
1590
|
+
readonly maxEntries?: number;
|
|
1591
|
+
/** Deepest level reported; the root's children are depth 1. Default 16, at most 64. */
|
|
1592
|
+
readonly maxDepth?: number;
|
|
1593
|
+
/** Report and descend into dot-prefixed entries. Default true. */
|
|
1594
|
+
readonly includeHidden?: boolean;
|
|
1595
|
+
}
|
|
1596
|
+
|
|
1597
|
+
declare interface KayAppUserFileWalk {
|
|
1598
|
+
readonly entries: readonly KayAppUserFileWalkEntry[];
|
|
1599
|
+
/** True when the walk stopped at `maxEntries`. */
|
|
1600
|
+
readonly entryLimitReached: boolean;
|
|
1601
|
+
/** True when a directory at `maxDepth` was reported but not descended into. */
|
|
1602
|
+
readonly depthLimitReached: boolean;
|
|
1603
|
+
}
|
|
1604
|
+
|
|
1605
|
+
declare interface KayAppUserFileWalkEntry {
|
|
1606
|
+
/** Path segments below the walk's root. */
|
|
1607
|
+
readonly segments: readonly string[];
|
|
1608
|
+
readonly kind: KayAppUserFileKind;
|
|
1609
|
+
}
|
|
1610
|
+
|
|
1474
1611
|
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
1612
|
|
|
1476
1613
|
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,6 +135,16 @@ 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
150
|
filesystem: {
|
|
@@ -191,7 +201,16 @@ function fauxKayAgentCapabilities() {
|
|
|
191
201
|
// zone-of-record path overrides this handle after the spread.
|
|
192
202
|
time: {
|
|
193
203
|
snapshot: () => ({ nowMs: 0, zone: "UTC", zoneSource: "utc-fallback" })
|
|
194
|
-
}
|
|
204
|
+
},
|
|
205
|
+
// Answers every call `error` naming itself, keeping the real contract's promise never to
|
|
206
|
+
// reject. A test that exercises a plugin's file I/O overrides this handle after the spread.
|
|
207
|
+
userFiles: Object.fromEntries(USER_FILE_METHODS.map((name) => [
|
|
208
|
+
name,
|
|
209
|
+
async () => ({
|
|
210
|
+
kind: "error",
|
|
211
|
+
detail: `userFiles.${name} is not wired in this test double`
|
|
212
|
+
})
|
|
213
|
+
]))
|
|
195
214
|
};
|
|
196
215
|
}
|
|
197
216
|
function defaultTestToolContext() {
|
package/dist/kay-agent.d.ts
CHANGED
|
@@ -1628,6 +1628,14 @@ export declare interface KayAgentPluginApi {
|
|
|
1628
1628
|
* the same zone-of-record port the session stamp uses; see {@link KayAppTime.snapshot}.
|
|
1629
1629
|
*/
|
|
1630
1630
|
readonly time: KayAppTime;
|
|
1631
|
+
/**
|
|
1632
|
+
* 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
|
|
1636
|
+
* {@link KayAppUserFiles}.
|
|
1637
|
+
*/
|
|
1638
|
+
readonly userFiles: KayAppUserFiles;
|
|
1631
1639
|
/**
|
|
1632
1640
|
* Publish the plugin's declared events, for example so a default notification rule can tell the
|
|
1633
1641
|
* user what the agent just did. Always present, like {@link withJev}: there is nothing to
|
|
@@ -1946,6 +1954,135 @@ declare interface KayAppTimeSnapshot {
|
|
|
1946
1954
|
readonly zoneSource: "host" | "utc-fallback";
|
|
1947
1955
|
}
|
|
1948
1956
|
|
|
1957
|
+
export declare interface KayAppUserFileEntry {
|
|
1958
|
+
readonly name: string;
|
|
1959
|
+
/** From the directory entry itself: a symlink is reported as `symlink`, never followed. */
|
|
1960
|
+
readonly kind: KayAppUserFileKind;
|
|
1961
|
+
}
|
|
1962
|
+
|
|
1963
|
+
/**
|
|
1964
|
+
* The plugin-facing user-files contract: file I/O in folders the user owns, done by the host on
|
|
1965
|
+
* its own worker threads.
|
|
1966
|
+
*
|
|
1967
|
+
* Ungated and always present, like `app.paths`. It confers no authority: a plugin runs in the
|
|
1968
|
+
* daemon's process and can call `node:fs` itself. What the door adds is where the work runs. A
|
|
1969
|
+
* `node:fs` sync call blocks the daemon's event loop for as long as the path takes to answer,
|
|
1970
|
+
* which under a macOS-protected folder or on a drive that stopped answering can be a very long
|
|
1971
|
+
* time (kay#11575); an async one holds a thread of the pool the whole daemon shares. The host runs
|
|
1972
|
+
* each request on a dedicated worker, gives it a deadline, and answers a typed result instead of
|
|
1973
|
+
* throwing.
|
|
1974
|
+
*
|
|
1975
|
+
* This is a leaf module. It lives beside both target SDKs, like `time.ts`, so the `kay.agent` SDK
|
|
1976
|
+
* exposes the same door without importing the `kay.app` surface.
|
|
1977
|
+
*/
|
|
1978
|
+
export declare type KayAppUserFileKind = "file" | "directory" | "symlink" | "other";
|
|
1979
|
+
|
|
1980
|
+
export declare interface KayAppUserFileListing {
|
|
1981
|
+
readonly entries: readonly KayAppUserFileEntry[];
|
|
1982
|
+
/** True when the directory had more entries than `maxEntries`; the rest were not read. */
|
|
1983
|
+
readonly entryLimitReached: boolean;
|
|
1984
|
+
}
|
|
1985
|
+
|
|
1986
|
+
/**
|
|
1987
|
+
* File I/O in user folders, run by the host off the daemon's main thread. Every path is absolute.
|
|
1988
|
+
* No method rejects; each answers a {@link KayAppUserFilesResult}. This is not a sandbox: it does
|
|
1989
|
+
* not limit which paths a plugin may touch. Added in SDK 0.12.5: a plugin that calls it declares
|
|
1990
|
+
* `compatibility.sdk` `^0.12.5`, so an older Bonsai refuses a directory or repository plugin at
|
|
1991
|
+
* load instead of the call failing.
|
|
1992
|
+
*/
|
|
1993
|
+
export declare interface KayAppUserFiles {
|
|
1994
|
+
/** Follows symlinks. */
|
|
1995
|
+
stat(path: string, options?: KayAppUserFilesCallOptions): Promise<KayAppUserFilesResult<KayAppUserFileStat>>;
|
|
1996
|
+
/** UTF-8. */
|
|
1997
|
+
readText(path: string, options?: KayAppUserFilesReadTextOptions): Promise<KayAppUserFilesResult<string>>;
|
|
1998
|
+
list(path: string, options?: KayAppUserFilesListOptions): Promise<KayAppUserFilesResult<KayAppUserFileListing>>;
|
|
1999
|
+
/** Depth-first below `path`; symlinks are reported, never followed. */
|
|
2000
|
+
walk(path: string, options?: KayAppUserFilesWalkOptions): Promise<KayAppUserFilesResult<KayAppUserFileWalk>>;
|
|
2001
|
+
/** The path with every symlink resolved. */
|
|
2002
|
+
realpath(path: string, options?: KayAppUserFilesCallOptions): Promise<KayAppUserFilesResult<string>>;
|
|
2003
|
+
/**
|
|
2004
|
+
* Creates or replaces a UTF-8 file, not atomically. After `timeout` or `aborted` the write may
|
|
2005
|
+
* still happen.
|
|
2006
|
+
*/
|
|
2007
|
+
writeText(path: string, content: string, options?: KayAppUserFilesCallOptions): Promise<KayAppUserFilesResult<null>>;
|
|
2008
|
+
/** Creates the directory and any missing parents; succeeds when it already exists. */
|
|
2009
|
+
mkdir(path: string, options?: KayAppUserFilesCallOptions): Promise<KayAppUserFilesResult<null>>;
|
|
2010
|
+
rename(from: string, to: string, options?: KayAppUserFilesCallOptions): Promise<KayAppUserFilesResult<null>>;
|
|
2011
|
+
}
|
|
2012
|
+
|
|
2013
|
+
export declare interface KayAppUserFilesCallOptions {
|
|
2014
|
+
/** Deadline in milliseconds from the call, waiting included. Default 5000, at most 60000. */
|
|
2015
|
+
readonly timeoutMs?: number;
|
|
2016
|
+
readonly signal?: AbortSignal;
|
|
2017
|
+
}
|
|
2018
|
+
|
|
2019
|
+
export declare interface KayAppUserFilesListOptions extends KayAppUserFilesCallOptions {
|
|
2020
|
+
/** Default 5000, at most 50000. */
|
|
2021
|
+
readonly maxEntries?: number;
|
|
2022
|
+
}
|
|
2023
|
+
|
|
2024
|
+
export declare interface KayAppUserFilesReadTextOptions extends KayAppUserFilesCallOptions {
|
|
2025
|
+
/** A larger file answers `error` with code `EFBIG`. Default 8 MiB, at most 64 MiB. */
|
|
2026
|
+
readonly maxBytes?: number;
|
|
2027
|
+
}
|
|
2028
|
+
|
|
2029
|
+
/**
|
|
2030
|
+
* Every answer. `missing`: nothing exists at the path (ENOENT). `timeout`: no answer from the path
|
|
2031
|
+
* in time. Its `reason` is `deadline` (this request ran out of time), `cooling-down` (a request at
|
|
2032
|
+
* or above this path timed out recently, so the host did not try) or `saturated` (the host's
|
|
2033
|
+
* workers are stuck on other paths, so it did not try). `aborted`: the caller's signal fired.
|
|
2034
|
+
* `error`: anything else, with the Node error `code` when there is one (`EACCES`, `EISDIR`,
|
|
2035
|
+
* `EFBIG` for a file over `maxBytes`, `EINVAL` for a relative path).
|
|
2036
|
+
*/
|
|
2037
|
+
export declare type KayAppUserFilesResult<T> = {
|
|
2038
|
+
readonly kind: "ok";
|
|
2039
|
+
readonly value: T;
|
|
2040
|
+
} | {
|
|
2041
|
+
readonly kind: "missing";
|
|
2042
|
+
} | {
|
|
2043
|
+
readonly kind: "timeout";
|
|
2044
|
+
readonly reason: "deadline" | "cooling-down" | "saturated";
|
|
2045
|
+
readonly detail: string;
|
|
2046
|
+
} | {
|
|
2047
|
+
readonly kind: "aborted";
|
|
2048
|
+
} | {
|
|
2049
|
+
readonly kind: "error";
|
|
2050
|
+
readonly code?: string;
|
|
2051
|
+
readonly detail: string;
|
|
2052
|
+
};
|
|
2053
|
+
|
|
2054
|
+
export declare interface KayAppUserFileStat {
|
|
2055
|
+
/** What the path is after following symlinks; never `symlink`. */
|
|
2056
|
+
readonly kind: "file" | "directory" | "other";
|
|
2057
|
+
/** Bytes. */
|
|
2058
|
+
readonly size: number;
|
|
2059
|
+
/** Milliseconds since the Unix epoch. */
|
|
2060
|
+
readonly modifiedAtMs: number;
|
|
2061
|
+
}
|
|
2062
|
+
|
|
2063
|
+
export declare interface KayAppUserFilesWalkOptions extends KayAppUserFilesCallOptions {
|
|
2064
|
+
/** Default 10000, at most 100000. */
|
|
2065
|
+
readonly maxEntries?: number;
|
|
2066
|
+
/** Deepest level reported; the root's children are depth 1. Default 16, at most 64. */
|
|
2067
|
+
readonly maxDepth?: number;
|
|
2068
|
+
/** Report and descend into dot-prefixed entries. Default true. */
|
|
2069
|
+
readonly includeHidden?: boolean;
|
|
2070
|
+
}
|
|
2071
|
+
|
|
2072
|
+
export declare interface KayAppUserFileWalk {
|
|
2073
|
+
readonly entries: readonly KayAppUserFileWalkEntry[];
|
|
2074
|
+
/** True when the walk stopped at `maxEntries`. */
|
|
2075
|
+
readonly entryLimitReached: boolean;
|
|
2076
|
+
/** True when a directory at `maxDepth` was reported but not descended into. */
|
|
2077
|
+
readonly depthLimitReached: boolean;
|
|
2078
|
+
}
|
|
2079
|
+
|
|
2080
|
+
export declare interface KayAppUserFileWalkEntry {
|
|
2081
|
+
/** Path segments below the walk's root. */
|
|
2082
|
+
readonly segments: readonly string[];
|
|
2083
|
+
readonly kind: KayAppUserFileKind;
|
|
2084
|
+
}
|
|
2085
|
+
|
|
1949
2086
|
declare const KayPluginManifestV1: z.ZodObject<{
|
|
1950
2087
|
protocol: z.ZodLiteral<"kay.plugin.v1">;
|
|
1951
2088
|
id: z.ZodString;
|
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.
|