@yaklabs-ai/plugin-sdk 0.13.1 → 0.13.3
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 +38 -6
- package/dist/fs.js +1 -1
- package/dist/jev.d.ts +1 -1
- package/dist/kay-agent-testing.d.ts +36 -4
- package/dist/kay-agent.d.ts +266 -5
- package/dist/kay-agent.js +169 -2
- package/dist/kay-app.d.ts +267 -18
- package/dist/kay-app.js +16 -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.d.ts
CHANGED
|
@@ -244,7 +244,7 @@ export declare function asArray(value: unknown): readonly unknown[];
|
|
|
244
244
|
* - {@link asRecord}, {@link asArray}, {@link str}, {@link num}, {@link numLike}.
|
|
245
245
|
* does_not_own:
|
|
246
246
|
* - Schema-shaped validation. **Idiom-routing rule (read before reaching for these):** `z`
|
|
247
|
-
* (re-exported from this same `@
|
|
247
|
+
* (re-exported from this same `@bonsai/plugin-sdk/kay-agent` module) is the default for
|
|
248
248
|
* anything shape-contractual — a tool's own `parameters` (via `toolParameters`), and any
|
|
249
249
|
* upstream response you're going to treat as a stable contract going forward. Reach for these
|
|
250
250
|
* readers only for **tolerant salvage**: pulling one or two fields out of a response whose
|
|
@@ -315,6 +315,10 @@ declare interface BackgroundTaskCompletion {
|
|
|
315
315
|
readonly resultDelivery?: BackgroundTaskResultDelivery;
|
|
316
316
|
readonly output?: string;
|
|
317
317
|
readonly error?: string;
|
|
318
|
+
/** The thrown Error's stack, when a failed task threw one. */
|
|
319
|
+
readonly errorStack?: string;
|
|
320
|
+
/** Why a failed AGENT task's run failed, classified from what it threw; absent for other kinds. */
|
|
321
|
+
readonly failureReason?: RunFailureReason;
|
|
318
322
|
}
|
|
319
323
|
|
|
320
324
|
declare type BackgroundTaskInspector = () => Promise<string> | string;
|
|
@@ -611,6 +615,9 @@ export declare interface CreateJsonApiClientOptions {
|
|
|
611
615
|
readonly fetch?: typeof fetch;
|
|
612
616
|
}
|
|
613
617
|
|
|
618
|
+
/** One plugin's runner: its module, its label, and the app-specific failures it names. */
|
|
619
|
+
export declare function createOsascriptRunner(options: OsascriptRunnerOptions): OsascriptRunner;
|
|
620
|
+
|
|
614
621
|
/** What the module holds at mutation time: a provider revision, the current content, or both. */
|
|
615
622
|
export declare interface CurrentResourceState {
|
|
616
623
|
readonly revision?: string;
|
|
@@ -831,6 +838,12 @@ declare interface ExtensionPaths {
|
|
|
831
838
|
readonly dataDir: string;
|
|
832
839
|
}
|
|
833
840
|
|
|
841
|
+
/**
|
|
842
|
+
* Several lines of text inside a code fence none of its lines can close, so a message body or an
|
|
843
|
+
* invitation's notes cannot pass for a heading or a field of the read around them.
|
|
844
|
+
*/
|
|
845
|
+
export declare function fenced(text: string): readonly string[];
|
|
846
|
+
|
|
834
847
|
export declare function formatIsoDate(value?: string | number | Date): string;
|
|
835
848
|
|
|
836
849
|
export declare function formatNumber(n: number): string;
|
|
@@ -881,7 +894,7 @@ declare type InferToolInput<TParams extends ToolParametersWire> = TParams extend
|
|
|
881
894
|
|
|
882
895
|
/**
|
|
883
896
|
* The value a Browser Interaction driver sets as `credentialGuard` to declare that every act runs
|
|
884
|
-
* the page-side credential guard from `@
|
|
897
|
+
* the page-side credential guard from `@bonsai/interaction-page-scripts` (never type into or click a
|
|
885
898
|
* sign-in form). The engine refuses to register a browser driver without it.
|
|
886
899
|
*/
|
|
887
900
|
export declare const INTERACTION_CREDENTIAL_GUARD = "kay.credential-guard/v1";
|
|
@@ -1221,7 +1234,7 @@ export declare interface JevScoreQuestion {
|
|
|
1221
1234
|
* - The wire. The host serves `classify` over whichever route the user's Jev provider order
|
|
1222
1235
|
* picks; a plugin never sees a vendor client, a vendor type, or a route.
|
|
1223
1236
|
* - Credential resolution, the `jev.use` decision, the Jev-branch budget, or usage accounting.
|
|
1224
|
-
* Those are host-side (`@
|
|
1237
|
+
* Those are host-side (`@bonsai/agent-runtime`'s `kay/jev/`).
|
|
1225
1238
|
* ---
|
|
1226
1239
|
*
|
|
1227
1240
|
* The vocabulary is Bonsai's own (SDK 0.12.0). Before it, `use` received TypeSafe's `TypeSafeClient`
|
|
@@ -1875,7 +1888,7 @@ declare interface KayAppTimeSnapshot {
|
|
|
1875
1888
|
* The time zone the user is in, as an IANA id in the spelling ICU resolves (`America/New_York`).
|
|
1876
1889
|
* One zone can have two ids, and ICU picks one: `Asia/Kolkata` comes back as `Asia/Calcutta`. So
|
|
1877
1890
|
* never compare zone ids with `===`. A first-party plugin compares with `sameZone` from
|
|
1878
|
-
* `@
|
|
1891
|
+
* `@bonsai/time`. A plugin that imports only this SDK and node builtins resolves each id with
|
|
1879
1892
|
* `new Intl.DateTimeFormat("en-US", { timeZone: id }).resolvedOptions().timeZone` and compares the
|
|
1880
1893
|
* results. Pass `zone` as the `timeZone` of `Intl.DateTimeFormat` or `toLocaleString` to format a
|
|
1881
1894
|
* time for the user.
|
|
@@ -2811,6 +2824,7 @@ declare const KayPluginManifestV1: z.ZodObject<{
|
|
|
2811
2824
|
minKayVersion: z.ZodOptional<z.ZodString>;
|
|
2812
2825
|
sdk: z.ZodOptional<z.ZodString>;
|
|
2813
2826
|
}, z.core.$strict>>>;
|
|
2827
|
+
ownedByBonsai: z.ZodOptional<z.ZodBoolean>;
|
|
2814
2828
|
dependencies: z.ZodOptional<z.ZodObject<{
|
|
2815
2829
|
plugins: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
2816
2830
|
}, z.core.$strict>>;
|
|
@@ -2822,6 +2836,35 @@ declare type KnownApi = "openai-completions" | "mistral-conversations" | "openai
|
|
|
2822
2836
|
|
|
2823
2837
|
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";
|
|
2824
2838
|
|
|
2839
|
+
/**
|
|
2840
|
+
* A one-line label the host prints verbatim, such as an approval card's target. Line breaks,
|
|
2841
|
+
* other control characters, and line or paragraph separators become spaces, and invisible format
|
|
2842
|
+
* characters go: a zero-width joiner inside an emoji, a soft hyphen, a direction mark, a
|
|
2843
|
+
* zero-width space. The host refuses a target holding any of them, and drops the whole approval
|
|
2844
|
+
* card with it (`admitDescription` in herd-agent's `action-summary.ts`).
|
|
2845
|
+
*/
|
|
2846
|
+
export declare function labelOf(value: string | null | undefined): string;
|
|
2847
|
+
|
|
2848
|
+
/**
|
|
2849
|
+
* ---
|
|
2850
|
+
* responsibility: The flat authoring-helper layer's untrusted-text surface (decision 002,
|
|
2851
|
+
* kay#11957): render text someone else wrote (a shared calendar's name, a contact card synced
|
|
2852
|
+
* from another account, an email body) into a plugin's Markdown output or an approval card
|
|
2853
|
+
* without it forging structure around it. Apple Mail, Calendar, and Contacts had each grown a
|
|
2854
|
+
* copy.
|
|
2855
|
+
* owns:
|
|
2856
|
+
* - {@link lineOf}, {@link labelOf}, {@link markdownText}, {@link fenced}.
|
|
2857
|
+
* does_not_own:
|
|
2858
|
+
* - Deciding which fields are untrusted. Every value the user does not control is; the plugin
|
|
2859
|
+
* routes each one through these before it reaches output.
|
|
2860
|
+
* ---
|
|
2861
|
+
*/
|
|
2862
|
+
/**
|
|
2863
|
+
* A one-line field: every whitespace run, newlines included, becomes one space, so a value can
|
|
2864
|
+
* never open a line of its own (one that passes for an `Account:` line, for instance).
|
|
2865
|
+
*/
|
|
2866
|
+
export declare function lineOf(value: string | null | undefined): string;
|
|
2867
|
+
|
|
2825
2868
|
declare interface LineRange {
|
|
2826
2869
|
readonly start: number;
|
|
2827
2870
|
readonly end: number;
|
|
@@ -2839,6 +2882,17 @@ export declare function lintUriTemplate(template: UriTemplate): readonly UriTemp
|
|
|
2839
2882
|
|
|
2840
2883
|
export declare function markdownResource(uri: string, md: string, notes?: string[]): RawResource;
|
|
2841
2884
|
|
|
2885
|
+
/**
|
|
2886
|
+
* Text placed mid-line, after a label, that cannot forge a link, an image, an HTML tag, or a
|
|
2887
|
+
* field: a backslash goes before `[`, `]`, `!`, and `<`; before `|`, which a plugin may use to
|
|
2888
|
+
* separate the fields of a one-line summary; and before a backslash, so no escape can be undone.
|
|
2889
|
+
*
|
|
2890
|
+
* It does not neutralize everything Markdown does. Line-start syntax (`#`, `>`, `-`, `1.`),
|
|
2891
|
+
* emphasis, code spans, and bare-URL autolinks still render, so keep the value off the start of a
|
|
2892
|
+
* line (behind a label, after {@link lineOf}) or use {@link fenced} for whole blocks.
|
|
2893
|
+
*/
|
|
2894
|
+
export declare function markdownText(text: string): string;
|
|
2895
|
+
|
|
2842
2896
|
/**
|
|
2843
2897
|
* The execute-time surface a tool sees. These are the only fields a {@link ToolDefinition.execute}
|
|
2844
2898
|
* body can read. Runtime-optionals are absent without a live session: a tool invoked from a
|
|
@@ -3275,11 +3329,183 @@ declare interface OpenRouterRouting {
|
|
|
3275
3329
|
};
|
|
3276
3330
|
}
|
|
3277
3331
|
|
|
3332
|
+
/**
|
|
3333
|
+
* The JXA half of the envelope: paste it into a script's source, then end `run(argv)` with
|
|
3334
|
+
* `return jsonOk(data)` or `return jsonFail(code, message)`. {@link readOsascriptOutput} reads
|
|
3335
|
+
* exactly what these print. Both are total: `jsonOk()` with no value answers `null` (JSON drops an
|
|
3336
|
+
* `undefined` key, which the reader would refuse), and `jsonFail` turns its code and message into
|
|
3337
|
+
* strings, so a thrown non-Error or an Error object passed as the message still reaches the
|
|
3338
|
+
* caller as this script's refusal, under its own code.
|
|
3339
|
+
*/
|
|
3340
|
+
export declare const OSASCRIPT_ENVELOPE_JXA = "\nfunction jsonOk(data) {\n return JSON.stringify({ ok: true, data: data === undefined ? null : data });\n}\nfunction jsonFail(code, message) {\n return JSON.stringify({ ok: false, error: { code: String(code), message: String(message) } });\n}\n";
|
|
3341
|
+
|
|
3342
|
+
/** The runner's kill deadline when a call names none. */
|
|
3343
|
+
export declare const OSASCRIPT_TIMEOUT_MS = 30000;
|
|
3344
|
+
|
|
3345
|
+
/**
|
|
3346
|
+
* The argv for one script run: JavaScript, the script as a fixed `-e` constant, then `--` and the
|
|
3347
|
+
* dynamic values. `--` ends osascript's own option parsing: without it, a value in the first argv
|
|
3348
|
+
* slot that starts with `-` (a search for "-budget", a folder named "-Archive") is taken as an
|
|
3349
|
+
* option and the script never runs (the Apple Notes plugin verified this live). User values only
|
|
3350
|
+
* ever travel here, never in the script source: that is the injection boundary.
|
|
3351
|
+
*/
|
|
3352
|
+
export declare function osascriptArgs(script: string, argv: readonly string[]): readonly string[];
|
|
3353
|
+
|
|
3354
|
+
/** One script run: what the error names, and the bounds the runner enforces. */
|
|
3355
|
+
export declare interface OsascriptCall {
|
|
3356
|
+
readonly operation: UriOperation;
|
|
3357
|
+
readonly uri: string;
|
|
3358
|
+
readonly signal?: AbortSignal | undefined;
|
|
3359
|
+
readonly maxOutputChars: number;
|
|
3360
|
+
/** The runner's kill deadline; absent means {@link OSASCRIPT_TIMEOUT_MS}. */
|
|
3361
|
+
readonly timeoutMs?: number;
|
|
3362
|
+
/** What to do when the output is too large; absent means "narrow the request". */
|
|
3363
|
+
readonly truncatedAdvice?: string;
|
|
3364
|
+
/**
|
|
3365
|
+
* Set for a script that changes the app: the sentence that ends the error when its run fails
|
|
3366
|
+
* before Bonsai reads its answer, such as "The event may have been created: search
|
|
3367
|
+
* apple-calendar://events before trying again." The script may have saved before the runner
|
|
3368
|
+
* failed, osascript stopped (a timeout or a cancel), or its output became unreadable. A refusal
|
|
3369
|
+
* the script returns itself (`jsonFail`) does not end with this sentence: a script refuses
|
|
3370
|
+
* before it changes anything.
|
|
3371
|
+
*/
|
|
3372
|
+
readonly outcomeUnknown?: string;
|
|
3373
|
+
}
|
|
3374
|
+
|
|
3375
|
+
/** The runner a module's verbs use, with a simulator in the host's place when one is set. */
|
|
3376
|
+
export declare interface OsascriptDispatch {
|
|
3377
|
+
/**
|
|
3378
|
+
* {@link OsascriptRunner.requireExternalCli}, then the simulator's runner in the host's place.
|
|
3379
|
+
* The host's runner is required either way: its absence is how a not-connected service fails.
|
|
3380
|
+
*/
|
|
3381
|
+
readonly requireExternalCli: (ctx: UriResolveContext, operation: UriOperation, uri: string) => UriExternalCliRunner;
|
|
3382
|
+
/**
|
|
3383
|
+
* The runner for a path that tolerates its absence (an approval card's lookup): `undefined`
|
|
3384
|
+
* when the host injected none, the simulator's when one is set, the host's otherwise.
|
|
3385
|
+
*/
|
|
3386
|
+
readonly externalCliOf: (ctx: UriResolveContext) => UriExternalCliRunner | undefined;
|
|
3387
|
+
}
|
|
3388
|
+
|
|
3389
|
+
/** A failure the plugin names: its own code, and the advice that ends the message. */
|
|
3390
|
+
export declare interface OsascriptFailureAdvice {
|
|
3391
|
+
readonly code: string;
|
|
3392
|
+
readonly advice: string;
|
|
3393
|
+
}
|
|
3394
|
+
|
|
3395
|
+
/**
|
|
3396
|
+
* The activation options every osascript plugin's agent factory accepts
|
|
3397
|
+
* (`createAppleCalendarKayAgent(options)`), so the daemon's simulator roster sets each the same
|
|
3398
|
+
* way. Absent `simulator`, the plugin is exactly the shipped one.
|
|
3399
|
+
*/
|
|
3400
|
+
export declare interface OsascriptKayAgentOptions {
|
|
3401
|
+
readonly simulator?: OsascriptSimulatorOptions;
|
|
3402
|
+
}
|
|
3403
|
+
|
|
3404
|
+
/** What a script's stdout says, once read. */
|
|
3405
|
+
export declare type OsascriptOutput =
|
|
3406
|
+
/** `jsonOk(data)`. `data` is unchecked: validate it against the script's own shape. */
|
|
3407
|
+
{
|
|
3408
|
+
readonly kind: "data";
|
|
3409
|
+
readonly data: unknown;
|
|
3410
|
+
}
|
|
3411
|
+
/** `jsonFail(code, message)`: the script refused on its own terms. */
|
|
3412
|
+
| {
|
|
3413
|
+
readonly kind: "refused";
|
|
3414
|
+
readonly code: string;
|
|
3415
|
+
readonly message: string;
|
|
3416
|
+
}
|
|
3417
|
+
/**
|
|
3418
|
+
* Not JSON, or JSON that is not an envelope (`null`, `{}`, `42`, `{"ok":false}`, and
|
|
3419
|
+
* `{"ok":true}` with no `data` key, which {@link OSASCRIPT_ENVELOPE_JXA}'s `jsonOk` never prints).
|
|
3420
|
+
*/
|
|
3421
|
+
| {
|
|
3422
|
+
readonly kind: "invalid";
|
|
3423
|
+
readonly reason: string;
|
|
3424
|
+
};
|
|
3425
|
+
|
|
3426
|
+
export declare interface OsascriptRunner {
|
|
3427
|
+
/**
|
|
3428
|
+
* The host-injected runner, or the `auth_required` error the host classifies as not
|
|
3429
|
+
* connected: the in-handler twin of the host's pre-dispatch auth resolution.
|
|
3430
|
+
*/
|
|
3431
|
+
readonly requireExternalCli: (ctx: UriResolveContext, operation: UriOperation, uri: string) => UriExternalCliRunner;
|
|
3432
|
+
/**
|
|
3433
|
+
* The runners a module's verbs use: the host's exactly when `simulator` is absent, or the
|
|
3434
|
+
* simulator's in its place, per dispatch, after the host's connection gate.
|
|
3435
|
+
*/
|
|
3436
|
+
readonly dispatch: (simulator: OsascriptSimulatedRunner | undefined) => OsascriptDispatch;
|
|
3437
|
+
/**
|
|
3438
|
+
* Run `script` with `argv` and return the data it answered (unchecked: validate it). Every
|
|
3439
|
+
* other outcome throws a `UriProviderError`, except a runner that throws on its own: that
|
|
3440
|
+
* error passes through unchanged unless the call sets `outcomeUnknown`.
|
|
3441
|
+
*/
|
|
3442
|
+
readonly runScript: (externalCli: UriExternalCliRunner, script: string, argv: readonly string[], call: OsascriptCall) => Promise<unknown>;
|
|
3443
|
+
/** A `UriProviderError` from this plugin's module, never retryable. */
|
|
3444
|
+
readonly providerError: (call: Pick<OsascriptCall, "operation" | "uri">, providerCode: string, message: string) => UriProviderError;
|
|
3445
|
+
/**
|
|
3446
|
+
* The error for a run that exited non-zero, for a caller that reads the runner's result
|
|
3447
|
+
* itself (a send path that reads progress markers from stderr). Ends with the call's
|
|
3448
|
+
* `outcomeUnknown` sentence when it has one.
|
|
3449
|
+
*/
|
|
3450
|
+
readonly scriptFailure: (call: OsascriptCall, result: Pick<UriExternalCliRunResult, "stderr" | "stdout">) => UriProviderError;
|
|
3451
|
+
}
|
|
3452
|
+
|
|
3453
|
+
export declare interface OsascriptRunnerOptions {
|
|
3454
|
+
/** The URI module every error names. */
|
|
3455
|
+
readonly moduleId: string;
|
|
3456
|
+
/** The service a missing runner tells the agent to connect. */
|
|
3457
|
+
readonly serviceId: string;
|
|
3458
|
+
/** The product name that opens each message, such as "Apple Calendar". */
|
|
3459
|
+
readonly label: string;
|
|
3460
|
+
/**
|
|
3461
|
+
* What opens the message of a failed run; absent means "<label> automation failed". A plugin
|
|
3462
|
+
* that scripts no app (its JXA calls a framework directly) says "<label> script failed".
|
|
3463
|
+
*/
|
|
3464
|
+
readonly failurePrefix?: string;
|
|
3465
|
+
/**
|
|
3466
|
+
* Advice for macOS refusing the Apple Event (`-1743`, "not authorized"): the Automation grant
|
|
3467
|
+
* is missing or revoked. Set, such a run fails `automation-denied` with this advice; absent,
|
|
3468
|
+
* it is an ordinary `script-failed`.
|
|
3469
|
+
*/
|
|
3470
|
+
readonly automationDeniedAdvice?: string;
|
|
3471
|
+
/**
|
|
3472
|
+
* The plugin's code and advice for its app quitting mid-run: `-600` (application isn't
|
|
3473
|
+
* running) before the script's first Apple Event, `-609` (connection is invalid) after it.
|
|
3474
|
+
* Absent, such a run is an ordinary `script-failed`. The check a script makes itself
|
|
3475
|
+
* (`running()`, then `jsonFail`) is the plugin's, and comes back as that refusal.
|
|
3476
|
+
*/
|
|
3477
|
+
readonly appNotRunning?: OsascriptFailureAdvice;
|
|
3478
|
+
}
|
|
3479
|
+
|
|
3480
|
+
/** A plugin's simulator, as the runner sees it: the runner one dispatch uses in the host's place. */
|
|
3481
|
+
export declare interface OsascriptSimulatedRunner {
|
|
3482
|
+
readonly runnerFor: (ctx: UriResolveContext) => UriExternalCliRunner;
|
|
3483
|
+
}
|
|
3484
|
+
|
|
3485
|
+
/**
|
|
3486
|
+
* How a plugin is told to serve its module from its simulator instead of osascript: the one
|
|
3487
|
+
* option shape every osascript plugin's agent factory accepts as `simulator`. Only the daemon's
|
|
3488
|
+
* URI simulator roster sets it, for evals and dev; an ordinary install never does.
|
|
3489
|
+
*/
|
|
3490
|
+
export declare interface OsascriptSimulatorOptions {
|
|
3491
|
+
/** The directory holding the simulator's world; the daemon's process config names it. */
|
|
3492
|
+
readonly stateDir: string;
|
|
3493
|
+
}
|
|
3494
|
+
|
|
3278
3495
|
export declare function parseLineSelector(input: string): {
|
|
3279
3496
|
address: string;
|
|
3280
3497
|
selector: LineSelector;
|
|
3281
3498
|
};
|
|
3282
3499
|
|
|
3500
|
+
/**
|
|
3501
|
+
* The script and argv of a request {@link osascriptArgs} built, or `undefined` for any other
|
|
3502
|
+
* argv. A simulated runner reads requests through this, so the argv layout has one owner.
|
|
3503
|
+
*/
|
|
3504
|
+
export declare function parseOsascriptArgs(args: readonly string[]): {
|
|
3505
|
+
readonly script: string;
|
|
3506
|
+
readonly argv: readonly string[];
|
|
3507
|
+
} | undefined;
|
|
3508
|
+
|
|
3283
3509
|
export declare function parseUriConnectionSelector(input: string): UriConnectionSelectorParse;
|
|
3284
3510
|
|
|
3285
3511
|
/** Parse either dialect into the normalized replacement list. */
|
|
@@ -3422,6 +3648,10 @@ declare const PluginCapabilityRefusalV1: z.ZodObject<{
|
|
|
3422
3648
|
target: z.ZodLiteral<"kay.app">;
|
|
3423
3649
|
slug: z.ZodLiteral<"skills.read">;
|
|
3424
3650
|
envelope: z.ZodObject<{}, z.core.$strict>;
|
|
3651
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
3652
|
+
target: z.ZodLiteral<"kay.app">;
|
|
3653
|
+
slug: z.ZodLiteral<"tools.describe">;
|
|
3654
|
+
envelope: z.ZodObject<{}, z.core.$strict>;
|
|
3425
3655
|
}, z.core.$strict>, z.ZodObject<{
|
|
3426
3656
|
target: z.ZodLiteral<"kay.app">;
|
|
3427
3657
|
slug: z.ZodLiteral<"workspace.command">;
|
|
@@ -3884,6 +4114,9 @@ declare interface RawResourceMetadata {
|
|
|
3884
4114
|
*/
|
|
3885
4115
|
export declare function readBodyWithByteCap(response: Response, maxBytes: number): Promise<ByteCapReadResult | undefined>;
|
|
3886
4116
|
|
|
4117
|
+
/** Read a script's stdout. Never throws: anything but a well-formed envelope is `invalid`. */
|
|
4118
|
+
export declare function readOsascriptOutput(stdout: string): OsascriptOutput;
|
|
4119
|
+
|
|
3887
4120
|
/**
|
|
3888
4121
|
* The capability⇄service auth binding. A registration carrying this is gated on `serviceId`'s
|
|
3889
4122
|
* connectivity; the runtime answers "is this capability authorized?" from this plus vault state.
|
|
@@ -3998,6 +4231,28 @@ declare interface ResolveTokenSuccess {
|
|
|
3998
4231
|
readonly auth: ResolvedAuth;
|
|
3999
4232
|
}
|
|
4000
4233
|
|
|
4234
|
+
/**
|
|
4235
|
+
* Pure, provider-neutral classification of a failed model run.
|
|
4236
|
+
*
|
|
4237
|
+
* This is a leaf module with no runtime imports, because two callers that
|
|
4238
|
+
* cannot share a bundle must reach the same verdict: the kernel failure path
|
|
4239
|
+
* (`run-error.ts`, which reaches Pi and Node) and the browser-safe interactive
|
|
4240
|
+
* reducer that projects an errored message for a surface to render. Routing the
|
|
4241
|
+
* reducer through `run-error.ts` would drag `pi-agent-core` into the renderer
|
|
4242
|
+
* bundle; duplicating the rules there would let the reason a run was *retried
|
|
4243
|
+
* for* drift from the reason a user is *told about*.
|
|
4244
|
+
*
|
|
4245
|
+
* The leaf rule is why {@link readableFailureText} carries its own small HTML
|
|
4246
|
+
* extractor instead of reaching for `core/web/markdown.ts`. That module imports
|
|
4247
|
+
* `@herd/plugin-primitives`, and the browser-safety guard externalizes bare
|
|
4248
|
+
* specifiers, so it could not prove the import stays renderer-safe. It is also
|
|
4249
|
+
* the wrong tool: it emits markdown into what must remain a plain diagnostic,
|
|
4250
|
+
* and it discards `<head>`, where a gateway page puts the one line naming the
|
|
4251
|
+
* failure.
|
|
4252
|
+
*/
|
|
4253
|
+
/** Provider-neutral factual category for a failed model run. */
|
|
4254
|
+
declare type RunFailureReason = "auth" | "content_blocked" | "context_overflow" | "invalid_request" | "model_unavailable" | "network" | "overloaded" | "quota_exhausted" | "rate_limit" | "safeguard_block" | "seat_unpaid" | "server_error" | "stream_interrupted" | "timeout" | "unknown";
|
|
4255
|
+
|
|
4001
4256
|
export declare type SchemaInput = z.ZodType | JsonSchema;
|
|
4002
4257
|
|
|
4003
4258
|
/** One all-of arm in an ordered scope requirement. */
|
|
@@ -4939,6 +5194,12 @@ declare interface UriHelp {
|
|
|
4939
5194
|
readonly templates?: readonly UriTemplate[];
|
|
4940
5195
|
readonly examples?: readonly UriExample[];
|
|
4941
5196
|
readonly notes?: readonly string[];
|
|
5197
|
+
/**
|
|
5198
|
+
* Set when this help, for the address it was asked about, carries text a third party wrote and
|
|
5199
|
+
* the module relays as it received it (an MCP server's own tool names and descriptions), rather
|
|
5200
|
+
* than text the module's author wrote. Absent: the module's own text.
|
|
5201
|
+
*/
|
|
5202
|
+
readonly thirdPartyContent?: true;
|
|
4942
5203
|
}
|
|
4943
5204
|
|
|
4944
5205
|
declare interface UriHintTriggers {
|
|
@@ -5797,7 +6058,7 @@ declare interface UriValidationMessage {
|
|
|
5797
6058
|
* applies label changes"), never wire mechanics or URI shapes. Verbs the
|
|
5798
6059
|
* module does not support are omitted; at runtime a supported verb with no
|
|
5799
6060
|
* entry simply renders undocumented (fail-open metadata) — but for a plugin's
|
|
5800
|
-
* `kay.agent` URI modules, `auditPluginDisclosure` (`@
|
|
6061
|
+
* `kay.agent` URI modules, `auditPluginDisclosure` (`@bonsai/plugin-sdk/
|
|
5801
6062
|
* disclosure`) enforces coverage of every supported verb at authoring/load
|
|
5802
6063
|
* time.
|
|
5803
6064
|
*
|
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
|
};
|