@ryuhq/sdk 0.1.13 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -6
- package/dist/agent-plugin.cjs +46 -0
- package/dist/agent-plugin.d.cts +42 -32
- package/dist/agent-plugin.d.ts +42 -32
- package/dist/agent-plugin.js +1 -1
- package/dist/agent.cjs +9 -0
- package/dist/agent.d.cts +377 -1
- package/dist/agent.d.ts +377 -1
- package/dist/agent.js +4 -2
- package/dist/app-Bkw7LlCK.d.ts +129 -0
- package/dist/app-DNaGmLVf.d.cts +129 -0
- package/dist/builder.cjs +1095 -0
- package/dist/builder.d.cts +212 -0
- package/dist/builder.d.ts +212 -0
- package/dist/builder.js +28 -0
- package/dist/chunk-A3RGEPDG.js +250 -0
- package/dist/chunk-FZSFZOIN.js +200 -0
- package/dist/{chunk-ODFEUVPW.js → chunk-HACAGK65.js} +1 -18
- package/dist/{chunk-AO2KJRDD.js → chunk-IEUQ3CDG.js} +125 -2
- package/dist/chunk-IKEDLLFY.js +19 -0
- package/dist/chunk-IOLP5FFE.js +354 -0
- package/dist/{chunk-G6FLVEC4.js → chunk-JX6DDRXV.js} +46 -0
- package/dist/chunk-T5676WL2.js +240 -0
- package/dist/chunk-TLDPEGC7.js +21 -0
- package/dist/chunk-TXSHHZF2.js +0 -0
- package/dist/{chunk-MTUBUPIV.js → chunk-ULSVL7EC.js} +8 -227
- package/dist/chunk-VLIRNNAE.js +154 -0
- package/dist/chunk-W3KPP4WN.js +135 -0
- package/dist/cli.cjs +258 -14
- package/dist/cli.js +96 -16
- package/dist/client-D5U6ssPc.d.cts +84 -0
- package/dist/client-D5U6ssPc.d.ts +84 -0
- package/dist/index.cjs +519 -5
- package/dist/index.d.cts +16 -632
- package/dist/index.d.ts +16 -632
- package/dist/index.js +63 -695
- package/dist/manifest.cjs +129 -3
- package/dist/manifest.d.cts +105 -2
- package/dist/manifest.d.ts +105 -2
- package/dist/manifest.js +7 -1
- package/dist/mcp/client.cjs +180 -0
- package/dist/mcp/client.d.cts +49 -0
- package/dist/mcp/client.d.ts +49 -0
- package/dist/mcp/client.js +10 -0
- package/dist/mcp/server.cjs +370 -0
- package/dist/mcp/server.d.cts +126 -0
- package/dist/mcp/server.d.ts +126 -0
- package/dist/mcp/server.js +9 -0
- package/dist/mcp.cjs +376 -0
- package/dist/mcp.d.cts +2 -0
- package/dist/mcp.d.ts +2 -0
- package/dist/mcp.js +17 -0
- package/dist/model.cjs +141 -0
- package/dist/model.d.cts +33 -0
- package/dist/model.d.ts +33 -0
- package/dist/model.js +18 -0
- package/dist/plugin.cjs +46 -0
- package/dist/plugin.d.cts +215 -0
- package/dist/plugin.d.ts +215 -0
- package/dist/plugin.js +8 -0
- package/dist/runnable.cjs +1230 -0
- package/dist/runnable.d.cts +271 -0
- package/dist/runnable.d.ts +271 -0
- package/dist/runnable.js +28 -0
- package/dist/{index-B6SkaAjJ.d.ts → tool-DSx2bFx8.d.ts} +35 -458
- package/dist/{index-BvAB5eMk.d.cts → tool-u-VR0fLF.d.cts} +35 -458
- package/package.json +38 -2
- package/src/agent/loop.test.ts +4 -4
- package/src/agent/tools.ts +3 -3
- package/src/agent-plugin.test.ts +58 -0
- package/src/agent-plugin.ts +108 -35
- package/src/cli/dev.test.ts +26 -47
- package/src/cli/dev.ts +10 -2
- package/src/cli.ts +98 -15
- package/src/exports-lockstep.test.ts +92 -0
- package/src/generated/plugin-manifest.ts +243 -27
- package/src/index.ts +35 -0
- package/src/manifest-schema.test.ts +30 -1
- package/src/manifest.fixtures.test.ts +13 -3
- package/src/manifest.test.ts +96 -10
- package/src/manifest.ts +334 -187
- package/src/mcp/index.ts +18 -0
- package/src/model/index.ts +22 -0
- package/src/plugin/ryu-plugin.ts +82 -0
- package/src/runnable/app.test.ts +2 -0
- package/src/runnable/app.ts +5 -2
- package/src/runnable/index.ts +2 -0
- package/src/runnable/primitives.ts +57 -0
- package/src/runnable/tool.ts +1 -1
- package/src/runnable/turn-hook.ts +4 -1
package/src/manifest.test.ts
CHANGED
|
@@ -302,7 +302,7 @@ describe("defineApp", () => {
|
|
|
302
302
|
const widgets = manifest.contributes?.widgets ?? [];
|
|
303
303
|
|
|
304
304
|
expect(widgets).toHaveLength(1);
|
|
305
|
-
expect(widgets[0]?.tool_id).toBe("
|
|
305
|
+
expect(widgets[0]?.tool_id).toBe("checklist.render");
|
|
306
306
|
expect(widgets[0]?.uri).toBe("ui://widget/checklist.html");
|
|
307
307
|
expect(widgets[0]?.ui_entry).toBe("src/checklist.tsx");
|
|
308
308
|
expect(widgets[0]?.mime).toBe("text/html+skybridge");
|
|
@@ -314,9 +314,9 @@ describe("defineApp", () => {
|
|
|
314
314
|
expect(manifest.runnables).toHaveLength(2);
|
|
315
315
|
expect(manifest.runnables.every((r) => r.kind === "tool")).toBe(true);
|
|
316
316
|
|
|
317
|
-
const render = manifest.runnables.find((r) => r.id === "
|
|
317
|
+
const render = manifest.runnables.find((r) => r.id === "checklist.render");
|
|
318
318
|
expect(render?.config).toMatchObject({
|
|
319
|
-
slug: "
|
|
319
|
+
slug: "checklist.render",
|
|
320
320
|
// The manifest is the only channel for a packed app: description +
|
|
321
321
|
// input_schema must survive so Core can rebuild a driveable tool.
|
|
322
322
|
description: "Render a checklist",
|
|
@@ -332,9 +332,9 @@ describe("defineApp", () => {
|
|
|
332
332
|
invoked: "Ready",
|
|
333
333
|
});
|
|
334
334
|
|
|
335
|
-
const toggle = manifest.runnables.find((r) => r.id === "
|
|
335
|
+
const toggle = manifest.runnables.find((r) => r.id === "checklist.toggle");
|
|
336
336
|
expect(toggle?.config).toMatchObject({
|
|
337
|
-
slug: "
|
|
337
|
+
slug: "checklist.toggle",
|
|
338
338
|
widget: false,
|
|
339
339
|
widget_accessible: true,
|
|
340
340
|
});
|
|
@@ -350,13 +350,13 @@ describe("defineApp", () => {
|
|
|
350
350
|
uiEntry: "src/chart.tsx",
|
|
351
351
|
tools: [{ name: "render", description: "Render a chart" }],
|
|
352
352
|
});
|
|
353
|
-
const render = manifest.runnables.find((r) => r.id === "
|
|
353
|
+
const render = manifest.runnables.find((r) => r.id === "chart.render");
|
|
354
354
|
expect(render?.config).toMatchObject({
|
|
355
355
|
widget: true,
|
|
356
356
|
widget_accessible: false,
|
|
357
357
|
});
|
|
358
358
|
// `server` override qualifies the tool id and the widget binding.
|
|
359
|
-
expect(manifest.contributes?.widgets[0]?.tool_id).toBe("
|
|
359
|
+
expect(manifest.contributes?.widgets[0]?.tool_id).toBe("chart.render");
|
|
360
360
|
// The widget uri still derives from the slug, not the server.
|
|
361
361
|
expect(manifest.contributes?.widgets[0]?.uri).toBe(
|
|
362
362
|
"ui://widget/chart-studio.html"
|
|
@@ -377,12 +377,12 @@ describe("defineApp", () => {
|
|
|
377
377
|
}
|
|
378
378
|
expect(parsed.data.contributes?.widgets).toHaveLength(1);
|
|
379
379
|
expect(parsed.data.contributes?.widgets[0]?.tool_id).toBe(
|
|
380
|
-
"
|
|
380
|
+
"checklist.render"
|
|
381
381
|
);
|
|
382
382
|
// description + input_schema survive the strict parse (the only channel for
|
|
383
383
|
// a packed app — no `generated.rs` on the Core side).
|
|
384
384
|
const render = parsed.data.runnables.find(
|
|
385
|
-
(r) => r.id === "
|
|
385
|
+
(r) => r.id === "checklist.render"
|
|
386
386
|
);
|
|
387
387
|
expect(render?.config?.description).toBe("Render a checklist");
|
|
388
388
|
expect(render?.config?.input_schema).toBeDefined();
|
|
@@ -423,7 +423,7 @@ describe("AppBuilder", () => {
|
|
|
423
423
|
expect(manifest.id).toBe("com.example.checklist");
|
|
424
424
|
expect(manifest.runnables).toHaveLength(2);
|
|
425
425
|
expect(manifest.contributes?.widgets).toHaveLength(1);
|
|
426
|
-
expect(manifest.contributes?.widgets[0]?.tool_id).toBe("
|
|
426
|
+
expect(manifest.contributes?.widgets[0]?.tool_id).toBe("checklist.render");
|
|
427
427
|
// The author's own grant, plus the `widget:render` the builder adds because
|
|
428
428
|
// this app synthesises a widget — without it Core silently degrades the
|
|
429
429
|
// widget to plain text.
|
|
@@ -774,3 +774,89 @@ describe("contributes.lsp_servers", () => {
|
|
|
774
774
|
expect(parsed.data.contributes?.lsp_servers).toEqual({});
|
|
775
775
|
});
|
|
776
776
|
});
|
|
777
|
+
|
|
778
|
+
describe("contributes.message_actions", () => {
|
|
779
|
+
it("preserves renderer-specific action args through the pack-path parse", () => {
|
|
780
|
+
const action = {
|
|
781
|
+
args: {
|
|
782
|
+
dispatch: "reactions.toggle",
|
|
783
|
+
renderer: "reaction-picker",
|
|
784
|
+
},
|
|
785
|
+
capability: "reactions.toggle",
|
|
786
|
+
id: "reactions.picker",
|
|
787
|
+
kind: "menu",
|
|
788
|
+
label: "Add reaction",
|
|
789
|
+
plugin: "@ryu/reactions",
|
|
790
|
+
target: "user",
|
|
791
|
+
};
|
|
792
|
+
const parsed = PluginManifestSchema.safeParse({
|
|
793
|
+
id: "com.example.reactions",
|
|
794
|
+
name: "Reactions",
|
|
795
|
+
version: "1.0.0",
|
|
796
|
+
runnables: [],
|
|
797
|
+
contributes: { message_actions: [action] },
|
|
798
|
+
});
|
|
799
|
+
|
|
800
|
+
expect(parsed.success).toBe(true);
|
|
801
|
+
if (!parsed.success) {
|
|
802
|
+
return;
|
|
803
|
+
}
|
|
804
|
+
expect(parsed.data.contributes?.message_actions).toEqual([action]);
|
|
805
|
+
});
|
|
806
|
+
});
|
|
807
|
+
|
|
808
|
+
describe("mcp_servers OAuth", () => {
|
|
809
|
+
const manifest = {
|
|
810
|
+
id: "com.example.mail",
|
|
811
|
+
mcp_servers: {
|
|
812
|
+
mail: {
|
|
813
|
+
auth: { client_id: "public-client", type: "oauth" },
|
|
814
|
+
type: "streamable-http",
|
|
815
|
+
url: "https://mcp.example.com/mcp",
|
|
816
|
+
},
|
|
817
|
+
},
|
|
818
|
+
name: "Mail",
|
|
819
|
+
permission_grants: ["mcp:server", "identity.read"],
|
|
820
|
+
runnables: [],
|
|
821
|
+
version: "1.0.0",
|
|
822
|
+
};
|
|
823
|
+
|
|
824
|
+
it("preserves the public OAuth declaration through the pack-path parse", () => {
|
|
825
|
+
const parsed = PluginManifestSchema.parse(manifest);
|
|
826
|
+
expect(parsed.mcp_servers?.mail?.auth).toEqual({
|
|
827
|
+
client_id: "public-client",
|
|
828
|
+
type: "oauth",
|
|
829
|
+
});
|
|
830
|
+
});
|
|
831
|
+
|
|
832
|
+
it("rejects secret auth fields and non-loopback plaintext URLs", () => {
|
|
833
|
+
expect(
|
|
834
|
+
PluginManifestSchema.safeParse({
|
|
835
|
+
...manifest,
|
|
836
|
+
mcp_servers: {
|
|
837
|
+
mail: {
|
|
838
|
+
...manifest.mcp_servers.mail,
|
|
839
|
+
auth: { client_secret: "nope", type: "oauth" },
|
|
840
|
+
},
|
|
841
|
+
},
|
|
842
|
+
}).success
|
|
843
|
+
).toBe(false);
|
|
844
|
+
expect(
|
|
845
|
+
PluginManifestSchema.safeParse({
|
|
846
|
+
...manifest,
|
|
847
|
+
mcp_servers: {
|
|
848
|
+
mail: { auth: { type: "oauth" }, url: "http://mcp.example.com" },
|
|
849
|
+
},
|
|
850
|
+
}).success
|
|
851
|
+
).toBe(false);
|
|
852
|
+
});
|
|
853
|
+
|
|
854
|
+
it("requires both MCP and identity grants", () => {
|
|
855
|
+
expect(
|
|
856
|
+
PluginManifestSchema.safeParse({
|
|
857
|
+
...manifest,
|
|
858
|
+
permission_grants: ["mcp:server"],
|
|
859
|
+
}).success
|
|
860
|
+
).toBe(false);
|
|
861
|
+
});
|
|
862
|
+
});
|