@stage-labs/metro 0.1.0-beta.229 → 0.1.0-beta.230
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 +10 -0
- package/runtime/node_modules/@metro-labs/daemon/src/claude/setup.ts +1 -1
- package/runtime/node_modules/@metro-labs/threema/src/accounts.ts +2 -1
- package/runtime/node_modules/@metro-labs/threema/src/inbound.ts +2 -4
- package/runtime/runtime.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.230",
|
|
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",
|
|
@@ -23,6 +23,16 @@ Stage (https://stage.box) is a messenger built on XMTP. A Stage channel is an XM
|
|
|
23
23
|
- Assignees: `set_channel_metadata {"line": "…", "metadata": {"assigned": ["0x…"]}}`. Only 0x addresses of current members.
|
|
24
24
|
- Each key you send replaces that whole list. Keys you leave out stay as they are. To add one label or one assignee, read `group_info` first and send the old list plus the new one. `[]` clears a list. Read `group_info` again to check it saved.
|
|
25
25
|
|
|
26
|
+
**Task status labels.** When a channel is a task, keep exactly one of these status labels, plus any project labels:
|
|
27
|
+
- `🗒️ Backlog`
|
|
28
|
+
- `🎯 To-do`
|
|
29
|
+
- `🚧 In progress`
|
|
30
|
+
- `🔍 In review`
|
|
31
|
+
- `✅ Done`
|
|
32
|
+
- `🚫 Blocked`
|
|
33
|
+
|
|
34
|
+
Move it from Backlog or To-do to In progress, then In review, then Done. Use Blocked while you wait on someone. To change it, read `group_info`, swap the old status for the new one in `labels`, keep the other labels, and send the whole list with `set_channel_metadata` `metadata.labels`.
|
|
35
|
+
|
|
26
36
|
**Messages.**
|
|
27
37
|
- Send: `send {"line": "…", "text": "Hello"}`. Reply with a quote: `reply {"line": "…", "message_id": "…", "text": "…"}`.
|
|
28
38
|
- React: `react {"line": "…", "message_id": "…", "emoji": "👍"}`. `unreact` takes the same shape.
|
|
@@ -149,7 +149,7 @@ const PRIOR_METRO: ReadonlySet<string> = new Set([
|
|
|
149
149
|
'5ce3f76d610aae91adc922d0edc6c8be1f27aa2fec4a5e3a6d6231a04fb9310b',
|
|
150
150
|
'b910597d24f31fa479b130a2545f94dd23684d802d99e36b637fc57c818a33be',
|
|
151
151
|
]);
|
|
152
|
-
const PRIOR_STAGE: ReadonlySet<string> = new Set();
|
|
152
|
+
const PRIOR_STAGE: ReadonlySet<string> = new Set(['dd7d30474765de3865ddc87c1cf3220161ded09502027cdff18597e5df0aab43']);
|
|
153
153
|
|
|
154
154
|
interface ShippedSkill {
|
|
155
155
|
name: string;
|
|
@@ -45,6 +45,7 @@ export interface Account {
|
|
|
45
45
|
cfg: AccountConfig;
|
|
46
46
|
keys: KeyPair;
|
|
47
47
|
publicKeys: Map<string, Uint8Array>;
|
|
48
|
+
requestedRosters: Set<string>;
|
|
48
49
|
groups: GroupStore;
|
|
49
50
|
}
|
|
50
51
|
|
|
@@ -55,7 +56,7 @@ export const accounts = new Map<string, Account>();
|
|
|
55
56
|
export function bootAccount(cfg: AccountConfig): Account {
|
|
56
57
|
const key = parsePrivateKey(cfg.privateKey);
|
|
57
58
|
if (key === null) throw new Error(`account '${cfg.id}' has no usable private key`);
|
|
58
|
-
return { cfg, keys: keyPairFrom(key), publicKeys: new Map(), groups: new GroupStore(cfg.id, cfg.gatewayId) };
|
|
59
|
+
return { cfg, keys: keyPairFrom(key), publicKeys: new Map(), requestedRosters: new Set(), groups: new GroupStore(cfg.id, cfg.gatewayId) };
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
export function accountFor(id: string): Account {
|
|
@@ -12,8 +12,6 @@ import { deliverFile } from './files.js';
|
|
|
12
12
|
import type { Decoded, GroupRef } from './messages.js';
|
|
13
13
|
import { requestSync, sentByUs } from './outbound.js';
|
|
14
14
|
|
|
15
|
-
const synced = new Set<string>();
|
|
16
|
-
|
|
17
15
|
function roomOf(acct: Account, group: GroupRef | null): Room {
|
|
18
16
|
if (group === null) return DIRECT;
|
|
19
17
|
return { group, name: acct.groups.get(group)?.name ?? null };
|
|
@@ -21,8 +19,8 @@ function roomOf(acct: Account, group: GroupRef | null): Room {
|
|
|
21
19
|
|
|
22
20
|
function askForRoster(acct: Account, group: GroupRef): void {
|
|
23
21
|
const key = `${acct.cfg.id}:${group.creator}-${group.groupId}`;
|
|
24
|
-
if (acct.groups.get(group) !== undefined ||
|
|
25
|
-
|
|
22
|
+
if (acct.groups.get(group) !== undefined || acct.requestedRosters.has(key)) return;
|
|
23
|
+
acct.requestedRosters.add(key);
|
|
26
24
|
requestSync(acct, group).catch((err: unknown) => {
|
|
27
25
|
process.stderr.write(`threema[${acct.cfg.id}]: could not ask ${group.creator} for the group roster: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
28
26
|
});
|
package/runtime/runtime.json
CHANGED