@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.
@@ -153,9 +153,6 @@ export interface ToolRunnable<
153
153
  TInput extends Record<string, unknown> = Record<string, unknown>,
154
154
  TOutput = unknown,
155
155
  > extends Runnable<TInput, TOutput> {
156
- readonly kind: "tool";
157
- /** JSON Schema for this tool's input — compatible with Core's ToolInfo.schema. */
158
- readonly schema: ToolSchema;
159
156
  /**
160
157
  * The `run` body serialized for Core's `inline_deno` tool backend — the exact
161
158
  * same technique `defineTurnHook` uses for its `code`. This is what makes a
@@ -174,6 +171,9 @@ export interface ToolRunnable<
174
171
  * the sandbox form is the second parameter aliased to `host`.
175
172
  */
176
173
  readonly code: string;
174
+ readonly kind: "tool";
175
+ /** JSON Schema for this tool's input — compatible with Core's ToolInfo.schema. */
176
+ readonly schema: ToolSchema;
177
177
  }
178
178
 
179
179
  // ── Factory ───────────────────────────────────────────────────────────────────
@@ -232,7 +232,7 @@ export function defineTool<
232
232
  }
233
233
 
234
234
  /**
235
- * Convert a {@link ToolRunnable} into a `plugin.json` `kind:"tool"` runnable that
235
+ * Convert a {@link ToolRunnable} into a `manifest.json` `kind:"tool"` runnable that
236
236
  * ships its `run` body as Core's `inline_deno` backend. The emitted config
237
237
  * mirrors Core's `ToolConfig` (`apps/core/src/plugin_manifest/schema.rs`):
238
238
  * `{ slug, backend:"inline_deno", code, description?, input_schema }`. Core
@@ -15,6 +15,7 @@
15
15
 
16
16
  import type {
17
17
  Contributes,
18
+ HookEventContribution,
18
19
  PluginManifest,
19
20
  RunnableMeta,
20
21
  Surface,
@@ -90,9 +91,12 @@ export interface DefineTurnHookOptions {
90
91
  * is serialized into the sandbox `code` string and invoked with `ctx`/`host` at
91
92
  * run time.
92
93
  */
94
+ // `code` is optional on `TurnHookContribution` because a hand-authored manifest may
95
+ // carry `code_file` instead. This builder always produces the inline form, so it
96
+ // narrows the return type — callers get a `code` they need not null-check.
93
97
  export function defineTurnHook(
94
98
  options: DefineTurnHookOptions
95
- ): TurnHookContribution {
99
+ ): TurnHookContribution & { code: string } {
96
100
  const source = options.run.toString();
97
101
  // The sandbox wraps `code` in an async IIFE where `ctx`/`host` are in scope
98
102
  // and a bare `return` reports the directive — so call the serialized function
@@ -112,8 +116,24 @@ export interface DefinePluginOptions {
112
116
  composerControls?: Record<string, unknown>[];
113
117
  /** Capability grants the hooks need (e.g. `["hook:side-model", "storage:kv"]`). */
114
118
  grants?: string[];
119
+ /**
120
+ * App events this plugin EMITS — the provider half of the hook system whose
121
+ * consumer half is {@link DefinePluginOptions.turnHooks}. Each `id` must be
122
+ * namespaced to this plugin's own `id`; Core validates that at load and again
123
+ * on every emit.
124
+ */
125
+ hookEvents?: HookEventContribution[];
115
126
  /** Reverse-domain id (e.g. `"com.example.my-plugin"`). */
116
127
  id: string;
128
+ /**
129
+ * Language servers the plugin declares, keyed by server name — the same shape
130
+ * as Claude Code's `lspServers` / `.lsp.json`, passed verbatim. Loose records
131
+ * rather than a typed entry on purpose: Claude Code owns this field
132
+ * vocabulary, so typing it here would strip a field from a newer Claude
133
+ * release on its way through `ryu pack`. Core types it, because Core acts on
134
+ * it.
135
+ */
136
+ lspServers?: Record<string, Record<string, unknown>>;
117
137
  /** Display name. */
118
138
  name: string;
119
139
  /**
@@ -144,19 +164,25 @@ export interface DefinePluginOptions {
144
164
  }
145
165
 
146
166
  /**
147
- * Assemble a `plugin.json` manifest for a turn-hook plugin. The result matches
167
+ * Assemble a `manifest.json` manifest for a turn-hook plugin. The result matches
148
168
  * Core's `PluginManifest` serde shape and can be written to disk or validated via
149
169
  * `validateManifestStrict`.
150
170
  */
151
171
  export function definePlugin(options: DefinePluginOptions): PluginManifest {
152
172
  const contributes: Contributes = {
153
173
  turn_hooks: options.turnHooks ?? [],
174
+ hook_events: options.hookEvents ?? [],
154
175
  composer_controls: options.composerControls ?? [],
155
176
  settings_tabs: options.settingsTabs ?? [],
156
177
  slash_commands: options.slashCommands ?? [],
157
- // A turn-hook plugin contributes no app widgets; the field is required on the
158
- // resolved `Contributes` type (zod default applied), so set it explicitly.
178
+ lsp_servers: options.lspServers ?? {},
179
+ // A turn-hook plugin contributes no app widgets, sidebar entries or dock
180
+ // panels; the fields are required on the resolved `Contributes` type (zod
181
+ // defaults applied), so set them explicitly.
159
182
  widgets: [],
183
+ sidebar_sections: [],
184
+ sidebar_buttons: [],
185
+ dock_panels: [],
160
186
  };
161
187
  // Ship each inline tool as a `kind:"tool"` runnable (Core's `inline_deno`
162
188
  // backend). Shipping tools requires the `tool:execute` grant; add it once.