@stage-labs/metro 0.1.0-beta.216 → 0.1.0-beta.217

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stage-labs/metro",
3
- "version": "0.1.0-beta.216",
3
+ "version": "0.1.0-beta.217",
4
4
  "description": "The metro command line: run your agent on this machine, relaying its chat channels and connectors to Claude Code.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "metro",
3
- "version": "0.1.0-beta.216",
3
+ "version": "0.1.0-beta.217",
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",
@@ -228,7 +228,7 @@ async function applied(deps: AccountApiDeps): Promise<boolean> {
228
228
  await deps.reloadAgents();
229
229
  return true;
230
230
  } catch (err) {
231
- log.warn({ err: errMsg(err) }, 'account-api: allowlist reload failed, the change lands at the next boot');
231
+ log.warn({ err: errMsg(err) }, 'account-api: reload failed, the change lands at the next boot');
232
232
  return false;
233
233
  }
234
234
  }
@@ -275,7 +275,7 @@ async function handleEnabled(
275
275
  station: target.station,
276
276
  accountId: target.accountId,
277
277
  enabled,
278
- activated: await activate(deps, target.station),
278
+ activated: await applied(deps),
279
279
  });
280
280
  }
281
281
 
@@ -42,6 +42,11 @@ export function setDisabledAccounts(ids: Set<string>): void {
42
42
 
43
43
  export const accountEnabled = (station: string, accountId: string): boolean => !disabledAccounts.has(mapKey(station, accountId));
44
44
 
45
+ export function lineReceives(line: string): boolean {
46
+ const a = accountFromLine(line);
47
+ return a === undefined || accountEnabled(a.station, a.accountId);
48
+ }
49
+
45
50
  export function accountFromLine(
46
51
  line: string,
47
52
  ): { station: string; accountId: string } | undefined {
@@ -2,7 +2,7 @@ import type { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
2
  import { z } from 'zod';
3
3
  import type { InboundRelay } from '../channels/inbound.js';
4
4
  import { holdPrompt, type Behavior } from '../approvals/pending.js';
5
- import { approversForLine } from '../agents/map.js';
5
+ import { approversForLine, lineReceives } from '../agents/map.js';
6
6
  import { metroCall } from './ctx.js';
7
7
  import { promptBody } from './permission-prompt.js';
8
8
 
@@ -46,6 +46,10 @@ function relayLine(deps: PermissionRelayDeps, requestId: string): string | undef
46
46
  deps.log('permission_request: known line is outside the agent scope, held for the page only', requestId);
47
47
  return undefined;
48
48
  }
49
+ if (!lineReceives(line)) {
50
+ deps.log('permission_request: the known chat does not receive messages now, so no answer can arrive; held for the page only', requestId);
51
+ return undefined;
52
+ }
49
53
  if (approversForLine(line).length === 0) {
50
54
  deps.log('permission_request: nobody on that chat may approve, held for the page only', requestId);
51
55
  return undefined;
@@ -22,7 +22,7 @@ import {
22
22
  type MetroEvent,
23
23
  } from '@metro-labs/core/events';
24
24
  import type { TrainEvent } from '@metro-labs/core/trains/protocol';
25
- import { agentForLine, agentIdForLine } from '../agents/map.js';
25
+ import { agentForLine, agentIdForLine, lineReceives } from '../agents/map.js';
26
26
  import type { Endpoint } from '@metro-labs/core/endpoints';
27
27
  import { findEndpointByWebhookId, listEndpoints, tokenMatches } from '../stations/webhook-endpoints.js';
28
28
  import { attachmentEventUrl, handleAttachRequest, webhookPort } from '../files/attach-serve.js';
@@ -107,6 +107,10 @@ type Emit = (entry: MetroEvent) => void;
107
107
  export function makeEmit(dedupSeq?: DedupSeq): Emit {
108
108
  const tracker = dedupSeq ?? makeDedupSeq();
109
109
  return function emit(entry: MetroEvent): void {
110
+ if (!lineReceives(entry.line)) {
111
+ log.debug({ line: entry.line }, 'emit: dropped, this channel does not receive messages');
112
+ return;
113
+ }
110
114
  const seq = tracker.admit(entry);
111
115
  if (seq === null) return;
112
116
  const enriched: MetroEvent = withAttachmentUrl({
@@ -165,10 +165,7 @@ function writeStations(list: LoadedAgent[]): WrittenStations {
165
165
  }
166
166
  map[`${a.station}/${a.id}`] = agent.id;
167
167
  if (a.allowlist) allow[`${a.station}/${a.id}`] = a.allowlist;
168
- if (a.enabled === false) {
169
- disabled.add(`${a.station}/${a.id}`);
170
- continue;
171
- }
168
+ if (a.enabled === false) disabled.add(`${a.station}/${a.id}`);
172
169
  const cur = byStation.get(a.station);
173
170
  if (cur) cur.push(a);
174
171
  else byStation.set(a.station, [a]);
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "0.1.0-beta.216"
2
+ "version": "0.1.0-beta.217"
3
3
  }