@ryuhq/sdk 0.0.17 → 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/{chunk-SKVIJH5I.js → chunk-XTUK5I6I.js} +27 -1
- package/dist/cli.cjs +26 -1
- package/dist/cli.js +1 -1
- package/dist/index.cjs +37 -5
- package/dist/index.js +12 -5
- package/dist/manifest.cjs +28 -1
- package/dist/manifest.d.cts +39 -1
- package/dist/manifest.d.ts +39 -1
- package/dist/manifest.js +3 -1
- package/package.json +3 -3
- package/src/generated/plugin-manifest.ts +136 -2
- package/src/manifest.ts +52 -0
- package/src/runnable/app.ts +4 -0
- package/src/runnable/turn-hook.ts +6 -3
|
@@ -110,6 +110,14 @@ var HookEventContributionSchema = z.object({
|
|
|
110
110
|
/** Example of the `ctx.event` payload. Documentation, not a validated schema. */
|
|
111
111
|
payload_example: z.record(z.string(), z.unknown()).optional()
|
|
112
112
|
});
|
|
113
|
+
var PiExtensionContributionSchema = z.object({
|
|
114
|
+
/** Stable id for this extension within the plugin (`[a-z0-9][a-z0-9._-]*`). */
|
|
115
|
+
id: z.string().min(1),
|
|
116
|
+
/** Path to the source, relative to the plugin root: `pi-extensions/<name>.ts`. */
|
|
117
|
+
file: z.string().min(1),
|
|
118
|
+
/** Optional one-liner describing what the extension adds to the agent. */
|
|
119
|
+
description: z.string().optional()
|
|
120
|
+
});
|
|
113
121
|
var DEFAULT_WIDGET_MIME = "text/html+skybridge";
|
|
114
122
|
var DEFAULT_WIDGET_DISPLAY_MODE = "inline";
|
|
115
123
|
var WidgetContributionSchema = z.object({
|
|
@@ -171,6 +179,14 @@ var ContributesSchema = z.object({
|
|
|
171
179
|
* Rust-side `Contributes.dock_panels`; without it the CLI's zod parse would
|
|
172
180
|
* strip the dock panel an app declares here. */
|
|
173
181
|
dock_panels: z.array(z.record(z.string(), z.unknown())).default([]),
|
|
182
|
+
/** Deletable data categories the app owns — one "Delete all X" row in Settings
|
|
183
|
+
* → Danger Zone. Mirrors the Rust-side `Contributes.data_categories`; without
|
|
184
|
+
* it the CLI's zod parse would strip the declaration before signing, and the
|
|
185
|
+
* app's danger-zone row would simply never appear on any node that installed
|
|
186
|
+
* the packed bundle. Loosely typed here for the same reason as the surfaces
|
|
187
|
+
* above — Core is the layer that types it, because Core is the layer that has
|
|
188
|
+
* to resolve the id to something that can actually delete the rows. */
|
|
189
|
+
data_categories: z.array(z.record(z.string(), z.unknown())).default([]),
|
|
174
190
|
/** Language servers the plugin declares, keyed by server name — the mirror of
|
|
175
191
|
* Claude Code's `.lsp.json` / `lspServers`, so a config written for either host
|
|
176
192
|
* loads in the other. Mirrors the Rust-side `Contributes.lsp_servers`; without
|
|
@@ -183,7 +199,16 @@ var ContributesSchema = z.object({
|
|
|
183
199
|
* on its way through `ryu pack` — the same silent-deletion bug this field
|
|
184
200
|
* exists to fix, one level down. Core is the layer that types it, because Core
|
|
185
201
|
* is the layer that acts on it. */
|
|
186
|
-
lsp_servers: z.record(z.string(), z.record(z.string(), z.unknown())).default({})
|
|
202
|
+
lsp_servers: z.record(z.string(), z.record(z.string(), z.unknown())).default({}),
|
|
203
|
+
/** Pi extensions the plugin ships — TypeScript the managed `ryu` (Pi) agent
|
|
204
|
+
* loads at process start. Mirrors the Rust-side `Contributes.pi_extensions`;
|
|
205
|
+
* without it the CLI's zod parse would strip the declaration before signing,
|
|
206
|
+
* and the packed plugin would ship a `pi-extensions/` folder nothing loads.
|
|
207
|
+
*
|
|
208
|
+
* Typed (not a loose record) because Ryu owns this vocabulary — three fields,
|
|
209
|
+
* all of them Core-interpreted — unlike `lsp_servers`, whose entry shape is
|
|
210
|
+
* Claude Code's to extend. */
|
|
211
|
+
pi_extensions: z.array(PiExtensionContributionSchema).default([])
|
|
187
212
|
});
|
|
188
213
|
var SetupStepSchema = z.object({
|
|
189
214
|
/** Card heading (e.g. the companion app name). */
|
|
@@ -420,6 +445,7 @@ export {
|
|
|
420
445
|
CompanionSurfaceSchema,
|
|
421
446
|
TurnHookContributionSchema,
|
|
422
447
|
HookEventContributionSchema,
|
|
448
|
+
PiExtensionContributionSchema,
|
|
423
449
|
WidgetContributionSchema,
|
|
424
450
|
ToolAppConfigSchema,
|
|
425
451
|
ContributesSchema,
|
package/dist/cli.cjs
CHANGED
|
@@ -396,6 +396,14 @@ var HookEventContributionSchema = import_zod.z.object({
|
|
|
396
396
|
/** Example of the `ctx.event` payload. Documentation, not a validated schema. */
|
|
397
397
|
payload_example: import_zod.z.record(import_zod.z.string(), import_zod.z.unknown()).optional()
|
|
398
398
|
});
|
|
399
|
+
var PiExtensionContributionSchema = import_zod.z.object({
|
|
400
|
+
/** Stable id for this extension within the plugin (`[a-z0-9][a-z0-9._-]*`). */
|
|
401
|
+
id: import_zod.z.string().min(1),
|
|
402
|
+
/** Path to the source, relative to the plugin root: `pi-extensions/<name>.ts`. */
|
|
403
|
+
file: import_zod.z.string().min(1),
|
|
404
|
+
/** Optional one-liner describing what the extension adds to the agent. */
|
|
405
|
+
description: import_zod.z.string().optional()
|
|
406
|
+
});
|
|
399
407
|
var DEFAULT_WIDGET_MIME = "text/html+skybridge";
|
|
400
408
|
var DEFAULT_WIDGET_DISPLAY_MODE = "inline";
|
|
401
409
|
var WidgetContributionSchema = import_zod.z.object({
|
|
@@ -457,6 +465,14 @@ var ContributesSchema = import_zod.z.object({
|
|
|
457
465
|
* Rust-side `Contributes.dock_panels`; without it the CLI's zod parse would
|
|
458
466
|
* strip the dock panel an app declares here. */
|
|
459
467
|
dock_panels: import_zod.z.array(import_zod.z.record(import_zod.z.string(), import_zod.z.unknown())).default([]),
|
|
468
|
+
/** Deletable data categories the app owns — one "Delete all X" row in Settings
|
|
469
|
+
* → Danger Zone. Mirrors the Rust-side `Contributes.data_categories`; without
|
|
470
|
+
* it the CLI's zod parse would strip the declaration before signing, and the
|
|
471
|
+
* app's danger-zone row would simply never appear on any node that installed
|
|
472
|
+
* the packed bundle. Loosely typed here for the same reason as the surfaces
|
|
473
|
+
* above — Core is the layer that types it, because Core is the layer that has
|
|
474
|
+
* to resolve the id to something that can actually delete the rows. */
|
|
475
|
+
data_categories: import_zod.z.array(import_zod.z.record(import_zod.z.string(), import_zod.z.unknown())).default([]),
|
|
460
476
|
/** Language servers the plugin declares, keyed by server name — the mirror of
|
|
461
477
|
* Claude Code's `.lsp.json` / `lspServers`, so a config written for either host
|
|
462
478
|
* loads in the other. Mirrors the Rust-side `Contributes.lsp_servers`; without
|
|
@@ -469,7 +485,16 @@ var ContributesSchema = import_zod.z.object({
|
|
|
469
485
|
* on its way through `ryu pack` — the same silent-deletion bug this field
|
|
470
486
|
* exists to fix, one level down. Core is the layer that types it, because Core
|
|
471
487
|
* is the layer that acts on it. */
|
|
472
|
-
lsp_servers: import_zod.z.record(import_zod.z.string(), import_zod.z.record(import_zod.z.string(), import_zod.z.unknown())).default({})
|
|
488
|
+
lsp_servers: import_zod.z.record(import_zod.z.string(), import_zod.z.record(import_zod.z.string(), import_zod.z.unknown())).default({}),
|
|
489
|
+
/** Pi extensions the plugin ships — TypeScript the managed `ryu` (Pi) agent
|
|
490
|
+
* loads at process start. Mirrors the Rust-side `Contributes.pi_extensions`;
|
|
491
|
+
* without it the CLI's zod parse would strip the declaration before signing,
|
|
492
|
+
* and the packed plugin would ship a `pi-extensions/` folder nothing loads.
|
|
493
|
+
*
|
|
494
|
+
* Typed (not a loose record) because Ryu owns this vocabulary — three fields,
|
|
495
|
+
* all of them Core-interpreted — unlike `lsp_servers`, whose entry shape is
|
|
496
|
+
* Claude Code's to extend. */
|
|
497
|
+
pi_extensions: import_zod.z.array(PiExtensionContributionSchema).default([])
|
|
473
498
|
});
|
|
474
499
|
var SetupStepSchema = import_zod.z.object({
|
|
475
500
|
/** Card heading (e.g. the companion app name). */
|
package/dist/cli.js
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -940,6 +940,14 @@ var HookEventContributionSchema = import_zod.z.object({
|
|
|
940
940
|
/** Example of the `ctx.event` payload. Documentation, not a validated schema. */
|
|
941
941
|
payload_example: import_zod.z.record(import_zod.z.string(), import_zod.z.unknown()).optional()
|
|
942
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()
|
|
950
|
+
});
|
|
943
951
|
var DEFAULT_WIDGET_MIME = "text/html+skybridge";
|
|
944
952
|
var DEFAULT_WIDGET_DISPLAY_MODE = "inline";
|
|
945
953
|
var WidgetContributionSchema = import_zod.z.object({
|
|
@@ -1001,6 +1009,14 @@ var ContributesSchema = import_zod.z.object({
|
|
|
1001
1009
|
* Rust-side `Contributes.dock_panels`; without it the CLI's zod parse would
|
|
1002
1010
|
* strip the dock panel an app declares here. */
|
|
1003
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([]),
|
|
1004
1020
|
/** Language servers the plugin declares, keyed by server name — the mirror of
|
|
1005
1021
|
* Claude Code's `.lsp.json` / `lspServers`, so a config written for either host
|
|
1006
1022
|
* loads in the other. Mirrors the Rust-side `Contributes.lsp_servers`; without
|
|
@@ -1013,7 +1029,16 @@ var ContributesSchema = import_zod.z.object({
|
|
|
1013
1029
|
* on its way through `ryu pack` — the same silent-deletion bug this field
|
|
1014
1030
|
* exists to fix, one level down. Core is the layer that types it, because Core
|
|
1015
1031
|
* is the layer that acts on it. */
|
|
1016
|
-
lsp_servers: import_zod.z.record(import_zod.z.string(), import_zod.z.record(import_zod.z.string(), import_zod.z.unknown())).default({})
|
|
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([])
|
|
1017
1042
|
});
|
|
1018
1043
|
var SetupStepSchema = import_zod.z.object({
|
|
1019
1044
|
/** Card heading (e.g. the companion app name). */
|
|
@@ -1310,6 +1335,10 @@ function defineApp(options) {
|
|
|
1310
1335
|
// takes no `contributes` passthrough. An app that wants to declare language
|
|
1311
1336
|
// servers writes them in a hand-authored `manifest.json`.
|
|
1312
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: [],
|
|
1313
1342
|
widgets
|
|
1314
1343
|
};
|
|
1315
1344
|
const raw = {
|
|
@@ -1929,13 +1958,16 @@ function definePlugin(options) {
|
|
|
1929
1958
|
settings_tabs: options.settingsTabs ?? [],
|
|
1930
1959
|
slash_commands: options.slashCommands ?? [],
|
|
1931
1960
|
lsp_servers: options.lspServers ?? {},
|
|
1932
|
-
// A turn-hook plugin contributes no app widgets, sidebar entries
|
|
1933
|
-
// panels
|
|
1934
|
-
// defaults applied), so set them
|
|
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.
|
|
1935
1965
|
widgets: [],
|
|
1936
1966
|
sidebar_sections: [],
|
|
1937
1967
|
sidebar_buttons: [],
|
|
1938
|
-
dock_panels: []
|
|
1968
|
+
dock_panels: [],
|
|
1969
|
+
data_categories: [],
|
|
1970
|
+
pi_extensions: []
|
|
1939
1971
|
};
|
|
1940
1972
|
const tools = options.tools ?? [];
|
|
1941
1973
|
const runnables = tools.map((t) => inlineToolRunnable(t));
|
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,
|
|
@@ -98,6 +98,10 @@ function defineApp(options) {
|
|
|
98
98
|
// takes no `contributes` passthrough. An app that wants to declare language
|
|
99
99
|
// servers writes them in a hand-authored `manifest.json`.
|
|
100
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: [],
|
|
101
105
|
widgets
|
|
102
106
|
};
|
|
103
107
|
const raw = {
|
|
@@ -717,13 +721,16 @@ function definePlugin(options) {
|
|
|
717
721
|
settings_tabs: options.settingsTabs ?? [],
|
|
718
722
|
slash_commands: options.slashCommands ?? [],
|
|
719
723
|
lsp_servers: options.lspServers ?? {},
|
|
720
|
-
// A turn-hook plugin contributes no app widgets, sidebar entries
|
|
721
|
-
// panels
|
|
722
|
-
// defaults applied), so set them
|
|
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.
|
|
723
728
|
widgets: [],
|
|
724
729
|
sidebar_sections: [],
|
|
725
730
|
sidebar_buttons: [],
|
|
726
|
-
dock_panels: []
|
|
731
|
+
dock_panels: [],
|
|
732
|
+
data_categories: [],
|
|
733
|
+
pi_extensions: []
|
|
727
734
|
};
|
|
728
735
|
const tools = options.tools ?? [];
|
|
729
736
|
const runnables = tools.map((t) => inlineToolRunnable(t));
|
package/dist/manifest.cjs
CHANGED
|
@@ -25,6 +25,7 @@ __export(manifest_exports, {
|
|
|
25
25
|
CompanionSurfaceSchema: () => CompanionSurfaceSchema,
|
|
26
26
|
ContributesSchema: () => ContributesSchema,
|
|
27
27
|
HookEventContributionSchema: () => HookEventContributionSchema,
|
|
28
|
+
PiExtensionContributionSchema: () => PiExtensionContributionSchema,
|
|
28
29
|
PluginManifestSchema: () => PluginManifestSchema,
|
|
29
30
|
RequiresSchema: () => RequiresSchema,
|
|
30
31
|
RunnableKindSchema: () => RunnableKindSchema,
|
|
@@ -157,6 +158,14 @@ var HookEventContributionSchema = import_zod.z.object({
|
|
|
157
158
|
/** Example of the `ctx.event` payload. Documentation, not a validated schema. */
|
|
158
159
|
payload_example: import_zod.z.record(import_zod.z.string(), import_zod.z.unknown()).optional()
|
|
159
160
|
});
|
|
161
|
+
var PiExtensionContributionSchema = import_zod.z.object({
|
|
162
|
+
/** Stable id for this extension within the plugin (`[a-z0-9][a-z0-9._-]*`). */
|
|
163
|
+
id: import_zod.z.string().min(1),
|
|
164
|
+
/** Path to the source, relative to the plugin root: `pi-extensions/<name>.ts`. */
|
|
165
|
+
file: import_zod.z.string().min(1),
|
|
166
|
+
/** Optional one-liner describing what the extension adds to the agent. */
|
|
167
|
+
description: import_zod.z.string().optional()
|
|
168
|
+
});
|
|
160
169
|
var DEFAULT_WIDGET_MIME = "text/html+skybridge";
|
|
161
170
|
var DEFAULT_WIDGET_DISPLAY_MODE = "inline";
|
|
162
171
|
var WidgetContributionSchema = import_zod.z.object({
|
|
@@ -218,6 +227,14 @@ var ContributesSchema = import_zod.z.object({
|
|
|
218
227
|
* Rust-side `Contributes.dock_panels`; without it the CLI's zod parse would
|
|
219
228
|
* strip the dock panel an app declares here. */
|
|
220
229
|
dock_panels: import_zod.z.array(import_zod.z.record(import_zod.z.string(), import_zod.z.unknown())).default([]),
|
|
230
|
+
/** Deletable data categories the app owns — one "Delete all X" row in Settings
|
|
231
|
+
* → Danger Zone. Mirrors the Rust-side `Contributes.data_categories`; without
|
|
232
|
+
* it the CLI's zod parse would strip the declaration before signing, and the
|
|
233
|
+
* app's danger-zone row would simply never appear on any node that installed
|
|
234
|
+
* the packed bundle. Loosely typed here for the same reason as the surfaces
|
|
235
|
+
* above — Core is the layer that types it, because Core is the layer that has
|
|
236
|
+
* to resolve the id to something that can actually delete the rows. */
|
|
237
|
+
data_categories: import_zod.z.array(import_zod.z.record(import_zod.z.string(), import_zod.z.unknown())).default([]),
|
|
221
238
|
/** Language servers the plugin declares, keyed by server name — the mirror of
|
|
222
239
|
* Claude Code's `.lsp.json` / `lspServers`, so a config written for either host
|
|
223
240
|
* loads in the other. Mirrors the Rust-side `Contributes.lsp_servers`; without
|
|
@@ -230,7 +247,16 @@ var ContributesSchema = import_zod.z.object({
|
|
|
230
247
|
* on its way through `ryu pack` — the same silent-deletion bug this field
|
|
231
248
|
* exists to fix, one level down. Core is the layer that types it, because Core
|
|
232
249
|
* is the layer that acts on it. */
|
|
233
|
-
lsp_servers: import_zod.z.record(import_zod.z.string(), import_zod.z.record(import_zod.z.string(), import_zod.z.unknown())).default({})
|
|
250
|
+
lsp_servers: import_zod.z.record(import_zod.z.string(), import_zod.z.record(import_zod.z.string(), import_zod.z.unknown())).default({}),
|
|
251
|
+
/** Pi extensions the plugin ships — TypeScript the managed `ryu` (Pi) agent
|
|
252
|
+
* loads at process start. Mirrors the Rust-side `Contributes.pi_extensions`;
|
|
253
|
+
* without it the CLI's zod parse would strip the declaration before signing,
|
|
254
|
+
* and the packed plugin would ship a `pi-extensions/` folder nothing loads.
|
|
255
|
+
*
|
|
256
|
+
* Typed (not a loose record) because Ryu owns this vocabulary — three fields,
|
|
257
|
+
* all of them Core-interpreted — unlike `lsp_servers`, whose entry shape is
|
|
258
|
+
* Claude Code's to extend. */
|
|
259
|
+
pi_extensions: import_zod.z.array(PiExtensionContributionSchema).default([])
|
|
234
260
|
});
|
|
235
261
|
var SetupStepSchema = import_zod.z.object({
|
|
236
262
|
/** Card heading (e.g. the companion app name). */
|
|
@@ -466,6 +492,7 @@ function coreManifestJsonSchema() {
|
|
|
466
492
|
CompanionSurfaceSchema,
|
|
467
493
|
ContributesSchema,
|
|
468
494
|
HookEventContributionSchema,
|
|
495
|
+
PiExtensionContributionSchema,
|
|
469
496
|
PluginManifestSchema,
|
|
470
497
|
RequiresSchema,
|
|
471
498
|
RunnableKindSchema,
|
package/dist/manifest.d.cts
CHANGED
|
@@ -115,6 +115,32 @@ declare const HookEventContributionSchema: z.ZodObject<{
|
|
|
115
115
|
payload_example: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
116
116
|
}, z.core.$strip>;
|
|
117
117
|
type HookEventContribution = z.infer<typeof HookEventContributionSchema>;
|
|
118
|
+
/**
|
|
119
|
+
* One Pi extension the plugin ships — a TypeScript file the managed `ryu` (Pi)
|
|
120
|
+
* agent loads at process start. Mirrors Rust `PiExtensionContribution`.
|
|
121
|
+
*
|
|
122
|
+
* Carries a PATH, never a body: unlike `turn_hooks` there is no inline `code`
|
|
123
|
+
* twin, because nothing downstream reads the source as a string.
|
|
124
|
+
*
|
|
125
|
+
* That makes it a SIDECAR FILE, and `ryu pack` emits a single JSON bundle — so a
|
|
126
|
+
* plugin installed from a packed bundle arrives without its `pi-extensions/`
|
|
127
|
+
* directory and Core resolves the declaration to a visible skip. Same open gap as
|
|
128
|
+
* `skills/**`, which the bundle likewise does not carry. Today the path that works
|
|
129
|
+
* is a plugin whose directory is on disk (a built-in, a satellite checkout, a dev
|
|
130
|
+
* tree). Do not "fix" this by inlining the source into the manifest: a 50 KB
|
|
131
|
+
* TypeScript program escaped into a JSON string is the unauditable form the whole
|
|
132
|
+
* `code_file` extraction exists to prevent.
|
|
133
|
+
*
|
|
134
|
+
* Note this is UNSANDBOXED code: it runs inside the agent process with full host
|
|
135
|
+
* privilege, so Core gates it behind the operator-only `pi:extension` grant for
|
|
136
|
+
* any non-built-in plugin.
|
|
137
|
+
*/
|
|
138
|
+
declare const PiExtensionContributionSchema: z.ZodObject<{
|
|
139
|
+
id: z.ZodString;
|
|
140
|
+
file: z.ZodString;
|
|
141
|
+
description: z.ZodOptional<z.ZodString>;
|
|
142
|
+
}, z.core.$strip>;
|
|
143
|
+
type PiExtensionContribution = z.infer<typeof PiExtensionContributionSchema>;
|
|
118
144
|
/**
|
|
119
145
|
* One app-widget contribution (Ryu Apps). Binds the render tool that produces the
|
|
120
146
|
* widget to its `ui://widget/<slug>.html` template. Shape-identical to Core's
|
|
@@ -187,7 +213,13 @@ declare const ContributesSchema: z.ZodObject<{
|
|
|
187
213
|
sidebar_sections: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
188
214
|
sidebar_buttons: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
189
215
|
dock_panels: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
216
|
+
data_categories: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
190
217
|
lsp_servers: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
218
|
+
pi_extensions: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
219
|
+
id: z.ZodString;
|
|
220
|
+
file: z.ZodString;
|
|
221
|
+
description: z.ZodOptional<z.ZodString>;
|
|
222
|
+
}, z.core.$strip>>>;
|
|
191
223
|
}, z.core.$strip>;
|
|
192
224
|
type Contributes = z.infer<typeof ContributesSchema>;
|
|
193
225
|
/**
|
|
@@ -338,7 +370,13 @@ declare const PluginManifestSchema: z.ZodObject<{
|
|
|
338
370
|
sidebar_sections: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
339
371
|
sidebar_buttons: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
340
372
|
dock_panels: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
373
|
+
data_categories: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
341
374
|
lsp_servers: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
375
|
+
pi_extensions: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
376
|
+
id: z.ZodString;
|
|
377
|
+
file: z.ZodString;
|
|
378
|
+
description: z.ZodOptional<z.ZodString>;
|
|
379
|
+
}, z.core.$strip>>>;
|
|
342
380
|
}, z.core.$strip>>;
|
|
343
381
|
requires: z.ZodOptional<z.ZodObject<{
|
|
344
382
|
apps: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
@@ -435,4 +473,4 @@ declare function validateManifestStrict(manifestJson: string): string;
|
|
|
435
473
|
*/
|
|
436
474
|
declare function coreManifestJsonSchema(): unknown;
|
|
437
475
|
|
|
438
|
-
export { type AppDependency, AppDependencySchema, type CapabilityReq, CapabilityReqSchema, type CompanionSurface, CompanionSurfaceSchema, type Contributes, ContributesSchema, type HookEventContribution, HookEventContributionSchema, type PluginManifest, PluginManifestSchema, type Requires, RequiresSchema, type RunnableKind, RunnableKindSchema, type RunnableMeta, RunnableMetaSchema, type SetupStep, SetupStepSchema, type Surface, SurfaceSchema, type ToolAppConfig, ToolAppConfigSchema, type TurnHookContribution, TurnHookContributionSchema, type WidgetContribution, WidgetContributionSchema, coreManifestJsonSchema, labelImpersonatesSystemChrome, validateManifestStrict, validatePluginId };
|
|
476
|
+
export { type AppDependency, AppDependencySchema, type CapabilityReq, CapabilityReqSchema, type CompanionSurface, CompanionSurfaceSchema, type Contributes, ContributesSchema, type HookEventContribution, HookEventContributionSchema, type PiExtensionContribution, PiExtensionContributionSchema, type PluginManifest, PluginManifestSchema, type Requires, RequiresSchema, type RunnableKind, RunnableKindSchema, type RunnableMeta, RunnableMetaSchema, type SetupStep, SetupStepSchema, type Surface, SurfaceSchema, type ToolAppConfig, ToolAppConfigSchema, type TurnHookContribution, TurnHookContributionSchema, type WidgetContribution, WidgetContributionSchema, coreManifestJsonSchema, labelImpersonatesSystemChrome, validateManifestStrict, validatePluginId };
|
package/dist/manifest.d.ts
CHANGED
|
@@ -115,6 +115,32 @@ declare const HookEventContributionSchema: z.ZodObject<{
|
|
|
115
115
|
payload_example: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
116
116
|
}, z.core.$strip>;
|
|
117
117
|
type HookEventContribution = z.infer<typeof HookEventContributionSchema>;
|
|
118
|
+
/**
|
|
119
|
+
* One Pi extension the plugin ships — a TypeScript file the managed `ryu` (Pi)
|
|
120
|
+
* agent loads at process start. Mirrors Rust `PiExtensionContribution`.
|
|
121
|
+
*
|
|
122
|
+
* Carries a PATH, never a body: unlike `turn_hooks` there is no inline `code`
|
|
123
|
+
* twin, because nothing downstream reads the source as a string.
|
|
124
|
+
*
|
|
125
|
+
* That makes it a SIDECAR FILE, and `ryu pack` emits a single JSON bundle — so a
|
|
126
|
+
* plugin installed from a packed bundle arrives without its `pi-extensions/`
|
|
127
|
+
* directory and Core resolves the declaration to a visible skip. Same open gap as
|
|
128
|
+
* `skills/**`, which the bundle likewise does not carry. Today the path that works
|
|
129
|
+
* is a plugin whose directory is on disk (a built-in, a satellite checkout, a dev
|
|
130
|
+
* tree). Do not "fix" this by inlining the source into the manifest: a 50 KB
|
|
131
|
+
* TypeScript program escaped into a JSON string is the unauditable form the whole
|
|
132
|
+
* `code_file` extraction exists to prevent.
|
|
133
|
+
*
|
|
134
|
+
* Note this is UNSANDBOXED code: it runs inside the agent process with full host
|
|
135
|
+
* privilege, so Core gates it behind the operator-only `pi:extension` grant for
|
|
136
|
+
* any non-built-in plugin.
|
|
137
|
+
*/
|
|
138
|
+
declare const PiExtensionContributionSchema: z.ZodObject<{
|
|
139
|
+
id: z.ZodString;
|
|
140
|
+
file: z.ZodString;
|
|
141
|
+
description: z.ZodOptional<z.ZodString>;
|
|
142
|
+
}, z.core.$strip>;
|
|
143
|
+
type PiExtensionContribution = z.infer<typeof PiExtensionContributionSchema>;
|
|
118
144
|
/**
|
|
119
145
|
* One app-widget contribution (Ryu Apps). Binds the render tool that produces the
|
|
120
146
|
* widget to its `ui://widget/<slug>.html` template. Shape-identical to Core's
|
|
@@ -187,7 +213,13 @@ declare const ContributesSchema: z.ZodObject<{
|
|
|
187
213
|
sidebar_sections: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
188
214
|
sidebar_buttons: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
189
215
|
dock_panels: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
216
|
+
data_categories: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
190
217
|
lsp_servers: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
218
|
+
pi_extensions: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
219
|
+
id: z.ZodString;
|
|
220
|
+
file: z.ZodString;
|
|
221
|
+
description: z.ZodOptional<z.ZodString>;
|
|
222
|
+
}, z.core.$strip>>>;
|
|
191
223
|
}, z.core.$strip>;
|
|
192
224
|
type Contributes = z.infer<typeof ContributesSchema>;
|
|
193
225
|
/**
|
|
@@ -338,7 +370,13 @@ declare const PluginManifestSchema: z.ZodObject<{
|
|
|
338
370
|
sidebar_sections: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
339
371
|
sidebar_buttons: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
340
372
|
dock_panels: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
373
|
+
data_categories: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
341
374
|
lsp_servers: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
375
|
+
pi_extensions: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
376
|
+
id: z.ZodString;
|
|
377
|
+
file: z.ZodString;
|
|
378
|
+
description: z.ZodOptional<z.ZodString>;
|
|
379
|
+
}, z.core.$strip>>>;
|
|
342
380
|
}, z.core.$strip>>;
|
|
343
381
|
requires: z.ZodOptional<z.ZodObject<{
|
|
344
382
|
apps: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
@@ -435,4 +473,4 @@ declare function validateManifestStrict(manifestJson: string): string;
|
|
|
435
473
|
*/
|
|
436
474
|
declare function coreManifestJsonSchema(): unknown;
|
|
437
475
|
|
|
438
|
-
export { type AppDependency, AppDependencySchema, type CapabilityReq, CapabilityReqSchema, type CompanionSurface, CompanionSurfaceSchema, type Contributes, ContributesSchema, type HookEventContribution, HookEventContributionSchema, type PluginManifest, PluginManifestSchema, type Requires, RequiresSchema, type RunnableKind, RunnableKindSchema, type RunnableMeta, RunnableMetaSchema, type SetupStep, SetupStepSchema, type Surface, SurfaceSchema, type ToolAppConfig, ToolAppConfigSchema, type TurnHookContribution, TurnHookContributionSchema, type WidgetContribution, WidgetContributionSchema, coreManifestJsonSchema, labelImpersonatesSystemChrome, validateManifestStrict, validatePluginId };
|
|
476
|
+
export { type AppDependency, AppDependencySchema, type CapabilityReq, CapabilityReqSchema, type CompanionSurface, CompanionSurfaceSchema, type Contributes, ContributesSchema, type HookEventContribution, HookEventContributionSchema, type PiExtensionContribution, PiExtensionContributionSchema, type PluginManifest, PluginManifestSchema, type Requires, RequiresSchema, type RunnableKind, RunnableKindSchema, type RunnableMeta, RunnableMetaSchema, type SetupStep, SetupStepSchema, type Surface, SurfaceSchema, type ToolAppConfig, ToolAppConfigSchema, type TurnHookContribution, TurnHookContributionSchema, type WidgetContribution, WidgetContributionSchema, coreManifestJsonSchema, labelImpersonatesSystemChrome, validateManifestStrict, validatePluginId };
|
package/dist/manifest.js
CHANGED
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
CompanionSurfaceSchema,
|
|
5
5
|
ContributesSchema,
|
|
6
6
|
HookEventContributionSchema,
|
|
7
|
+
PiExtensionContributionSchema,
|
|
7
8
|
PluginManifestSchema,
|
|
8
9
|
RequiresSchema,
|
|
9
10
|
RunnableKindSchema,
|
|
@@ -17,13 +18,14 @@ import {
|
|
|
17
18
|
labelImpersonatesSystemChrome,
|
|
18
19
|
validateManifestStrict,
|
|
19
20
|
validatePluginId
|
|
20
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-XTUK5I6I.js";
|
|
21
22
|
export {
|
|
22
23
|
AppDependencySchema,
|
|
23
24
|
CapabilityReqSchema,
|
|
24
25
|
CompanionSurfaceSchema,
|
|
25
26
|
ContributesSchema,
|
|
26
27
|
HookEventContributionSchema,
|
|
28
|
+
PiExtensionContributionSchema,
|
|
27
29
|
PluginManifestSchema,
|
|
28
30
|
RequiresSchema,
|
|
29
31
|
RunnableKindSchema,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ryuhq/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Ryu developer SDK: typed builders and CLI for authoring manifest.json Plugin bundles",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -44,11 +44,11 @@
|
|
|
44
44
|
"clean": "rm -rf dist"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@ryuhq/sdk-native": "
|
|
47
|
+
"@ryuhq/sdk-native": "workspace:*",
|
|
48
48
|
"zod": "^4.1.13"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
|
-
"@types/bun": "
|
|
51
|
+
"@types/bun": "catalog:",
|
|
52
52
|
"json-schema-to-typescript": "^15.0.4",
|
|
53
53
|
"tsup": "^8.5.1",
|
|
54
54
|
"typescript": "^5"
|
|
@@ -49,7 +49,7 @@ export type ProviderTarget = "local-machine" | "remote-desktop";
|
|
|
49
49
|
* An **empty/absent** `targets` list means the plugin runs on *every* surface —
|
|
50
50
|
* that is the backward-compatible default and MUST NOT be read as "hidden".
|
|
51
51
|
*/
|
|
52
|
-
export type Surface = "gateway" | "core" | "desktop" | "island" | "mobile" | "extension" | "web" | "cli";
|
|
52
|
+
export type Surface = "gateway" | "core" | "desktop" | "island" | "mobile" | "extension" | "web" | "cli" | "unknown";
|
|
53
53
|
|
|
54
54
|
/**
|
|
55
55
|
* An installable Ryu App manifest (`manifest.json`).
|
|
@@ -487,6 +487,40 @@ export interface Contributes {
|
|
|
487
487
|
* older shells" instead of breaking the composer.
|
|
488
488
|
*/
|
|
489
489
|
composer_controls?: unknown[];
|
|
490
|
+
/**
|
|
491
|
+
* **Deletable data categories** the app owns — one "Delete all X" row in
|
|
492
|
+
* Settings → Danger Zone (see [`DataCategoryContribution`]).
|
|
493
|
+
*
|
|
494
|
+
* The danger zone used to be two hardcoded lists that had to be edited
|
|
495
|
+
* together: a `DataCategory` enum in Core and a `CATEGORIES` array carrying the
|
|
496
|
+
* user-facing copy in the closed desktop source. Monitors and Meetings are
|
|
497
|
+
* app-owned data, so both lists named apps — which meant a node where Monitors
|
|
498
|
+
* was never enabled still offered to delete monitors, and the count was always
|
|
499
|
+
* 0. Declaring the category here makes the owning app the single source of both
|
|
500
|
+
* its existence and its wording, and makes the row appear and disappear with
|
|
501
|
+
* the app instead of with a client-side feature-detect.
|
|
502
|
+
*
|
|
503
|
+
* # Core-interpreted, so a typed struct — and NOT on the contributions endpoint
|
|
504
|
+
*
|
|
505
|
+
* Core has to resolve the id to something that can actually count and delete
|
|
506
|
+
* the rows, so per this type's own doc comment this gets a typed struct rather
|
|
507
|
+
* than opaque JSON, and it is gathered at its consumption site
|
|
508
|
+
* (`GET /api/data/counts`, which serves each category's descriptor next to its
|
|
509
|
+
* live count) rather than at `GET /api/plugins/contributions` — the same
|
|
510
|
+
* disposition as [`Contributes::tool_filters`] and [`Contributes::lsp_servers`].
|
|
511
|
+
*
|
|
512
|
+
* # Declaration, not implementation
|
|
513
|
+
*
|
|
514
|
+
* A declared category is served only when Core knows how to clear it; an id
|
|
515
|
+
* Core does not implement is skipped with a warn rather than being offered as a
|
|
516
|
+
* button that 400s. That split is deliberate and not a stepping stone to a
|
|
517
|
+
* generic HTTP truncate: clearing monitors has to tear down each monitor's
|
|
518
|
+
* backing scheduler job, and clearing meetings has to broadcast on the meetings
|
|
519
|
+
* SSE stream, so a blind `DELETE /monitors` would leave jobs ticking forever.
|
|
520
|
+
* The manifest owns *whether the row exists and what it says*; Core owns *what
|
|
521
|
+
* deleting actually entails*.
|
|
522
|
+
*/
|
|
523
|
+
data_categories?: DataCategoryContribution[];
|
|
490
524
|
/**
|
|
491
525
|
* App-registered **workspace dock panels** — a tab in the desktop's bottom or
|
|
492
526
|
* right dock (Terminal / Code Review / Browser / Simulator live there today).
|
|
@@ -582,6 +616,45 @@ export interface Contributes {
|
|
|
582
616
|
lsp_servers?: {
|
|
583
617
|
[k: string]: LspServerContribution;
|
|
584
618
|
};
|
|
619
|
+
/**
|
|
620
|
+
* **Pi extensions** the plugin ships — TypeScript files the managed `ryu` (Pi)
|
|
621
|
+
* agent loads at process start:
|
|
622
|
+
*
|
|
623
|
+
* ```json
|
|
624
|
+
* "pi_extensions": [
|
|
625
|
+
* { "id": "shell", "file": "pi-extensions/ryu-shell.ts",
|
|
626
|
+
* "description": "background bash for the managed Pi agent" }
|
|
627
|
+
* ]
|
|
628
|
+
* ```
|
|
629
|
+
*
|
|
630
|
+
* Pi ships none of plan mode, sub-agents, permission prompts or background bash
|
|
631
|
+
* and says so deliberately in its own docs — "you can build or install those
|
|
632
|
+
* workflows as extensions or packages". This surface is that seam: the
|
|
633
|
+
* capabilities Core used to hardcode into the spawn path become plugins the user
|
|
634
|
+
* can enable and disable, and a third party can ship one at all.
|
|
635
|
+
*
|
|
636
|
+
* # This is UNSANDBOXED code, and the tier gate is not optional
|
|
637
|
+
*
|
|
638
|
+
* A [`Contributes::turn_hooks`] body runs in the deny-by-default Deno sandbox
|
|
639
|
+
* behind capability-gated `host.*` calls. A file named here runs **inside the Pi
|
|
640
|
+
* process** with full host privilege: the first-party ones spawn children and
|
|
641
|
+
* POST to Core. That is the same arbitrary-code-execution class as
|
|
642
|
+
* [`PluginManifest::mcp_servers`], so Core gates it identically — Core tier is
|
|
643
|
+
* auto-allowed, Community tier needs an operator-allowlisted grant, and the gate
|
|
644
|
+
* sits at the materializer, because writing the file is what makes it run.
|
|
645
|
+
*
|
|
646
|
+
* # Core-interpreted, so a typed struct — and NOT on the contributions endpoint
|
|
647
|
+
*
|
|
648
|
+
* Core resolves each `file` and projects it into the managed Pi's config dir, so
|
|
649
|
+
* per this type's own doc comment it gets a typed struct and is gathered at its
|
|
650
|
+
* consumption site (`pi_config::app_extensions`) rather than served from
|
|
651
|
+
* `GET /api/plugins/contributions` — the same disposition as
|
|
652
|
+
* [`Contributes::lsp_servers`].
|
|
653
|
+
*
|
|
654
|
+
* The `file` is deliberately NOT hydrated into an inline string the way a
|
|
655
|
+
* `code_file` is; see [`PluginManifest::pi_extension_refs`] for why.
|
|
656
|
+
*/
|
|
657
|
+
pi_extensions?: PiExtensionContribution[];
|
|
585
658
|
/**
|
|
586
659
|
* Gateway policies the plugin contributes (referenced by runnable id).
|
|
587
660
|
*/
|
|
@@ -699,6 +772,42 @@ export interface ContributionId {
|
|
|
699
772
|
*/
|
|
700
773
|
title?: string | null;
|
|
701
774
|
}
|
|
775
|
+
/**
|
|
776
|
+
* One **deletable data category** an app owns (see [`Contributes::data_categories`]).
|
|
777
|
+
*
|
|
778
|
+
* Everything the Danger Zone needs to draw and arm one destructive row, so the copy
|
|
779
|
+
* lives with the app whose data it describes rather than in the desktop's source.
|
|
780
|
+
*/
|
|
781
|
+
export interface DataCategoryContribution {
|
|
782
|
+
/**
|
|
783
|
+
* The word the user must type to arm the delete. Absent = the [`noun`], which is
|
|
784
|
+
* the right default often enough that requiring it would just be ceremony.
|
|
785
|
+
* Matched case-insensitively by the client.
|
|
786
|
+
*
|
|
787
|
+
* [`noun`]: DataCategoryContribution::noun
|
|
788
|
+
*/
|
|
789
|
+
confirm_word?: string | null;
|
|
790
|
+
/**
|
|
791
|
+
* Exactly what disappears, shown in the confirm dialog. Required, and required
|
|
792
|
+
* to be specific: this is the last thing the user reads before an irreversible
|
|
793
|
+
* delete, and "this cannot be undone" tells them nothing they did not know.
|
|
794
|
+
*/
|
|
795
|
+
detail: string;
|
|
796
|
+
/**
|
|
797
|
+
* Stable id — this is the `category` a `POST /api/data/clear` names, so it is
|
|
798
|
+
* the app's half of the delete contract and renaming it breaks the button.
|
|
799
|
+
*/
|
|
800
|
+
id: string;
|
|
801
|
+
/**
|
|
802
|
+
* Plural noun for the live count line ("42 monitors" / "No monitors") and the
|
|
803
|
+
* "N deleted" toast. Lower-case: it is used mid-sentence.
|
|
804
|
+
*/
|
|
805
|
+
noun: string;
|
|
806
|
+
/**
|
|
807
|
+
* The destructive button label and confirm-dialog title ("Delete all monitors").
|
|
808
|
+
*/
|
|
809
|
+
title: string;
|
|
810
|
+
}
|
|
702
811
|
/**
|
|
703
812
|
* One app-registered **workspace dock panel** — a tab in the desktop's bottom or
|
|
704
813
|
* right dock (see [`Contributes::dock_panels`]).
|
|
@@ -955,6 +1064,31 @@ export interface LspServerContribution {
|
|
|
955
1064
|
*/
|
|
956
1065
|
workspaceFolder?: string | null;
|
|
957
1066
|
}
|
|
1067
|
+
/**
|
|
1068
|
+
* One **Pi extension** a plugin ships (a [`Contributes::pi_extensions`] row).
|
|
1069
|
+
*
|
|
1070
|
+
* Carries a path, never a body: unlike [`TurnHookContribution`] there is no inline
|
|
1071
|
+
* `code` twin, because nothing downstream reads the source as a string.
|
|
1072
|
+
*/
|
|
1073
|
+
export interface PiExtensionContribution {
|
|
1074
|
+
/**
|
|
1075
|
+
* Optional human-facing one-liner (what the extension adds to the agent).
|
|
1076
|
+
*/
|
|
1077
|
+
description?: string | null;
|
|
1078
|
+
/**
|
|
1079
|
+
* Path to the TypeScript source, relative to the plugin root — exactly
|
|
1080
|
+
* `pi-extensions/<name>.ts`. See [`validate_pi_extension_path`].
|
|
1081
|
+
*/
|
|
1082
|
+
file: string;
|
|
1083
|
+
/**
|
|
1084
|
+
* Stable id for this extension within the plugin (`[a-z0-9][a-z0-9._-]*`).
|
|
1085
|
+
*
|
|
1086
|
+
* Part of the materialized file name, so it is what makes one plugin's
|
|
1087
|
+
* extensions distinguishable from another's on disk — and why it is validated
|
|
1088
|
+
* with the same alphabet as an event name rather than left free-form.
|
|
1089
|
+
*/
|
|
1090
|
+
id: string;
|
|
1091
|
+
}
|
|
958
1092
|
/**
|
|
959
1093
|
* One **settings tab** a plugin contributes (see [`Contributes::settings_tabs`]).
|
|
960
1094
|
*
|
|
@@ -2209,7 +2343,7 @@ export interface SurfaceEntry {
|
|
|
2209
2343
|
/**
|
|
2210
2344
|
* How much of the plugin this surface supports.
|
|
2211
2345
|
*/
|
|
2212
|
-
support?: "full" | "limited" | "list" | "commands" | "none";
|
|
2346
|
+
support?: "full" | "limited" | "list" | "commands" | "none" | "unknown";
|
|
2213
2347
|
/**
|
|
2214
2348
|
* Optional surface-specific UI descriptor (bundle id, mount point, …),
|
|
2215
2349
|
* interpreted by the surface's app host. Opaque to the contract.
|
package/src/manifest.ts
CHANGED
|
@@ -239,6 +239,41 @@ export const HookEventContributionSchema = z.object({
|
|
|
239
239
|
|
|
240
240
|
export type HookEventContribution = z.infer<typeof HookEventContributionSchema>;
|
|
241
241
|
|
|
242
|
+
// ── PiExtensionContribution ───────────────────────────────────────────────────
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* One Pi extension the plugin ships — a TypeScript file the managed `ryu` (Pi)
|
|
246
|
+
* agent loads at process start. Mirrors Rust `PiExtensionContribution`.
|
|
247
|
+
*
|
|
248
|
+
* Carries a PATH, never a body: unlike `turn_hooks` there is no inline `code`
|
|
249
|
+
* twin, because nothing downstream reads the source as a string.
|
|
250
|
+
*
|
|
251
|
+
* That makes it a SIDECAR FILE, and `ryu pack` emits a single JSON bundle — so a
|
|
252
|
+
* plugin installed from a packed bundle arrives without its `pi-extensions/`
|
|
253
|
+
* directory and Core resolves the declaration to a visible skip. Same open gap as
|
|
254
|
+
* `skills/**`, which the bundle likewise does not carry. Today the path that works
|
|
255
|
+
* is a plugin whose directory is on disk (a built-in, a satellite checkout, a dev
|
|
256
|
+
* tree). Do not "fix" this by inlining the source into the manifest: a 50 KB
|
|
257
|
+
* TypeScript program escaped into a JSON string is the unauditable form the whole
|
|
258
|
+
* `code_file` extraction exists to prevent.
|
|
259
|
+
*
|
|
260
|
+
* Note this is UNSANDBOXED code: it runs inside the agent process with full host
|
|
261
|
+
* privilege, so Core gates it behind the operator-only `pi:extension` grant for
|
|
262
|
+
* any non-built-in plugin.
|
|
263
|
+
*/
|
|
264
|
+
export const PiExtensionContributionSchema = z.object({
|
|
265
|
+
/** Stable id for this extension within the plugin (`[a-z0-9][a-z0-9._-]*`). */
|
|
266
|
+
id: z.string().min(1),
|
|
267
|
+
/** Path to the source, relative to the plugin root: `pi-extensions/<name>.ts`. */
|
|
268
|
+
file: z.string().min(1),
|
|
269
|
+
/** Optional one-liner describing what the extension adds to the agent. */
|
|
270
|
+
description: z.string().optional(),
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
export type PiExtensionContribution = z.infer<
|
|
274
|
+
typeof PiExtensionContributionSchema
|
|
275
|
+
>;
|
|
276
|
+
|
|
242
277
|
// ── WidgetContribution (Ryu Apps) ─────────────────────────────────────────────
|
|
243
278
|
|
|
244
279
|
/** Default widget MIME dialect. Mirrors Core `default_widget_mime`. */
|
|
@@ -335,6 +370,14 @@ export const ContributesSchema = z.object({
|
|
|
335
370
|
* Rust-side `Contributes.dock_panels`; without it the CLI's zod parse would
|
|
336
371
|
* strip the dock panel an app declares here. */
|
|
337
372
|
dock_panels: z.array(z.record(z.string(), z.unknown())).default([]),
|
|
373
|
+
/** Deletable data categories the app owns — one "Delete all X" row in Settings
|
|
374
|
+
* → Danger Zone. Mirrors the Rust-side `Contributes.data_categories`; without
|
|
375
|
+
* it the CLI's zod parse would strip the declaration before signing, and the
|
|
376
|
+
* app's danger-zone row would simply never appear on any node that installed
|
|
377
|
+
* the packed bundle. Loosely typed here for the same reason as the surfaces
|
|
378
|
+
* above — Core is the layer that types it, because Core is the layer that has
|
|
379
|
+
* to resolve the id to something that can actually delete the rows. */
|
|
380
|
+
data_categories: z.array(z.record(z.string(), z.unknown())).default([]),
|
|
338
381
|
/** Language servers the plugin declares, keyed by server name — the mirror of
|
|
339
382
|
* Claude Code's `.lsp.json` / `lspServers`, so a config written for either host
|
|
340
383
|
* loads in the other. Mirrors the Rust-side `Contributes.lsp_servers`; without
|
|
@@ -350,6 +393,15 @@ export const ContributesSchema = z.object({
|
|
|
350
393
|
lsp_servers: z
|
|
351
394
|
.record(z.string(), z.record(z.string(), z.unknown()))
|
|
352
395
|
.default({}),
|
|
396
|
+
/** Pi extensions the plugin ships — TypeScript the managed `ryu` (Pi) agent
|
|
397
|
+
* loads at process start. Mirrors the Rust-side `Contributes.pi_extensions`;
|
|
398
|
+
* without it the CLI's zod parse would strip the declaration before signing,
|
|
399
|
+
* and the packed plugin would ship a `pi-extensions/` folder nothing loads.
|
|
400
|
+
*
|
|
401
|
+
* Typed (not a loose record) because Ryu owns this vocabulary — three fields,
|
|
402
|
+
* all of them Core-interpreted — unlike `lsp_servers`, whose entry shape is
|
|
403
|
+
* Claude Code's to extend. */
|
|
404
|
+
pi_extensions: z.array(PiExtensionContributionSchema).default([]),
|
|
353
405
|
});
|
|
354
406
|
|
|
355
407
|
export type Contributes = z.infer<typeof ContributesSchema>;
|
package/src/runnable/app.ts
CHANGED
|
@@ -228,6 +228,10 @@ export function defineApp(options: DefineAppOptions): PluginManifest {
|
|
|
228
228
|
// takes no `contributes` passthrough. An app that wants to declare language
|
|
229
229
|
// servers writes them in a hand-authored `manifest.json`.
|
|
230
230
|
lsp_servers: {},
|
|
231
|
+
// Same reason again: a danger-zone category and a Pi extension are both
|
|
232
|
+
// hand-authored declarations, not something derivable from runnables.
|
|
233
|
+
data_categories: [],
|
|
234
|
+
pi_extensions: [],
|
|
231
235
|
widgets,
|
|
232
236
|
};
|
|
233
237
|
|
|
@@ -176,13 +176,16 @@ export function definePlugin(options: DefinePluginOptions): PluginManifest {
|
|
|
176
176
|
settings_tabs: options.settingsTabs ?? [],
|
|
177
177
|
slash_commands: options.slashCommands ?? [],
|
|
178
178
|
lsp_servers: options.lspServers ?? {},
|
|
179
|
-
// A turn-hook plugin contributes no app widgets, sidebar entries
|
|
180
|
-
// panels
|
|
181
|
-
// defaults applied), so set them
|
|
179
|
+
// A turn-hook plugin contributes no app widgets, sidebar entries, dock
|
|
180
|
+
// panels, danger-zone categories or Pi extensions; the fields are required
|
|
181
|
+
// on the resolved `Contributes` type (zod defaults applied), so set them
|
|
182
|
+
// explicitly.
|
|
182
183
|
widgets: [],
|
|
183
184
|
sidebar_sections: [],
|
|
184
185
|
sidebar_buttons: [],
|
|
185
186
|
dock_panels: [],
|
|
187
|
+
data_categories: [],
|
|
188
|
+
pi_extensions: [],
|
|
186
189
|
};
|
|
187
190
|
// Ship each inline tool as a `kind:"tool"` runnable (Core's `inline_deno`
|
|
188
191
|
// backend). Shipping tools requires the `tool:execute` grant; add it once.
|