agent-embassy 2.0.1 → 3.0.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.
Files changed (144) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/CONTRIBUTING.md +19 -34
  3. package/README.md +110 -228
  4. package/SECURITY.md +55 -89
  5. package/dist/src/errors.d.ts +10 -1
  6. package/dist/src/errors.js +3 -1
  7. package/dist/src/errors.js.map +1 -1
  8. package/dist/src/gateway/claude-helper-protocol.d.ts +8 -11
  9. package/dist/src/gateway/claude-helper-protocol.js +12 -11
  10. package/dist/src/gateway/claude-helper-protocol.js.map +1 -1
  11. package/dist/src/gateway/claude-helper-supervisor.d.ts +1 -5
  12. package/dist/src/gateway/claude-helper-supervisor.js +10 -9
  13. package/dist/src/gateway/claude-helper-supervisor.js.map +1 -1
  14. package/dist/src/gateway/claude-helper.js +6 -6
  15. package/dist/src/gateway/claude-helper.js.map +1 -1
  16. package/dist/src/gateway/claude-peer.d.ts +0 -3
  17. package/dist/src/gateway/claude-peer.js +6 -18
  18. package/dist/src/gateway/claude-peer.js.map +1 -1
  19. package/dist/src/gateway/cli.d.ts +17 -6
  20. package/dist/src/gateway/cli.js +912 -261
  21. package/dist/src/gateway/cli.js.map +1 -1
  22. package/dist/src/gateway/codex-socket-holder.d.ts +26 -0
  23. package/dist/src/gateway/codex-socket-holder.js +76 -0
  24. package/dist/src/gateway/codex-socket-holder.js.map +1 -0
  25. package/dist/src/gateway/codex-stateless-transport.js +1 -1
  26. package/dist/src/gateway/codex-stateless-transport.js.map +1 -1
  27. package/dist/src/gateway/config.d.ts +1 -10
  28. package/dist/src/gateway/config.js +4 -10
  29. package/dist/src/gateway/config.js.map +1 -1
  30. package/dist/src/gateway/control.d.ts +45 -77
  31. package/dist/src/gateway/control.js +56 -141
  32. package/dist/src/gateway/control.js.map +1 -1
  33. package/dist/src/gateway/federation-nodes.d.ts +29 -2
  34. package/dist/src/gateway/federation-nodes.js +177 -7
  35. package/dist/src/gateway/federation-nodes.js.map +1 -1
  36. package/dist/src/gateway/peer-client.d.ts +4 -3
  37. package/dist/src/gateway/peer-client.js +22 -13
  38. package/dist/src/gateway/peer-client.js.map +1 -1
  39. package/dist/src/gateway/peer-protocol.d.ts +8 -11
  40. package/dist/src/gateway/peer-protocol.js +5 -12
  41. package/dist/src/gateway/peer-protocol.js.map +1 -1
  42. package/dist/src/gateway/provenance-envelope.d.ts +0 -1
  43. package/dist/src/gateway/provenance-envelope.js +4 -19
  44. package/dist/src/gateway/provenance-envelope.js.map +1 -1
  45. package/dist/src/gateway/providers.d.ts +7 -4
  46. package/dist/src/gateway/providers.js +16 -20
  47. package/dist/src/gateway/providers.js.map +1 -1
  48. package/dist/src/gateway/server.d.ts +3 -12
  49. package/dist/src/gateway/server.js +31 -50
  50. package/dist/src/gateway/server.js.map +1 -1
  51. package/dist/src/gateway/service-agent.d.ts +187 -0
  52. package/dist/src/gateway/service-agent.js +758 -0
  53. package/dist/src/gateway/service-agent.js.map +1 -0
  54. package/dist/src/gateway/service.d.ts +114 -31
  55. package/dist/src/gateway/service.js +461 -566
  56. package/dist/src/gateway/service.js.map +1 -1
  57. package/dist/src/gateway/status-view.d.ts +167 -0
  58. package/dist/src/gateway/status-view.js +488 -0
  59. package/dist/src/gateway/status-view.js.map +1 -0
  60. package/dist/src/gateway/store.d.ts +103 -21
  61. package/dist/src/gateway/store.js +454 -529
  62. package/dist/src/gateway/store.js.map +1 -1
  63. package/dist/src/gateway/types.d.ts +48 -99
  64. package/dist/src/gateway/types.js +15 -52
  65. package/dist/src/gateway/types.js.map +1 -1
  66. package/docs/CONFIGURATION.md +173 -44
  67. package/docs/DELIVERY.md +11 -11
  68. package/docs/GATEWAY-ARCHITECTURE.md +277 -375
  69. package/package.json +4 -12
  70. package/skills/embassy-peer/SKILL.md +65 -90
  71. package/skills/embassy-peer/agents/openai.yaml +1 -1
  72. package/README.zh-CN.md +0 -275
  73. package/assets/live-dashboard/app.css +0 -1619
  74. package/assets/vendor/react/LICENSE +0 -21
  75. package/assets/vendor/react/react-dom.production.min.js +0 -267
  76. package/assets/vendor/react/react.production.min.js +0 -31
  77. package/dist/src/gateway/acp-client.d.ts +0 -110
  78. package/dist/src/gateway/acp-client.js +0 -407
  79. package/dist/src/gateway/acp-client.js.map +0 -1
  80. package/dist/src/gateway/acp-provider.d.ts +0 -66
  81. package/dist/src/gateway/acp-provider.js +0 -275
  82. package/dist/src/gateway/acp-provider.js.map +0 -1
  83. package/dist/src/gateway/cli-copy.d.ts +0 -8
  84. package/dist/src/gateway/cli-copy.en.d.ts +0 -22
  85. package/dist/src/gateway/cli-copy.en.js +0 -62
  86. package/dist/src/gateway/cli-copy.en.js.map +0 -1
  87. package/dist/src/gateway/cli-copy.js +0 -27
  88. package/dist/src/gateway/cli-copy.js.map +0 -1
  89. package/dist/src/gateway/cli-copy.zh-CN.d.ts +0 -22
  90. package/dist/src/gateway/cli-copy.zh-CN.js +0 -62
  91. package/dist/src/gateway/cli-copy.zh-CN.js.map +0 -1
  92. package/dist/src/gateway/codex-doctor.d.ts +0 -36
  93. package/dist/src/gateway/codex-doctor.js +0 -127
  94. package/dist/src/gateway/codex-doctor.js.map +0 -1
  95. package/dist/src/gateway/dashboard-copy.d.ts +0 -7
  96. package/dist/src/gateway/dashboard-copy.en.d.ts +0 -504
  97. package/dist/src/gateway/dashboard-copy.en.js +0 -505
  98. package/dist/src/gateway/dashboard-copy.en.js.map +0 -1
  99. package/dist/src/gateway/dashboard-copy.js +0 -514
  100. package/dist/src/gateway/dashboard-copy.js.map +0 -1
  101. package/dist/src/gateway/dashboard-copy.zh-CN.d.ts +0 -504
  102. package/dist/src/gateway/dashboard-copy.zh-CN.js +0 -505
  103. package/dist/src/gateway/dashboard-copy.zh-CN.js.map +0 -1
  104. package/dist/src/gateway/dashboard-model.d.ts +0 -343
  105. package/dist/src/gateway/dashboard-model.js +0 -1061
  106. package/dist/src/gateway/dashboard-model.js.map +0 -1
  107. package/dist/src/gateway/dashboard.d.ts +0 -20
  108. package/dist/src/gateway/dashboard.js +0 -874
  109. package/dist/src/gateway/dashboard.js.map +0 -1
  110. package/dist/src/gateway/deepseek-detect.d.ts +0 -14
  111. package/dist/src/gateway/deepseek-detect.js +0 -41
  112. package/dist/src/gateway/deepseek-detect.js.map +0 -1
  113. package/dist/src/gateway/live-dashboard-app/app.js +0 -2385
  114. package/dist/src/gateway/live-dashboard-assets.d.ts +0 -10
  115. package/dist/src/gateway/live-dashboard-assets.js +0 -74
  116. package/dist/src/gateway/live-dashboard-assets.js.map +0 -1
  117. package/dist/src/gateway/live-dashboard-command.d.ts +0 -60
  118. package/dist/src/gateway/live-dashboard-command.js +0 -334
  119. package/dist/src/gateway/live-dashboard-command.js.map +0 -1
  120. package/dist/src/gateway/live-dashboard-http.d.ts +0 -39
  121. package/dist/src/gateway/live-dashboard-http.js +0 -383
  122. package/dist/src/gateway/live-dashboard-http.js.map +0 -1
  123. package/dist/src/gateway/live-dashboard-protocol.d.ts +0 -34
  124. package/dist/src/gateway/live-dashboard-protocol.js +0 -114
  125. package/dist/src/gateway/live-dashboard-protocol.js.map +0 -1
  126. package/dist/src/gateway/live-dashboard-server.d.ts +0 -33
  127. package/dist/src/gateway/live-dashboard-server.js +0 -144
  128. package/dist/src/gateway/live-dashboard-server.js.map +0 -1
  129. package/dist/src/gateway/live-dashboard-stream.d.ts +0 -46
  130. package/dist/src/gateway/live-dashboard-stream.js +0 -234
  131. package/dist/src/gateway/live-dashboard-stream.js.map +0 -1
  132. package/dist/src/gateway/live-dashboard.d.ts +0 -28
  133. package/dist/src/gateway/live-dashboard.js +0 -154
  134. package/dist/src/gateway/live-dashboard.js.map +0 -1
  135. package/dist/src/gateway/locale.d.ts +0 -4
  136. package/dist/src/gateway/locale.js +0 -10
  137. package/dist/src/gateway/locale.js.map +0 -1
  138. package/dist/src/gateway/progress-watch-machine.d.ts +0 -45
  139. package/dist/src/gateway/progress-watch-machine.js +0 -70
  140. package/dist/src/gateway/progress-watch-machine.js.map +0 -1
  141. package/docs/CONFIGURATION.zh-CN.md +0 -97
  142. package/docs/DASHBOARD.md +0 -98
  143. package/docs/DASHBOARD.zh-CN.md +0 -49
  144. package/docs/DELIVERY.zh-CN.md +0 -55
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/gateway/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/gateway/config.ts"],"names":[],"mappings":"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"}
@@ -1,13 +1,13 @@
1
1
  import type { GatewayPublicSnapshot } from "./types.js";
