@ryuhq/sdk 0.0.5 → 0.1.2
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/dist/agent.cjs +4 -1
- package/dist/agent.d.cts +1 -1
- package/dist/agent.d.ts +1 -1
- package/dist/agent.js +1 -1
- package/dist/{chunk-KPKMMGVC.js → chunk-MTUBUPIV.js} +4 -1
- package/dist/{chunk-GXHL5CO7.js → chunk-XTUK5I6I.js} +110 -2
- package/dist/cli.cjs +163 -10
- package/dist/cli.js +56 -9
- package/dist/{index-DAxq7Y0R.d.ts → index-B6SkaAjJ.d.ts} +4 -4
- package/dist/{index-CEbS1SlS.d.cts → index-BvAB5eMk.d.cts} +4 -4
- package/dist/index.cjs +167 -9
- package/dist/index.d.cts +30 -12
- package/dist/index.d.ts +30 -12
- package/dist/index.js +57 -8
- package/dist/manifest.cjs +112 -2
- package/dist/manifest.d.cts +131 -10
- package/dist/manifest.d.ts +131 -10
- package/dist/manifest.js +5 -1
- package/package.json +4 -4
- package/src/builder.ts +4 -4
- package/src/cli.ts +98 -13
- package/src/contracts-lockstep.test.ts +4 -4
- package/src/generated/plugin-manifest.ts +1284 -24
- package/src/manifest-schema.test.ts +182 -0
- package/src/manifest.fixtures.test.ts +447 -0
- package/src/manifest.test.ts +100 -16
- package/src/manifest.ts +189 -17
- package/src/plugin/ryu-plugin.ts +1 -1
- package/src/runnable/agent.ts +3 -3
- package/src/runnable/app.test.ts +67 -0
- package/src/runnable/app.ts +58 -4
- package/src/runnable/primitives.test.ts +1 -5
- package/src/runnable/primitives.ts +6 -5
- package/src/runnable/tool.ts +4 -4
- package/src/runnable/turn-hook.ts +33 -4
package/dist/index.cjs
CHANGED
|
@@ -194,7 +194,10 @@ function dataUrlToBytes(dataUrl) {
|
|
|
194
194
|
}
|
|
195
195
|
return { bytes, mediaType };
|
|
196
196
|
}
|
|
197
|
-
return {
|
|
197
|
+
return {
|
|
198
|
+
bytes: new TextEncoder().encode(decodeURIComponent(payload)),
|
|
199
|
+
mediaType
|
|
200
|
+
};
|
|
198
201
|
}
|
|
199
202
|
function bytesToDataUrl(bytes, mediaType) {
|
|
200
203
|
let binary = "";
|
|
@@ -903,7 +906,47 @@ var TurnHookContributionSchema = import_zod.z.object({
|
|
|
903
906
|
/** Turn boundary this fires on. Today only `"post_assistant_turn"`. */
|
|
904
907
|
on: import_zod.z.string().min(1).default("post_assistant_turn"),
|
|
905
908
|
/** The JS hook body executed in the sandbox (returns a directive). */
|
|
906
|
-
code: import_zod.z.string().min(1)
|
|
909
|
+
code: import_zod.z.string().min(1).optional(),
|
|
910
|
+
/** Path to the hook body, relative to the plugin root (`hooks/<name>.js`). */
|
|
911
|
+
code_file: import_zod.z.string().min(1).optional(),
|
|
912
|
+
/**
|
|
913
|
+
* Cheap pre-gate mirroring Core's `HookMatch` (serde name `match` on
|
|
914
|
+
* `TurnHookContribution.run_when`). MUST round-trip through this schema:
|
|
915
|
+
* `ryu pack`/`publish` persist `safeParse(...).data`, so a field missing here
|
|
916
|
+
* is silently STRIPPED before signing — a tool-gated `pre_tool_use` hook
|
|
917
|
+
* (e.g. `tools: ["bash*"]`) would lose its gate and run on EVERY tool call.
|
|
918
|
+
*/
|
|
919
|
+
match: import_zod.z.object({
|
|
920
|
+
/** Run only if the request set this composer flag true. */
|
|
921
|
+
flag: import_zod.z.string().optional(),
|
|
922
|
+
/** Run if the last user message starts with any of these prefixes. */
|
|
923
|
+
commands: import_zod.z.array(import_zod.z.string()).default([]),
|
|
924
|
+
/** Run if the plugin has stored state for this conversation. */
|
|
925
|
+
stateful: import_zod.z.boolean().default(false),
|
|
926
|
+
/** Run if `ctx.tool_name` matches any of these `*`-wildcard patterns. */
|
|
927
|
+
tools: import_zod.z.array(import_zod.z.string()).default([])
|
|
928
|
+
}).optional()
|
|
929
|
+
}).refine((h) => Boolean(h.code) !== Boolean(h.code_file), {
|
|
930
|
+
message: "a turn hook must declare exactly one of 'code' (inline body) or 'code_file' (path to hooks/<name>.js)",
|
|
931
|
+
path: ["code_file"]
|
|
932
|
+
});
|
|
933
|
+
var HookEventContributionSchema = import_zod.z.object({
|
|
934
|
+
/** Fully-qualified event id: `<plugin id>#<event name>`, e.g. `@acme/meetings#meeting.ended`. */
|
|
935
|
+
id: import_zod.z.string().min(1),
|
|
936
|
+
/** Human-readable title for the event picker. */
|
|
937
|
+
title: import_zod.z.string().min(1),
|
|
938
|
+
/** What the event means and when it fires. */
|
|
939
|
+
description: import_zod.z.string().optional(),
|
|
940
|
+
/** Example of the `ctx.event` payload. Documentation, not a validated schema. */
|
|
941
|
+
payload_example: import_zod.z.record(import_zod.z.string(), import_zod.z.unknown()).optional()
|
|
942
|
+
});
|
|
943
|
+
var PiExtensionContributionSchema = import_zod.z.object({
|
|
944
|
+
/** Stable id for this extension within the plugin (`[a-z0-9][a-z0-9._-]*`). */
|
|
945
|
+
id: import_zod.z.string().min(1),
|
|
946
|
+
/** Path to the source, relative to the plugin root: `pi-extensions/<name>.ts`. */
|
|
947
|
+
file: import_zod.z.string().min(1),
|
|
948
|
+
/** Optional one-liner describing what the extension adds to the agent. */
|
|
949
|
+
description: import_zod.z.string().optional()
|
|
907
950
|
});
|
|
908
951
|
var DEFAULT_WIDGET_MIME = "text/html+skybridge";
|
|
909
952
|
var DEFAULT_WIDGET_DISPLAY_MODE = "inline";
|
|
@@ -941,6 +984,11 @@ var ToolAppConfigSchema = import_zod.z.object({
|
|
|
941
984
|
});
|
|
942
985
|
var ContributesSchema = import_zod.z.object({
|
|
943
986
|
turn_hooks: import_zod.z.array(TurnHookContributionSchema).default([]),
|
|
987
|
+
/** App events this plugin EMITS — the provider half of the hook system, whose
|
|
988
|
+
* consumer half is `turn_hooks`. Mirrors the Rust `Contributes.hook_events`;
|
|
989
|
+
* omitting it here would have `ryu pack` strip every declared event before
|
|
990
|
+
* signing, leaving an app that emits events nothing is allowed to subscribe to. */
|
|
991
|
+
hook_events: import_zod.z.array(HookEventContributionSchema).default([]),
|
|
944
992
|
composer_controls: import_zod.z.array(import_zod.z.record(import_zod.z.string(), import_zod.z.unknown())).default([]),
|
|
945
993
|
settings_tabs: import_zod.z.array(import_zod.z.record(import_zod.z.string(), import_zod.z.unknown())).default([]),
|
|
946
994
|
slash_commands: import_zod.z.array(import_zod.z.record(import_zod.z.string(), import_zod.z.unknown())).default([]),
|
|
@@ -948,7 +996,49 @@ var ContributesSchema = import_zod.z.object({
|
|
|
948
996
|
* `ui://widget/<slug>.html` template. Mirrors the Rust-side
|
|
949
997
|
* `Contributes.widgets` field, without which the CLI's zod parse would strip
|
|
950
998
|
* every widget an app authored here declares. */
|
|
951
|
-
widgets: import_zod.z.array(WidgetContributionSchema).default([])
|
|
999
|
+
widgets: import_zod.z.array(WidgetContributionSchema).default([]),
|
|
1000
|
+
/** App-registered sidebar sections (header + live list) and buttons (single nav
|
|
1001
|
+
* rows). Loosely typed here — the shell owns the spec vocabulary — matching how
|
|
1002
|
+
* `composer_controls`/`settings_tabs` are declared. Mirrors the Rust-side
|
|
1003
|
+
* `Contributes.sidebar_sections` / `Contributes.sidebar_buttons`. */
|
|
1004
|
+
sidebar_sections: import_zod.z.array(import_zod.z.record(import_zod.z.string(), import_zod.z.unknown())).default([]),
|
|
1005
|
+
sidebar_buttons: import_zod.z.array(import_zod.z.record(import_zod.z.string(), import_zod.z.unknown())).default([]),
|
|
1006
|
+
/** App-registered workspace dock panels (a tab in the desktop's bottom/right
|
|
1007
|
+
* dock). Loosely typed for the same reason as the surfaces above — the shell
|
|
1008
|
+
* owns the `panel` render-mode vocabulary and the `spec` payload. Mirrors the
|
|
1009
|
+
* Rust-side `Contributes.dock_panels`; without it the CLI's zod parse would
|
|
1010
|
+
* strip the dock panel an app declares here. */
|
|
1011
|
+
dock_panels: import_zod.z.array(import_zod.z.record(import_zod.z.string(), import_zod.z.unknown())).default([]),
|
|
1012
|
+
/** Deletable data categories the app owns — one "Delete all X" row in Settings
|
|
1013
|
+
* → Danger Zone. Mirrors the Rust-side `Contributes.data_categories`; without
|
|
1014
|
+
* it the CLI's zod parse would strip the declaration before signing, and the
|
|
1015
|
+
* app's danger-zone row would simply never appear on any node that installed
|
|
1016
|
+
* the packed bundle. Loosely typed here for the same reason as the surfaces
|
|
1017
|
+
* above — Core is the layer that types it, because Core is the layer that has
|
|
1018
|
+
* to resolve the id to something that can actually delete the rows. */
|
|
1019
|
+
data_categories: import_zod.z.array(import_zod.z.record(import_zod.z.string(), import_zod.z.unknown())).default([]),
|
|
1020
|
+
/** Language servers the plugin declares, keyed by server name — the mirror of
|
|
1021
|
+
* Claude Code's `.lsp.json` / `lspServers`, so a config written for either host
|
|
1022
|
+
* loads in the other. Mirrors the Rust-side `Contributes.lsp_servers`; without
|
|
1023
|
+
* it the CLI's zod parse would strip every language server a plugin declares,
|
|
1024
|
+
* before the manifest is signed.
|
|
1025
|
+
*
|
|
1026
|
+
* The ENTRY is deliberately a loose record and not a 13-field `z.object()`
|
|
1027
|
+
* mirroring `LspServerContribution`. Claude Code owns this field vocabulary,
|
|
1028
|
+
* not Ryu: a typed object here would strip a field from a newer Claude release
|
|
1029
|
+
* on its way through `ryu pack` — the same silent-deletion bug this field
|
|
1030
|
+
* exists to fix, one level down. Core is the layer that types it, because Core
|
|
1031
|
+
* is the layer that acts on it. */
|
|
1032
|
+
lsp_servers: import_zod.z.record(import_zod.z.string(), import_zod.z.record(import_zod.z.string(), import_zod.z.unknown())).default({}),
|
|
1033
|
+
/** Pi extensions the plugin ships — TypeScript the managed `ryu` (Pi) agent
|
|
1034
|
+
* loads at process start. Mirrors the Rust-side `Contributes.pi_extensions`;
|
|
1035
|
+
* without it the CLI's zod parse would strip the declaration before signing,
|
|
1036
|
+
* and the packed plugin would ship a `pi-extensions/` folder nothing loads.
|
|
1037
|
+
*
|
|
1038
|
+
* Typed (not a loose record) because Ryu owns this vocabulary — three fields,
|
|
1039
|
+
* all of them Core-interpreted — unlike `lsp_servers`, whose entry shape is
|
|
1040
|
+
* Claude Code's to extend. */
|
|
1041
|
+
pi_extensions: import_zod.z.array(PiExtensionContributionSchema).default([])
|
|
952
1042
|
});
|
|
953
1043
|
var SetupStepSchema = import_zod.z.object({
|
|
954
1044
|
/** Card heading (e.g. the companion app name). */
|
|
@@ -1129,6 +1219,25 @@ var PluginManifestSchema = import_zod.z.object({
|
|
|
1129
1219
|
license: import_zod.z.string().optional(),
|
|
1130
1220
|
/** Square logo/icon URL for the listing card + detail header. */
|
|
1131
1221
|
iconUrl: import_zod.z.string().optional(),
|
|
1222
|
+
/**
|
|
1223
|
+
* Icon-primitive id for the listing card (Ryu extension): an Iconify/icons0
|
|
1224
|
+
* `prefix:name`, a bare Hugeicons name, or a URL, resolved by the shared `Icon`
|
|
1225
|
+
* primitive. A monochrome GLYPH masked with the current text colour — distinct
|
|
1226
|
+
* from `iconUrl` (a raster logo). Falls back to `iconUrl` when omitted.
|
|
1227
|
+
*/
|
|
1228
|
+
icon: import_zod.z.string().optional(),
|
|
1229
|
+
/**
|
|
1230
|
+
* Dithered-gradient background for the card's icon square (Ryu extension),
|
|
1231
|
+
* mirroring dither-kit's `DitherGradient` props. `from`/`to` are a palette-colour
|
|
1232
|
+
* name (`green`, `blue`, `purple`, `pink`, `orange`, `red`, `grey`) or a hue
|
|
1233
|
+
* number (0–360); `direction` is where `to` ends up. Renders behind the glyph in
|
|
1234
|
+
* place of a flat `iconBackground`; the render layer validates + falls back.
|
|
1235
|
+
*/
|
|
1236
|
+
iconDither: import_zod.z.object({
|
|
1237
|
+
from: import_zod.z.union([import_zod.z.string(), import_zod.z.number()]),
|
|
1238
|
+
to: import_zod.z.union([import_zod.z.string(), import_zod.z.number()]).optional(),
|
|
1239
|
+
direction: import_zod.z.enum(["up", "down", "left", "right"]).optional()
|
|
1240
|
+
}).optional(),
|
|
1132
1241
|
/** Ordered App-Store-style screenshot gallery URLs (Ryu extension). */
|
|
1133
1242
|
screenshots: import_zod.z.array(import_zod.z.string()).optional(),
|
|
1134
1243
|
/** Privacy policy URL surfaced on detail (Ryu extension). */
|
|
@@ -1162,6 +1271,14 @@ function coreManifestJsonSchema() {
|
|
|
1162
1271
|
// src/runnable/app.ts
|
|
1163
1272
|
var DEFAULT_APP_WIDGET_MIME = "text/html+skybridge";
|
|
1164
1273
|
var DEFAULT_APP_DISPLAY_MODE = "inline";
|
|
1274
|
+
var WIDGET_RENDER_GRANT = "widget:render";
|
|
1275
|
+
function withWidgetRenderGrant(grants, widgets) {
|
|
1276
|
+
const out = [...grants];
|
|
1277
|
+
if (widgets.length > 0 && !out.includes(WIDGET_RENDER_GRANT)) {
|
|
1278
|
+
out.push(WIDGET_RENDER_GRANT);
|
|
1279
|
+
}
|
|
1280
|
+
return out;
|
|
1281
|
+
}
|
|
1165
1282
|
function appToolId(server, name) {
|
|
1166
1283
|
return `${server}__${name}`;
|
|
1167
1284
|
}
|
|
@@ -1203,9 +1320,25 @@ function defineApp(options) {
|
|
|
1203
1320
|
}
|
|
1204
1321
|
const contributes = {
|
|
1205
1322
|
turn_hooks: [],
|
|
1323
|
+
// This builder synthesises an app from its runnables; an app that emits
|
|
1324
|
+
// events declares them in a hand-authored `manifest.json`, same as
|
|
1325
|
+
// `lsp_servers` below.
|
|
1326
|
+
hook_events: [],
|
|
1206
1327
|
composer_controls: [],
|
|
1207
1328
|
settings_tabs: [],
|
|
1208
1329
|
slash_commands: [],
|
|
1330
|
+
sidebar_sections: [],
|
|
1331
|
+
sidebar_buttons: [],
|
|
1332
|
+
dock_panels: [],
|
|
1333
|
+
// Empty for the same reason as every sibling family above: this builder
|
|
1334
|
+
// synthesises `widgets` from the app's own runnables and nothing else, and
|
|
1335
|
+
// takes no `contributes` passthrough. An app that wants to declare language
|
|
1336
|
+
// servers writes them in a hand-authored `manifest.json`.
|
|
1337
|
+
lsp_servers: {},
|
|
1338
|
+
// Same reason again: a danger-zone category and a Pi extension are both
|
|
1339
|
+
// hand-authored declarations, not something derivable from runnables.
|
|
1340
|
+
data_categories: [],
|
|
1341
|
+
pi_extensions: [],
|
|
1209
1342
|
widgets
|
|
1210
1343
|
};
|
|
1211
1344
|
const raw = {
|
|
@@ -1213,7 +1346,21 @@ function defineApp(options) {
|
|
|
1213
1346
|
name: options.title,
|
|
1214
1347
|
version: options.version,
|
|
1215
1348
|
runnables,
|
|
1216
|
-
|
|
1349
|
+
// An app that synthesises widgets MUST hold `widget:render`, so this
|
|
1350
|
+
// builder declares it rather than leaving the author to discover it.
|
|
1351
|
+
//
|
|
1352
|
+
// Core gates widget promotion on declared-AND-enabled-AND-granted, and a
|
|
1353
|
+
// missing grant fails as `DeniedNoGrant` — which is an `info!` log and
|
|
1354
|
+
// nothing else. The widget silently renders as plain text, with no error
|
|
1355
|
+
// in the UI and nothing pointing at the manifest. Every app scaffolded
|
|
1356
|
+
// through `defineApp` hit that, because the only fix was a grant string
|
|
1357
|
+
// the templates never mention and the builder never added; the one
|
|
1358
|
+
// working example on disk hand-writes it.
|
|
1359
|
+
//
|
|
1360
|
+
// Added only when there is a widget to render, and unioned rather than
|
|
1361
|
+
// overwritten so an author's own `grants` list survives and re-declaring
|
|
1362
|
+
// it is not an error.
|
|
1363
|
+
permission_grants: withWidgetRenderGrant(options.grants ?? [], widgets),
|
|
1217
1364
|
activation_events: options.activationEvents ?? ["*"],
|
|
1218
1365
|
contributes,
|
|
1219
1366
|
// `targets: []` means EVERY surface, so an app that declares none is
|
|
@@ -1235,7 +1382,9 @@ function defineApp(options) {
|
|
|
1235
1382
|
const first = result.error.issues[0];
|
|
1236
1383
|
const field = first?.path.join(".") ?? "unknown";
|
|
1237
1384
|
const message = first?.message ?? "validation failed";
|
|
1238
|
-
throw new Error(
|
|
1385
|
+
throw new Error(
|
|
1386
|
+
`manifest.json validation failed at '${field}': ${message}`
|
|
1387
|
+
);
|
|
1239
1388
|
}
|
|
1240
1389
|
return result.data;
|
|
1241
1390
|
}
|
|
@@ -1431,7 +1580,7 @@ var PluginBuilder = class {
|
|
|
1431
1580
|
const field = first?.path.join(".") ?? "unknown";
|
|
1432
1581
|
const message = first?.message ?? "validation failed";
|
|
1433
1582
|
throw new Error(
|
|
1434
|
-
`
|
|
1583
|
+
`manifest.json validation failed at '${field}': ${message}`
|
|
1435
1584
|
);
|
|
1436
1585
|
}
|
|
1437
1586
|
return result.data;
|
|
@@ -1804,12 +1953,21 @@ function defineTurnHook(options) {
|
|
|
1804
1953
|
function definePlugin(options) {
|
|
1805
1954
|
const contributes = {
|
|
1806
1955
|
turn_hooks: options.turnHooks ?? [],
|
|
1956
|
+
hook_events: options.hookEvents ?? [],
|
|
1807
1957
|
composer_controls: options.composerControls ?? [],
|
|
1808
1958
|
settings_tabs: options.settingsTabs ?? [],
|
|
1809
1959
|
slash_commands: options.slashCommands ?? [],
|
|
1810
|
-
|
|
1811
|
-
//
|
|
1812
|
-
|
|
1960
|
+
lsp_servers: options.lspServers ?? {},
|
|
1961
|
+
// A turn-hook plugin contributes no app widgets, sidebar entries, dock
|
|
1962
|
+
// panels, danger-zone categories or Pi extensions; the fields are required
|
|
1963
|
+
// on the resolved `Contributes` type (zod defaults applied), so set them
|
|
1964
|
+
// explicitly.
|
|
1965
|
+
widgets: [],
|
|
1966
|
+
sidebar_sections: [],
|
|
1967
|
+
sidebar_buttons: [],
|
|
1968
|
+
dock_panels: [],
|
|
1969
|
+
data_categories: [],
|
|
1970
|
+
pi_extensions: []
|
|
1813
1971
|
};
|
|
1814
1972
|
const tools = options.tools ?? [];
|
|
1815
1973
|
const runnables = tools.map((t) => inlineToolRunnable(t));
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { R as Runnable, a as RunnableContext, T as ToolRunnable } from './index-
|
|
2
|
-
export { A as Agent, b as AgentConfig, c as AgentEvent, d as AgentTool, C as ChatDelta, e as ChatMessage, f as ChatResult, D as DurableClient, E as Endpoint, g as EnginesClient, G as GatewayClient, h as GenerateResult, H as HttpPrimitiveTransportOptions, I as ImageClient, J as JsonSchemaProperty, M as MemoryClient, i as MemoryItem, j as ModelClient, k as ModelClientOptions, P as PRIMITIVE_BINDINGS, l as PrimitiveBinding, m as PrimitiveTransport, Q as QueryInput, n as QueryOptions, o as RagChunk, p as RagClient, q as RagRerankResult, r as RealtimeClient, s as RealtimeSubscription, t as RemoteToolRef, u as RyuPrimitives, S as SttClient, v as ToolOptions, w as ToolSchema, x as TtsClient, y as createAgent, z as createPrimitives, B as defineModel, F as defineTool, K as httpPrimitiveTransport, L as inlineToolRunnable, N as query, O as ryuTool } from './index-
|
|
3
|
-
import { Requires, Surface, PluginManifest, RunnableMeta, CompanionSurface, CapabilityReq, TurnHookContribution } from './manifest.cjs';
|
|
1
|
+
import { R as Runnable, a as RunnableContext, T as ToolRunnable } from './index-BvAB5eMk.cjs';
|
|
2
|
+
export { A as Agent, b as AgentConfig, c as AgentEvent, d as AgentTool, C as ChatDelta, e as ChatMessage, f as ChatResult, D as DurableClient, E as Endpoint, g as EnginesClient, G as GatewayClient, h as GenerateResult, H as HttpPrimitiveTransportOptions, I as ImageClient, J as JsonSchemaProperty, M as MemoryClient, i as MemoryItem, j as ModelClient, k as ModelClientOptions, P as PRIMITIVE_BINDINGS, l as PrimitiveBinding, m as PrimitiveTransport, Q as QueryInput, n as QueryOptions, o as RagChunk, p as RagClient, q as RagRerankResult, r as RealtimeClient, s as RealtimeSubscription, t as RemoteToolRef, u as RyuPrimitives, S as SttClient, v as ToolOptions, w as ToolSchema, x as TtsClient, y as createAgent, z as createPrimitives, B as defineModel, F as defineTool, K as httpPrimitiveTransport, L as inlineToolRunnable, N as query, O as ryuTool } from './index-BvAB5eMk.cjs';
|
|
3
|
+
import { Requires, Surface, PluginManifest, RunnableMeta, CompanionSurface, CapabilityReq, HookEventContribution, TurnHookContribution } from './manifest.cjs';
|
|
4
4
|
export { AppDependency, AppDependencySchema, CapabilityReqSchema, CompanionSurfaceSchema, Contributes, PluginManifestSchema, RequiresSchema, RunnableKind, RunnableKindSchema, RunnableMetaSchema, SurfaceSchema, ToolAppConfig, ToolAppConfigSchema, WidgetContribution, WidgetContributionSchema, coreManifestJsonSchema, validateManifestStrict, validatePluginId } from './manifest.cjs';
|
|
5
5
|
import 'zod';
|
|
6
6
|
|
|
@@ -9,7 +9,7 @@ import 'zod';
|
|
|
9
9
|
*
|
|
10
10
|
* A "Ryu App" bundles one or more tools whose results render an interactive
|
|
11
11
|
* widget inline in chat (the ChatGPT-Apps-style surface). `defineApp` assembles a
|
|
12
|
-
* complete `
|
|
12
|
+
* complete `manifest.json` `PluginManifest` from a declarative description, deriving
|
|
13
13
|
* the render-vs-companion split exactly the way Core's in-process provider does
|
|
14
14
|
* (`apps/core/src/sidecar/mcp/apps/mod.rs` `tools()`):
|
|
15
15
|
*
|
|
@@ -107,7 +107,7 @@ interface DefineAppOptions {
|
|
|
107
107
|
/** Build a fully-qualified tool id from a server namespace and tool name. */
|
|
108
108
|
declare function appToolId(server: string, name: string): string;
|
|
109
109
|
/**
|
|
110
|
-
* Assemble a `
|
|
110
|
+
* Assemble a `manifest.json` manifest for a Ryu App. The result matches Core's
|
|
111
111
|
* `PluginManifest` serde shape (validated through `PluginManifestSchema`) and can
|
|
112
112
|
* be written to disk, packed with `ryu pack`, or published with `ryu publish`.
|
|
113
113
|
*
|
|
@@ -132,7 +132,7 @@ declare function defineApp(options: DefineAppOptions): PluginManifest;
|
|
|
132
132
|
|
|
133
133
|
/**
|
|
134
134
|
* Ryu SDK typed builders — one builder per RunnableKind plus a PluginBuilder that
|
|
135
|
-
* assembles a complete, validated `
|
|
135
|
+
* assembles a complete, validated `manifest.json` manifest.
|
|
136
136
|
*
|
|
137
137
|
* Each builder follows a fluent interface: construct, chain setter calls, then
|
|
138
138
|
* call `.build()` to get a validated result. Invalid manifests throw a
|
|
@@ -174,7 +174,7 @@ declare const tool: () => ToolBuilder;
|
|
|
174
174
|
/** Create a SkillBuilder. */
|
|
175
175
|
declare const skill: () => SkillBuilder;
|
|
176
176
|
/**
|
|
177
|
-
* Fluent builder for a complete `
|
|
177
|
+
* Fluent builder for a complete `manifest.json` Plugin manifest. Produces a
|
|
178
178
|
* validated `PluginManifest` on `.build()` or throws a descriptive `Error`
|
|
179
179
|
* naming the first invalid field.
|
|
180
180
|
*
|
|
@@ -252,7 +252,7 @@ declare class PluginBuilder {
|
|
|
252
252
|
build(): PluginManifest;
|
|
253
253
|
}
|
|
254
254
|
/**
|
|
255
|
-
* Fluent builder for a Ryu App — a `
|
|
255
|
+
* Fluent builder for a Ryu App — a `manifest.json` whose tools render interactive
|
|
256
256
|
* widgets inline in chat. Delegates to {@link defineApp} on `.build()`, so it
|
|
257
257
|
* derives the render-vs-companion split and validates through
|
|
258
258
|
* `PluginManifestSchema` (throwing a descriptive `Error` on bad input) exactly
|
|
@@ -470,7 +470,7 @@ interface AgentRunnable<TInput = unknown, TOutput = unknown> extends Runnable<TI
|
|
|
470
470
|
/** The lowered slot card (empty edges when no slots were declared). */
|
|
471
471
|
readonly card: AgentCard;
|
|
472
472
|
/**
|
|
473
|
-
* Lower this agent (card + run identity) to a single-agent `
|
|
473
|
+
* Lower this agent (card + run identity) to a single-agent `manifest.json`
|
|
474
474
|
* `PluginManifest`: the agent `RunnableMeta` carries the persona/model
|
|
475
475
|
* config; `requires.capabilities` carries the slot edges. Throws if the
|
|
476
476
|
* assembled manifest is invalid.
|
|
@@ -493,7 +493,7 @@ interface AgentManifestOptions {
|
|
|
493
493
|
*
|
|
494
494
|
* The returned value satisfies `Runnable<TInput, TOutput>` with `kind = "agent"`
|
|
495
495
|
* and additionally exposes the lowered {@link AgentCard} + a `toManifest()`
|
|
496
|
-
* lowering, so a slot-composed agent round-trips to a valid `
|
|
496
|
+
* lowering, so a slot-composed agent round-trips to a valid `manifest.json`.
|
|
497
497
|
*
|
|
498
498
|
* @example Classic (unchanged, back-compat):
|
|
499
499
|
* ```ts
|
|
@@ -651,7 +651,9 @@ interface DefineTurnHookOptions {
|
|
|
651
651
|
* is serialized into the sandbox `code` string and invoked with `ctx`/`host` at
|
|
652
652
|
* run time.
|
|
653
653
|
*/
|
|
654
|
-
declare function defineTurnHook(options: DefineTurnHookOptions): TurnHookContribution
|
|
654
|
+
declare function defineTurnHook(options: DefineTurnHookOptions): TurnHookContribution & {
|
|
655
|
+
code: string;
|
|
656
|
+
};
|
|
655
657
|
interface DefinePluginOptions {
|
|
656
658
|
/** Activation events (default `["*"]` — driven by the enabled flag). */
|
|
657
659
|
activationEvents?: string[];
|
|
@@ -659,8 +661,24 @@ interface DefinePluginOptions {
|
|
|
659
661
|
composerControls?: Record<string, unknown>[];
|
|
660
662
|
/** Capability grants the hooks need (e.g. `["hook:side-model", "storage:kv"]`). */
|
|
661
663
|
grants?: string[];
|
|
664
|
+
/**
|
|
665
|
+
* App events this plugin EMITS — the provider half of the hook system whose
|
|
666
|
+
* consumer half is {@link DefinePluginOptions.turnHooks}. Each `id` must be
|
|
667
|
+
* namespaced to this plugin's own `id`; Core validates that at load and again
|
|
668
|
+
* on every emit.
|
|
669
|
+
*/
|
|
670
|
+
hookEvents?: HookEventContribution[];
|
|
662
671
|
/** Reverse-domain id (e.g. `"com.example.my-plugin"`). */
|
|
663
672
|
id: string;
|
|
673
|
+
/**
|
|
674
|
+
* Language servers the plugin declares, keyed by server name — the same shape
|
|
675
|
+
* as Claude Code's `lspServers` / `.lsp.json`, passed verbatim. Loose records
|
|
676
|
+
* rather than a typed entry on purpose: Claude Code owns this field
|
|
677
|
+
* vocabulary, so typing it here would strip a field from a newer Claude
|
|
678
|
+
* release on its way through `ryu pack`. Core types it, because Core acts on
|
|
679
|
+
* it.
|
|
680
|
+
*/
|
|
681
|
+
lspServers?: Record<string, Record<string, unknown>>;
|
|
664
682
|
/** Display name. */
|
|
665
683
|
name: string;
|
|
666
684
|
/**
|
|
@@ -690,7 +708,7 @@ interface DefinePluginOptions {
|
|
|
690
708
|
version: string;
|
|
691
709
|
}
|
|
692
710
|
/**
|
|
693
|
-
* Assemble a `
|
|
711
|
+
* Assemble a `manifest.json` manifest for a turn-hook plugin. The result matches
|
|
694
712
|
* Core's `PluginManifest` serde shape and can be written to disk or validated via
|
|
695
713
|
* `validateManifestStrict`.
|
|
696
714
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { R as Runnable, a as RunnableContext, T as ToolRunnable } from './index-
|
|
2
|
-
export { A as Agent, b as AgentConfig, c as AgentEvent, d as AgentTool, C as ChatDelta, e as ChatMessage, f as ChatResult, D as DurableClient, E as Endpoint, g as EnginesClient, G as GatewayClient, h as GenerateResult, H as HttpPrimitiveTransportOptions, I as ImageClient, J as JsonSchemaProperty, M as MemoryClient, i as MemoryItem, j as ModelClient, k as ModelClientOptions, P as PRIMITIVE_BINDINGS, l as PrimitiveBinding, m as PrimitiveTransport, Q as QueryInput, n as QueryOptions, o as RagChunk, p as RagClient, q as RagRerankResult, r as RealtimeClient, s as RealtimeSubscription, t as RemoteToolRef, u as RyuPrimitives, S as SttClient, v as ToolOptions, w as ToolSchema, x as TtsClient, y as createAgent, z as createPrimitives, B as defineModel, F as defineTool, K as httpPrimitiveTransport, L as inlineToolRunnable, N as query, O as ryuTool } from './index-
|
|
3
|
-
import { Requires, Surface, PluginManifest, RunnableMeta, CompanionSurface, CapabilityReq, TurnHookContribution } from './manifest.js';
|
|
1
|
+
import { R as Runnable, a as RunnableContext, T as ToolRunnable } from './index-B6SkaAjJ.js';
|
|
2
|
+
export { A as Agent, b as AgentConfig, c as AgentEvent, d as AgentTool, C as ChatDelta, e as ChatMessage, f as ChatResult, D as DurableClient, E as Endpoint, g as EnginesClient, G as GatewayClient, h as GenerateResult, H as HttpPrimitiveTransportOptions, I as ImageClient, J as JsonSchemaProperty, M as MemoryClient, i as MemoryItem, j as ModelClient, k as ModelClientOptions, P as PRIMITIVE_BINDINGS, l as PrimitiveBinding, m as PrimitiveTransport, Q as QueryInput, n as QueryOptions, o as RagChunk, p as RagClient, q as RagRerankResult, r as RealtimeClient, s as RealtimeSubscription, t as RemoteToolRef, u as RyuPrimitives, S as SttClient, v as ToolOptions, w as ToolSchema, x as TtsClient, y as createAgent, z as createPrimitives, B as defineModel, F as defineTool, K as httpPrimitiveTransport, L as inlineToolRunnable, N as query, O as ryuTool } from './index-B6SkaAjJ.js';
|
|
3
|
+
import { Requires, Surface, PluginManifest, RunnableMeta, CompanionSurface, CapabilityReq, HookEventContribution, TurnHookContribution } from './manifest.js';
|
|
4
4
|
export { AppDependency, AppDependencySchema, CapabilityReqSchema, CompanionSurfaceSchema, Contributes, PluginManifestSchema, RequiresSchema, RunnableKind, RunnableKindSchema, RunnableMetaSchema, SurfaceSchema, ToolAppConfig, ToolAppConfigSchema, WidgetContribution, WidgetContributionSchema, coreManifestJsonSchema, validateManifestStrict, validatePluginId } from './manifest.js';
|
|
5
5
|
import 'zod';
|
|
6
6
|
|
|
@@ -9,7 +9,7 @@ import 'zod';
|
|
|
9
9
|
*
|
|
10
10
|
* A "Ryu App" bundles one or more tools whose results render an interactive
|
|
11
11
|
* widget inline in chat (the ChatGPT-Apps-style surface). `defineApp` assembles a
|
|
12
|
-
* complete `
|
|
12
|
+
* complete `manifest.json` `PluginManifest` from a declarative description, deriving
|
|
13
13
|
* the render-vs-companion split exactly the way Core's in-process provider does
|
|
14
14
|
* (`apps/core/src/sidecar/mcp/apps/mod.rs` `tools()`):
|
|
15
15
|
*
|
|
@@ -107,7 +107,7 @@ interface DefineAppOptions {
|
|
|
107
107
|
/** Build a fully-qualified tool id from a server namespace and tool name. */
|
|
108
108
|
declare function appToolId(server: string, name: string): string;
|
|
109
109
|
/**
|
|
110
|
-
* Assemble a `
|
|
110
|
+
* Assemble a `manifest.json` manifest for a Ryu App. The result matches Core's
|
|
111
111
|
* `PluginManifest` serde shape (validated through `PluginManifestSchema`) and can
|
|
112
112
|
* be written to disk, packed with `ryu pack`, or published with `ryu publish`.
|
|
113
113
|
*
|
|
@@ -132,7 +132,7 @@ declare function defineApp(options: DefineAppOptions): PluginManifest;
|
|
|
132
132
|
|
|
133
133
|
/**
|
|
134
134
|
* Ryu SDK typed builders — one builder per RunnableKind plus a PluginBuilder that
|
|
135
|
-
* assembles a complete, validated `
|
|
135
|
+
* assembles a complete, validated `manifest.json` manifest.
|
|
136
136
|
*
|
|
137
137
|
* Each builder follows a fluent interface: construct, chain setter calls, then
|
|
138
138
|
* call `.build()` to get a validated result. Invalid manifests throw a
|
|
@@ -174,7 +174,7 @@ declare const tool: () => ToolBuilder;
|
|
|
174
174
|
/** Create a SkillBuilder. */
|
|
175
175
|
declare const skill: () => SkillBuilder;
|
|
176
176
|
/**
|
|
177
|
-
* Fluent builder for a complete `
|
|
177
|
+
* Fluent builder for a complete `manifest.json` Plugin manifest. Produces a
|
|
178
178
|
* validated `PluginManifest` on `.build()` or throws a descriptive `Error`
|
|
179
179
|
* naming the first invalid field.
|
|
180
180
|
*
|
|
@@ -252,7 +252,7 @@ declare class PluginBuilder {
|
|
|
252
252
|
build(): PluginManifest;
|
|
253
253
|
}
|
|
254
254
|
/**
|
|
255
|
-
* Fluent builder for a Ryu App — a `
|
|
255
|
+
* Fluent builder for a Ryu App — a `manifest.json` whose tools render interactive
|
|
256
256
|
* widgets inline in chat. Delegates to {@link defineApp} on `.build()`, so it
|
|
257
257
|
* derives the render-vs-companion split and validates through
|
|
258
258
|
* `PluginManifestSchema` (throwing a descriptive `Error` on bad input) exactly
|
|
@@ -470,7 +470,7 @@ interface AgentRunnable<TInput = unknown, TOutput = unknown> extends Runnable<TI
|
|
|
470
470
|
/** The lowered slot card (empty edges when no slots were declared). */
|
|
471
471
|
readonly card: AgentCard;
|
|
472
472
|
/**
|
|
473
|
-
* Lower this agent (card + run identity) to a single-agent `
|
|
473
|
+
* Lower this agent (card + run identity) to a single-agent `manifest.json`
|
|
474
474
|
* `PluginManifest`: the agent `RunnableMeta` carries the persona/model
|
|
475
475
|
* config; `requires.capabilities` carries the slot edges. Throws if the
|
|
476
476
|
* assembled manifest is invalid.
|
|
@@ -493,7 +493,7 @@ interface AgentManifestOptions {
|
|
|
493
493
|
*
|
|
494
494
|
* The returned value satisfies `Runnable<TInput, TOutput>` with `kind = "agent"`
|
|
495
495
|
* and additionally exposes the lowered {@link AgentCard} + a `toManifest()`
|
|
496
|
-
* lowering, so a slot-composed agent round-trips to a valid `
|
|
496
|
+
* lowering, so a slot-composed agent round-trips to a valid `manifest.json`.
|
|
497
497
|
*
|
|
498
498
|
* @example Classic (unchanged, back-compat):
|
|
499
499
|
* ```ts
|
|
@@ -651,7 +651,9 @@ interface DefineTurnHookOptions {
|
|
|
651
651
|
* is serialized into the sandbox `code` string and invoked with `ctx`/`host` at
|
|
652
652
|
* run time.
|
|
653
653
|
*/
|
|
654
|
-
declare function defineTurnHook(options: DefineTurnHookOptions): TurnHookContribution
|
|
654
|
+
declare function defineTurnHook(options: DefineTurnHookOptions): TurnHookContribution & {
|
|
655
|
+
code: string;
|
|
656
|
+
};
|
|
655
657
|
interface DefinePluginOptions {
|
|
656
658
|
/** Activation events (default `["*"]` — driven by the enabled flag). */
|
|
657
659
|
activationEvents?: string[];
|
|
@@ -659,8 +661,24 @@ interface DefinePluginOptions {
|
|
|
659
661
|
composerControls?: Record<string, unknown>[];
|
|
660
662
|
/** Capability grants the hooks need (e.g. `["hook:side-model", "storage:kv"]`). */
|
|
661
663
|
grants?: string[];
|
|
664
|
+
/**
|
|
665
|
+
* App events this plugin EMITS — the provider half of the hook system whose
|
|
666
|
+
* consumer half is {@link DefinePluginOptions.turnHooks}. Each `id` must be
|
|
667
|
+
* namespaced to this plugin's own `id`; Core validates that at load and again
|
|
668
|
+
* on every emit.
|
|
669
|
+
*/
|
|
670
|
+
hookEvents?: HookEventContribution[];
|
|
662
671
|
/** Reverse-domain id (e.g. `"com.example.my-plugin"`). */
|
|
663
672
|
id: string;
|
|
673
|
+
/**
|
|
674
|
+
* Language servers the plugin declares, keyed by server name — the same shape
|
|
675
|
+
* as Claude Code's `lspServers` / `.lsp.json`, passed verbatim. Loose records
|
|
676
|
+
* rather than a typed entry on purpose: Claude Code owns this field
|
|
677
|
+
* vocabulary, so typing it here would strip a field from a newer Claude
|
|
678
|
+
* release on its way through `ryu pack`. Core types it, because Core acts on
|
|
679
|
+
* it.
|
|
680
|
+
*/
|
|
681
|
+
lspServers?: Record<string, Record<string, unknown>>;
|
|
664
682
|
/** Display name. */
|
|
665
683
|
name: string;
|
|
666
684
|
/**
|
|
@@ -690,7 +708,7 @@ interface DefinePluginOptions {
|
|
|
690
708
|
version: string;
|
|
691
709
|
}
|
|
692
710
|
/**
|
|
693
|
-
* Assemble a `
|
|
711
|
+
* Assemble a `manifest.json` manifest for a turn-hook plugin. The result matches
|
|
694
712
|
* Core's `PluginManifest` serde shape and can be written to disk or validated via
|
|
695
713
|
* `validateManifestStrict`.
|
|
696
714
|
*/
|
package/dist/index.js
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
coreManifestJsonSchema,
|
|
13
13
|
validateManifestStrict,
|
|
14
14
|
validatePluginId
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-XTUK5I6I.js";
|
|
16
16
|
import {
|
|
17
17
|
Agent,
|
|
18
18
|
PRIMITIVE_BINDINGS,
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
httpPrimitiveTransport,
|
|
22
22
|
query,
|
|
23
23
|
ryuTool
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-MTUBUPIV.js";
|
|
25
25
|
import {
|
|
26
26
|
DEFAULT_GATEWAY_URL,
|
|
27
27
|
ModelClient,
|
|
@@ -34,6 +34,14 @@ import {
|
|
|
34
34
|
// src/runnable/app.ts
|
|
35
35
|
var DEFAULT_APP_WIDGET_MIME = "text/html+skybridge";
|
|
36
36
|
var DEFAULT_APP_DISPLAY_MODE = "inline";
|
|
37
|
+
var WIDGET_RENDER_GRANT = "widget:render";
|
|
38
|
+
function withWidgetRenderGrant(grants, widgets) {
|
|
39
|
+
const out = [...grants];
|
|
40
|
+
if (widgets.length > 0 && !out.includes(WIDGET_RENDER_GRANT)) {
|
|
41
|
+
out.push(WIDGET_RENDER_GRANT);
|
|
42
|
+
}
|
|
43
|
+
return out;
|
|
44
|
+
}
|
|
37
45
|
function appToolId(server, name) {
|
|
38
46
|
return `${server}__${name}`;
|
|
39
47
|
}
|
|
@@ -75,9 +83,25 @@ function defineApp(options) {
|
|
|
75
83
|
}
|
|
76
84
|
const contributes = {
|
|
77
85
|
turn_hooks: [],
|
|
86
|
+
// This builder synthesises an app from its runnables; an app that emits
|
|
87
|
+
// events declares them in a hand-authored `manifest.json`, same as
|
|
88
|
+
// `lsp_servers` below.
|
|
89
|
+
hook_events: [],
|
|
78
90
|
composer_controls: [],
|
|
79
91
|
settings_tabs: [],
|
|
80
92
|
slash_commands: [],
|
|
93
|
+
sidebar_sections: [],
|
|
94
|
+
sidebar_buttons: [],
|
|
95
|
+
dock_panels: [],
|
|
96
|
+
// Empty for the same reason as every sibling family above: this builder
|
|
97
|
+
// synthesises `widgets` from the app's own runnables and nothing else, and
|
|
98
|
+
// takes no `contributes` passthrough. An app that wants to declare language
|
|
99
|
+
// servers writes them in a hand-authored `manifest.json`.
|
|
100
|
+
lsp_servers: {},
|
|
101
|
+
// Same reason again: a danger-zone category and a Pi extension are both
|
|
102
|
+
// hand-authored declarations, not something derivable from runnables.
|
|
103
|
+
data_categories: [],
|
|
104
|
+
pi_extensions: [],
|
|
81
105
|
widgets
|
|
82
106
|
};
|
|
83
107
|
const raw = {
|
|
@@ -85,7 +109,21 @@ function defineApp(options) {
|
|
|
85
109
|
name: options.title,
|
|
86
110
|
version: options.version,
|
|
87
111
|
runnables,
|
|
88
|
-
|
|
112
|
+
// An app that synthesises widgets MUST hold `widget:render`, so this
|
|
113
|
+
// builder declares it rather than leaving the author to discover it.
|
|
114
|
+
//
|
|
115
|
+
// Core gates widget promotion on declared-AND-enabled-AND-granted, and a
|
|
116
|
+
// missing grant fails as `DeniedNoGrant` — which is an `info!` log and
|
|
117
|
+
// nothing else. The widget silently renders as plain text, with no error
|
|
118
|
+
// in the UI and nothing pointing at the manifest. Every app scaffolded
|
|
119
|
+
// through `defineApp` hit that, because the only fix was a grant string
|
|
120
|
+
// the templates never mention and the builder never added; the one
|
|
121
|
+
// working example on disk hand-writes it.
|
|
122
|
+
//
|
|
123
|
+
// Added only when there is a widget to render, and unioned rather than
|
|
124
|
+
// overwritten so an author's own `grants` list survives and re-declaring
|
|
125
|
+
// it is not an error.
|
|
126
|
+
permission_grants: withWidgetRenderGrant(options.grants ?? [], widgets),
|
|
89
127
|
activation_events: options.activationEvents ?? ["*"],
|
|
90
128
|
contributes,
|
|
91
129
|
// `targets: []` means EVERY surface, so an app that declares none is
|
|
@@ -107,7 +145,9 @@ function defineApp(options) {
|
|
|
107
145
|
const first = result.error.issues[0];
|
|
108
146
|
const field = first?.path.join(".") ?? "unknown";
|
|
109
147
|
const message = first?.message ?? "validation failed";
|
|
110
|
-
throw new Error(
|
|
148
|
+
throw new Error(
|
|
149
|
+
`manifest.json validation failed at '${field}': ${message}`
|
|
150
|
+
);
|
|
111
151
|
}
|
|
112
152
|
return result.data;
|
|
113
153
|
}
|
|
@@ -303,7 +343,7 @@ var PluginBuilder = class {
|
|
|
303
343
|
const field = first?.path.join(".") ?? "unknown";
|
|
304
344
|
const message = first?.message ?? "validation failed";
|
|
305
345
|
throw new Error(
|
|
306
|
-
`
|
|
346
|
+
`manifest.json validation failed at '${field}': ${message}`
|
|
307
347
|
);
|
|
308
348
|
}
|
|
309
349
|
return result.data;
|
|
@@ -676,12 +716,21 @@ function defineTurnHook(options) {
|
|
|
676
716
|
function definePlugin(options) {
|
|
677
717
|
const contributes = {
|
|
678
718
|
turn_hooks: options.turnHooks ?? [],
|
|
719
|
+
hook_events: options.hookEvents ?? [],
|
|
679
720
|
composer_controls: options.composerControls ?? [],
|
|
680
721
|
settings_tabs: options.settingsTabs ?? [],
|
|
681
722
|
slash_commands: options.slashCommands ?? [],
|
|
682
|
-
|
|
683
|
-
//
|
|
684
|
-
|
|
723
|
+
lsp_servers: options.lspServers ?? {},
|
|
724
|
+
// A turn-hook plugin contributes no app widgets, sidebar entries, dock
|
|
725
|
+
// panels, danger-zone categories or Pi extensions; the fields are required
|
|
726
|
+
// on the resolved `Contributes` type (zod defaults applied), so set them
|
|
727
|
+
// explicitly.
|
|
728
|
+
widgets: [],
|
|
729
|
+
sidebar_sections: [],
|
|
730
|
+
sidebar_buttons: [],
|
|
731
|
+
dock_panels: [],
|
|
732
|
+
data_categories: [],
|
|
733
|
+
pi_extensions: []
|
|
685
734
|
};
|
|
686
735
|
const tools = options.tools ?? [];
|
|
687
736
|
const runnables = tools.map((t) => inlineToolRunnable(t));
|