@ryuhq/sdk 0.0.5 → 0.0.17

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/manifest.cjs CHANGED
@@ -24,6 +24,7 @@ __export(manifest_exports, {
24
24
  CapabilityReqSchema: () => CapabilityReqSchema,
25
25
  CompanionSurfaceSchema: () => CompanionSurfaceSchema,
26
26
  ContributesSchema: () => ContributesSchema,
27
+ HookEventContributionSchema: () => HookEventContributionSchema,
27
28
  PluginManifestSchema: () => PluginManifestSchema,
28
29
  RequiresSchema: () => RequiresSchema,
29
30
  RunnableKindSchema: () => RunnableKindSchema,
@@ -122,7 +123,39 @@ var TurnHookContributionSchema = import_zod.z.object({
122
123
  /** Turn boundary this fires on. Today only `"post_assistant_turn"`. */
123
124
  on: import_zod.z.string().min(1).default("post_assistant_turn"),
124
125
  /** The JS hook body executed in the sandbox (returns a directive). */
125
- code: import_zod.z.string().min(1)
126
+ code: import_zod.z.string().min(1).optional(),
127
+ /** Path to the hook body, relative to the plugin root (`hooks/<name>.js`). */
128
+ code_file: import_zod.z.string().min(1).optional(),
129
+ /**
130
+ * Cheap pre-gate mirroring Core's `HookMatch` (serde name `match` on
131
+ * `TurnHookContribution.run_when`). MUST round-trip through this schema:
132
+ * `ryu pack`/`publish` persist `safeParse(...).data`, so a field missing here
133
+ * is silently STRIPPED before signing — a tool-gated `pre_tool_use` hook
134
+ * (e.g. `tools: ["bash*"]`) would lose its gate and run on EVERY tool call.
135
+ */
136
+ match: import_zod.z.object({
137
+ /** Run only if the request set this composer flag true. */
138
+ flag: import_zod.z.string().optional(),
139
+ /** Run if the last user message starts with any of these prefixes. */
140
+ commands: import_zod.z.array(import_zod.z.string()).default([]),
141
+ /** Run if the plugin has stored state for this conversation. */
142
+ stateful: import_zod.z.boolean().default(false),
143
+ /** Run if `ctx.tool_name` matches any of these `*`-wildcard patterns. */
144
+ tools: import_zod.z.array(import_zod.z.string()).default([])
145
+ }).optional()
146
+ }).refine((h) => Boolean(h.code) !== Boolean(h.code_file), {
147
+ message: "a turn hook must declare exactly one of 'code' (inline body) or 'code_file' (path to hooks/<name>.js)",
148
+ path: ["code_file"]
149
+ });
150
+ var HookEventContributionSchema = import_zod.z.object({
151
+ /** Fully-qualified event id: `<plugin id>#<event name>`, e.g. `@acme/meetings#meeting.ended`. */
152
+ id: import_zod.z.string().min(1),
153
+ /** Human-readable title for the event picker. */
154
+ title: import_zod.z.string().min(1),
155
+ /** What the event means and when it fires. */
156
+ description: import_zod.z.string().optional(),
157
+ /** Example of the `ctx.event` payload. Documentation, not a validated schema. */
158
+ payload_example: import_zod.z.record(import_zod.z.string(), import_zod.z.unknown()).optional()
126
159
  });
127
160
  var DEFAULT_WIDGET_MIME = "text/html+skybridge";
128
161
  var DEFAULT_WIDGET_DISPLAY_MODE = "inline";
@@ -160,6 +193,11 @@ var ToolAppConfigSchema = import_zod.z.object({
160
193
  });
161
194
  var ContributesSchema = import_zod.z.object({
162
195
  turn_hooks: import_zod.z.array(TurnHookContributionSchema).default([]),
196
+ /** App events this plugin EMITS — the provider half of the hook system, whose
197
+ * consumer half is `turn_hooks`. Mirrors the Rust `Contributes.hook_events`;
198
+ * omitting it here would have `ryu pack` strip every declared event before
199
+ * signing, leaving an app that emits events nothing is allowed to subscribe to. */
200
+ hook_events: import_zod.z.array(HookEventContributionSchema).default([]),
163
201
  composer_controls: import_zod.z.array(import_zod.z.record(import_zod.z.string(), import_zod.z.unknown())).default([]),
164
202
  settings_tabs: import_zod.z.array(import_zod.z.record(import_zod.z.string(), import_zod.z.unknown())).default([]),
165
203
  slash_commands: import_zod.z.array(import_zod.z.record(import_zod.z.string(), import_zod.z.unknown())).default([]),
@@ -167,7 +205,32 @@ var ContributesSchema = import_zod.z.object({
167
205
  * `ui://widget/<slug>.html` template. Mirrors the Rust-side
168
206
  * `Contributes.widgets` field, without which the CLI's zod parse would strip
169
207
  * every widget an app authored here declares. */
170
- widgets: import_zod.z.array(WidgetContributionSchema).default([])
208
+ widgets: import_zod.z.array(WidgetContributionSchema).default([]),
209
+ /** App-registered sidebar sections (header + live list) and buttons (single nav
210
+ * rows). Loosely typed here — the shell owns the spec vocabulary — matching how
211
+ * `composer_controls`/`settings_tabs` are declared. Mirrors the Rust-side
212
+ * `Contributes.sidebar_sections` / `Contributes.sidebar_buttons`. */
213
+ sidebar_sections: import_zod.z.array(import_zod.z.record(import_zod.z.string(), import_zod.z.unknown())).default([]),
214
+ sidebar_buttons: import_zod.z.array(import_zod.z.record(import_zod.z.string(), import_zod.z.unknown())).default([]),
215
+ /** App-registered workspace dock panels (a tab in the desktop's bottom/right
216
+ * dock). Loosely typed for the same reason as the surfaces above — the shell
217
+ * owns the `panel` render-mode vocabulary and the `spec` payload. Mirrors the
218
+ * Rust-side `Contributes.dock_panels`; without it the CLI's zod parse would
219
+ * strip the dock panel an app declares here. */
220
+ dock_panels: import_zod.z.array(import_zod.z.record(import_zod.z.string(), import_zod.z.unknown())).default([]),
221
+ /** Language servers the plugin declares, keyed by server name — the mirror of
222
+ * Claude Code's `.lsp.json` / `lspServers`, so a config written for either host
223
+ * loads in the other. Mirrors the Rust-side `Contributes.lsp_servers`; without
224
+ * it the CLI's zod parse would strip every language server a plugin declares,
225
+ * before the manifest is signed.
226
+ *
227
+ * The ENTRY is deliberately a loose record and not a 13-field `z.object()`
228
+ * mirroring `LspServerContribution`. Claude Code owns this field vocabulary,
229
+ * not Ryu: a typed object here would strip a field from a newer Claude release
230
+ * on its way through `ryu pack` — the same silent-deletion bug this field
231
+ * exists to fix, one level down. Core is the layer that types it, because Core
232
+ * 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({})
171
234
  });
172
235
  var SetupStepSchema = import_zod.z.object({
173
236
  /** Card heading (e.g. the companion app name). */
@@ -348,6 +411,25 @@ var PluginManifestSchema = import_zod.z.object({
348
411
  license: import_zod.z.string().optional(),
349
412
  /** Square logo/icon URL for the listing card + detail header. */
350
413
  iconUrl: import_zod.z.string().optional(),
414
+ /**
415
+ * Icon-primitive id for the listing card (Ryu extension): an Iconify/icons0
416
+ * `prefix:name`, a bare Hugeicons name, or a URL, resolved by the shared `Icon`
417
+ * primitive. A monochrome GLYPH masked with the current text colour — distinct
418
+ * from `iconUrl` (a raster logo). Falls back to `iconUrl` when omitted.
419
+ */
420
+ icon: import_zod.z.string().optional(),
421
+ /**
422
+ * Dithered-gradient background for the card's icon square (Ryu extension),
423
+ * mirroring dither-kit's `DitherGradient` props. `from`/`to` are a palette-colour
424
+ * name (`green`, `blue`, `purple`, `pink`, `orange`, `red`, `grey`) or a hue
425
+ * number (0–360); `direction` is where `to` ends up. Renders behind the glyph in
426
+ * place of a flat `iconBackground`; the render layer validates + falls back.
427
+ */
428
+ iconDither: import_zod.z.object({
429
+ from: import_zod.z.union([import_zod.z.string(), import_zod.z.number()]),
430
+ to: import_zod.z.union([import_zod.z.string(), import_zod.z.number()]).optional(),
431
+ direction: import_zod.z.enum(["up", "down", "left", "right"]).optional()
432
+ }).optional(),
351
433
  /** Ordered App-Store-style screenshot gallery URLs (Ryu extension). */
352
434
  screenshots: import_zod.z.array(import_zod.z.string()).optional(),
353
435
  /** Privacy policy URL surfaced on detail (Ryu extension). */
@@ -383,6 +465,7 @@ function coreManifestJsonSchema() {
383
465
  CapabilityReqSchema,
384
466
  CompanionSurfaceSchema,
385
467
  ContributesSchema,
468
+ HookEventContributionSchema,
386
469
  PluginManifestSchema,
387
470
  RequiresSchema,
388
471
  RunnableKindSchema,
@@ -67,16 +67,54 @@ declare const CompanionSurfaceSchema: z.ZodObject<{
67
67
  type CompanionSurface = z.infer<typeof CompanionSurfaceSchema>;
68
68
  /**
69
69
  * A server-side chat turn hook. Mirrors `TurnHookContribution` in
70
- * `apps/core/src/plugin_manifest/mod.rs`. `code` is a JS body run in the plugin
71
- * sandbox with `ctx` + `host` in scope; it returns a directive. Authors usually
72
- * build this via `defineTurnHook` rather than writing the string by hand.
70
+ * `crates/core/kernel-contracts/src/manifest.rs`. The body is a JS fragment run in
71
+ * the plugin sandbox with `ctx` + `host` in scope; it returns a directive.
72
+ *
73
+ * It arrives one of two ways, and **exactly one** must be present:
74
+ *
75
+ * - `code_file` — the authoring form: a path to a real `hooks/<name>.js` file next
76
+ * to the manifest. Readable, lintable, diffable, and reviewable for what it
77
+ * actually does. Every first-party plugin uses this.
78
+ * - `code` — the wire form: the body inline. `ryu pack` produces it by reading
79
+ * `code_file`, which is what keeps the whole hook body INSIDE the Gateway-signed
80
+ * surface; Core also accepts it directly for a hand-written or `defineTurnHook`
81
+ * generated manifest.
73
82
  */
74
83
  declare const TurnHookContributionSchema: z.ZodObject<{
75
84
  id: z.ZodString;
76
85
  on: z.ZodDefault<z.ZodString>;
77
- code: z.ZodString;
86
+ code: z.ZodOptional<z.ZodString>;
87
+ code_file: z.ZodOptional<z.ZodString>;
88
+ match: z.ZodOptional<z.ZodObject<{
89
+ flag: z.ZodOptional<z.ZodString>;
90
+ commands: z.ZodDefault<z.ZodArray<z.ZodString>>;
91
+ stateful: z.ZodDefault<z.ZodBoolean>;
92
+ tools: z.ZodDefault<z.ZodArray<z.ZodString>>;
93
+ }, z.core.$strip>>;
78
94
  }, z.core.$strip>;
79
95
  type TurnHookContribution = z.infer<typeof TurnHookContributionSchema>;
96
+ /**
97
+ * One **app event** this plugin declares it emits. Mirrors `HookEventContribution`
98
+ * in `crates/core/kernel-contracts/src/manifest.rs`.
99
+ *
100
+ * `turn_hooks` is the *consuming* half of the hook system; this is the *providing*
101
+ * half. Declaring an event here lets any other plugin react to it with a
102
+ * `turn_hooks[].on` naming the event, and any workflow react to it with an `event`
103
+ * trigger — without the emitter knowing a consumer exists. The event is raised at
104
+ * runtime by this plugin's own sidecar calling the `events.emit` host capability.
105
+ *
106
+ * `id` MUST be `<this plugin's id>#<event name>`. Core validates the namespace half
107
+ * against the owning manifest at load and re-checks it on every emit, which is both
108
+ * what makes collisions with Core's own hook phases impossible (a Core phase never
109
+ * contains `#`) and what stops one app emitting another's events.
110
+ */
111
+ declare const HookEventContributionSchema: z.ZodObject<{
112
+ id: z.ZodString;
113
+ title: z.ZodString;
114
+ description: z.ZodOptional<z.ZodString>;
115
+ payload_example: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
116
+ }, z.core.$strip>;
117
+ type HookEventContribution = z.infer<typeof HookEventContributionSchema>;
80
118
  /**
81
119
  * One app-widget contribution (Ryu Apps). Binds the render tool that produces the
82
120
  * widget to its `ui://widget/<slug>.html` template. Shape-identical to Core's
@@ -121,7 +159,20 @@ declare const ContributesSchema: z.ZodObject<{
121
159
  turn_hooks: z.ZodDefault<z.ZodArray<z.ZodObject<{
122
160
  id: z.ZodString;
123
161
  on: z.ZodDefault<z.ZodString>;
124
- code: z.ZodString;
162
+ code: z.ZodOptional<z.ZodString>;
163
+ code_file: z.ZodOptional<z.ZodString>;
164
+ match: z.ZodOptional<z.ZodObject<{
165
+ flag: z.ZodOptional<z.ZodString>;
166
+ commands: z.ZodDefault<z.ZodArray<z.ZodString>>;
167
+ stateful: z.ZodDefault<z.ZodBoolean>;
168
+ tools: z.ZodDefault<z.ZodArray<z.ZodString>>;
169
+ }, z.core.$strip>>;
170
+ }, z.core.$strip>>>;
171
+ hook_events: z.ZodDefault<z.ZodArray<z.ZodObject<{
172
+ id: z.ZodString;
173
+ title: z.ZodString;
174
+ description: z.ZodOptional<z.ZodString>;
175
+ payload_example: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
125
176
  }, z.core.$strip>>>;
126
177
  composer_controls: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
127
178
  settings_tabs: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
@@ -133,6 +184,10 @@ declare const ContributesSchema: z.ZodObject<{
133
184
  mime: z.ZodDefault<z.ZodString>;
134
185
  default_display_mode: z.ZodDefault<z.ZodString>;
135
186
  }, z.core.$strip>>>;
187
+ sidebar_sections: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
188
+ sidebar_buttons: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
189
+ dock_panels: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
190
+ lsp_servers: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
136
191
  }, z.core.$strip>;
137
192
  type Contributes = z.infer<typeof ContributesSchema>;
138
193
  /**
@@ -218,7 +273,7 @@ declare const SurfaceSchema: z.ZodEnum<{
218
273
  }>;
219
274
  type Surface = z.infer<typeof SurfaceSchema>;
220
275
  /**
221
- * Full schema for a `plugin.json` Plugin manifest. Mirrors `PluginManifest` in
276
+ * Full schema for a `manifest.json` Plugin manifest. Mirrors `PluginManifest` in
222
277
  * `apps/core/src/plugin_manifest/mod.rs`.
223
278
  *
224
279
  * Validation rules (matching Core's `PluginManifestLoader`):
@@ -255,7 +310,20 @@ declare const PluginManifestSchema: z.ZodObject<{
255
310
  turn_hooks: z.ZodDefault<z.ZodArray<z.ZodObject<{
256
311
  id: z.ZodString;
257
312
  on: z.ZodDefault<z.ZodString>;
258
- code: z.ZodString;
313
+ code: z.ZodOptional<z.ZodString>;
314
+ code_file: z.ZodOptional<z.ZodString>;
315
+ match: z.ZodOptional<z.ZodObject<{
316
+ flag: z.ZodOptional<z.ZodString>;
317
+ commands: z.ZodDefault<z.ZodArray<z.ZodString>>;
318
+ stateful: z.ZodDefault<z.ZodBoolean>;
319
+ tools: z.ZodDefault<z.ZodArray<z.ZodString>>;
320
+ }, z.core.$strip>>;
321
+ }, z.core.$strip>>>;
322
+ hook_events: z.ZodDefault<z.ZodArray<z.ZodObject<{
323
+ id: z.ZodString;
324
+ title: z.ZodString;
325
+ description: z.ZodOptional<z.ZodString>;
326
+ payload_example: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
259
327
  }, z.core.$strip>>>;
260
328
  composer_controls: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
261
329
  settings_tabs: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
@@ -267,6 +335,10 @@ declare const PluginManifestSchema: z.ZodObject<{
267
335
  mime: z.ZodDefault<z.ZodString>;
268
336
  default_display_mode: z.ZodDefault<z.ZodString>;
269
337
  }, z.core.$strip>>>;
338
+ sidebar_sections: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
339
+ sidebar_buttons: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
340
+ dock_panels: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
341
+ lsp_servers: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
270
342
  }, z.core.$strip>>;
271
343
  requires: z.ZodOptional<z.ZodObject<{
272
344
  apps: z.ZodDefault<z.ZodArray<z.ZodObject<{
@@ -317,6 +389,17 @@ declare const PluginManifestSchema: z.ZodObject<{
317
389
  category: z.ZodOptional<z.ZodString>;
318
390
  license: z.ZodOptional<z.ZodString>;
319
391
  iconUrl: z.ZodOptional<z.ZodString>;
392
+ icon: z.ZodOptional<z.ZodString>;
393
+ iconDither: z.ZodOptional<z.ZodObject<{
394
+ from: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
395
+ to: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
396
+ direction: z.ZodOptional<z.ZodEnum<{
397
+ up: "up";
398
+ down: "down";
399
+ left: "left";
400
+ right: "right";
401
+ }>>;
402
+ }, z.core.$strip>>;
320
403
  screenshots: z.ZodOptional<z.ZodArray<z.ZodString>>;
321
404
  privacyPolicyUrl: z.ZodOptional<z.ZodString>;
322
405
  termsOfServiceUrl: z.ZodOptional<z.ZodString>;
@@ -341,15 +424,15 @@ type PluginManifest = z.infer<typeof PluginManifestSchema>;
341
424
  */
342
425
  declare function validatePluginId(id: string): void;
343
426
  /**
344
- * Validate a full `plugin.json` string against Core's authoritative rules
427
+ * Validate a full `manifest.json` string against Core's authoritative rules
345
428
  * (id, semver, per-kind runnable config contracts). Returns the normalized
346
429
  * manifest JSON string, or throws.
347
430
  */
348
431
  declare function validateManifestStrict(manifestJson: string): string;
349
432
  /**
350
- * The Core-derived JSON Schema for a `plugin.json`, as a parsed object. Stays in
433
+ * The Core-derived JSON Schema for a `manifest.json`, as a parsed object. Stays in
351
434
  * lockstep with the Rust types because it is emitted from them.
352
435
  */
353
436
  declare function coreManifestJsonSchema(): unknown;
354
437
 
355
- export { type AppDependency, AppDependencySchema, type CapabilityReq, CapabilityReqSchema, type CompanionSurface, CompanionSurfaceSchema, type Contributes, ContributesSchema, 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 };
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 };
@@ -67,16 +67,54 @@ declare const CompanionSurfaceSchema: z.ZodObject<{
67
67
  type CompanionSurface = z.infer<typeof CompanionSurfaceSchema>;
68
68
  /**
69
69
  * A server-side chat turn hook. Mirrors `TurnHookContribution` in
70
- * `apps/core/src/plugin_manifest/mod.rs`. `code` is a JS body run in the plugin
71
- * sandbox with `ctx` + `host` in scope; it returns a directive. Authors usually
72
- * build this via `defineTurnHook` rather than writing the string by hand.
70
+ * `crates/core/kernel-contracts/src/manifest.rs`. The body is a JS fragment run in
71
+ * the plugin sandbox with `ctx` + `host` in scope; it returns a directive.
72
+ *
73
+ * It arrives one of two ways, and **exactly one** must be present:
74
+ *
75
+ * - `code_file` — the authoring form: a path to a real `hooks/<name>.js` file next
76
+ * to the manifest. Readable, lintable, diffable, and reviewable for what it
77
+ * actually does. Every first-party plugin uses this.
78
+ * - `code` — the wire form: the body inline. `ryu pack` produces it by reading
79
+ * `code_file`, which is what keeps the whole hook body INSIDE the Gateway-signed
80
+ * surface; Core also accepts it directly for a hand-written or `defineTurnHook`
81
+ * generated manifest.
73
82
  */
74
83
  declare const TurnHookContributionSchema: z.ZodObject<{
75
84
  id: z.ZodString;
76
85
  on: z.ZodDefault<z.ZodString>;
77
- code: z.ZodString;
86
+ code: z.ZodOptional<z.ZodString>;
87
+ code_file: z.ZodOptional<z.ZodString>;
88
+ match: z.ZodOptional<z.ZodObject<{
89
+ flag: z.ZodOptional<z.ZodString>;
90
+ commands: z.ZodDefault<z.ZodArray<z.ZodString>>;
91
+ stateful: z.ZodDefault<z.ZodBoolean>;
92
+ tools: z.ZodDefault<z.ZodArray<z.ZodString>>;
93
+ }, z.core.$strip>>;
78
94
  }, z.core.$strip>;
79
95
  type TurnHookContribution = z.infer<typeof TurnHookContributionSchema>;
96
+ /**
97
+ * One **app event** this plugin declares it emits. Mirrors `HookEventContribution`
98
+ * in `crates/core/kernel-contracts/src/manifest.rs`.
99
+ *
100
+ * `turn_hooks` is the *consuming* half of the hook system; this is the *providing*
101
+ * half. Declaring an event here lets any other plugin react to it with a
102
+ * `turn_hooks[].on` naming the event, and any workflow react to it with an `event`
103
+ * trigger — without the emitter knowing a consumer exists. The event is raised at
104
+ * runtime by this plugin's own sidecar calling the `events.emit` host capability.
105
+ *
106
+ * `id` MUST be `<this plugin's id>#<event name>`. Core validates the namespace half
107
+ * against the owning manifest at load and re-checks it on every emit, which is both
108
+ * what makes collisions with Core's own hook phases impossible (a Core phase never
109
+ * contains `#`) and what stops one app emitting another's events.
110
+ */
111
+ declare const HookEventContributionSchema: z.ZodObject<{
112
+ id: z.ZodString;
113
+ title: z.ZodString;
114
+ description: z.ZodOptional<z.ZodString>;
115
+ payload_example: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
116
+ }, z.core.$strip>;
117
+ type HookEventContribution = z.infer<typeof HookEventContributionSchema>;
80
118
  /**
81
119
  * One app-widget contribution (Ryu Apps). Binds the render tool that produces the
82
120
  * widget to its `ui://widget/<slug>.html` template. Shape-identical to Core's
@@ -121,7 +159,20 @@ declare const ContributesSchema: z.ZodObject<{
121
159
  turn_hooks: z.ZodDefault<z.ZodArray<z.ZodObject<{
122
160
  id: z.ZodString;
123
161
  on: z.ZodDefault<z.ZodString>;
124
- code: z.ZodString;
162
+ code: z.ZodOptional<z.ZodString>;
163
+ code_file: z.ZodOptional<z.ZodString>;
164
+ match: z.ZodOptional<z.ZodObject<{
165
+ flag: z.ZodOptional<z.ZodString>;
166
+ commands: z.ZodDefault<z.ZodArray<z.ZodString>>;
167
+ stateful: z.ZodDefault<z.ZodBoolean>;
168
+ tools: z.ZodDefault<z.ZodArray<z.ZodString>>;
169
+ }, z.core.$strip>>;
170
+ }, z.core.$strip>>>;
171
+ hook_events: z.ZodDefault<z.ZodArray<z.ZodObject<{
172
+ id: z.ZodString;
173
+ title: z.ZodString;
174
+ description: z.ZodOptional<z.ZodString>;
175
+ payload_example: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
125
176
  }, z.core.$strip>>>;
126
177
  composer_controls: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
127
178
  settings_tabs: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
@@ -133,6 +184,10 @@ declare const ContributesSchema: z.ZodObject<{
133
184
  mime: z.ZodDefault<z.ZodString>;
134
185
  default_display_mode: z.ZodDefault<z.ZodString>;
135
186
  }, z.core.$strip>>>;
187
+ sidebar_sections: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
188
+ sidebar_buttons: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
189
+ dock_panels: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
190
+ lsp_servers: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
136
191
  }, z.core.$strip>;
137
192
  type Contributes = z.infer<typeof ContributesSchema>;
138
193
  /**
@@ -218,7 +273,7 @@ declare const SurfaceSchema: z.ZodEnum<{
218
273
  }>;
219
274
  type Surface = z.infer<typeof SurfaceSchema>;
220
275
  /**
221
- * Full schema for a `plugin.json` Plugin manifest. Mirrors `PluginManifest` in
276
+ * Full schema for a `manifest.json` Plugin manifest. Mirrors `PluginManifest` in
222
277
  * `apps/core/src/plugin_manifest/mod.rs`.
223
278
  *
224
279
  * Validation rules (matching Core's `PluginManifestLoader`):
@@ -255,7 +310,20 @@ declare const PluginManifestSchema: z.ZodObject<{
255
310
  turn_hooks: z.ZodDefault<z.ZodArray<z.ZodObject<{
256
311
  id: z.ZodString;
257
312
  on: z.ZodDefault<z.ZodString>;
258
- code: z.ZodString;
313
+ code: z.ZodOptional<z.ZodString>;
314
+ code_file: z.ZodOptional<z.ZodString>;
315
+ match: z.ZodOptional<z.ZodObject<{
316
+ flag: z.ZodOptional<z.ZodString>;
317
+ commands: z.ZodDefault<z.ZodArray<z.ZodString>>;
318
+ stateful: z.ZodDefault<z.ZodBoolean>;
319
+ tools: z.ZodDefault<z.ZodArray<z.ZodString>>;
320
+ }, z.core.$strip>>;
321
+ }, z.core.$strip>>>;
322
+ hook_events: z.ZodDefault<z.ZodArray<z.ZodObject<{
323
+ id: z.ZodString;
324
+ title: z.ZodString;
325
+ description: z.ZodOptional<z.ZodString>;
326
+ payload_example: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
259
327
  }, z.core.$strip>>>;
260
328
  composer_controls: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
261
329
  settings_tabs: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
@@ -267,6 +335,10 @@ declare const PluginManifestSchema: z.ZodObject<{
267
335
  mime: z.ZodDefault<z.ZodString>;
268
336
  default_display_mode: z.ZodDefault<z.ZodString>;
269
337
  }, z.core.$strip>>>;
338
+ sidebar_sections: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
339
+ sidebar_buttons: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
340
+ dock_panels: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
341
+ lsp_servers: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
270
342
  }, z.core.$strip>>;
271
343
  requires: z.ZodOptional<z.ZodObject<{
272
344
  apps: z.ZodDefault<z.ZodArray<z.ZodObject<{
@@ -317,6 +389,17 @@ declare const PluginManifestSchema: z.ZodObject<{
317
389
  category: z.ZodOptional<z.ZodString>;
318
390
  license: z.ZodOptional<z.ZodString>;
319
391
  iconUrl: z.ZodOptional<z.ZodString>;
392
+ icon: z.ZodOptional<z.ZodString>;
393
+ iconDither: z.ZodOptional<z.ZodObject<{
394
+ from: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
395
+ to: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
396
+ direction: z.ZodOptional<z.ZodEnum<{
397
+ up: "up";
398
+ down: "down";
399
+ left: "left";
400
+ right: "right";
401
+ }>>;
402
+ }, z.core.$strip>>;
320
403
  screenshots: z.ZodOptional<z.ZodArray<z.ZodString>>;
321
404
  privacyPolicyUrl: z.ZodOptional<z.ZodString>;
322
405
  termsOfServiceUrl: z.ZodOptional<z.ZodString>;
@@ -341,15 +424,15 @@ type PluginManifest = z.infer<typeof PluginManifestSchema>;
341
424
  */
342
425
  declare function validatePluginId(id: string): void;
343
426
  /**
344
- * Validate a full `plugin.json` string against Core's authoritative rules
427
+ * Validate a full `manifest.json` string against Core's authoritative rules
345
428
  * (id, semver, per-kind runnable config contracts). Returns the normalized
346
429
  * manifest JSON string, or throws.
347
430
  */
348
431
  declare function validateManifestStrict(manifestJson: string): string;
349
432
  /**
350
- * The Core-derived JSON Schema for a `plugin.json`, as a parsed object. Stays in
433
+ * The Core-derived JSON Schema for a `manifest.json`, as a parsed object. Stays in
351
434
  * lockstep with the Rust types because it is emitted from them.
352
435
  */
353
436
  declare function coreManifestJsonSchema(): unknown;
354
437
 
355
- export { type AppDependency, AppDependencySchema, type CapabilityReq, CapabilityReqSchema, type CompanionSurface, CompanionSurfaceSchema, type Contributes, ContributesSchema, 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 };
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 };
package/dist/manifest.js CHANGED
@@ -3,6 +3,7 @@ import {
3
3
  CapabilityReqSchema,
4
4
  CompanionSurfaceSchema,
5
5
  ContributesSchema,
6
+ HookEventContributionSchema,
6
7
  PluginManifestSchema,
7
8
  RequiresSchema,
8
9
  RunnableKindSchema,
@@ -16,12 +17,13 @@ import {
16
17
  labelImpersonatesSystemChrome,
17
18
  validateManifestStrict,
18
19
  validatePluginId
19
- } from "./chunk-GXHL5CO7.js";
20
+ } from "./chunk-SKVIJH5I.js";
20
21
  export {
21
22
  AppDependencySchema,
22
23
  CapabilityReqSchema,
23
24
  CompanionSurfaceSchema,
24
25
  ContributesSchema,
26
+ HookEventContributionSchema,
25
27
  PluginManifestSchema,
26
28
  RequiresSchema,
27
29
  RunnableKindSchema,
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@ryuhq/sdk",
3
- "version": "0.0.5",
3
+ "version": "0.0.17",
4
4
  "type": "module",
5
- "description": "Ryu developer SDK: typed builders and CLI for authoring plugin.json Plugin bundles",
5
+ "description": "Ryu developer SDK: typed builders and CLI for authoring manifest.json Plugin bundles",
6
6
  "main": "./dist/index.cjs",
7
7
  "types": "./dist/index.d.ts",
8
8
  "exports": {
package/src/builder.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Ryu SDK typed builders — one builder per RunnableKind plus a PluginBuilder that
3
- * assembles a complete, validated `plugin.json` manifest.
3
+ * assembles a complete, validated `manifest.json` manifest.
4
4
  *
5
5
  * Each builder follows a fluent interface: construct, chain setter calls, then
6
6
  * call `.build()` to get a validated result. Invalid manifests throw a
@@ -125,7 +125,7 @@ export const skill = () => new SkillBuilder();
125
125
  // ── PluginBuilder ─────────────────────────────────────────────────────────────
126
126
 
127
127
  /**
128
- * Fluent builder for a complete `plugin.json` Plugin manifest. Produces a
128
+ * Fluent builder for a complete `manifest.json` Plugin manifest. Produces a
129
129
  * validated `PluginManifest` on `.build()` or throws a descriptive `Error`
130
130
  * naming the first invalid field.
131
131
  *
@@ -279,7 +279,7 @@ export class PluginBuilder {
279
279
  const field = first?.path.join(".") ?? "unknown";
280
280
  const message = first?.message ?? "validation failed";
281
281
  throw new Error(
282
- `plugin.json validation failed at '${field}': ${message}`
282
+ `manifest.json validation failed at '${field}': ${message}`
283
283
  );
284
284
  }
285
285
  return result.data;
@@ -289,7 +289,7 @@ export class PluginBuilder {
289
289
  // ── AppBuilder (Ryu Apps) ─────────────────────────────────────────────────────
290
290
 
291
291
  /**
292
- * Fluent builder for a Ryu App — a `plugin.json` whose tools render interactive
292
+ * Fluent builder for a Ryu App — a `manifest.json` whose tools render interactive
293
293
  * widgets inline in chat. Delegates to {@link defineApp} on `.build()`, so it
294
294
  * derives the render-vs-companion split and validates through
295
295
  * `PluginManifestSchema` (throwing a descriptive `Error` on bad input) exactly