@yaklabs-ai/plugin-sdk 0.13.2 → 0.13.4
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 +13 -13
- package/THIRD-PARTY-INVENTORY.json +1 -1
- package/dist/disclosure.d.ts +32 -6
- package/dist/fs.js +1 -1
- package/dist/jev.d.ts +1 -1
- package/dist/kay-agent-testing.d.ts +30 -4
- package/dist/kay-agent.d.ts +255 -5
- package/dist/kay-agent.js +169 -2
- package/dist/kay-app.d.ts +172 -18
- package/dist/kay-app.js +8 -0
- package/dist/signals.d.ts +2 -2
- package/package.json +1 -1
- package/skills/directory-plugin-authoring/SKILL.md +18 -18
package/dist/kay-agent.js
CHANGED
|
@@ -1011,7 +1011,7 @@ async function readBodyWithByteCap(response, maxBytes) {
|
|
|
1011
1011
|
}
|
|
1012
1012
|
|
|
1013
1013
|
// packages/plugin-sdk/dist/kay-agent/index.js
|
|
1014
|
-
import { z as
|
|
1014
|
+
import { z as z7 } from "zod";
|
|
1015
1015
|
|
|
1016
1016
|
// packages/plugin-sdk/dist/kay-agent/http-client.js
|
|
1017
1017
|
var PluginApiError = class extends Error {
|
|
@@ -1164,6 +1164,163 @@ function bytesToBase64(bytes) {
|
|
|
1164
1164
|
return output;
|
|
1165
1165
|
}
|
|
1166
1166
|
|
|
1167
|
+
// packages/plugin-sdk/dist/kay-agent/osascript.js
|
|
1168
|
+
import { z as z6 } from "zod";
|
|
1169
|
+
var OSASCRIPT_TIMEOUT_MS = 3e4;
|
|
1170
|
+
var OSASCRIPT_ENVELOPE_JXA = `
|
|
1171
|
+
function jsonOk(data) {
|
|
1172
|
+
return JSON.stringify({ ok: true, data: data === undefined ? null : data });
|
|
1173
|
+
}
|
|
1174
|
+
function jsonFail(code, message) {
|
|
1175
|
+
return JSON.stringify({ ok: false, error: { code: String(code), message: String(message) } });
|
|
1176
|
+
}
|
|
1177
|
+
`;
|
|
1178
|
+
var envelopeSchema = z6.discriminatedUnion("ok", [
|
|
1179
|
+
z6.object({ ok: z6.literal(true), data: z6.unknown() }),
|
|
1180
|
+
z6.object({
|
|
1181
|
+
ok: z6.literal(false),
|
|
1182
|
+
error: z6.object({ code: z6.string(), message: z6.string() })
|
|
1183
|
+
})
|
|
1184
|
+
]);
|
|
1185
|
+
function readOsascriptOutput(stdout) {
|
|
1186
|
+
let json;
|
|
1187
|
+
try {
|
|
1188
|
+
json = JSON.parse(stdout);
|
|
1189
|
+
} catch (error) {
|
|
1190
|
+
return {
|
|
1191
|
+
kind: "invalid",
|
|
1192
|
+
reason: `output that was not valid JSON: ${error instanceof Error ? error.message : String(error)}`
|
|
1193
|
+
};
|
|
1194
|
+
}
|
|
1195
|
+
const envelope = envelopeSchema.safeParse(json);
|
|
1196
|
+
if (!envelope.success) {
|
|
1197
|
+
return {
|
|
1198
|
+
kind: "invalid",
|
|
1199
|
+
reason: "output in a shape Bonsai does not know."
|
|
1200
|
+
};
|
|
1201
|
+
}
|
|
1202
|
+
return envelope.data.ok ? { kind: "data", data: envelope.data.data } : {
|
|
1203
|
+
kind: "refused",
|
|
1204
|
+
code: envelope.data.error.code,
|
|
1205
|
+
message: envelope.data.error.message
|
|
1206
|
+
};
|
|
1207
|
+
}
|
|
1208
|
+
function osascriptArgs(script, argv) {
|
|
1209
|
+
return ["-l", "JavaScript", "-e", script, "--", ...argv];
|
|
1210
|
+
}
|
|
1211
|
+
function parseOsascriptArgs(args) {
|
|
1212
|
+
const [language, name, flag, script, separator, ...argv] = args;
|
|
1213
|
+
if (language !== "-l" || name !== "JavaScript" || flag !== "-e" || script === void 0 || separator !== "--") {
|
|
1214
|
+
return void 0;
|
|
1215
|
+
}
|
|
1216
|
+
return { script, argv };
|
|
1217
|
+
}
|
|
1218
|
+
function withOutcome(call, message) {
|
|
1219
|
+
if (call.outcomeUnknown === void 0)
|
|
1220
|
+
return message;
|
|
1221
|
+
const sentence = /[.!?]$/.test(message) ? message : `${message}.`;
|
|
1222
|
+
return `${sentence} ${call.outcomeUnknown}`;
|
|
1223
|
+
}
|
|
1224
|
+
function createOsascriptRunner(options) {
|
|
1225
|
+
const failurePrefix = options.failurePrefix ?? `${options.label} automation failed`;
|
|
1226
|
+
const providerError = (call, providerCode, message) => new UriProviderError({
|
|
1227
|
+
moduleId: options.moduleId,
|
|
1228
|
+
operation: call.operation,
|
|
1229
|
+
uri: call.uri,
|
|
1230
|
+
message,
|
|
1231
|
+
providerCode,
|
|
1232
|
+
retryable: false
|
|
1233
|
+
});
|
|
1234
|
+
const requireExternalCli = (ctx, operation, uri) => {
|
|
1235
|
+
const externalCli = ctx.auth?.externalCli;
|
|
1236
|
+
if (externalCli === void 0) {
|
|
1237
|
+
throw new UriProviderError({
|
|
1238
|
+
moduleId: options.moduleId,
|
|
1239
|
+
operation,
|
|
1240
|
+
uri,
|
|
1241
|
+
message: `${options.label} access is not connected. Run service_connect for ${options.serviceId}.`,
|
|
1242
|
+
providerCode: "auth_required"
|
|
1243
|
+
});
|
|
1244
|
+
}
|
|
1245
|
+
return externalCli;
|
|
1246
|
+
};
|
|
1247
|
+
const dispatch = (simulator) => simulator === void 0 ? {
|
|
1248
|
+
requireExternalCli,
|
|
1249
|
+
externalCliOf: (ctx) => ctx.auth?.externalCli
|
|
1250
|
+
} : {
|
|
1251
|
+
requireExternalCli: (ctx, operation, uri) => {
|
|
1252
|
+
requireExternalCli(ctx, operation, uri);
|
|
1253
|
+
return simulator.runnerFor(ctx);
|
|
1254
|
+
},
|
|
1255
|
+
externalCliOf: (ctx) => ctx.auth?.externalCli === void 0 ? void 0 : simulator.runnerFor(ctx)
|
|
1256
|
+
};
|
|
1257
|
+
const scriptFailure = (call, result) => {
|
|
1258
|
+
const detail = (result.stderr.trim() !== "" ? result.stderr : result.stdout).trim();
|
|
1259
|
+
const base = `${failurePrefix}: ${detail !== "" ? detail : "osascript exited with a non-zero status."}`;
|
|
1260
|
+
const denied = options.automationDeniedAdvice;
|
|
1261
|
+
if (denied !== void 0 && (/-1743/.test(detail) || /not authorized/i.test(detail))) {
|
|
1262
|
+
return providerError(call, "automation-denied", withOutcome(call, `${base} ${denied}`));
|
|
1263
|
+
}
|
|
1264
|
+
const notRunning = options.appNotRunning;
|
|
1265
|
+
if (notRunning !== void 0 && (/-60[09]\b/.test(detail) || /isn.t running/i.test(detail))) {
|
|
1266
|
+
return providerError(call, notRunning.code, withOutcome(call, `${base} ${notRunning.advice}`));
|
|
1267
|
+
}
|
|
1268
|
+
return providerError(call, "script-failed", withOutcome(call, base));
|
|
1269
|
+
};
|
|
1270
|
+
const runScript = async (externalCli, script, argv, call) => {
|
|
1271
|
+
let result;
|
|
1272
|
+
try {
|
|
1273
|
+
result = await externalCli.run({
|
|
1274
|
+
args: osascriptArgs(script, argv),
|
|
1275
|
+
timeoutMs: call.timeoutMs ?? OSASCRIPT_TIMEOUT_MS,
|
|
1276
|
+
maxOutputChars: call.maxOutputChars,
|
|
1277
|
+
...call.signal !== void 0 ? { signal: call.signal } : {}
|
|
1278
|
+
});
|
|
1279
|
+
} catch (error) {
|
|
1280
|
+
if (call.outcomeUnknown === void 0)
|
|
1281
|
+
throw error;
|
|
1282
|
+
throw providerError(call, "script-failed", withOutcome(call, `${failurePrefix}: ${error instanceof Error ? error.message : String(error)}`));
|
|
1283
|
+
}
|
|
1284
|
+
if (result.exitCode !== 0)
|
|
1285
|
+
throw scriptFailure(call, result);
|
|
1286
|
+
if (result.stdoutTruncated === true) {
|
|
1287
|
+
throw providerError(call, "output-truncated", withOutcome(call, `${options.label} script output was truncated; ${call.truncatedAdvice ?? "narrow the request"}.`));
|
|
1288
|
+
}
|
|
1289
|
+
const output = readOsascriptOutput(result.stdout);
|
|
1290
|
+
switch (output.kind) {
|
|
1291
|
+
case "data":
|
|
1292
|
+
return output.data;
|
|
1293
|
+
case "refused":
|
|
1294
|
+
throw providerError(call, output.code, output.message);
|
|
1295
|
+
case "invalid":
|
|
1296
|
+
throw providerError(call, "output-invalid", withOutcome(call, `${options.label} script produced ${output.reason}`));
|
|
1297
|
+
}
|
|
1298
|
+
};
|
|
1299
|
+
return {
|
|
1300
|
+
requireExternalCli,
|
|
1301
|
+
dispatch,
|
|
1302
|
+
runScript,
|
|
1303
|
+
providerError,
|
|
1304
|
+
scriptFailure
|
|
1305
|
+
};
|
|
1306
|
+
}
|
|
1307
|
+
|
|
1308
|
+
// packages/plugin-sdk/dist/kay-agent/untrusted-text.js
|
|
1309
|
+
function lineOf(value) {
|
|
1310
|
+
return (value ?? "").trim().replace(/\s+/g, " ");
|
|
1311
|
+
}
|
|
1312
|
+
function labelOf(value) {
|
|
1313
|
+
return lineOf((value ?? "").replace(/[\p{Cc}\p{Zl}\p{Zp}]/gu, " ").replace(/\p{Cf}/gu, ""));
|
|
1314
|
+
}
|
|
1315
|
+
function markdownText(text) {
|
|
1316
|
+
return text.replace(/[\\[\]!<|]/g, (character) => `\\${character}`);
|
|
1317
|
+
}
|
|
1318
|
+
function fenced(text) {
|
|
1319
|
+
const runs = text.match(/`+/g) ?? [];
|
|
1320
|
+
const fence = "`".repeat(Math.max(3, ...runs.map((run) => run.length + 1)));
|
|
1321
|
+
return [`${fence}text`, text, fence];
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1167
1324
|
// packages/plugin-sdk/dist/kay-agent/advertisement.js
|
|
1168
1325
|
function defineKayAgentAdvertisement(advertisement) {
|
|
1169
1326
|
return advertisement;
|
|
@@ -1399,6 +1556,8 @@ export {
|
|
|
1399
1556
|
KayAgentCapabilityError,
|
|
1400
1557
|
KayAgentWebSessionError,
|
|
1401
1558
|
OBSERVATION_MIME,
|
|
1559
|
+
OSASCRIPT_ENVELOPE_JXA,
|
|
1560
|
+
OSASCRIPT_TIMEOUT_MS,
|
|
1402
1561
|
PluginApiError,
|
|
1403
1562
|
SearchProviderError,
|
|
1404
1563
|
URI_TEXT_EDIT_SHAPE_SUMMARY,
|
|
@@ -1420,28 +1579,36 @@ export {
|
|
|
1420
1579
|
contentResult,
|
|
1421
1580
|
createFallbackOnlyWithJev,
|
|
1422
1581
|
createJsonApiClient,
|
|
1582
|
+
createOsascriptRunner,
|
|
1423
1583
|
declareProducedResources,
|
|
1424
1584
|
defineAuthedTool,
|
|
1425
1585
|
defineKayAgentAdvertisement,
|
|
1426
1586
|
defineTool,
|
|
1427
1587
|
describeUriTextEditTarget,
|
|
1588
|
+
fenced,
|
|
1428
1589
|
formatIsoDate,
|
|
1429
1590
|
formatNumber,
|
|
1430
1591
|
getBytes,
|
|
1431
1592
|
isDelegatedRefreshRejected,
|
|
1432
1593
|
jsonResource,
|
|
1594
|
+
labelOf,
|
|
1595
|
+
lineOf,
|
|
1433
1596
|
lintUriHelpContracts,
|
|
1434
1597
|
lintUriTemplate,
|
|
1435
1598
|
markdownResource,
|
|
1599
|
+
markdownText,
|
|
1436
1600
|
num,
|
|
1437
1601
|
numLike,
|
|
1438
1602
|
observationFromResource,
|
|
1439
1603
|
observationResource,
|
|
1604
|
+
osascriptArgs,
|
|
1440
1605
|
parseLineSelector,
|
|
1606
|
+
parseOsascriptArgs,
|
|
1441
1607
|
parseUriConnectionSelector,
|
|
1442
1608
|
parseUriTextEditPayload,
|
|
1443
1609
|
payload,
|
|
1444
1610
|
readBodyWithByteCap,
|
|
1611
|
+
readOsascriptOutput,
|
|
1445
1612
|
str,
|
|
1446
1613
|
textResult,
|
|
1447
1614
|
toJsonSchema,
|
|
@@ -1452,5 +1619,5 @@ export {
|
|
|
1452
1619
|
uriTextEditPayloadSchema,
|
|
1453
1620
|
withResolvedAuth,
|
|
1454
1621
|
withResolvedSearchProvider,
|
|
1455
|
-
|
|
1622
|
+
z7 as z
|
|
1456
1623
|
};
|
package/dist/kay-app.d.ts
CHANGED
|
@@ -224,6 +224,10 @@ declare interface BackgroundTaskCompletion {
|
|
|
224
224
|
readonly resultDelivery?: BackgroundTaskResultDelivery;
|
|
225
225
|
readonly output?: string;
|
|
226
226
|
readonly error?: string;
|
|
227
|
+
/** The thrown Error's stack, when a failed task threw one. */
|
|
228
|
+
readonly errorStack?: string;
|
|
229
|
+
/** Why a failed AGENT task's run failed, classified from what it threw; absent for other kinds. */
|
|
230
|
+
readonly failureReason?: RunFailureReason;
|
|
227
231
|
}
|
|
228
232
|
|
|
229
233
|
declare type BackgroundTaskInspector = () => Promise<string> | string;
|
|
@@ -437,6 +441,12 @@ export declare function createUnavailableSkills(message: string): KayAppSkills;
|
|
|
437
441
|
*/
|
|
438
442
|
export declare function createUnavailableTools(): KayAppTools;
|
|
439
443
|
|
|
444
|
+
/**
|
|
445
|
+
* A `KayAppUsage` that answers `unavailable` to every call: what a host with no telemetry lane
|
|
446
|
+
* binds, so `app.usage` stays present on every host.
|
|
447
|
+
*/
|
|
448
|
+
export declare function createUnavailableUsage(message: string): KayAppUsage;
|
|
449
|
+
|
|
440
450
|
declare interface CustomEntry extends EntryBase {
|
|
441
451
|
type: "custom";
|
|
442
452
|
customType: string;
|
|
@@ -765,7 +775,7 @@ export declare interface JevScoreQuestion {
|
|
|
765
775
|
* - The wire. The host serves `classify` over whichever route the user's Jev provider order
|
|
766
776
|
* picks; a plugin never sees a vendor client, a vendor type, or a route.
|
|
767
777
|
* - Credential resolution, the `jev.use` decision, the Jev-branch budget, or usage accounting.
|
|
768
|
-
* Those are host-side (`@
|
|
778
|
+
* Those are host-side (`@bonsai/agent-runtime`'s `kay/jev/`).
|
|
769
779
|
* ---
|
|
770
780
|
*
|
|
771
781
|
* The vocabulary is Bonsai's own (SDK 0.12.0). Before it, `use` received TypeSafe's `TypeSafeClient`
|
|
@@ -1155,6 +1165,24 @@ export declare interface KayAppAgentDefinition {
|
|
|
1155
1165
|
* position: the two are separately compared, so moving a rule between them is a different claim.
|
|
1156
1166
|
*/
|
|
1157
1167
|
readonly permissionsFallback?: readonly PluginAgentDefinitionPermissionRule[];
|
|
1168
|
+
/**
|
|
1169
|
+
* The URI schemes this definition's runs MAINTAIN, e.g. `["memory"]` for a job that curates,
|
|
1170
|
+
* prunes or rewrites the memory notebook. Bare scheme names, lowercase, no `://`.
|
|
1171
|
+
*
|
|
1172
|
+
* What it changes, and only this: a READ under a declared scheme, made by a session of this
|
|
1173
|
+
* definition or by any session in that session's family (its subagents, keyed by root), is not
|
|
1174
|
+
* counted as use of the resource in Bonsai's per-resource read activity (the `uriReadActivity`
|
|
1175
|
+
* metric, `analytics://memory`, and `app.usage`'s answers). A job that keeps a notebook tidy
|
|
1176
|
+
* reads old and irrelevant notes as a matter of course, and counting those reads would make
|
|
1177
|
+
* every note it touches look used. Reads by every other session, including other background
|
|
1178
|
+
* jobs, still count: a job that reads a note to do its own work found the note useful.
|
|
1179
|
+
*
|
|
1180
|
+
* It confers no authority and removes none. The host re-reads it from the live definition at
|
|
1181
|
+
* every activation, like {@link permissions}, and stamps it on the session's activation row.
|
|
1182
|
+
* Adding or removing one scheme here is the whole switch for moving a job between the excluded
|
|
1183
|
+
* and the counted side. Absent means the job maintains nothing. SDK 0.13.3.
|
|
1184
|
+
*/
|
|
1185
|
+
readonly maintains?: readonly string[];
|
|
1158
1186
|
}
|
|
1159
1187
|
|
|
1160
1188
|
/** The inert session-config subset a plugin-authored agent definition may contribute. */
|
|
@@ -1927,8 +1955,8 @@ export declare interface KayAppConfig {
|
|
|
1927
1955
|
/**
|
|
1928
1956
|
* Where a folded config value's winner was defined: the config LEVEL that won and the absolute
|
|
1929
1957
|
* path of the winning file. A JSON-safe twin of the runtime's `KayConfigValueOrigin`
|
|
1930
|
-
* (`@
|
|
1931
|
-
* here and an assignability test in `@
|
|
1958
|
+
* (`@bonsai/product-catalog`) — this SDK cannot import that package, so the shape is re-declared
|
|
1959
|
+
* here and an assignability test in `@bonsai/agent-runtime` pins the two together. The level union
|
|
1932
1960
|
* is the closed, protocol-owned fold precedence stack (`baseline < learned < global < project`).
|
|
1933
1961
|
* `"baseline"` names a host-composed, in-memory, build/channel-scoped default with no file
|
|
1934
1962
|
* behind it (`KayConfigStoreOptions.baselineDefaults`) — a plugin can still be handed one as a
|
|
@@ -2677,8 +2705,8 @@ export declare interface KayAppPermissions {
|
|
|
2677
2705
|
export declare interface KayAppPhaseShiftSessionEvent extends KayAppSessionEventBase {
|
|
2678
2706
|
readonly type: "phase-shift";
|
|
2679
2707
|
/**
|
|
2680
|
-
* The accepted observation, in the SURFACE-FRIENDLY resolved shape (`@
|
|
2681
|
-
* `PhaseShiftTimelineRecord`, re-exported from `@
|
|
2708
|
+
* The accepted observation, in the SURFACE-FRIENDLY resolved shape (`@bonsai/plugin-protocol`'s
|
|
2709
|
+
* `PhaseShiftTimelineRecord`, re-exported from `@bonsai/plugin-sdk/phase-shift`) rather than the
|
|
2682
2710
|
* raw validated one: source timestamps already resolved, total and pure, no entry read needed
|
|
2683
2711
|
* to place it in time. Re-validate its onsets against the branch you actually read — a rewind
|
|
2684
2712
|
* can race between publish and read — the same discipline `resolveClosedPhase` already applies.
|
|
@@ -2877,6 +2905,16 @@ export declare interface KayAppPluginApi {
|
|
|
2877
2905
|
* Always present, like {@link skills}.
|
|
2878
2906
|
*/
|
|
2879
2907
|
readonly tools: KayAppTools;
|
|
2908
|
+
/**
|
|
2909
|
+
* Read and change activity for the resources under this plugin's OWN URI schemes, counted under
|
|
2910
|
+
* Bonsai's read rule (reads by a job that declares it maintains the scheme never count). Each
|
|
2911
|
+
* call checks, against the live registry, that the asked prefix is under a scheme this plugin's
|
|
2912
|
+
* registered URI modules serve; any other prefix resolves to `{ status: "refused" }`. A host
|
|
2913
|
+
* with no telemetry lane, or a scan that cannot complete, resolves to `{ status: "unavailable" }`.
|
|
2914
|
+
* No call rejects while the plugin is enabled; after it is disabled, a kept handle's method
|
|
2915
|
+
* throws synchronously. Always present, like {@link skills}.
|
|
2916
|
+
*/
|
|
2917
|
+
readonly usage: KayAppUsage;
|
|
2880
2918
|
/** The app-wide endpoint bus (register handlers a consuming surface invokes). */
|
|
2881
2919
|
readonly endpoints: KayAppEndpoints;
|
|
2882
2920
|
/** Publish one event declared by this plugin's `kay.app` manifest target. */
|
|
@@ -3090,6 +3128,17 @@ export declare interface KayAppResolvedCredential {
|
|
|
3090
3128
|
readonly fields?: Readonly<Record<string, string>>;
|
|
3091
3129
|
}
|
|
3092
3130
|
|
|
3131
|
+
/**
|
|
3132
|
+
* What one run produced, as named counts: `{ suggestions: 2, pullRequests: 0 }`. Optional, and
|
|
3133
|
+
* read by Bonsai's own analytics, not shown to a person.
|
|
3134
|
+
*
|
|
3135
|
+
* Keys are your own names, in camelCase (a letter first, then letters and digits, at most 40
|
|
3136
|
+
* characters), at most 16 per run; values are whole numbers of zero or more. Report a zero rather
|
|
3137
|
+
* than leaving a key out: "made nothing" is the answer a reader is usually asking about. A result
|
|
3138
|
+
* that breaks these rules is dropped whole, with the run otherwise recorded as usual.
|
|
3139
|
+
*/
|
|
3140
|
+
export declare type KayAppRunProduced = Readonly<Record<string, number>>;
|
|
3141
|
+
|
|
3093
3142
|
export declare interface KayAppRunSummary {
|
|
3094
3143
|
/** One plain-text line, at most 100 characters. */
|
|
3095
3144
|
readonly headline: string;
|
|
@@ -3100,8 +3149,8 @@ export declare interface KayAppRunSummary {
|
|
|
3100
3149
|
|
|
3101
3150
|
/**
|
|
3102
3151
|
* The session provenance vocabulary, as the plugin protocol declares it. These used to be spelled
|
|
3103
|
-
* out here because the canonical schemas lived in `@
|
|
3104
|
-
* package may not import; they now live in `@
|
|
3152
|
+
* out here because the canonical schemas lived in `@bonsai/agent-runtime-protocol`, which this
|
|
3153
|
+
* package may not import; they now live in `@bonsai/plugin-protocol` (so artifact writers and the
|
|
3105
3154
|
* daemon share one shape), and a mirror here would be exactly the second declaration the
|
|
3106
3155
|
* placement law forbids. Each name is kept as an alias so existing plugin code keeps compiling.
|
|
3107
3156
|
*/
|
|
@@ -3236,6 +3285,12 @@ export declare interface KayAppSessionEventsSubscribeOptions {
|
|
|
3236
3285
|
* immediately.
|
|
3237
3286
|
*/
|
|
3238
3287
|
readonly serialize?: boolean;
|
|
3288
|
+
/**
|
|
3289
|
+
* Your own name for this handler (the id you would grep a log for). The host names it, with
|
|
3290
|
+
* your plugin id, on the record it writes when the handler throws, so a failure says whose it
|
|
3291
|
+
* was. Optional; unnamed handlers are recorded without it.
|
|
3292
|
+
*/
|
|
3293
|
+
readonly handlerId?: string;
|
|
3239
3294
|
readonly handler: (event: KayAppSessionEvent, context: KayAppSessionEventContext) => void | Promise<void>;
|
|
3240
3295
|
}
|
|
3241
3296
|
|
|
@@ -3734,7 +3789,7 @@ export declare type KayAppSignalsAnswerFilter = {
|
|
|
3734
3789
|
*/
|
|
3735
3790
|
export declare interface KayAppSignalsDetectorInput {
|
|
3736
3791
|
/**
|
|
3737
|
-
* Stable identifier, e.g. `memory-
|
|
3792
|
+
* Stable identifier, e.g. `memory-packet`: a lowercase slug (a-z and 0-9 in words joined
|
|
3738
3793
|
* by single hyphens), at most 64 characters, plugin-scoped. It becomes a `signals://` path
|
|
3739
3794
|
* segment.
|
|
3740
3795
|
*/
|
|
@@ -4169,7 +4224,7 @@ export declare interface KayAppTimeSnapshot {
|
|
|
4169
4224
|
* The time zone the user is in, as an IANA id in the spelling ICU resolves (`America/New_York`).
|
|
4170
4225
|
* One zone can have two ids, and ICU picks one: `Asia/Kolkata` comes back as `Asia/Calcutta`. So
|
|
4171
4226
|
* never compare zone ids with `===`. A first-party plugin compares with `sameZone` from
|
|
4172
|
-
* `@
|
|
4227
|
+
* `@bonsai/time`. A plugin that imports only this SDK and node builtins resolves each id with
|
|
4173
4228
|
* `new Intl.DateTimeFormat("en-US", { timeZone: id }).resolvedOptions().timeZone` and compares the
|
|
4174
4229
|
* results. Pass `zone` as the `timeZone` of `Intl.DateTimeFormat` or `toLocaleString` to format a
|
|
4175
4230
|
* time for the user.
|
|
@@ -4365,7 +4420,7 @@ export declare interface KayAppTurnSettledSessionEvent extends KayAppSessionEven
|
|
|
4365
4420
|
*
|
|
4366
4421
|
* Optional on this SDK-facing type only for fixture leniency (a handcrafted test event may omit
|
|
4367
4422
|
* it); the daemon's own emitter always populates it for a genuine settle — see
|
|
4368
|
-
* `TurnSettledSessionEvent.runId` (`@
|
|
4423
|
+
* `TurnSettledSessionEvent.runId` (`@bonsai/agent-runtime`'s internal twin of this event, which
|
|
4369
4424
|
* DOES require it) for the producer side of that guarantee.
|
|
4370
4425
|
*/
|
|
4371
4426
|
readonly runId?: string;
|
|
@@ -4398,6 +4453,97 @@ export declare interface KayAppUiActionSessionEvent extends KayAppSessionEventBa
|
|
|
4398
4453
|
readonly toolCallId: string;
|
|
4399
4454
|
}
|
|
4400
4455
|
|
|
4456
|
+
/** How one resource under the asked prefix has been read and changed. */
|
|
4457
|
+
export declare interface KayAppUriActivity {
|
|
4458
|
+
/** The canonical URI as the read or change recorded it. */
|
|
4459
|
+
readonly uri: string;
|
|
4460
|
+
/** One entry per window, in `KayAppUriActivityAnswer.windowDays` order. */
|
|
4461
|
+
readonly windows: readonly KayAppUriActivityWindow[];
|
|
4462
|
+
/** The newest counted read, ISO-8601 UTC; absent when none fell inside the scan. */
|
|
4463
|
+
readonly lastReadAt?: string;
|
|
4464
|
+
/** The newest change, ISO-8601 UTC; absent when none fell inside the scan. */
|
|
4465
|
+
readonly lastChangedAt?: string;
|
|
4466
|
+
}
|
|
4467
|
+
|
|
4468
|
+
export declare type KayAppUriActivityAnswer = {
|
|
4469
|
+
readonly status: "ok";
|
|
4470
|
+
/** The instant the windows are measured back from, ISO-8601 UTC. */
|
|
4471
|
+
readonly asOf: string;
|
|
4472
|
+
/** The windows every resource reports, in order. */
|
|
4473
|
+
readonly windowDays: readonly number[];
|
|
4474
|
+
/**
|
|
4475
|
+
* Every resource under the prefix the scan saw read or changed. One read only by a
|
|
4476
|
+
* maintaining job is listed with zero counts and no `lastReadAt`.
|
|
4477
|
+
*/
|
|
4478
|
+
readonly resources: readonly KayAppUriActivity[];
|
|
4479
|
+
} | {
|
|
4480
|
+
/** The prefix is not under a scheme this plugin's registered URI modules serve. */
|
|
4481
|
+
readonly status: "refused";
|
|
4482
|
+
readonly message: string;
|
|
4483
|
+
} | {
|
|
4484
|
+
/** No telemetry lane on this host, or the scan could not complete. */
|
|
4485
|
+
readonly status: "unavailable";
|
|
4486
|
+
readonly message: string;
|
|
4487
|
+
};
|
|
4488
|
+
|
|
4489
|
+
/**
|
|
4490
|
+
* The plugin-facing `kay.app` usage contract: how the resources under a plugin's OWN URI schemes
|
|
4491
|
+
* have been read and changed, as Bonsai's telemetry records it. SDK 0.13.3; a plugin that calls it
|
|
4492
|
+
* declares `compatibility.sdk` `^0.13.3`.
|
|
4493
|
+
*
|
|
4494
|
+
* Scoped, not gated. A plugin may ask only about a prefix under a scheme one of its own registered
|
|
4495
|
+
* URI modules serves; that check runs at every call against the live registry, and a prefix under
|
|
4496
|
+
* any other scheme answers `{ status: "refused" }`. The member is ALWAYS present and no call
|
|
4497
|
+
* rejects while the plugin is enabled: no telemetry lane on this host, a query that could not
|
|
4498
|
+
* complete, or an answer too large to return all resolve to `{ status: "unavailable" }`. After the
|
|
4499
|
+
* plugin is disabled, a kept handle's method throws synchronously.
|
|
4500
|
+
*
|
|
4501
|
+
* ## What counts as a read
|
|
4502
|
+
*
|
|
4503
|
+
* Every executed read counts, from any session (a person's conversation and its subagents,
|
|
4504
|
+
* automations, loops, watches, Dream passes, any other job), EXCEPT a read made by a session whose
|
|
4505
|
+
* agent definition declares that it maintains the read's scheme (`KayAppAgentDefinition.maintains`)
|
|
4506
|
+
* or by any session in that session's family. Each counted read is split by who it serves:
|
|
4507
|
+
* `personReads` when its session tree was started by a person, `jobReads` otherwise. Changes
|
|
4508
|
+
* (writes and edits) count from every session, maintainers included.
|
|
4509
|
+
*
|
|
4510
|
+
* Reads recorded before the host build that stamps the declaration follow the earlier rule until
|
|
4511
|
+
* they leave the 90-day window: such a read counts only when a person started the session that made it (a person's subagents
|
|
4512
|
+
* did not count under that rule).
|
|
4513
|
+
*
|
|
4514
|
+
* ## Zero and unavailable are different answers
|
|
4515
|
+
*
|
|
4516
|
+
* An `ok` answer describes a complete scan: a resource absent from `resources` was neither read
|
|
4517
|
+
* nor changed inside the scan, so it has zero counted reads. When the scan could not complete the answer is `unavailable`,
|
|
4518
|
+
* never a list of zeros, because "nothing read this" and "nothing could tell" are different facts.
|
|
4519
|
+
*/
|
|
4520
|
+
/** One window's activity for one resource. */
|
|
4521
|
+
export declare interface KayAppUriActivityWindow {
|
|
4522
|
+
/** The span, in days, measured back from the answer's `asOf`. */
|
|
4523
|
+
readonly windowDays: number;
|
|
4524
|
+
/** Counted reads: `personReads + jobReads`. */
|
|
4525
|
+
readonly reads: number;
|
|
4526
|
+
/** Counted reads whose session tree a person started. */
|
|
4527
|
+
readonly personReads: number;
|
|
4528
|
+
/** Counted reads by every other session tree (automations, Dream passes, other jobs). */
|
|
4529
|
+
readonly jobReads: number;
|
|
4530
|
+
/** Distinct session trees (keyed by root session) behind the counted reads. */
|
|
4531
|
+
readonly sessions: number;
|
|
4532
|
+
/** Writes and edits of any origin, maintainers included. */
|
|
4533
|
+
readonly changes: number;
|
|
4534
|
+
}
|
|
4535
|
+
|
|
4536
|
+
export declare interface KayAppUsage {
|
|
4537
|
+
/**
|
|
4538
|
+
* Read and change activity for every resource whose URI starts with `prefix`, for example
|
|
4539
|
+
* `memory://` or `memory://projects/`. The prefix must name a scheme (`<scheme>://`) that one of
|
|
4540
|
+
* this plugin's registered URI modules serves.
|
|
4541
|
+
*/
|
|
4542
|
+
uriActivity(input: {
|
|
4543
|
+
readonly prefix: string;
|
|
4544
|
+
}): Promise<KayAppUriActivityAnswer>;
|
|
4545
|
+
}
|
|
4546
|
+
|
|
4401
4547
|
export declare interface KayAppUserFileEntry {
|
|
4402
4548
|
readonly name: string;
|
|
4403
4549
|
/** From the directory entry itself: a symlink is reported as `symlink`, never followed. */
|
|
@@ -4680,6 +4826,7 @@ export declare interface KayAppWorkflowDefinition {
|
|
|
4680
4826
|
}>;
|
|
4681
4827
|
readonly run: (context: KayAppWorkflowContext) => Promise<{
|
|
4682
4828
|
readonly summary: KayAppRunSummary;
|
|
4829
|
+
readonly produced?: KayAppRunProduced;
|
|
4683
4830
|
}>;
|
|
4684
4831
|
}
|
|
4685
4832
|
|
|
@@ -4750,7 +4897,7 @@ export declare interface KayAppWorkspace {
|
|
|
4750
4897
|
/**
|
|
4751
4898
|
* The full workspace arrangement verb catalog: tab lifecycle/reorder/grouping, pane split/close/
|
|
4752
4899
|
* focus/maximize/restore/place, shell panel toggles, and opening a session. A JSON-safe twin of
|
|
4753
|
-
* `KayWorkspaceCommand` in `@
|
|
4900
|
+
* `KayWorkspaceCommand` in `@bonsai/agent-runtime-protocol`.
|
|
4754
4901
|
*/
|
|
4755
4902
|
export declare type KayAppWorkspaceCommand = {
|
|
4756
4903
|
verb: "tabs.open";
|
|
@@ -4828,7 +4975,14 @@ export declare type KayAppWorkspaceCommand = {
|
|
|
4828
4975
|
verb: "shell.togglePanel";
|
|
4829
4976
|
} | {
|
|
4830
4977
|
verb: "shell.toggleInspector";
|
|
4831
|
-
}
|
|
4978
|
+
}
|
|
4979
|
+
/**
|
|
4980
|
+
* Open a session without taking the user's focus. A session no pane shows gets a tab of its own
|
|
4981
|
+
* in the background (`opened`); one some pane already shows is left as it is (`applied`). The
|
|
4982
|
+
* active tab and every focus stay as they were. The wire's `reveal` flag, which asks for a
|
|
4983
|
+
* sidebar-click-style open, is not offered here: it is for Bonsai Desktop's own menus.
|
|
4984
|
+
*/
|
|
4985
|
+
| {
|
|
4832
4986
|
verb: "sessions.open";
|
|
4833
4987
|
sessionId: string;
|
|
4834
4988
|
title?: string | undefined;
|
|
@@ -4836,7 +4990,7 @@ export declare type KayAppWorkspaceCommand = {
|
|
|
4836
4990
|
|
|
4837
4991
|
/**
|
|
4838
4992
|
* The one outcome grammar every {@link KayAppWorkspaceCommand} resolves to. A JSON-safe twin of
|
|
4839
|
-
* `WorkspaceCommandOutcome` in `@
|
|
4993
|
+
* `WorkspaceCommandOutcome` in `@bonsai/agent-runtime-protocol`.
|
|
4840
4994
|
*/
|
|
4841
4995
|
export declare type KayAppWorkspaceCommandOutcome = "applied" | "opened" | "focused-existing" | "no-room" | "no-window" | "not-found" | "invalid";
|
|
4842
4996
|
|
|
@@ -4847,8 +5001,8 @@ export declare interface KayAppWorkspaceExecuteContext {
|
|
|
4847
5001
|
|
|
4848
5002
|
/**
|
|
4849
5003
|
* What one pane item shows. A JSON-safe, hand-copied twin of `WorkspacePaneContent` in
|
|
4850
|
-
* `@
|
|
4851
|
-
* module's own doc comment), so the shape is re-declared here. A parity check in `@
|
|
5004
|
+
* `@bonsai/agent-runtime-protocol` — this package cannot import that protocol package (see this
|
|
5005
|
+
* module's own doc comment), so the shape is re-declared here. A parity check in `@bonsai/agent-runtime`
|
|
4852
5006
|
* asserts `app.workspace` (the runtime's `KayWorkspaceCapability`, built from the protocol types)
|
|
4853
5007
|
* stays structurally assignable to {@link KayAppWorkspace} below.
|
|
4854
5008
|
*
|
|
@@ -5592,14 +5746,14 @@ declare interface ScopeRequirement {
|
|
|
5592
5746
|
* this list. Two consequences worth knowing:
|
|
5593
5747
|
*
|
|
5594
5748
|
* - `sessions.create` and `sessions.run` are the two separately-granted plugin doors
|
|
5595
|
-
* (`@
|
|
5749
|
+
* (`@bonsai/plugin-protocol`'s `permissions.ts`: `create` mints a persisted user-visible session,
|
|
5596
5750
|
* `run` executes a hidden headless one). Each names ITSELF at the site that mints the session;
|
|
5597
5751
|
* neither is inferred from the surface string, which cannot tell them apart.
|
|
5598
5752
|
* - `sessions.create` stamps a plugin creator only for a create that declares a plugin-surfaced
|
|
5599
5753
|
* `system` origin. The SDK `create` door passes no origin today, so its sessions read as the
|
|
5600
5754
|
* ordinary chats they are; the value is still the honest one for that door when it does.
|
|
5601
5755
|
* - `agents.run` (G1, 2026-09) is the generic session-event run door
|
|
5602
|
-
* (`app.agents.run(ref, input, cause, {fork?})`, `@
|
|
5756
|
+
* (`app.agents.run(ref, input, cause, {fork?})`, `@bonsai/plugin-sdk`'s `kay-app/agents.ts`): a
|
|
5603
5757
|
* plugin's `app.sessionEvents.subscribe` handler spins up a bounded agent run in response to a
|
|
5604
5758
|
* published session event. `callerSessionId` carries the cause's `sourceSessionId` — the session
|
|
5605
5759
|
* whose event caused this run — and {@link SessionProvenanceRecord.causedByEvent} carries the
|
|
@@ -7339,7 +7493,7 @@ declare interface UriValidationMessage {
|
|
|
7339
7493
|
* applies label changes"), never wire mechanics or URI shapes. Verbs the
|
|
7340
7494
|
* module does not support are omitted; at runtime a supported verb with no
|
|
7341
7495
|
* entry simply renders undocumented (fail-open metadata) — but for a plugin's
|
|
7342
|
-
* `kay.agent` URI modules, `auditPluginDisclosure` (`@
|
|
7496
|
+
* `kay.agent` URI modules, `auditPluginDisclosure` (`@bonsai/plugin-sdk/
|
|
7343
7497
|
* disclosure`) enforces coverage of every supported verb at authoring/load
|
|
7344
7498
|
* time.
|
|
7345
7499
|
*
|
package/dist/kay-app.js
CHANGED
|
@@ -538,6 +538,13 @@ function transcriptRoleLabel(role) {
|
|
|
538
538
|
return role === "user" ? "User" : "Assistant";
|
|
539
539
|
}
|
|
540
540
|
|
|
541
|
+
// packages/plugin-sdk/dist/kay-app/usage.js
|
|
542
|
+
function createUnavailableUsage(message) {
|
|
543
|
+
return {
|
|
544
|
+
uriActivity: async () => ({ status: "unavailable", message })
|
|
545
|
+
};
|
|
546
|
+
}
|
|
547
|
+
|
|
541
548
|
// packages/plugin-sdk/dist/kay-app/workflows.js
|
|
542
549
|
var KayAppWorkflowFailure = class extends Error {
|
|
543
550
|
summary;
|
|
@@ -580,6 +587,7 @@ export {
|
|
|
580
587
|
createFallbackOnlyWithJev,
|
|
581
588
|
createUnavailableSkills,
|
|
582
589
|
createUnavailableTools,
|
|
590
|
+
createUnavailableUsage,
|
|
583
591
|
invalidObservation,
|
|
584
592
|
isRetryable,
|
|
585
593
|
parseLineSelector,
|
package/dist/signals.d.ts
CHANGED
|
@@ -86,7 +86,7 @@ declare interface JevScoreQuestion {
|
|
|
86
86
|
* - The wire. The host serves `classify` over whichever route the user's Jev provider order
|
|
87
87
|
* picks; a plugin never sees a vendor client, a vendor type, or a route.
|
|
88
88
|
* - Credential resolution, the `jev.use` decision, the Jev-branch budget, or usage accounting.
|
|
89
|
-
* Those are host-side (`@
|
|
89
|
+
* Those are host-side (`@bonsai/agent-runtime`'s `kay/jev/`).
|
|
90
90
|
* ---
|
|
91
91
|
*
|
|
92
92
|
* The vocabulary is Bonsai's own (SDK 0.12.0). Before it, `use` received TypeSafe's `TypeSafeClient`
|
|
@@ -301,7 +301,7 @@ export declare type KayAppSignalsAnswerFilter = {
|
|
|
301
301
|
*/
|
|
302
302
|
export declare interface KayAppSignalsDetectorInput {
|
|
303
303
|
/**
|
|
304
|
-
* Stable identifier, e.g. `memory-
|
|
304
|
+
* Stable identifier, e.g. `memory-packet`: a lowercase slug (a-z and 0-9 in words joined
|
|
305
305
|
* by single hyphens), at most 64 characters, plugin-scoped. It becomes a `signals://` path
|
|
306
306
|
* segment.
|
|
307
307
|
*/
|