2
2
  import { type PeerCatalogResult, type PeerHandoffParams, type PeerHandoffResult } from "./peer-protocol.js";
3
3
  import { type PeerMailboxAwaitResult } from "./peer-mailbox.js";
4
- export declare const GATEWAY_CONTROL_PROTOCOL_VERSION: 2;
4
+ export declare const GATEWAY_CONTROL_PROTOCOL_VERSION: 3;
5
5
  export declare const GATEWAY_CONTROL_MAX_FRAME_BYTES: number;
6
6
  export declare const GATEWAY_CONTROL_MAX_RESPONSE_BYTES: number;
7
7
  export declare const GATEWAY_CONTROL_MAX_MESSAGE_BYTES: number;
8
8
  export declare const GATEWAY_CONTROL_DEFAULT_TIMEOUT_MS = 3000;
9
9
  export declare const GATEWAY_CONTROL_MAX_CONNECTIONS = 32;
10
- export declare const gatewayControlMethods: readonly ["health", "register_codex", "unregister_codex", "remove_codex_registration", "select_claude", "unselect_claude", "pair", "unpair", "list_snapshot", "observe_snapshot", "delivery_status", "untrack", "send", "reply", "refresh_dashboard", "peer_catalog", "peer_handoff", "register_peer", "unregister_peer", "await_peer", "peer_receipt"];
10
+ export declare const gatewayControlMethods: readonly ["health", "register_codex", "unregister_codex", "list_snapshot", "observe_snapshot", "delivery_status", "send", "refresh_discovery", "peer_catalog", "peer_handoff", "register_peer", "unregister_peer", "await_peer", "peer_receipt"];
11
11
  export type GatewayControlMethod = (typeof gatewayControlMethods)[number];
12
12
  export type GatewayBusyPolicy = "queue";
