@stage-labs/metro 0.1.0-beta.286 → 0.1.0-beta.287
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/package.json +1 -1
- package/runtime/marketplace/plugin/.claude-plugin/plugin.json +1 -1
- package/runtime/marketplace/plugin/STAGE.md +11 -0
- package/runtime/node_modules/@metro-labs/daemon/src/claude/setup.ts +2 -0
- package/runtime/node_modules/@metro-labs/daemon/src/mcp/frame-schema.ts +4 -0
- package/runtime/runtime.json +1 -1
- package/runtime/sdk-runner/runner.json +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "metro",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.287",
|
|
4
4
|
"description": "Metro for Claude Code, installed by the metro daemon on this machine: every connector the agent holds as its own MCP server relayed through the daemon, the orchestrator-only guard on the main thread, and the standing rules loaded at each session start. No vendor credential ever sits in a config file.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Bonustrack",
|
|
@@ -82,6 +82,17 @@ The separate `metadata.status` and `metadata.priority` fields are optional. Stat
|
|
|
82
82
|
]}}
|
|
83
83
|
}}}
|
|
84
84
|
```
|
|
85
|
+
- Live frames: add `"source": {"url": "https://…"}` to the frame to name the node that serves its widget, an https URL that answers with ChatKit widget JSON (Stage's node protocol: https://github.com/bonustrack/stage/blob/main/NODES.md). Stage then sends the frame's actions to that node, not to you. The node's reply replaces the frame in place, on that person's device only, and no message comes to you. Only an action with ChatKit's `"handler": "client"` still comes to you as a frame action, like every action of a frame without `source`. `frame.open` and `frame.back` stay in Stage. Here `24h` goes to the node, and `Ask` comes to you as `Frame action: ask (tapped "Ask")`:
|
|
86
|
+
```json
|
|
87
|
+
{"line": "…", "frame": {"source": {"url": "https://eth.example.com/"}, "widget": {"type": "Card", "children": [
|
|
88
|
+
{"type": "Title", "value": "ETH 2,410 USD"},
|
|
89
|
+
{"type": "Row", "children": [
|
|
90
|
+
{"type": "Button", "label": "24h", "onClickAction": {"type": "range", "payload": {"days": 1}}},
|
|
91
|
+
{"type": "Button", "label": "Ask", "color": "secondary", "onClickAction": {"type": "ask", "handler": "client"}}
|
|
92
|
+
]}
|
|
93
|
+
]}}}
|
|
94
|
+
```
|
|
95
|
+
Stage calls the node only on a tap or on Refresh in the frame's three-dot menu, and only once the person has accepted the chat. Until then, and again after the app restarts, it shows the widget as you sent it. Do not add a Refresh button to a node: every live frame and Dashboard widget has Refresh in its menu. Add to dashboard on the frame adds a live widget loaded from that URL, and its `"handler": "client"` actions still come to this chat.
|
|
85
96
|
|
|
86
97
|
**Wallet cards.** The payment and signature cards Stage's own Request payment and Request signature send. Sending one moves nothing and signs nothing: the person taps Pay or Sign and confirms in Stage. Send one only when you were asked to.
|
|
87
98
|
- Send: `send {"line": "…", "wallet": {"type": "<type>", "content": {…}}}`. With `text` or a `frame` as well, the card goes last, and the `message_id` you get back is the card's.
|
|
@@ -159,8 +159,10 @@ const PRIOR_STAGE: ReadonlySet<string> = new Set([
|
|
|
159
159
|
'08a30f5cd5cf8013ab70c1fa9e1109018c0337552296a8efe5c0cf543b284991',
|
|
160
160
|
'f87e9494ea6151d140b742c1b88b4f435ae653559be641fddc2160cd24dd4e1b',
|
|
161
161
|
'cb4307b016855c1a09d48bc8b3924a3080bd78b205963df3d6f20401d0486df9',
|
|
162
|
+
'd25a8575b1c27ee725ff3a3ec6e1ba42aebd08ba545012c4807c072627c5dd4a',
|
|
162
163
|
'f2be51c5290d2e61b47f10c379fa45d051a59a6b3f06d99174c2a170074bc8f5',
|
|
163
164
|
'4c727aa110c9023371cfb364f3304ad9db22cdf2501208ef1e42e6ccc245b00f',
|
|
165
|
+
'f3901d8a4537441b1d7fe8e4073322a97b779472df6b4a8e0f2091ab5ab0ae09',
|
|
164
166
|
]);
|
|
165
167
|
const PRIOR_MEMORY: ReadonlySet<string> = new Set(['08795399635c8cdec2b50cb4e336f89ae880f3997ae52560ef647a9cdc8f1b08']);
|
|
166
168
|
|
|
@@ -32,6 +32,10 @@ export const frameSchema = {
|
|
|
32
32
|
type: 'object',
|
|
33
33
|
description:
|
|
34
34
|
'Optional: {"url": "https://…"}, a node URL that serves this widget live (2048 characters at most). ' +
|
|
35
|
+
"Stage then sends the frame's actions to that node, not to you, and the node's reply replaces the " +
|
|
36
|
+
'frame on that device, with no message to you. Only an action with "handler": "client" (e.g. ' +
|
|
37
|
+
'{"type": "ask", "handler": "client"}) still comes back to you as a Frame action; without a source, ' +
|
|
38
|
+
"every action does. Refresh is in the frame's three-dot menu, so a node needs no Refresh button. " +
|
|
35
39
|
'Add to dashboard on the frame then adds a live widget loaded from that URL instead of a copy.',
|
|
36
40
|
properties: { url: { type: 'string' } },
|
|
37
41
|
required: ['url'],
|
package/runtime/runtime.json
CHANGED