create-ryu-app 0.1.14 → 0.2.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/README.md CHANGED
@@ -20,6 +20,7 @@ Ryu extensions come in two shapes, and `--template` picks which one you get.
20
20
  | Template | Emits | Factory |
21
21
  |---|---|---|
22
22
  | `agent` | A loop-owning Runnable agent | `Agent` / `ryuTool` |
23
+ | `action` | A governed business operation with input/output contracts | `defineAction` |
23
24
  | `hook-plugin` | A post-assistant-turn plugin | `definePlugin` + `defineTurnHook` |
24
25
  | `ryu-app` | An interactive in-chat widget | `defineApp` + a self-contained widget |
25
26
  | `companion-plugin` | A Ryu App whose widget calls a companion tool, plus a panel surface | `defineApp` |
package/dist/index.js CHANGED
@@ -16,13 +16,18 @@ var RE_WORD_SEPARATOR = /[-_\s]+/;
16
16
  var RE_VALID_NAME = /^[a-z0-9][a-z0-9-_]*$/i;
17
17
  var RE_LABEL_IMPERSONATES = /ryu|system/i;
18
18
  var SAFE_COMPANION_LABEL = "App Panel";
19
- var SDK_DEPENDENCY_RANGE = "^0.1.14";
19
+ var SDK_DEPENDENCY_RANGE = "^0.2.2";
20
20
  var TEMPLATES = {
21
21
  agent: {
22
22
  kind: "plugin",
23
23
  summary: "a loop-owning Runnable agent (Agent + ryuTool)",
24
24
  devEntry: "src/agent.ts"
25
25
  },
26
+ action: {
27
+ kind: "plugin",
28
+ summary: "a governed business action (defineAction)",
29
+ devEntry: "src/action.ts"
30
+ },
26
31
  "hook-plugin": {
27
32
  kind: "plugin",
28
33
  summary: "a post-assistant-turn hook (definePlugin + defineTurnHook)",
package/package.json CHANGED
@@ -1,8 +1,12 @@
1
1
  {
2
2
  "name": "create-ryu-app",
3
- "version": "0.1.14",
3
+ "version": "0.2.2",
4
4
  "type": "module",
5
5
  "description": "Scaffold a starter Ryu SDK project with a Runnable, gateway-pointed model config, and manifest.json manifest",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/amajorai/ryu"
9
+ },
6
10
  "bin": {
7
11
  "create-ryu-app": "./dist/index.js"
8
12
  },
@@ -20,10 +24,10 @@
20
24
  "clean": "rm -rf dist"
21
25
  },
22
26
  "dependencies": {
23
- "@ryuhq/sdk": "^0.1.14"
27
+ "@ryuhq/sdk": "^0.2.2"
24
28
  },
25
29
  "devDependencies": {
26
- "@types/bun": "^1.3.4",
30
+ "@types/bun": "catalog:",
27
31
  "tsup": "^8.5.1",
28
32
  "typescript": "^5"
29
33
  }
@@ -0,0 +1,45 @@
1
+ {
2
+ "id": "com.example.__APP_NAME__",
3
+ "name": "__APP_DISPLAY_NAME__",
4
+ "version": "0.1.0",
5
+ "runnables": [
6
+ {
7
+ "id": "action-main",
8
+ "name": "Main Action",
9
+ "kind": "tool",
10
+ "config": {
11
+ "slug": "action-main",
12
+ "backend": "inline_deno",
13
+ "code": "return await (async ({ message }) => ({ ok: true, message }))(input, host);",
14
+ "action": true,
15
+ "description": "Accept a message and return a governed receipt.",
16
+ "input_schema": {
17
+ "type": "object",
18
+ "properties": {
19
+ "message": {
20
+ "type": "string",
21
+ "description": "The message to record."
22
+ }
23
+ },
24
+ "required": ["message"]
25
+ },
26
+ "output_schema": {
27
+ "type": "object",
28
+ "properties": {
29
+ "ok": { "type": "boolean" },
30
+ "message": { "type": "string" }
31
+ },
32
+ "required": ["ok", "message"]
33
+ },
34
+ "annotations": {
35
+ "readOnlyHint": false,
36
+ "destructiveHint": true
37
+ },
38
+ "needs_approval": true
39
+ }
40
+ }
41
+ ],
42
+ "permission_grants": ["tool:execute"],
43
+ "activation_events": ["*"],
44
+ "targets": []
45
+ }
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * __APP_DISPLAY_NAME__ — a governed business Action.
4
+ *
5
+ * The Action is the single implementation used by local TypeScript callers,
6
+ * the SDK MCP adapter, and the Core inline tool emitted by toManifest().
7
+ *
8
+ * bun run src/action.ts # prints the generated manifest
9
+ * bunx ryu pack . # validates and bundles manifest.json
10
+ */
11
+
12
+ import { defineAction } from "@ryuhq/sdk";
13
+
14
+ const action = defineAction({
15
+ id: "action-main",
16
+ name: "Main Action",
17
+ description: "Accept a message and return a governed receipt.",
18
+ schema: {
19
+ type: "object",
20
+ properties: {
21
+ message: { type: "string", description: "The message to record." },
22
+ },
23
+ required: ["message"],
24
+ },
25
+ outputSchema: {
26
+ type: "object",
27
+ properties: {
28
+ ok: { type: "boolean" },
29
+ message: { type: "string" },
30
+ },
31
+ required: ["ok", "message"],
32
+ },
33
+ effect: "mutate",
34
+ needsApproval: true,
35
+ run: async ({ message }) => ({ ok: true, message }),
36
+ });
37
+
38
+ const manifest = action.toManifest({
39
+ id: "com.example.__APP_NAME__",
40
+ name: "__APP_DISPLAY_NAME__",
41
+ version: "0.1.0",
42
+ });
43
+
44
+ export default manifest;
45
+
46
+ if (import.meta.main) {
47
+ process.stdout.write(`${JSON.stringify(manifest, null, 2)}\n`);
48
+ }
@@ -36,7 +36,7 @@ const agent = new Agent({
36
36
  "expense emails, read the relevant ones, and return a concise list of " +
37
37
  "expenses with amount, merchant, date, and a category.",
38
38
  tools: {
39
- gmailSearch: ryuTool("composio__GMAIL_SEARCH_EMAILS", {
39
+ gmailSearch: ryuTool("composio.GMAIL_SEARCH_EMAILS", {
40
40
  description: "Search the user's Gmail messages",
41
41
  parameters: {
42
42
  type: "object",
@@ -50,7 +50,7 @@ const agent = new Agent({
50
50
  required: ["query"],
51
51
  },
52
52
  }),
53
- gmailGet: ryuTool("composio__GMAIL_GET_EMAIL", {
53
+ gmailGet: ryuTool("composio.GMAIL_GET_EMAIL", {
54
54
  description: "Fetch a single Gmail message by id",
55
55
  }),
56
56
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@example/__APP_NAME__-sidecar",
3
3
  "private": true,
4
- "version": "0.1.14",
4
+ "version": "0.2.2",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "ryu-__APP_NAME__": "./src/main/index.ts"
@@ -4,11 +4,11 @@
4
4
  "version": "0.1.0",
5
5
  "runnables": [
6
6
  {
7
- "id": "__APP_NAME____render",
7
+ "id": "__APP_NAME__.render",
8
8
  "name": "render",
9
9
  "kind": "tool",
10
10
  "config": {
11
- "slug": "__APP_NAME____render",
11
+ "slug": "__APP_NAME__.render",
12
12
  "description": "Render the interactive panel inline in the chat reply.",
13
13
  "widget": true,
14
14
  "widget_accessible": true,
@@ -17,11 +17,11 @@
17
17
  }
18
18
  },
19
19
  {
20
- "id": "__APP_NAME____save",
20
+ "id": "__APP_NAME__.save",
21
21
  "name": "save",
22
22
  "kind": "tool",
23
23
  "config": {
24
- "slug": "__APP_NAME____save",
24
+ "slug": "__APP_NAME__.save",
25
25
  "description": "Persist the panel's current state. Callable by the mounted widget via callTool.",
26
26
  "widget": false,
27
27
  "widget_accessible": true,
@@ -46,7 +46,7 @@
46
46
  "slash_commands": [],
47
47
  "widgets": [
48
48
  {
49
- "tool_id": "__APP_NAME____render",
49
+ "tool_id": "__APP_NAME__.render",
50
50
  "uri": "ui://widget/__APP_NAME__.html",
51
51
  "ui_entry": "src/widget.tsx",
52
52
  "mime": "text/html+skybridge",
@@ -5,7 +5,7 @@
5
5
  * that mounts the widget, it declares a `save` tool marked `accessible: true` — a
6
6
  * COMPANION the mounted widget may invoke over the capability-gated bridge:
7
7
  *
8
- * await window.openai.callTool("__APP_NAME____save", { state })
8
+ * await window.openai.callTool("__APP_NAME__.save", { state })
9
9
  *
10
10
  * The host routes that call through the Gateway (allowlist + audit) before it
11
11
  * reaches Core; the frame never holds a token. It also declares a full-page
@@ -27,7 +27,7 @@ declare global {
27
27
  }
28
28
  }
29
29
 
30
- const SAVE_TOOL_ID = "__APP_NAME____save";
30
+ const SAVE_TOOL_ID = "__APP_NAME__.save";
31
31
 
32
32
  function Widget() {
33
33
  const bridge = window.openai ?? {};
@@ -4,11 +4,11 @@
4
4
  "version": "0.1.0",
5
5
  "runnables": [
6
6
  {
7
- "id": "__APP_NAME____render",
7
+ "id": "__APP_NAME__.render",
8
8
  "name": "render",
9
9
  "kind": "tool",
10
10
  "config": {
11
- "slug": "__APP_NAME____render",
11
+ "slug": "__APP_NAME__.render",
12
12
  "description": "Render the __APP_DISPLAY_NAME__ widget inline in the chat reply.",
13
13
  "widget": true,
14
14
  "widget_accessible": false,
@@ -43,7 +43,7 @@
43
43
  "slash_commands": [],
44
44
  "widgets": [
45
45
  {
46
- "tool_id": "__APP_NAME____render",
46
+ "tool_id": "__APP_NAME__.render",
47
47
  "uri": "ui://widget/__APP_NAME__.html",
48
48
  "ui_entry": "src/widget.tsx",
49
49
  "mime": "text/html+skybridge",