13
13
  export type RegisterCodexParams = {
@@ -28,39 +28,11 @@ export type UnregisterCodexParams = {
28
28
  alias: string;
29
29
  threadId: string;
30
30
  };
31
- export type RemoveCodexRegistrationParams = {
32
- alias: string;
33
- };
34
- export type SelectClaudeParams = {
35
- alias: string;
36
- };
37
- export type PairParams = {
38
- aliases: readonly [string, string];
39
- };
40
31
  type SendBase = {
41
32
  fromAlias: string;
42
- toAlias: string;
43
33
  text: string;
44
- expectsReply?: boolean;
45
- trackIdleMinutes?: number;
46
34
  };
47
- type ValidatedSendBase = Omit<SendBase, "expectsReply"> & {
48
- expectsReply: boolean;
49
- };
50
- export type SendParams = SendBase & ({
51
- threadId: string;
52
- replyAddress?: never;
53
- peerToken?: never;
54
- } | {
55
- replyAddress: string;
56
- threadId?: never;
57
- peerToken?: never;
58
- } | {
59
- peerToken: string;
60
- threadId?: never;
61
- replyAddress?: never;
62
- });
63
- export type ValidatedSendParams = ValidatedSendBase & ({
35
+ type SendAuthority = {
64
36
  threadId: string;
65
37
  replyAddress?: never;
66
38
  peerToken?: never;
@@ -72,29 +44,32 @@ export type ValidatedSendParams = ValidatedSendBase & ({
72
44
  peerToken: string;
73
45
  threadId?: never;
74
46
  replyAddress?: never;
75
- });
76
- export type GatewayReplyCaller = {
77
- kind: "codex";
78
- alias: string;
79
- threadId: string;
80
- } | {
81
- kind: "claude";
82
- alias: string;
83
- replyAddress?: string;
84
- } | {
85
- kind: "peer";
86
- alias: string;
87
- token: string;
88
47
  };
89
- export type ReplyParams = {
48
+ /**
49
+ * A send addresses either a route by name or an open conversation by its
50
+ * token, never both. The conversation form is what `reply` used to be: the
51
+ * caller owns one end, the other end is the conversation's recorded binding,
52
+ * and the answer always expects a reply, so `expectsReply` is not accepted
53
+ * with it.
54
+ */
55
+ export type SendParams = (SendBase & SendAuthority & {
56
+ toAlias: string;
57
+ conversationId?: never;
58
+ expectsReply?: boolean;
59
+ }) | (SendBase & SendAuthority & {
90
60
  conversationId: string;
91
- text: string;
92
- caller: GatewayReplyCaller;
93
- trackIdleMinutes?: number;
94
- };
95
- export type UntrackParams = {
61
+ toAlias?: never;
62
+ expectsReply?: never;
63
+ });
64
+ export type ValidatedSendParams = (SendBase & SendAuthority & {
65
+ toAlias: string;
66
+ conversationId?: never;
67
+ expectsReply: boolean;
68
+ }) | (SendBase & SendAuthority & {
96
69
  conversationId: string;
97
- };
70
+ toAlias?: never;
71
+ expectsReply?: never;
72
+ });
98
73
  export type DeliveryStatusParams = {
99
74
  token: string;
100
75
  };
@@ -108,7 +83,13 @@ export type PeerHandoffControlParams = {
108
83
  export type RegisterPeerParams = {
109
84
  alias: string;
110
85
  token?: string;
86
+ ephemeral?: true;
87
+ ttlMs?: number;
111
88
  };
89
+ /** Bounds on an ephemeral peer registration's lifetime, in milliseconds. */
90
+ export declare const GATEWAY_EPHEMERAL_PEER_TTL_DEFAULT_MS = 300000;
91
+ export declare const GATEWAY_EPHEMERAL_PEER_TTL_MIN_MS = 1000;
92
+ export declare const GATEWAY_EPHEMERAL_PEER_TTL_MAX_MS = 3600000;
112
93
  export type PeerPrincipalParams = {
113
94
  alias: string;
114
95
  token: string;
@@ -120,18 +101,11 @@ type RequestParams = {
120
101
  health: Record<string, never>;
121
102
  register_codex: RegisterCodexParams;
122
103
  unregister_codex: UnregisterCodexParams;
123
- remove_codex_registration: RemoveCodexRegistrationParams;
124
- select_claude: SelectClaudeParams;
125
- unselect_claude: SelectClaudeParams;
126
- pair: PairParams;
127
- unpair: PairParams;
128
104
  list_snapshot: Record<string, never>;
129
105
  observe_snapshot: Record<string, never>;
130
106
  delivery_status: DeliveryStatusParams;
131
- untrack: UntrackParams;
132
107
  send: SendParams;
133
- reply: ReplyParams;
134
- refresh_dashboard: Record<string, never>;
108
+ refresh_discovery: Record<string, never>;
135
109
  peer_catalog: PeerCatalogParams;
136
110
  peer_handoff: PeerHandoffControlParams;
137
111
  register_peer: RegisterPeerParams;
@@ -146,15 +120,22 @@ export type GatewayControlRequest = {
146
120
  params: RequestParams[M];
147
121
  };
148
122
  }[GatewayControlMethod];
149
- export type GatewayDecisionCode = "ok" | "not_found" | "conflict" | "watch_owner_conflict" | "route_mismatch" | "busy" | "unavailable" | "rejected";
123
+ export type GatewayDecisionCode = "ok" | "not_found" | "conflict" | "route_mismatch" | "busy" | "unavailable" | "rejected";
150
124
  export type GatewayDecision = {
151
125
  accepted: true;
152
126
  code: "ok";
153
127
  } | {
154
128
  accepted: false;
155
129
  code: Exclude<GatewayDecisionCode, "ok">;
156
- ownerHost?: string;
157
130
  };
131
+ /**
132
+ * A refused send carries an optional `reason`: the safe error code
133
+ * behind the coarse decision. The decision code stays the contract clients
134
+ * branch on; `reason` exists so the CLI can name the one remedy that fits
135
+ * (rename a session, move a workspace, fix `--from`, rescan) instead of
136
+ * printing one generic line for six different failures. It is a safe code:
137
+ * bounded, allowlisted-shaped, and never a message, path, or identifier.
138
+ */
158
139
  export type GatewaySendResult = {
159
140
  accepted: true;
160
141
  code: "ok";
@@ -163,6 +144,7 @@ export type GatewaySendResult = {
163
144
  } | {
164
145
  accepted: false;
165
146
  code: Exclude<GatewayDecisionCode, "ok">;
147
+ reason?: string;
166
148
  };
167
149
  export type GatewayHealthResult = {
168
150
  status: "ok" | "degraded";
@@ -197,18 +179,11 @@ type ResultByMethod = {
197
179
  health: GatewayHealthResult;
198
180
  register_codex: GatewayDecision;
199
181
  unregister_codex: GatewayDecision;
200
- remove_codex_registration: GatewayDecision;
201
- select_claude: GatewayDecision;
202
- unselect_claude: GatewayDecision;
203
- pair: GatewayDecision;
204
- unpair: GatewayDecision;
205
182
  list_snapshot: GatewaySnapshot;
206
183
  observe_snapshot: GatewaySnapshotObservation;
207
184
  delivery_status: GatewayDeliveryStatusResult;
208
- untrack: GatewayDecision;
209
185
  send: GatewaySendResult;
210
- reply: GatewaySendResult;
211
- refresh_dashboard: GatewayRefreshResult;
186
+ refresh_discovery: GatewayRefreshResult;
212
187
  peer_catalog: PeerCatalogResult;
213
188
  peer_handoff: PeerHandoffResult;
214
189
  register_peer: GatewayRegisterPeerResult;
@@ -221,18 +196,11 @@ export type GatewayControlHandlers = {
221
196
  health: () => MaybePromise<GatewayHealthResult>;
222
197
  registerCodex: (params: Readonly<ValidatedRegisterCodexParams>) => MaybePromise<GatewayDecision>;
223
198
  unregisterCodex: (params: Readonly<UnregisterCodexParams>) => MaybePromise<GatewayDecision>;
224
- removeCodexRegistration: (params: Readonly<RemoveCodexRegistrationParams>) => MaybePromise<GatewayDecision>;
225
- selectClaude: (params: Readonly<SelectClaudeParams>) => MaybePromise<GatewayDecision>;
226
- unselectClaude: (params: Readonly<SelectClaudeParams>) => MaybePromise<GatewayDecision>;
227
- pair: (params: Readonly<PairParams>) => MaybePromise<GatewayDecision>;
228
- unpair: (params: Readonly<PairParams>) => MaybePromise<GatewayDecision>;
229
199
  listSnapshot: () => MaybePromise<GatewaySnapshot>;
230
200
  observeSnapshot: () => MaybePromise<GatewaySnapshotObservation>;
231
201
  deliveryStatus: (params: Readonly<DeliveryStatusParams>) => MaybePromise<GatewayDeliveryStatusResult>;
232
- untrack: (params: Readonly<UntrackParams>) => MaybePromise<GatewayDecision>;
233
202
  send: (params: Readonly<ValidatedSendParams>) => MaybePromise<GatewaySendResult>;
234
- reply: (params: Readonly<ReplyParams>) => MaybePromise<GatewaySendResult>;
235
- refreshDashboard: () => MaybePromise<GatewayRefreshResult>;
203
+ refreshDiscovery: () => MaybePromise<GatewayRefreshResult>;
236
204
  peerCatalog?: (params: Readonly<PeerCatalogParams>) => MaybePromise<PeerCatalogResult>;
237
205
  peerHandoff?: (params: Readonly<PeerHandoffControlParams>) => MaybePromise<PeerHandoffResult>;
238
206
  registerPeer: (params: Readonly<RegisterPeerParams>) => MaybePromise<GatewayRegisterPeerResult>;
@@ -4,10 +4,10 @@ import { chmod, lstat, mkdtemp, realpath, rename, rmdir, unlink } from "node:fs/
4
4
  import net from "node:net";
5
5
  import path from "node:path";
6
6
  import { TextDecoder } from "node:util";
7
- import { CONNECTOR_OBSERVATION_STALE_AFTER_MS, GATEWAY_PUBLIC_SNAPSHOT_BYTE_BUDGET, gatewayProviders, gatewayPublicSnapshotLimits, isGatewayProvider, isMessageDirection, isPublicRegistryObservationSnapshot, } from "./types.js";
7
+ import { CONNECTOR_OBSERVATION_STALE_AFTER_MS, GATEWAY_PUBLIC_SNAPSHOT_BYTE_BUDGET, gatewayPublicSnapshotLimits, isGatewayProvider, isMessageDirection, isPublicRegistryObservationSnapshot, } from "./types.js";
8
8
  import { decodePeerParams, decodePeerResult } from "./peer-protocol.js";
9
9
  import { isPeerMailboxAwaitResult } from "./peer-mailbox.js";
10
- export const GATEWAY_CONTROL_PROTOCOL_VERSION = 2;
10
+ export const GATEWAY_CONTROL_PROTOCOL_VERSION = 3;
11
11
  export const GATEWAY_CONTROL_MAX_FRAME_BYTES = 32 * 1024;
12
12
  export const GATEWAY_CONTROL_MAX_RESPONSE_BYTES = 256 * 1024;
13
13
  export const GATEWAY_CONTROL_MAX_MESSAGE_BYTES = 16 * 1024;
@@ -30,12 +30,15 @@ const MESSAGE_SUFFIX_PATTERN = /^[0-9a-f]{8}$/;
30
30
  const CONVERSATION_SUFFIX_PATTERN = /^[A-Za-z0-9_-]{8}$/;
31
31
  const ISO_TIMESTAMP_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z$/;
32
32
  export const gatewayControlMethods = [
33
- "health", "register_codex", "unregister_codex", "remove_codex_registration",
34
- "select_claude", "unselect_claude", "pair", "unpair", "list_snapshot",
35
- "observe_snapshot", "delivery_status", "untrack", "send", "reply",
36
- "refresh_dashboard", "peer_catalog", "peer_handoff",
33
+ "health", "register_codex", "unregister_codex", "list_snapshot",
34
+ "observe_snapshot", "delivery_status", "send",
35
+ "refresh_discovery", "peer_catalog", "peer_handoff",
37
36
  "register_peer", "unregister_peer", "await_peer", "peer_receipt",
38
37
  ];
38
+ /** Bounds on an ephemeral peer registration's lifetime, in milliseconds. */
39
+ export const GATEWAY_EPHEMERAL_PEER_TTL_DEFAULT_MS = 300_000;
40
+ export const GATEWAY_EPHEMERAL_PEER_TTL_MIN_MS = 1_000;
41
+ export const GATEWAY_EPHEMERAL_PEER_TTL_MAX_MS = 3_600_000;
39
42
  const WIRE_ERROR_MESSAGES = {
40
43
  INVALID_JSON: "The control frame is not valid JSON.", FRAME_TOO_LARGE: "The control frame exceeds the size limit.",
41
44
  INVALID_REQUEST: "The control request is invalid.", UNSUPPORTED_VERSION: "The control protocol version is unsupported.",
@@ -129,12 +132,6 @@ function isNonNegativeInteger(value) {
129
132
  value >= 0 &&
130
133
  value <= MAX_REVISION);
131
134
  }
132
- function isTrackIdleMinutes(value) {
133
- return (typeof value === "number" &&
134
- Number.isSafeInteger(value) &&
135
- value >= 1 &&
136
- value <= 24 * 60);
137
- }
138
135
  function isIsoTimestamp(value) {
139
136
  if (typeof value !== "string" || !ISO_TIMESTAMP_PATTERN.test(value)) {
140
137
  return false;
@@ -159,7 +156,6 @@ function isMessageText(value) {
159
156
  }
160
157
  const exact = hasExactKeys;
161
158
  const nonNegative = isNonNegativeInteger;
162
- const trackMinutes = isTrackIdleMinutes;
163
159
  const iso = isIsoTimestamp;
164
160
  const uuid = isUuid;
165
161
  const alias = isAlias;
@@ -200,9 +196,20 @@ function decodePeerHandoff(value) {
200
196
  }
201
197
  }
202
198
  function decodeRegisterPeer(value) {
203
- if (!shape(value, { alias: peerAlias }, { token: peerToken }))
199
+ // `ephemeral` belongs only to a first registration: re-presenting a token
200
+ // proves an existing route, and an existing route's lifetime is already
201
+ // fixed. `ttlMs` without `ephemeral` would name a lifetime nothing honours.
202
+ if (!shape(value, { alias: peerAlias }, { token: peerToken, ephemeral: oneOf(true),
203
+ ttlMs: (item) => Number.isSafeInteger(item) &&
204
+ Number(item) >= GATEWAY_EPHEMERAL_PEER_TTL_MIN_MS &&
205
+ Number(item) <= GATEWAY_EPHEMERAL_PEER_TTL_MAX_MS }) ||
206
+ (value.ephemeral !== undefined && value.token !== undefined) ||
207
+ (value.ttlMs !== undefined && value.ephemeral === undefined))
204
208
  invalid();
205
- return { alias: value.alias, ...(value.token === undefined ? {} : { token: value.token }) };
209
+ return { alias: value.alias,
210
+ ...(value.token === undefined ? {} : { token: value.token }),
211
+ ...(value.ephemeral === undefined ? {} : { ephemeral: true }),
212
+ ...(value.ttlMs === undefined ? {} : { ttlMs: value.ttlMs }) };
206
213
  }
207
214
  function decodePeerPrincipal(value) {
208
215
  if (!shape(value, { alias: peerAlias, token: peerToken }))
@@ -251,79 +258,35 @@ function decodeUnregister(value) {
251
258
  invalid();
252
259
  return { alias: value.alias, threadId: value.threadId.toLowerCase() };
253
260
  }
254
- function decodeRemoval(value) {
255
- if (!shape(value, { alias }) || !value.alias.startsWith("codex-"))
256
- invalid();
257
- return { alias: value.alias };
258
- }
259
- function decodeSelection(value) {
260
- if (!isRecord(value) || !exact(value, ["alias"]) ||
261
- typeof value.alias !== "string" || !isClaudeSessionSelector(value.alias))
262
- invalid();
263
- return { alias: UUID_PATTERN.test(value.alias) ? value.alias.toLowerCase() : value.alias };
264
- }
265
- function decodePair(value) {
266
- if (!isRecord(value) || !exact(value, ["aliases"]) || !Array.isArray(value.aliases) ||
267
- value.aliases.length !== 2 || !alias(value.aliases[0]) || !alias(value.aliases[1]) ||
268
- value.aliases[0] === value.aliases[1])
269
- invalid();
270
- return { aliases: [value.aliases[0], value.aliases[1]] };
271
- }
272
261
  function decodeSend(value) {
273
- if (!isRecord(value) || !exact(value, ["fromAlias", "toAlias", "text"], ["threadId", "replyAddress", "peerToken", "expectsReply", "trackIdleMinutes"]) ||
274
- !alias(value.fromAlias) || typeof value.toAlias !== "string" || !isClaudeSessionSelector(value.toAlias) ||
275
- !messageText(value.text) || [value.threadId, value.replyAddress, value.peerToken].filter((item) => item !== undefined).length !== 1 ||
262
+ if (!isRecord(value) || !exact(value, ["fromAlias", "text"], ["toAlias", "conversationId", "threadId", "replyAddress", "peerToken", "expectsReply"]) ||
263
+ !alias(value.fromAlias) || !messageText(value.text) ||
264
+ [value.toAlias, value.conversationId].filter((item) => item !== undefined).length !== 1 ||
265
+ (value.toAlias !== undefined && (typeof value.toAlias !== "string" || !isClaudeSessionSelector(value.toAlias))) ||
266
+ (value.conversationId !== undefined && (typeof value.conversationId !== "string" || !isGatewayConversationId(value.conversationId))) ||
267
+ [value.threadId, value.replyAddress, value.peerToken].filter((item) => item !== undefined).length !== 1 ||
276
268
  (value.threadId !== undefined && !uuid(value.threadId)) ||
277
269
  (value.replyAddress !== undefined && (typeof value.replyAddress !== "string" || !isGatewayReplyAddress(value.replyAddress))) ||
278
270
  (value.peerToken !== undefined && !peerToken(value.peerToken)) ||
279
- (value.expectsReply !== undefined && typeof value.expectsReply !== "boolean") ||
280
- (value.trackIdleMinutes !== undefined && !trackMinutes(value.trackIdleMinutes)))
271
+ (value.expectsReply !== undefined &&
272
+ (typeof value.expectsReply !== "boolean" || value.conversationId !== undefined)))
281
273
  invalid();
282
274
  const authority = value.threadId !== undefined ? { threadId: value.threadId.toLowerCase() }
283
275
  : value.replyAddress !== undefined ? { replyAddress: value.replyAddress }
284
276
  : { peerToken: value.peerToken };
285
- return { fromAlias: value.fromAlias, toAlias: UUID_PATTERN.test(value.toAlias) ? value.toAlias.toLowerCase() : value.toAlias,
286
- text: value.text, ...authority, expectsReply: value.expectsReply === true,
287
- ...(value.trackIdleMinutes === undefined ? {} : { trackIdleMinutes: value.trackIdleMinutes }) };
288
- }
289
- function normalizeReplyCaller(value) {
290
- if (!isRecord(value))
291
- invalid();
292
- if (value.kind === "codex" && shape(value, { kind: oneOf("codex"), alias, threadId: uuid }))
293
- return { kind: "codex", alias: value.alias,
294
- threadId: value.threadId.toLowerCase() };
295
- if (value.kind === "claude" && isRecord(value) && exact(value, ["kind", "alias"], ["replyAddress"]) &&
296
- alias(value.alias) && (value.replyAddress === undefined ||
297
- (typeof value.replyAddress === "string" && isGatewayReplyAddress(value.replyAddress))))
298
- return { kind: "claude", alias: value.alias,
299
- ...(value.replyAddress === undefined ? {} : { replyAddress: value.replyAddress }) };
300
- if (value.kind === "peer" && shape(value, { kind: oneOf("peer"), alias: peerAlias, token: peerToken }))
301
- return { kind: "peer", alias: value.alias, token: value.token };
302
- return invalid();
303
- }
304
- function decodeReply(value) {
305
- if (!isRecord(value) || !exact(value, ["conversationId", "text", "caller"], ["trackIdleMinutes"]) ||
306
- typeof value.conversationId !== "string" || !isGatewayConversationId(value.conversationId) ||
307
- !messageText(value.text) ||
308
- (value.trackIdleMinutes !== undefined && !trackMinutes(value.trackIdleMinutes)))
309
- invalid();
310
- return { conversationId: value.conversationId, text: value.text, caller: normalizeReplyCaller(value.caller),
311
- ...(value.trackIdleMinutes === undefined ? {} : { trackIdleMinutes: value.trackIdleMinutes }) };
277
+ const target = value.conversationId !== undefined
278
+ ? { conversationId: value.conversationId }
279
+ : { toAlias: UUID_PATTERN.test(value.toAlias) ? value.toAlias.toLowerCase() : value.toAlias,
280
+ expectsReply: value.expectsReply === true };
281
+ return { fromAlias: value.fromAlias, text: value.text, ...target, ...authority };
312
282
  }
313
283
  function decodeDeliveryStatus(value) {
314
284
  if (!shape(value, { token: (item) => typeof item === "string" && DELIVERY_TOKEN_PATTERN.test(item) }))
315
285
  invalid();
316
286
  return { token: value.token };
317
287
  }
318
- function decodeUntrack(value) {
319
- if (!shape(value, { conversationId: (item) => typeof item === "string" && CONVERSATION_ID_PATTERN.test(item) }))
320
- invalid();
321
- return { conversationId: value.conversationId };
322
- }
323
288
  function isDecision(value) {
324
- return shape(value, { accepted: (item) => typeof item === "boolean", code: oneOf("ok", "not_found", "conflict", "watch_owner_conflict", "route_mismatch", "busy", "unavailable", "rejected") }, { ownerHost: host }) && (value.accepted === true
325
- ? value.code === "ok" && value.ownerHost === undefined
326
- : value.code !== "ok" && (value.ownerHost === undefined || value.code === "conflict"));
289
+ return shape(value, { accepted: (item) => typeof item === "boolean", code: oneOf("ok", "not_found", "conflict", "route_mismatch", "busy", "unavailable", "rejected") }) && (value.accepted === true ? value.code === "ok" : value.code !== "ok");
327
290
  }
328
291
  function isRegisterPeerResult(value) {
329
292
  return isDecision(value) || shape(value, { accepted: oneOf(true), code: oneOf("ok"), token: peerToken });
@@ -332,14 +295,15 @@ function isHealthResult(value) {
332
295
  return shape(value, { status: oneOf("ok", "degraded"), revision: nonNegative });
333
296
  }
334
297
  function isSendResult(value) {
335
- if (!isRecord(value) || value.accepted !== true)
336
- return isDecision(value);
298
+ if (!isRecord(value) || value.accepted !== true) {
299
+ return shape(value, { accepted: oneOf(false), code: oneOf("not_found", "conflict", "route_mismatch", "busy", "unavailable", "rejected") }, { reason: safeCode });
300
+ }
337
301
  return shape(value, { accepted: oneOf(true), code: oneOf("ok"),
338
302
  conversationId: (item) => typeof item === "string" && CONVERSATION_ID_PATTERN.test(item),
339
303
  deliveryToken: (item) => typeof item === "string" && DELIVERY_TOKEN_PATTERN.test(item) });
340
304
  }
341
305
  function isRefreshResult(value) {
342
- return shape(value, { accepted: (item) => typeof item === "boolean", code: oneOf("ok", "not_found", "conflict", "watch_owner_conflict", "route_mismatch", "busy", "unavailable", "rejected"), revision: nonNegative }) && isDecision({ accepted: value.accepted, code: value.code });
306
+ return shape(value, { accepted: (item) => typeof item === "boolean", code: oneOf("ok", "not_found", "conflict", "route_mismatch", "busy", "unavailable", "rejected"), revision: nonNegative }) && isDecision({ accepted: value.accepted, code: value.code });
343
307
  }
344
308
  const TERMINAL = new Set(["delivered", "unconfirmed", "expired", "failed", "ambiguous", "cancelled"]);
345
309
  function isDeliveryStatusResult(value) {
@@ -359,13 +323,9 @@ function isConnectorSnapshot(value) {
359
323
  if (!shape(value, { provider: isGatewayProvider, host, health: isConnectorHealth,
360
324
  protocol: (item) => typeof item === "string" && PROTOCOL_PATTERN.test(item),
361
325
  protocolVersion: (item) => typeof item === "string" && PROTOCOL_VERSION_PATTERN.test(item) }, { lastSeenAt: iso, observationAgeMs: nonNegative, safeErrorCode: safeCode,
362
- registry: isPublicRegistryObservationSnapshot, codexDoctor: (item) => shape(item, {
363
- conditions: (rows) => Array.isArray(rows) && rows.length > 0 && rows.length <= 2 &&
364
- rows.every(oneOf("split_brain", "orphaned", "attached", "observation_stale", "managed_layout_missing", "unknown")),
365
- }) }))
326
+ registry: isPublicRegistryObservationSnapshot }))
366
327
  return false;
367
- return (value.codexDoctor === undefined || value.provider === "codex") &&
368
- (value.registry === undefined || value.provider === "claude");
328
+ return value.registry === undefined || value.provider === "claude";
369
329
  }
370
330
  function isRouteSnapshot(value) {
371
331
  if (!shape(value, { alias, provider: isGatewayProvider, host, enabled: (item) => typeof item === "boolean",
@@ -376,24 +336,10 @@ function isRouteSnapshot(value) {
376
336
  return row.alias.endsWith(`@${row.host}`) &&
377
337
  (row.oldestQueuedAt === undefined ? row.queueDepth === 0 : row.queueDepth > 0);
378
338
  }
379
- function compareConsentEndpoints(left, right) {
380
- return gatewayProviders.indexOf(left.provider) -
381
- gatewayProviders.indexOf(right.provider) || left.alias.localeCompare(right.alias);
382
- }
383
- function isConsentEdgeSnapshot(value) {
384
- const endpoint = (item) => shape(item, { alias, provider: isGatewayProvider });
385
- if (!shape(value, { endpoints: (rows) => Array.isArray(rows) && rows.length === 2 && rows.every(endpoint),
386
- host, counters: isRouteCounters }, { mutable: (item) => typeof item === "boolean" }))
387
- return false;
388
- const [left, right] = value.endpoints;
389
- const hosts = [left.alias.slice(left.alias.lastIndexOf("@") + 1), right.alias.slice(right.alias.lastIndexOf("@") + 1)];
390
- return left.alias !== right.alias && compareConsentEndpoints(left, right) < 0 &&
391
- (left.provider !== right.provider || hosts[0] !== hosts[1]) && value.host === [...hosts].sort()[0];
392
- }
393
339
  function isAvailablePeerSnapshot(value) {
394
340
  return shape(value, { alias, provider: oneOf("claude"), host,
395
341
  state: oneOf("idle", "busy", "awaiting_approval", "offline"),
396
- validated: (item) => typeof item === "boolean", selected: (item) => typeof item === "boolean" }, { lastSeenAt: iso, safeErrorCode: safeCode }) &&
342
+ validated: (item) => typeof item === "boolean", routed: (item) => typeof item === "boolean" }, { lastSeenAt: iso, safeErrorCode: safeCode }) &&
397
343
  value.alias.endsWith(`@${String(value.host)}`);
398
344
  }
399
345
  function isNormalizedMessageEvent(value) {
@@ -415,40 +361,17 @@ function isAccounting(value) {
415
361
  function isSafeAlert(value) {
416
362
  return shape(value, { code: safeCode, severity: oneOf("info", "warning", "error"), timestamp: iso }, { provider: isGatewayProvider, host, alias });
417
363
  }
418
- function isProgressWatchSnapshot(value) {
419
- return shape(value, {
420
- conversationIdSuffix: (item) => typeof item === "string" && CONVERSATION_SUFFIX_PATTERN.test(item),
421
- ownerAlias: alias, workerAlias: alias, lastActivityAt: iso, nextActionAt: iso,
422
- nudgeCount: oneOf(0, 1, 2),
423
- }) && value.ownerAlias !== value.workerAlias;
424
- }
425
- function isProgressWatchEventSnapshot(value) {
426
- if (!shape(value, { sequence: nonNegative, timestamp: iso,
427
- conversationIdSuffix: (item) => typeof item === "string" && CONVERSATION_SUFFIX_PATTERN.test(item),
428
- ownerAlias: alias, workerAlias: alias, kind: oneOf("opened", "replaced", "settled"),
429
- actor: oneOf("owner", "worker", "operator", "gateway", "unknown") }, { reason: oneOf("done", "untracked", "idle_timeout", "tracking_disabled", "endpoint_retired", "pair_removed") }))
430
- return false;
431
- if (value.kind === "opened")
432
- return value.actor === "owner" && value.reason === undefined;
433
- if (value.kind === "replaced")
434
- return (value.actor === "owner" || value.actor === "unknown") && value.reason === undefined;
435
- return (value.reason === "done" && (value.actor === "owner" || value.actor === "worker")) ||
436
- (value.reason === "untracked" && value.actor === "operator") ||
437
- ((value.reason === "idle_timeout" || value.reason === "tracking_disabled") && value.actor === "gateway") ||
438
- (value.reason === "endpoint_retired" && (value.actor === "gateway" || value.actor === "operator")) ||
439
- (value.reason === "pair_removed" && value.actor === "operator");
440
- }
441
364
  function isGatewayActivityEvent(value) {
442
365
  if (!shape(value, { sequence: positive, timestamp: iso,
443
- kind: oneOf("discovery", "selection", "registration", "pairing", "watch"),
444
- action: oneOf("discovery_refreshed", "claude_selected", "claude_unselected", "codex_registered", "codex_succeeded", "codex_unregistered", "routes_paired", "routes_unpaired", "watch_ended"),
366
+ kind: oneOf("discovery", "registration"),
367
+ action: oneOf("discovery_refreshed", "codex_registered", "codex_succeeded", "codex_unregistered", "claude_route_installed", "claude_route_retired"),
445
368
  outcome: oneOf("accepted", "rejected"), aliases: (rows) => arrayOf(rows, 2, alias),
446
369
  operatorAction: oneOf(true) }, { safeErrorCode: safeCode }))
447
370
  return false;
448
371
  const allowed = {
449
- discovery: ["discovery_refreshed"], selection: ["claude_selected", "claude_unselected"],
450
- registration: ["codex_registered", "codex_succeeded", "codex_unregistered"],
451
- pairing: ["routes_paired", "routes_unpaired"], watch: ["watch_ended"],
372
+ discovery: ["discovery_refreshed"],
373
+ registration: ["codex_registered", "codex_succeeded", "codex_unregistered",
374
+ "claude_route_installed", "claude_route_retired"],
452
375
  };
453
376
  return new Set(value.aliases).size === value.aliases.length &&
454
377
  (allowed[value.kind]?.includes(value.action) ?? false);
@@ -466,23 +389,20 @@ function isDeadlinePressure(value) {
466
389
  rows.reduce((sum, row) => sum + Number(row.expired), 0) === value.expiredEvents;
467
390
  }
468
391
  function isSnapshotTruncation(value) {
469
- const required = ["connectors", "availablePeers", "routes", "consentEdges", "messages", "alerts"];
470
- const optional = ["progressWatches", "progressWatchEvents", "activityEvents"];
392
+ const required = ["connectors", "availablePeers", "routes", "messages", "alerts"];
393
+ const optional = ["activityEvents"];
471
394
  return isRecord(value) && exact(value, required, optional) &&
472
395
  [...required, ...optional].every((key) => value[key] === undefined || nonNegative(value[key]));
473
396
  }
474
397
  export function isGatewaySnapshot(value) {
475
- if (!shape(value, { schemaVersion: oneOf(2), generatedAt: iso, inboundMode: oneOf("paired", "open"),
398
+ if (!shape(value, { schemaVersion: oneOf(2), generatedAt: iso,
476
399
  health: isConnectorHealth,
477
400
  connectors: (rows) => arrayOf(rows, gatewayPublicSnapshotLimits.connectors, isConnectorSnapshot),
478
401
  availablePeers: (rows) => arrayOf(rows, gatewayPublicSnapshotLimits.availablePeers, isAvailablePeerSnapshot),
479
402
  routes: (rows) => arrayOf(rows, gatewayPublicSnapshotLimits.routes, isRouteSnapshot),
480
- consentEdges: (rows) => arrayOf(rows, gatewayPublicSnapshotLimits.consentEdges, isConsentEdgeSnapshot),
481
403
  messages: (rows) => arrayOf(rows, gatewayPublicSnapshotLimits.messages, isNormalizedMessageEvent),
482
404
  accounting: isAccounting, alerts: (rows) => arrayOf(rows, gatewayPublicSnapshotLimits.alerts, isSafeAlert),
483
- truncation: isSnapshotTruncation }, { progressWatches: (rows) => arrayOf(rows, gatewayPublicSnapshotLimits.progressWatches, isProgressWatchSnapshot),
484
- progressWatchEvents: (rows) => arrayOf(rows, gatewayPublicSnapshotLimits.progressWatchEvents, isProgressWatchEventSnapshot),
485
- activityEvents: (rows) => arrayOf(rows, gatewayPublicSnapshotLimits.activityEvents, isGatewayActivityEvent),
405
+ truncation: isSnapshotTruncation }, { activityEvents: (rows) => arrayOf(rows, gatewayPublicSnapshotLimits.activityEvents, isGatewayActivityEvent),
486
406
  deadlinePressure: isDeadlinePressure }))
487
407
  return false;
488
408
  const snapshot = value;
@@ -491,16 +411,13 @@ export function isGatewaySnapshot(value) {
491
411
  const connectorKeys = snapshot.connectors.map((row) => `${row.provider}@${row.host}`);
492
412
  const aliases = snapshot.routes.map((row) => row.alias);
493
413
  const peers = snapshot.availablePeers.map((row) => row.alias);
494
- const edgeKeys = snapshot.consentEdges.map((row) => `${row.endpoints[0].alias}\0${row.endpoints[1].alias}`);
495
- const routeByAlias = new Map(snapshot.routes.map((row) => [row.alias, row]));
496
414
  const honest = snapshot.connectors.every((row) => {
497
415
  const seen = row.lastSeenAt === undefined ? undefined : Date.parse(row.lastSeenAt);
498
416
  const age = seen === undefined ? undefined : Math.min(MAX_REVISION, Math.max(0, generated - seen));
499
417
  return (row.observationAgeMs === undefined || row.observationAgeMs === age) &&
500
418
  (row.health !== "healthy" || (age !== undefined && age <= CONNECTOR_OBSERVATION_STALE_AFTER_MS));
501
419
  });
502
- return honest && unique(connectorKeys) && unique(aliases) && unique(peers) && unique(edgeKeys) &&
503
- snapshot.consentEdges.every((edge) => edge.endpoints.every((endpoint) => routeByAlias.get(endpoint.alias)?.provider === endpoint.provider)) &&
420
+ return honest && unique(connectorKeys) && unique(aliases) && unique(peers) &&
504
421
  Buffer.byteLength(JSON.stringify(snapshot), "utf8") <= GATEWAY_PUBLIC_SNAPSHOT_BYTE_BUDGET;
505
422
  }
506
423
  function isSnapshotObservation(value) {
@@ -508,13 +425,11 @@ function isSnapshotObservation(value) {
508
425
  }
509
426
  const descriptors = {
510
427
  health: { handler: "health", decode: emptyParams, result: isHealthResult, mutation: false }, register_codex: { handler: "registerCodex", decode: decodeRegister, result: isDecision, mutation: true },
511
- unregister_codex: { handler: "unregisterCodex", decode: decodeUnregister, result: isDecision, mutation: true }, remove_codex_registration: { handler: "removeCodexRegistration", decode: decodeRemoval, result: isDecision, mutation: true },
512
- select_claude: { handler: "selectClaude", decode: decodeSelection, result: isDecision, mutation: true }, unselect_claude: { handler: "unselectClaude", decode: decodeSelection, result: isDecision, mutation: true },
513
- pair: { handler: "pair", decode: decodePair, result: isDecision, mutation: true }, unpair: { handler: "unpair", decode: decodePair, result: isDecision, mutation: true },
428
+ unregister_codex: { handler: "unregisterCodex", decode: decodeUnregister, result: isDecision, mutation: true },
514
429
  list_snapshot: { handler: "listSnapshot", decode: emptyParams, result: isGatewaySnapshot, mutation: false }, observe_snapshot: { handler: "observeSnapshot", decode: emptyParams, result: isSnapshotObservation, mutation: false },
515
- delivery_status: { handler: "deliveryStatus", decode: decodeDeliveryStatus, result: isDeliveryStatusResult, mutation: false }, untrack: { handler: "untrack", decode: decodeUntrack, result: isDecision, mutation: false },
430
+ delivery_status: { handler: "deliveryStatus", decode: decodeDeliveryStatus, result: isDeliveryStatusResult, mutation: false },
516
431
  send: { handler: "send", decode: decodeSend, result: isSendResult, mutation: true },
517
- reply: { handler: "reply", decode: decodeReply, result: isSendResult, mutation: true }, refresh_dashboard: { handler: "refreshDashboard", decode: emptyParams, result: isRefreshResult, mutation: false },
432
+ refresh_discovery: { handler: "refreshDiscovery", decode: emptyParams, result: isRefreshResult, mutation: false },
518
433
  peer_catalog: { handler: "peerCatalog", decode: decodePeerCatalog, result: isPeerCatalog, mutation: false },
519
434
  peer_handoff: { handler: "peerHandoff", decode: decodePeerHandoff, result: isPeerHandoffResult, mutation: true },
520
435
  register_peer: { handler: "registerPeer", decode: decodeRegisterPeer, result: isRegisterPeerResult, mutation: true },