@yaklabs-ai/plugin-sdk 0.12.5 → 0.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -33
- package/THIRD-PARTY-INVENTORY.json +1 -1
- package/dist/disclosure.d.ts +59 -77
- package/dist/disclosure.js +4 -14
- package/dist/fs.d.ts +156 -0
- package/dist/fs.js +895 -0
- package/dist/jev.d.ts +1 -1
- package/dist/kay-agent-testing.d.ts +58 -76
- package/dist/kay-agent-testing.js +4 -12
- package/dist/kay-agent.d.ts +65 -119
- package/dist/kay-agent.js +0 -11
- package/dist/kay-app.d.ts +156 -61
- package/dist/kay-app.js +22 -1
- package/dist/signals.d.ts +175 -1
- package/dist/signals.js +141 -2
- package/package.json +5 -1
- package/skills/directory-plugin-authoring/SKILL.md +18 -17
package/dist/jev.d.ts
CHANGED
|
@@ -138,7 +138,7 @@ export declare interface JevScoreQuestion {
|
|
|
138
138
|
* Those are host-side (`@kay/agent-runtime`'s `kay/jev/`).
|
|
139
139
|
* ---
|
|
140
140
|
*
|
|
141
|
-
* The vocabulary is
|
|
141
|
+
* The vocabulary is Bonsai's own (SDK 0.12.0). Before it, `use` received TypeSafe's `TypeSafeClient`
|
|
142
142
|
* and plugins coded against a vendor's types. It follows pi's classifier contract, which the host
|
|
143
143
|
* runs Jev through: a yes/no question is `bool` and answers a `probability`, every instruction and
|
|
144
144
|
* criterion is text, and the state is a JSON object.
|
|
@@ -20,7 +20,7 @@ declare interface AccountIdentity {
|
|
|
20
20
|
readonly displayName?: string;
|
|
21
21
|
/** Absolute URL of the account's avatar. */
|
|
22
22
|
readonly avatarUrl?: string;
|
|
23
|
-
/** Issuer-asserted beta-tester flag; only
|
|
23
|
+
/** Issuer-asserted beta-tester flag; only Bonsai's product-account service sets it. */
|
|
24
24
|
readonly betaTester?: boolean;
|
|
25
25
|
readonly activeOrganizationId?: string;
|
|
26
26
|
readonly organizationSelectionState?: "selected" | "unresolved";
|
|
@@ -28,7 +28,7 @@ declare interface AccountIdentity {
|
|
|
28
28
|
/**
|
|
29
29
|
* Provider-native session id claim (WorkOS's `sid`), needed to call the provider's own
|
|
30
30
|
* session-revocation endpoint at sign-out (`POST /user_management/sessions/revoke`, not yet
|
|
31
|
-
* wired — see `docs/kay-account-auth.md`'s "Sign-out guarantee" section). Only
|
|
31
|
+
* wired — see `docs/kay-account-auth.md`'s "Sign-out guarantee" section). Only Bonsai's WorkOS
|
|
32
32
|
* product-account exchange/refresh sets it; every other provider leaves it absent.
|
|
33
33
|
*/
|
|
34
34
|
readonly providerSessionId?: string;
|
|
@@ -164,7 +164,7 @@ declare interface ApiKeyAuthSchemeField {
|
|
|
164
164
|
readonly label: string;
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
-
/** Provider-owned instructions for creating a credential outside
|
|
167
|
+
/** Provider-owned instructions for creating a credential outside Bonsai. */
|
|
168
168
|
declare interface ApiKeyAuthSchemeSetup {
|
|
169
169
|
readonly instructions: string;
|
|
170
170
|
/** Absolute HTTPS page where the user can create or manage the credential. */
|
|
@@ -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
|
|
|
@@ -641,7 +641,7 @@ declare interface InteractionCandidate {
|
|
|
641
641
|
declare type InteractionCandidateKind = "click" | "fill" | "select" | "scroll" | "wait" | "activate" | "press";
|
|
642
642
|
|
|
643
643
|
declare interface InteractionDriver {
|
|
644
|
-
/** Unique in the session. `builtin:` is reserved for
|
|
644
|
+
/** Unique in the session. `builtin:` is reserved for Bonsai's own drivers. */
|
|
645
645
|
readonly id: string;
|
|
646
646
|
/** Human-readable name the agent sees beside the driver's targets. */
|
|
647
647
|
readonly label: string;
|
|
@@ -664,7 +664,7 @@ declare interface InteractionDriver {
|
|
|
664
664
|
}
|
|
665
665
|
|
|
666
666
|
/**
|
|
667
|
-
* The Interaction driver contract: what a plugin implements to let
|
|
667
|
+
* The Interaction driver contract: what a plugin implements to let Bonsai's agent drive something
|
|
668
668
|
* on the user's machine (a browser, an app, a remote screen) through the harness-owned
|
|
669
669
|
* Interaction engine.
|
|
670
670
|
*
|
|
@@ -677,7 +677,7 @@ declare interface InteractionDriver {
|
|
|
677
677
|
* every tool work on every driver.
|
|
678
678
|
*
|
|
679
679
|
* Shape mirrors `SearchProvider` behind `web_search`: one tool set owned by the harness, many
|
|
680
|
-
* backends registered per session, the `builtin:` id namespace reserved for
|
|
680
|
+
* backends registered per session, the `builtin:` id namespace reserved for Bonsai's own.
|
|
681
681
|
*/
|
|
682
682
|
/** "Browser Interaction" drives web pages; "Computer Use Interaction" drives native apps. */
|
|
683
683
|
declare type InteractionDriverKind = "browser" | "computer-use";
|
|
@@ -736,7 +736,7 @@ declare interface InteractionRegion {
|
|
|
736
736
|
}
|
|
737
737
|
|
|
738
738
|
/**
|
|
739
|
-
* One surface
|
|
739
|
+
* One surface Bonsai ships, in the driver contract's own shape, so a plugin's driver is the surface
|
|
740
740
|
* plus an identity: `{ id, label, kind, ...api.interaction.desktop }`. Each call is checked
|
|
741
741
|
* against the plugin's `interaction.surface {surface}` grant, and then against the session's
|
|
742
742
|
* permissions exactly as the agent's `interaction_*` tools are: an act is judged as the plugin
|
|
@@ -876,7 +876,7 @@ declare interface JevScoreQuestion {
|
|
|
876
876
|
* Those are host-side (`@kay/agent-runtime`'s `kay/jev/`).
|
|
877
877
|
* ---
|
|
878
878
|
*
|
|
879
|
-
* The vocabulary is
|
|
879
|
+
* The vocabulary is Bonsai's own (SDK 0.12.0). Before it, `use` received TypeSafe's `TypeSafeClient`
|
|
880
880
|
* and plugins coded against a vendor's types. It follows pi's classifier contract, which the host
|
|
881
881
|
* runs Jev through: a yes/no question is `bool` and answers a `probability`, every instruction and
|
|
882
882
|
* criterion is text, and the state is a JSON object.
|
|
@@ -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 {
|
|
@@ -982,7 +944,7 @@ declare interface KayAgentInteractionSurfaces {
|
|
|
982
944
|
readonly browserPane: InteractionSurface;
|
|
983
945
|
/**
|
|
984
946
|
* The user's desktop through the platform's accessibility APIs: native apps as targets
|
|
985
|
-
* (`app://<bundle id>`), their windows' controls as elements. On macOS
|
|
947
|
+
* (`app://<bundle id>`), their windows' controls as elements. On macOS Bonsai drives it with its
|
|
986
948
|
* bundled accessibility worker under the app's Accessibility permission; on a platform with no
|
|
987
949
|
* backend it reports itself unavailable.
|
|
988
950
|
*/
|
|
@@ -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. */
|
|
@@ -1142,7 +1101,7 @@ declare interface KayAgentPluginApi {
|
|
|
1142
1101
|
*/
|
|
1143
1102
|
readonly process: KayAgentProcess;
|
|
1144
1103
|
/**
|
|
1145
|
-
* Always present; the interaction surfaces
|
|
1104
|
+
* Always present; the interaction surfaces Bonsai ships (its browser pane, and the desktop through
|
|
1146
1105
|
* the platform accessibility APIs), each call checked against `interaction.surface {surface}`
|
|
1147
1106
|
* and the session's permissions (see {@link InteractionSurface}).
|
|
1148
1107
|
* Wrap one in an {@link InteractionDriver} and register it with
|
|
@@ -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:
|
|
1173
|
-
*
|
|
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;
|
|
@@ -1742,7 +1700,7 @@ declare type ModelPromptCache = Partial<Record<Exclude<CacheRetention, "none">,
|
|
|
1742
1700
|
declare type ModelThinkingLevel = "off" | ThinkingLevel;
|
|
1743
1701
|
|
|
1744
1702
|
/**
|
|
1745
|
-
* Who may supply the OAuth client for a scheme:
|
|
1703
|
+
* Who may supply the OAuth client for a scheme: Bonsai's embedded client, or one the user pastes in
|
|
1746
1704
|
* (BYOOC). An UNORDERED SET — list order carries no meaning (nothing reads it as a preference).
|
|
1747
1705
|
*/
|
|
1748
1706
|
declare type OAuthClientSupplier = "kay" | "user";
|
|
@@ -1755,7 +1713,7 @@ declare interface OAuthRedirectResult {
|
|
|
1755
1713
|
|
|
1756
1714
|
/**
|
|
1757
1715
|
* The two client-supply axes, structured so the illegal cell is unrepresentable: a `confidential`
|
|
1758
|
-
* exchange's secret may only ever be
|
|
1716
|
+
* exchange's secret may only ever be Bonsai's (held by the host's broker, never pasted by a
|
|
1759
1717
|
* customer), so `confidential` types `clientSuppliers` as `readonly ["kay"]` — `confidential ×
|
|
1760
1718
|
* user` is a compile-time impossibility in v1, not a runtime refusal. `pkce`'s `clientSuppliers`
|
|
1761
1719
|
* is a non-empty set; {@link createOAuthPkceAuthScheme} dedupes it and refuses empty.
|
|
@@ -1994,7 +1952,7 @@ declare interface PluginDelegatedScheme {
|
|
|
1994
1952
|
readonly connect: (ctx: PluginDelegatedConnectContext) => Promise<PluginDelegatedConnectResult>;
|
|
1995
1953
|
/**
|
|
1996
1954
|
* Mint fresh material from the current (expiring) material, including the `data` the last
|
|
1997
|
-
* connect or refresh returned.
|
|
1955
|
+
* connect or refresh returned. Bonsai calls this only inside its credential authority, which holds
|
|
1998
1956
|
* the refresh lease and saves the result; this hook performs the exchange and nothing else.
|
|
1999
1957
|
* Returned `data` replaces the stored `data`; omitted `data` keeps it. Returned `expiresAt`
|
|
2000
1958
|
* replaces the stored expiry; omitted `expiresAt` means the new material does not expire.
|
|
@@ -2068,7 +2026,7 @@ declare type PluginOAuthPkceScheme = PluginOAuthSchemeClientAxes & {
|
|
|
2068
2026
|
readonly summary?: string;
|
|
2069
2027
|
readonly authorizationUrl: string;
|
|
2070
2028
|
readonly tokenUrl: string;
|
|
2071
|
-
/** The
|
|
2029
|
+
/** The Bonsai-supplied embedded client id; omit for a `confidential` scheme or a `pkce` scheme
|
|
2072
2030
|
* the host ships no client for. */
|
|
2073
2031
|
readonly clientId?: string;
|
|
2074
2032
|
/**
|
|
@@ -2731,6 +2689,14 @@ declare interface ToolDefinition<TParams extends ToolParametersWire = ToolParame
|
|
|
2731
2689
|
* explicit Stop.
|
|
2732
2690
|
*/
|
|
2733
2691
|
durationClass?: "fast" | "long";
|
|
2692
|
+
/**
|
|
2693
|
+
* Set only for a tool whose rerun with the same arguments is harmless, such
|
|
2694
|
+
* as one keyed on its own call: after a crash cuts a call off, a pi-durable
|
|
2695
|
+
* session may rerun it with its recorded arguments (without `before_tool`)
|
|
2696
|
+
* instead of ending it as an interrupted error. Absent: never rerun. Ignored
|
|
2697
|
+
* on pi 0.99.1.
|
|
2698
|
+
*/
|
|
2699
|
+
replaySafe?: true;
|
|
2734
2700
|
/**
|
|
2735
2701
|
* Optional capability⇄scheme binding. When present this tool is auth-gated: discoverable when
|
|
2736
2702
|
* unauthed, callable once the binding is satisfied. The SDK's {@link withResolvedAuth}
|
|
@@ -2814,9 +2780,9 @@ declare type ToolParametersWire = unknown;
|
|
|
2814
2780
|
*
|
|
2815
2781
|
* The host is trusted to supply honest values; a declared `kind` of `read` moves a call below
|
|
2816
2782
|
* the protected-path hard-deny (which only fires for non-read kinds), so a tool that could
|
|
2817
|
-
* touch protected config must NOT declare `read`.
|
|
2783
|
+
* touch protected config must NOT declare `read`. Bonsai's embedded-experience tools never touch
|
|
2818
2784
|
* `configDir`, so this is safe for them. `read` is also what every capability surface reports as
|
|
2819
|
-
* "read-only" (
|
|
2785
|
+
* "read-only" (Bonsai's Permissions page groups and defaults on it), so it is a claim about what the
|
|
2820
2786
|
* tool DOES — never a way to buy silence. A tool that should raise no ask on its own account
|
|
2821
2787
|
* declares {@link ToolPermissionHint.quiet} and keeps its honest `kind`.
|
|
2822
2788
|
*/
|
|
@@ -2857,7 +2823,7 @@ declare interface ToolPermissionHint {
|
|
|
2857
2823
|
* because the same tool can read on one input and execute on another, which a static `kind`
|
|
2858
2824
|
* cannot express.
|
|
2859
2825
|
*
|
|
2860
|
-
* Exemplar —
|
|
2826
|
+
* Exemplar — Bonsai's `mcp` proxy tool, one tool spanning every server: `search`/`describe` derive
|
|
2861
2827
|
* `{ kind: "read" }` (metadata lookups), while `call` derives
|
|
2862
2828
|
* `{ kind: "execute", ruleKey: "mcp:<server>::<tool>", scheme: "<server>" }`, so a
|
|
2863
2829
|
* `{ scheme: "<server>" }` rule gates a whole server and a `{ ruleKey: "mcp:<server>::<tool>" }`
|
|
@@ -2898,7 +2864,7 @@ declare interface ToolPermissionHint {
|
|
|
2898
2864
|
* really had — not that the result is always stricter than the target's. How much gate is left
|
|
2899
2865
|
* on such a call is exactly how much the CARRIER carries: an `execute` carrier is stricter than
|
|
2900
2866
|
* a `read` target and equal to a `mutate`/`destructive` one outside allow mode, while a
|
|
2901
|
-
* {@link quiet} carrier (
|
|
2867
|
+
* {@link quiet} carrier (Bonsai's own `call_tool`) contributes no mode default at all, so the
|
|
2902
2868
|
* fallback leaves nothing but the carrier's rules and the protected-path deny — and the carrier
|
|
2903
2869
|
* names no path, so that deny has nothing to fire on. This is why a carrier must refuse a target
|
|
2904
2870
|
* that is itself a carrier: no chain long or circular enough to reach the fallback can be built,
|
|
@@ -2922,7 +2888,7 @@ declare interface ToolPermissionHint {
|
|
|
2922
2888
|
* whose only effect is invoking the target the gate is already classifying beside it: the
|
|
2923
2889
|
* target's kind, rules, resources and the protected-path deny all still decide, so a proxied
|
|
2924
2890
|
* call is gated exactly like the direct one — no more, and no ask the direct call would never
|
|
2925
|
-
* have raised.
|
|
2891
|
+
* have raised. Bonsai's `call_tool` declares `{ kind: "execute", quiet: true }` (owner ruling,
|
|
2926
2892
|
* 2026-08-18): honest about everything it can reach, silent on its own account.
|
|
2927
2893
|
*
|
|
2928
2894
|
* Quiet is not ungated, but it IS nearly all the gate a lone carrier has. On a call that
|
|
@@ -3112,13 +3078,19 @@ declare interface UriExtensionModule extends Omit<UriModule, "verbs"> {
|
|
|
3112
3078
|
readonly permissionDefaults?: UriPermissionDefaults;
|
|
3113
3079
|
/** Requires a resolved URI connection before any verb handler runs. */
|
|
3114
3080
|
readonly requiresConnection?: boolean;
|
|
3115
|
-
/** Pure route-aware permission facts;
|
|
3081
|
+
/** Pure route-aware permission facts; see {@link UriExtensionOperationPermissionPolicy}. */
|
|
3116
3082
|
readonly permission?: UriExtensionOperationPermissionPolicy;
|
|
3117
3083
|
/** False rejects generic write-tool `source` copies before source fetch. */
|
|
3118
3084
|
readonly acceptsSourceCopy?: boolean;
|
|
3119
3085
|
}
|
|
3120
3086
|
|
|
3121
3087
|
declare interface UriExtensionOperationPermissionPolicy {
|
|
3088
|
+
/**
|
|
3089
|
+
* Classify one canonical route, purely. `write`/`edit`/`delete` may only be made stricter
|
|
3090
|
+
* than the verb default; `help`/`read`/`list`/`search` must stay `"read"` (a `ruleKey` is
|
|
3091
|
+
* allowed), because the kernel reruns a crash-interrupted read without asking again. Any
|
|
3092
|
+
* other answer, or a throw, fails the call closed.
|
|
3093
|
+
*/
|
|
3122
3094
|
classifyOperation(request: {
|
|
3123
3095
|
readonly operation: UriOperation;
|
|
3124
3096
|
readonly uri: string;
|
|
@@ -3346,7 +3318,15 @@ declare interface UriModule {
|
|
|
3346
3318
|
normalize?(input: string, ctx: UriResolveContext): UriNormalizeResult | undefined;
|
|
3347
3319
|
describe?(input: string, ctx: UriDescribeContext): UriResourceDescription | undefined;
|
|
3348
3320
|
locate?(input: string, ctx: UriLocateContext): Promise<UriLocateResult>;
|
|
3321
|
+
/**
|
|
3322
|
+
* `read`, `help`, `list` and `search` observe; they never change the resource or anything
|
|
3323
|
+
* outside the host. Repeating one with the same input must be harmless: the kernel reruns a
|
|
3324
|
+
* call of these verbs that a crash cut off, with the same input, without asking the user
|
|
3325
|
+
* again. Idempotent bookkeeping (a cache fill, an index of what was read, a usage count) is
|
|
3326
|
+
* fine; a send, a mark-as-read or a create is not, and belongs on a mutating verb.
|
|
3327
|
+
*/
|
|
3349
3328
|
read(input: string, ctx: UriResolveContext): Promise<RawResource>;
|
|
3329
|
+
/** Observes only; see {@link read}. */
|
|
3350
3330
|
help?(input: string, ctx: UriResolveContext): Promise<UriHelp>;
|
|
3351
3331
|
write?(input: string, content: UriPayload, ctx: UriResolveContext): Promise<UriMutationResult | void>;
|
|
3352
3332
|
/** Opt-in structured write with one or more host-resolved resources delivered beside the content. */
|
|
@@ -3369,7 +3349,9 @@ declare interface UriModule {
|
|
|
3369
3349
|
*/
|
|
3370
3350
|
writeBytes?(input: string, bytes: Uint8Array, source: UriSourceDescriptor, ctx: UriResolveContext): Promise<UriMutationResult | void>;
|
|
3371
3351
|
edit?(input: string, patch: UriPayload, ctx: UriResolveContext): Promise<UriMutationResult>;
|
|
3352
|
+
/** Observes only; see {@link read}. */
|
|
3372
3353
|
list?(input: string, params: UriListParams, ctx: UriResolveContext): Promise<UriListResult>;
|
|
3354
|
+
/** Observes only; see {@link read}. */
|
|
3373
3355
|
search?(input: string, params: UriSearchParams, ctx: UriResolveContext): Promise<UriSearchResult>;
|
|
3374
3356
|
delete?(input: string, ctx: UriResolveContext): Promise<UriMutationResult>;
|
|
3375
3357
|
toMarkdown?(input: UriMarkdownRenderInput, ctx: UriResolveContext): string | undefined;
|
|
@@ -3587,7 +3569,7 @@ declare interface UriResolveContext {
|
|
|
3587
3569
|
* {@link UriResolveContext.sessionId} and just as un-influenceable by the caller — so a module
|
|
3588
3570
|
* writing to a store it owns can record the actor without the agent being able to choose one.
|
|
3589
3571
|
*
|
|
3590
|
-
* Free text minted by the host's own runtime (
|
|
3572
|
+
* Free text minted by the host's own runtime (Bonsai's form is `user`, `subagent`,
|
|
3591
3573
|
* `system/<surface>`, `followup/<surface>`) rather than a closed union: the surface half is the
|
|
3592
3574
|
* host's vocabulary, and a second enumeration of it here would drift from the first.
|
|
3593
3575
|
*
|
|
@@ -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() {
|