linkshell-cli 0.9.0 → 0.10.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 (153) hide show
  1. package/README.md +11 -6
  2. package/dist/cli/src/commands/gateway.d.ts +2 -0
  3. package/dist/cli/src/commands/gateway.js +29 -0
  4. package/dist/cli/src/commands/gateway.js.map +1 -0
  5. package/dist/cli/src/commands/host.d.ts +2 -0
  6. package/dist/cli/src/commands/host.js +12 -2
  7. package/dist/cli/src/commands/host.js.map +1 -1
  8. package/dist/cli/src/commands/setup.js +4 -2
  9. package/dist/cli/src/commands/setup.js.map +1 -1
  10. package/dist/cli/src/index.js +12 -334
  11. package/dist/cli/src/index.js.map +1 -1
  12. package/dist/cli/src/utils/daemon.d.ts +0 -7
  13. package/dist/cli/src/utils/daemon.js +1 -18
  14. package/dist/cli/src/utils/daemon.js.map +1 -1
  15. package/dist/cli/tsconfig.tsbuildinfo +1 -1
  16. package/dist/gateway/src/accounts.d.ts +6 -0
  17. package/dist/gateway/src/accounts.js +32 -0
  18. package/dist/gateway/src/accounts.js.map +1 -0
  19. package/dist/gateway/src/index.d.ts +4 -0
  20. package/dist/gateway/src/index.js +5 -0
  21. package/dist/gateway/src/index.js.map +1 -0
  22. package/dist/gateway/src/main.d.ts +1 -0
  23. package/dist/gateway/src/main.js +57 -0
  24. package/dist/gateway/src/main.js.map +1 -0
  25. package/dist/gateway/src/rate-limit.d.ts +22 -0
  26. package/dist/gateway/src/rate-limit.js +66 -0
  27. package/dist/gateway/src/rate-limit.js.map +1 -0
  28. package/dist/gateway/src/relay.d.ts +84 -0
  29. package/dist/gateway/src/relay.js +434 -0
  30. package/dist/gateway/src/relay.js.map +1 -0
  31. package/dist/gateway/src/serve.d.ts +34 -0
  32. package/dist/gateway/src/serve.js +102 -0
  33. package/dist/gateway/src/serve.js.map +1 -0
  34. package/dist/gateway/src/store.d.ts +35 -0
  35. package/dist/gateway/src/store.js +109 -0
  36. package/dist/gateway/src/store.js.map +1 -0
  37. package/dist/gateway/src/subscription.d.ts +18 -0
  38. package/dist/gateway/src/subscription.js +46 -0
  39. package/dist/gateway/src/subscription.js.map +1 -0
  40. package/dist/host/src/drivers/claude/transcript.d.ts +23 -23
  41. package/dist/host/src/fs.d.ts +3 -3
  42. package/dist/host/src/input.d.ts +4 -4
  43. package/dist/host/src/terminals.d.ts +1 -1
  44. package/dist/wire/src/model.d.ts +6 -6
  45. package/dist/wire/src/relay.d.ts +8 -8
  46. package/dist/wire/src/rpc.d.ts +818 -818
  47. package/dist/wire/src/updates.d.ts +18 -18
  48. package/package.json +4 -13
  49. package/src/commands/gateway.ts +31 -0
  50. package/src/commands/host.ts +13 -2
  51. package/src/commands/setup.ts +4 -2
  52. package/src/index.ts +14 -429
  53. package/src/utils/daemon.ts +2 -27
  54. package/dist/cli/src/config.d.ts +0 -14
  55. package/dist/cli/src/config.js +0 -23
  56. package/dist/cli/src/config.js.map +0 -1
  57. package/dist/cli/src/machine-id.d.ts +0 -6
  58. package/dist/cli/src/machine-id.js +0 -50
  59. package/dist/cli/src/machine-id.js.map +0 -1
  60. package/dist/cli/src/providers.d.ts +0 -13
  61. package/dist/cli/src/providers.js +0 -77
  62. package/dist/cli/src/providers.js.map +0 -1
  63. package/dist/cli/src/runtime/acp/acp-client.d.ts +0 -128
  64. package/dist/cli/src/runtime/acp/acp-client.js +0 -430
  65. package/dist/cli/src/runtime/acp/acp-client.js.map +0 -1
  66. package/dist/cli/src/runtime/acp/agent-process-discovery.d.ts +0 -48
  67. package/dist/cli/src/runtime/acp/agent-process-discovery.js +0 -278
  68. package/dist/cli/src/runtime/acp/agent-process-discovery.js.map +0 -1
  69. package/dist/cli/src/runtime/acp/agent-session.d.ts +0 -62
  70. package/dist/cli/src/runtime/acp/agent-session.js +0 -1081
  71. package/dist/cli/src/runtime/acp/agent-session.js.map +0 -1
  72. package/dist/cli/src/runtime/acp/agent-workspace.d.ts +0 -311
  73. package/dist/cli/src/runtime/acp/agent-workspace.js +0 -6083
  74. package/dist/cli/src/runtime/acp/agent-workspace.js.map +0 -1
  75. package/dist/cli/src/runtime/acp/claude-sdk-client.d.ts +0 -121
  76. package/dist/cli/src/runtime/acp/claude-sdk-client.js +0 -1147
  77. package/dist/cli/src/runtime/acp/claude-sdk-client.js.map +0 -1
  78. package/dist/cli/src/runtime/acp/claude-stream-json-client.d.ts +0 -53
  79. package/dist/cli/src/runtime/acp/claude-stream-json-client.js +0 -552
  80. package/dist/cli/src/runtime/acp/claude-stream-json-client.js.map +0 -1
  81. package/dist/cli/src/runtime/acp/json-rpc.d.ts +0 -22
  82. package/dist/cli/src/runtime/acp/json-rpc.js +0 -160
  83. package/dist/cli/src/runtime/acp/json-rpc.js.map +0 -1
  84. package/dist/cli/src/runtime/acp/provider-resolver.d.ts +0 -16
  85. package/dist/cli/src/runtime/acp/provider-resolver.js +0 -132
  86. package/dist/cli/src/runtime/acp/provider-resolver.js.map +0 -1
  87. package/dist/cli/src/runtime/bridge-session.d.ts +0 -97
  88. package/dist/cli/src/runtime/bridge-session.js +0 -1364
  89. package/dist/cli/src/runtime/bridge-session.js.map +0 -1
  90. package/dist/cli/src/runtime/hook-command.d.ts +0 -9
  91. package/dist/cli/src/runtime/hook-command.js +0 -80
  92. package/dist/cli/src/runtime/hook-command.js.map +0 -1
  93. package/dist/cli/src/runtime/screen-fallback.d.ts +0 -22
  94. package/dist/cli/src/runtime/screen-fallback.js +0 -202
  95. package/dist/cli/src/runtime/screen-fallback.js.map +0 -1
  96. package/dist/cli/src/runtime/screen-share.d.ts +0 -34
  97. package/dist/cli/src/runtime/screen-share.js +0 -376
  98. package/dist/cli/src/runtime/screen-share.js.map +0 -1
  99. package/dist/cli/src/runtime/scrollback.d.ts +0 -11
  100. package/dist/cli/src/runtime/scrollback.js +0 -33
  101. package/dist/cli/src/runtime/scrollback.js.map +0 -1
  102. package/dist/cli/src/runtime/usage-report.d.ts +0 -34
  103. package/dist/cli/src/runtime/usage-report.js +0 -332
  104. package/dist/cli/src/runtime/usage-report.js.map +0 -1
  105. package/dist/cli/src/utils/keep-awake.d.ts +0 -6
  106. package/dist/cli/src/utils/keep-awake.js +0 -48
  107. package/dist/cli/src/utils/keep-awake.js.map +0 -1
  108. package/dist/cli/src/utils/lan-ip.d.ts +0 -9
  109. package/dist/cli/src/utils/lan-ip.js +0 -61
  110. package/dist/cli/src/utils/lan-ip.js.map +0 -1
  111. package/dist/host/src/input-helper.d.ts +0 -1
  112. package/dist/host/src/input-helper.js +0 -564
  113. package/dist/host/src/input-helper.js.map +0 -1
  114. package/dist/shared-protocol/src/index.d.ts +0 -17029
  115. package/dist/shared-protocol/src/index.js +0 -1064
  116. package/dist/shared-protocol/src/index.js.map +0 -1
  117. package/scripts/copy-web.mjs +0 -34
  118. package/src/config.ts +0 -36
  119. package/src/machine-id.ts +0 -61
  120. package/src/providers.ts +0 -97
  121. package/src/runtime/acp/acp-client.ts +0 -521
  122. package/src/runtime/acp/agent-process-discovery.ts +0 -308
  123. package/src/runtime/acp/agent-session.ts +0 -1186
  124. package/src/runtime/acp/agent-workspace.ts +0 -6590
  125. package/src/runtime/acp/claude-sdk-client.ts +0 -1221
  126. package/src/runtime/acp/claude-stream-json-client.ts +0 -633
  127. package/src/runtime/acp/json-rpc.ts +0 -184
  128. package/src/runtime/acp/provider-resolver.ts +0 -154
  129. package/src/runtime/bridge-session.ts +0 -1549
  130. package/src/runtime/hook-command.ts +0 -73
  131. package/src/runtime/screen-fallback.ts +0 -235
  132. package/src/runtime/screen-share.ts +0 -426
  133. package/src/runtime/scrollback.ts +0 -43
  134. package/src/runtime/usage-report.ts +0 -342
  135. package/src/utils/keep-awake.ts +0 -61
  136. package/src/utils/lan-ip.ts +0 -61
  137. package/web/assets/FileBrowser-wOAfY-xj.js +0 -2
  138. package/web/assets/PortPreview-Cbvv7yzA.js +0 -2
  139. package/web/assets/TerminalPanel-CTSklkct.js +0 -1
  140. package/web/assets/UsageDashboard-CJ1AsNmd.js +0 -1
  141. package/web/assets/index-BsnDaeCt.css +0 -33
  142. package/web/assets/index-q85psYZ5.js +0 -36
  143. package/web/assets/vendor-highlight-NXWAAyIv.js +0 -5
  144. package/web/assets/vendor-react-M7xG3qiw.js +0 -49
  145. package/web/assets/vendor-xterm-D15THcI4.js +0 -9
  146. package/web/index.html +0 -37
  147. package/web/logos/claude.png +0 -0
  148. package/web/logos/codex.png +0 -0
  149. package/web/logos/copilot.png +0 -0
  150. package/web/logos/gemini.png +0 -0
  151. package/web/logos/linkshell-1024.png +0 -0
  152. package/web/logos/linkshell-splash.png +0 -0
  153. package/web/logos/linkshell.png +0 -0
@@ -1,1064 +0,0 @@
1
- import { z } from "zod";
2
- // ── Protocol version ────────────────────────────────────────────────
3
- export const PROTOCOL_VERSION = 1;
4
- // Oldest peer protocol version this build still interoperates with. The CLI and
5
- // app ship and update independently, so version negotiation must DEGRADE, never
6
- // hard-reject: a peer that omits its version is a legacy pre-versioning client
7
- // and is always treated as compatible.
8
- export const PROTOCOL_MIN_COMPATIBLE_VERSION = 1;
9
- /**
10
- * Decide whether a peer's advertised protocol version can interoperate with
11
- * this build. Returns true when the version is absent (legacy client) or within
12
- * the supported range. Callers should warn — not disconnect — on `false`, so an
13
- * out-of-date CLI/app keeps working in degraded mode rather than breaking.
14
- */
15
- export function isProtocolVersionCompatible(remoteVersion) {
16
- if (remoteVersion === undefined || remoteVersion === null)
17
- return true;
18
- if (!Number.isFinite(remoteVersion))
19
- return false;
20
- return remoteVersion >= PROTOCOL_MIN_COMPATIBLE_VERSION;
21
- }
22
- // ── Payload size caps ───────────────────────────────────────────────
23
- // Bound unbounded base64/data strings so a malicious or buggy peer can't
24
- // OOM the relay. These are runtime-only constraints; the static type of
25
- // each field stays `string`.
26
- const MAX_TERMINAL_DATA = 1_048_576; // 1 MB — terminal stdin/stdout chunk
27
- const MAX_SCREEN_FRAME_DATA = 4_194_304; // 4 MB — base64 JPEG frame
28
- const MAX_FILE_UPLOAD_DATA = 8_388_608; // 8 MB — uploaded file payload
29
- const MAX_TUNNEL_BODY = 8_388_608; // 8 MB — tunnel HTTP body chunk
30
- const MAX_TUNNEL_WS_DATA = 1_048_576; // 1 MB — tunnel websocket frame
31
- const MAX_AGENT_BLOCK_DATA = 8_388_608; // 8 MB — agent content block data
32
- const MAX_TUNNEL_URL = 8192; // tunnel request URL length
33
- const MAX_HTTP_METHOD = 16; // HTTP verb length
34
- // ── Device & Session enums ──────────────────────────────────────────
35
- export const deviceRoleSchema = z.enum(["host", "client"]);
36
- export const sessionStateSchema = z.enum([
37
- "pending_pairing",
38
- "connecting",
39
- "active",
40
- "reconnecting",
41
- "idle",
42
- "terminated",
43
- ]);
44
- export const terminalProviderSchema = z.enum([
45
- "claude",
46
- "codex",
47
- "gemini",
48
- "copilot",
49
- "custom",
50
- ]);
51
- export const errorCodeSchema = z.enum([
52
- "session_not_found",
53
- "pairing_expired",
54
- "pairing_not_found",
55
- "control_conflict",
56
- "session_terminated",
57
- "ack_out_of_range",
58
- "invalid_message",
59
- "unauthorized",
60
- ]);
61
- // ── Envelope ────────────────────────────────────────────────────────
62
- export const envelopeSchema = z.object({
63
- id: z.string().min(1),
64
- type: z.string().min(1),
65
- sessionId: z.string().min(1),
66
- terminalId: z.string().min(1).optional(),
67
- deviceId: z.string().min(1).optional(),
68
- timestamp: z.string().datetime(),
69
- traceId: z.string().min(1).optional(),
70
- seq: z.number().int().nonnegative().optional(),
71
- ack: z.number().int().nonnegative().optional(),
72
- payload: z.unknown(),
73
- });
74
- // ── Payload schemas ─────────────────────────────────────────────────
75
- export const terminalOutputPayloadSchema = z.object({
76
- stream: z.enum(["stdout", "stderr"]),
77
- data: z.string().max(MAX_TERMINAL_DATA),
78
- encoding: z.literal("utf8").default("utf8"),
79
- isReplay: z.boolean().default(false),
80
- isFinal: z.boolean().default(false),
81
- });
82
- export const terminalInputPayloadSchema = z.object({
83
- data: z.string().max(MAX_TERMINAL_DATA),
84
- });
85
- export const terminalResizePayloadSchema = z.object({
86
- cols: z.number().int().positive(),
87
- rows: z.number().int().positive(),
88
- });
89
- export const sessionConnectPayloadSchema = z.object({
90
- role: deviceRoleSchema,
91
- clientName: z.string().min(1),
92
- provider: terminalProviderSchema.optional(),
93
- protocolVersion: z.number().int().optional(),
94
- machineId: z.string().min(1).optional(),
95
- hostname: z.string().optional(),
96
- platform: z.string().optional(),
97
- cwd: z.string().optional(),
98
- projectName: z.string().optional(),
99
- });
100
- export const terminalExitPayloadSchema = z.object({
101
- exitCode: z.number().int().nullable(),
102
- signal: z.number().int().nullable().optional(),
103
- });
104
- export const sessionAckPayloadSchema = z.object({
105
- seq: z.number().int().nonnegative(),
106
- });
107
- export const sessionResumePayloadSchema = z.object({
108
- // Backward-compatible single-terminal cursor.
109
- lastAckedSeq: z.number().int().min(-1).optional().default(-1),
110
- // Multi-terminal resume cursor keyed by terminalId.
111
- lastAckedSeqByTerminal: z.record(z.number().int().min(-1)).optional().default({}),
112
- machineId: z.string().min(1).optional(),
113
- });
114
- export const sessionHeartbeatPayloadSchema = z.object({
115
- ts: z.number(), // unix ms
116
- });
117
- export const pairingCreatedPayloadSchema = z.object({
118
- pairingCode: z.string().regex(/^\d{6}$/),
119
- sessionId: z.string().min(1),
120
- expiresAt: z.string().datetime(),
121
- });
122
- export const sessionClaimPayloadSchema = z.object({
123
- pairingCode: z.string().regex(/^\d{6}$/),
124
- });
125
- export const sessionClaimedPayloadSchema = z.object({
126
- sessionId: z.string().min(1),
127
- });
128
- export const controlClaimPayloadSchema = z.object({
129
- deviceId: z.string().min(1),
130
- });
131
- export const controlGrantPayloadSchema = z.object({
132
- deviceId: z.string().min(1),
133
- });
134
- export const controlRejectPayloadSchema = z.object({
135
- deviceId: z.string().min(1),
136
- reason: z.string().min(1),
137
- });
138
- export const controlReleasePayloadSchema = z.object({
139
- deviceId: z.string().min(1),
140
- });
141
- export const sessionHostDisconnectedPayloadSchema = z.object({
142
- reason: z.string().optional(),
143
- });
144
- export const sessionHostReconnectedPayloadSchema = z.object({});
145
- // ── Screen sharing payloads ─────────────────────────────────────────
146
- export const screenStartPayloadSchema = z.object({
147
- fps: z.number().int().min(1).max(30).default(5),
148
- quality: z.number().int().min(10).max(100).default(60),
149
- scale: z.number().min(0.1).max(1).default(0.5),
150
- });
151
- export const screenStopPayloadSchema = z.object({});
152
- export const screenFramePayloadSchema = z.object({
153
- data: z.string().max(MAX_SCREEN_FRAME_DATA), // base64 JPEG
154
- width: z.number().int(),
155
- height: z.number().int(),
156
- frameId: z.number().int(),
157
- chunkIndex: z.number().int().default(0),
158
- chunkTotal: z.number().int().default(1),
159
- });
160
- export const screenStatusPayloadSchema = z.object({
161
- active: z.boolean(),
162
- mode: z.enum(["webrtc", "fallback", "off"]).default("off"),
163
- error: z.string().optional(),
164
- });
165
- export const screenOfferPayloadSchema = z.object({
166
- sdp: z.string(),
167
- });
168
- export const screenAnswerPayloadSchema = z.object({
169
- sdp: z.string(),
170
- });
171
- export const screenIcePayloadSchema = z.object({
172
- candidate: z.string(),
173
- sdpMid: z.string().nullable().optional(),
174
- sdpMLineIndex: z.number().nullable().optional(),
175
- });
176
- // ── Terminal spawn/list payloads ───────────────────────────────────
177
- export const terminalSpawnPayloadSchema = z.object({
178
- cwd: z.string().min(1),
179
- provider: terminalProviderSchema.optional(),
180
- // When true, always spawn a fresh PTY even if one already exists for this cwd
181
- // (lets a client open multiple terminal tabs in the same directory). Omitted/
182
- // false preserves the legacy one-terminal-per-cwd dedup (mobile relies on it).
183
- forceNew: z.boolean().optional(),
184
- });
185
- export const terminalInfoSchema = z.object({
186
- terminalId: z.string().min(1),
187
- cwd: z.string(),
188
- projectName: z.string(),
189
- provider: z.string(),
190
- status: z.enum(["running", "exited"]),
191
- });
192
- export const terminalListPayloadSchema = z.object({
193
- terminals: z.array(terminalInfoSchema),
194
- });
195
- export const terminalSpawnedPayloadSchema = z.object({
196
- terminalId: z.string().min(1),
197
- cwd: z.string(),
198
- projectName: z.string(),
199
- provider: z.string().optional(),
200
- });
201
- export const terminalKillPayloadSchema = z.object({
202
- terminalId: z.string().min(1),
203
- });
204
- export const terminalMkdirPayloadSchema = z.object({
205
- path: z.string().min(1),
206
- });
207
- // ── Terminal browse payloads ──────────────────────────────────────
208
- export const terminalBrowsePayloadSchema = z.object({
209
- path: z.string().min(1),
210
- includeFiles: z.boolean().optional().default(false),
211
- requestId: z.string().min(1).optional(),
212
- });
213
- export const terminalBrowseEntrySchema = z.object({
214
- name: z.string(),
215
- path: z.string(),
216
- isDirectory: z.boolean(),
217
- size: z.number().int().nonnegative().optional(),
218
- modifiedAt: z.string().datetime().optional(),
219
- });
220
- export const terminalBrowseResultPayloadSchema = z.object({
221
- path: z.string(),
222
- entries: z.array(terminalBrowseEntrySchema),
223
- error: z.string().optional(),
224
- requestId: z.string().min(1).optional(),
225
- });
226
- export const terminalFileReadPayloadSchema = z.object({
227
- path: z.string().min(1),
228
- maxBytes: z.number().int().positive().max(1_000_000).optional().default(256_000),
229
- requestId: z.string().min(1).optional(),
230
- });
231
- export const terminalFileReadResultPayloadSchema = z.object({
232
- path: z.string(),
233
- content: z.string().default(""),
234
- encoding: z.literal("utf8").default("utf8"),
235
- size: z.number().int().nonnegative().optional(),
236
- truncated: z.boolean().default(false),
237
- error: z.string().optional(),
238
- requestId: z.string().min(1).optional(),
239
- });
240
- // ── Terminal status payloads (from Claude Code hooks) ────────────────
241
- export const terminalStatusPayloadSchema = z.object({
242
- phase: z.enum([
243
- "thinking",
244
- "tool_use",
245
- "outputting",
246
- "waiting",
247
- "idle",
248
- "error",
249
- ]),
250
- provider: terminalProviderSchema.optional(),
251
- seq: z.number().optional(),
252
- toolName: z.string().optional(),
253
- toolInput: z.string().optional(),
254
- permissionRequest: z.string().optional(),
255
- summary: z.string().optional(),
256
- topPermission: z
257
- .object({
258
- requestId: z.string(),
259
- toolName: z.string(),
260
- toolInput: z.string(),
261
- permissionRequest: z.string(),
262
- timestamp: z.number(),
263
- })
264
- .optional(),
265
- permissionResolution: z
266
- .object({
267
- requestId: z.string(),
268
- outcome: z.enum(["allow", "deny", "cancelled"]),
269
- source: z.string().optional(),
270
- delivered: z.boolean(),
271
- })
272
- .optional(),
273
- pendingPermissionCount: z.number().optional(),
274
- machineId: z.string().min(1).optional(),
275
- });
276
- // ── File upload payloads ────────────────────────────────────────────
277
- export const fileUploadPayloadSchema = z.object({
278
- data: z.string().max(MAX_FILE_UPLOAD_DATA), // base64 encoded
279
- filename: z
280
- .string()
281
- .min(1)
282
- .refine((s) => !s.includes("..") && !s.startsWith("/"), "invalid filename"),
283
- });
284
- export const permissionDecisionPayloadSchema = z.object({
285
- requestId: z.string().min(1),
286
- decision: z.enum(["allow", "deny"]),
287
- });
288
- export const permissionDecisionResultPayloadSchema = z.object({
289
- requestId: z.string().min(1),
290
- decision: z.enum(["allow", "deny"]),
291
- resolved: z.boolean(),
292
- delivered: z.boolean(),
293
- source: z.string().optional(),
294
- message: z.string().optional(),
295
- });
296
- export const errorPayloadSchema = z.object({
297
- code: z.string().min(1),
298
- message: z.string().min(1),
299
- });
300
- // ── Tunnel payloads ────────────────────────────────────────────────
301
- export const tunnelRequestPayloadSchema = z.object({
302
- requestId: z.string().min(1),
303
- method: z.string().min(1).max(MAX_HTTP_METHOD),
304
- url: z.string().max(MAX_TUNNEL_URL),
305
- headers: z.record(z.string()),
306
- body: z.string().max(MAX_TUNNEL_BODY).nullable(), // base64 encoded
307
- port: z.number().int().min(1).max(65535),
308
- });
309
- export const tunnelResponsePayloadSchema = z.object({
310
- requestId: z.string().min(1),
311
- statusCode: z.number().int(),
312
- headers: z.record(z.string()),
313
- body: z.string().max(MAX_TUNNEL_BODY), // base64 encoded chunk
314
- isFinal: z.boolean(),
315
- });
316
- export const tunnelWsDataPayloadSchema = z.object({
317
- requestId: z.string().min(1),
318
- data: z.string().max(MAX_TUNNEL_WS_DATA), // base64 encoded
319
- isBinary: z.boolean(),
320
- });
321
- export const tunnelWsClosePayloadSchema = z.object({
322
- requestId: z.string().min(1),
323
- code: z.number().int().optional(),
324
- reason: z.string().optional(),
325
- });
326
- // ── Terminal history payloads ─────────────────────────────────────
327
- export const terminalHistoryRequestPayloadSchema = z.object({
328
- count: z.number().int().min(1).max(500).default(100),
329
- });
330
- export const terminalHistoryResponsePayloadSchema = z.object({
331
- entries: z.array(z.string()),
332
- shell: z.string().optional(),
333
- });
334
- // ── Agent GUI / ACP payloads ───────────────────────────────────────
335
- // Open catalog: Codex / Claude have a remote conversation protocol; Gemini,
336
- // Copilot, OpenCode, Cursor, Kimi and others are still valid provider ids so
337
- // process discovery can name them without inventing an RPC adapter.
338
- export const agentProviderSchema = z.string().min(1);
339
- export const agentReasoningEffortSchema = z.enum([
340
- "none",
341
- "minimal",
342
- "low",
343
- "medium",
344
- "high",
345
- "xhigh",
346
- ]);
347
- export const agentPermissionModeSchema = z.enum([
348
- "read_only",
349
- "workspace_write",
350
- "full_access",
351
- ]);
352
- export const agentCollaborationModeSchema = z.enum(["default", "plan"]);
353
- export const agentContentBlockSchema = z.object({
354
- type: z.enum(["text", "image"]),
355
- text: z.string().optional(),
356
- data: z.string().max(MAX_AGENT_BLOCK_DATA).optional(),
357
- mimeType: z.string().optional(),
358
- });
359
- export const agentMessageSchema = z.object({
360
- id: z.string().min(1),
361
- role: z.enum(["user", "assistant", "system"]),
362
- content: z.string(),
363
- createdAt: z.number(),
364
- isStreaming: z.boolean().optional(),
365
- });
366
- export const agentToolCallSchema = z.object({
367
- id: z.string().min(1),
368
- name: z.string().min(1),
369
- input: z.string().optional(),
370
- output: z.string().optional(),
371
- createdAt: z.number().optional(),
372
- status: z.enum(["pending", "running", "completed", "failed"]).default("pending"),
373
- });
374
- export const agentPermissionSchema = z.object({
375
- requestId: z.string().min(1),
376
- toolName: z.string().optional(),
377
- toolInput: z.string().optional(),
378
- context: z.string().optional(),
379
- options: z.array(z.object({
380
- id: z.string().min(1),
381
- label: z.string().min(1),
382
- kind: z.enum(["allow", "deny", "other"]).default("other"),
383
- })).default([]),
384
- });
385
- export const agentModelOptionSchema = z.object({
386
- id: z.string().min(1),
387
- label: z.string().min(1),
388
- });
389
- export const agentCommandDescriptorSchema = z.object({
390
- id: z.string().min(1),
391
- name: z.string().min(1),
392
- title: z.string().min(1),
393
- description: z.string().optional(),
394
- provider: agentProviderSchema.optional(),
395
- source: z.enum(["built_in", "custom", "project", "user", "linkshell"]).default("built_in"),
396
- category: z.string().optional(),
397
- argsMode: z.enum(["none", "optional", "required", "raw"]).default("optional"),
398
- requiresIdle: z.boolean().optional(),
399
- destructive: z.boolean().optional(),
400
- disabledReason: z.string().optional(),
401
- executionKind: z.enum(["prompt", "native", "local_ui"]).default("prompt"),
402
- });
403
- export const agentModeDescriptorSchema = z.object({
404
- id: z.string().min(1),
405
- title: z.string().min(1),
406
- description: z.string().optional(),
407
- });
408
- // MCP server connection status, surfaced in the console so users see whether a
409
- // configured MCP server actually came up (parity with Claude Code / Codex).
410
- export const agentMcpServerStatusSchema = z.enum([
411
- "pending", // known from config, not yet connected
412
- "connecting", // handshake in progress
413
- "connected", // ready, tools available
414
- "failed", // startup/connection error (see error)
415
- "needs_auth", // OAuth / auth required before use
416
- "disabled", // configured but intentionally turned off
417
- ]);
418
- export const agentMcpServerDescriptorSchema = z.object({
419
- name: z.string().min(1),
420
- status: agentMcpServerStatusSchema,
421
- error: z.string().optional(), // failure detail, shown on hover
422
- toolCount: z.number().int().optional(), // tools exposed once connected
423
- });
424
- export const agentProviderCapabilitySchema = z.object({
425
- id: agentProviderSchema,
426
- label: z.string().min(1),
427
- enabled: z.boolean(),
428
- reason: z.string().optional(),
429
- supportsImages: z.boolean().optional(),
430
- supportsPermission: z.boolean().optional(),
431
- supportsPlan: z.boolean().optional(),
432
- supportsCancel: z.boolean().optional(),
433
- models: z.array(agentModelOptionSchema).optional(),
434
- defaultModel: z.string().min(1).optional(),
435
- reasoningEfforts: z.array(agentReasoningEffortSchema).optional(),
436
- permissionModes: z.array(agentPermissionModeSchema).optional(),
437
- commands: z.array(agentCommandDescriptorSchema).optional(),
438
- modes: z.array(agentModeDescriptorSchema).optional(),
439
- currentMode: z.string().optional(),
440
- features: z.record(z.boolean()).optional(),
441
- mcpServers: z.array(agentMcpServerDescriptorSchema).optional(),
442
- });
443
- export const agentCapabilitiesPayloadSchema = z.object({
444
- enabled: z.boolean(),
445
- provider: agentProviderSchema.optional(),
446
- machineId: z.string().min(1).optional(),
447
- providers: z.array(agentProviderCapabilitySchema).optional(),
448
- protocolVersion: z.number().int().optional(),
449
- error: z.string().optional(),
450
- supportsSessionList: z.boolean().default(false),
451
- supportsSessionLoad: z.boolean().default(false),
452
- supportsImages: z.boolean().default(false),
453
- supportsAudio: z.boolean().default(false),
454
- supportsPermission: z.boolean().default(false),
455
- supportsPlan: z.boolean().default(false),
456
- supportsCancel: z.boolean().default(false),
457
- });
458
- export const agentInitializePayloadSchema = z.object({});
459
- export const agentSessionNewPayloadSchema = z.object({
460
- cwd: z.string().optional(),
461
- provider: agentProviderSchema.optional(),
462
- mcpServers: z.record(z.unknown()).optional(),
463
- });
464
- export const agentSessionLoadPayloadSchema = z.object({
465
- agentSessionId: z.string().min(1),
466
- cwd: z.string().optional(),
467
- });
468
- export const agentSessionListPayloadSchema = z.object({});
469
- export const agentPromptPayloadSchema = z.object({
470
- agentSessionId: z.string().optional(),
471
- clientMessageId: z.string().min(1),
472
- contentBlocks: z.array(agentContentBlockSchema).min(1),
473
- model: z.string().min(1).optional(),
474
- reasoningEffort: agentReasoningEffortSchema.optional(),
475
- permissionMode: agentPermissionModeSchema.optional(),
476
- });
477
- export const agentCancelPayloadSchema = z.object({
478
- agentSessionId: z.string().optional(),
479
- });
480
- export const agentUpdatePayloadSchema = z.object({
481
- agentSessionId: z.string().optional(),
482
- kind: z.enum(["message", "message_delta", "tool_call", "tool_result", "plan", "status", "error"]),
483
- message: agentMessageSchema.optional(),
484
- delta: z.string().optional(),
485
- toolCall: agentToolCallSchema.optional(),
486
- plan: z.array(z.object({
487
- id: z.string().min(1),
488
- text: z.string().min(1),
489
- status: z.enum(["pending", "in_progress", "completed"]),
490
- })).optional(),
491
- status: z.enum(["idle", "running", "waiting_permission", "error"]).optional(),
492
- error: z.string().optional(),
493
- });
494
- export const agentPermissionRequestPayloadSchema = agentPermissionSchema.extend({
495
- agentSessionId: z.string().optional(),
496
- });
497
- export const agentPermissionResponsePayloadSchema = z.object({
498
- agentSessionId: z.string().optional(),
499
- requestId: z.string().min(1),
500
- outcome: z.enum(["allow", "deny", "cancelled"]),
501
- optionId: z.string().optional(),
502
- });
503
- export const agentSnapshotPayloadSchema = z.object({
504
- agentSessionId: z.string().optional(),
505
- capabilities: agentCapabilitiesPayloadSchema.optional(),
506
- messages: z.array(agentMessageSchema).default([]),
507
- toolCalls: z.array(agentToolCallSchema).default([]),
508
- pendingPermissions: z.array(agentPermissionSchema).default([]),
509
- status: z.enum(["unavailable", "idle", "running", "waiting_permission", "error"]).default("unavailable"),
510
- error: z.string().optional(),
511
- });
512
- // ── Agent Workspace v2 payloads ────────────────────────────────────
513
- export const agentV2StatusSchema = z.enum([
514
- "unavailable",
515
- "idle",
516
- "running",
517
- "waiting_permission",
518
- "error",
519
- ]);
520
- export const agentV2TimelineKindSchema = z.enum([
521
- "chat",
522
- "thinking",
523
- "tool_activity",
524
- "command_execution",
525
- "file_change",
526
- "subagent_action",
527
- "plan",
528
- "user_input_prompt",
529
- "review",
530
- "context_compaction",
531
- ]);
532
- export const agentV2FileChangeEntrySchema = z.object({
533
- path: z.string().min(1),
534
- kind: z.string().optional(),
535
- added: z.number().int().nonnegative().optional(),
536
- removed: z.number().int().nonnegative().optional(),
537
- });
538
- export const agentV2FileChangeSchema = z.object({
539
- entries: z.array(agentV2FileChangeEntrySchema).default([]),
540
- diff: z.string().optional(),
541
- summary: z.string().optional(),
542
- changeSetId: z.string().optional(),
543
- status: z.enum(["pending", "running", "completed", "failed"]).optional(),
544
- });
545
- export const agentV2CommandExecutionSchema = z.object({
546
- command: z.string().optional(),
547
- cwd: z.string().optional(),
548
- output: z.string().optional(),
549
- exitCode: z.number().int().nullable().optional(),
550
- status: z.enum(["pending", "running", "completed", "failed"]).optional(),
551
- });
552
- export const agentV2StructuredInputOptionSchema = z.object({
553
- id: z.string().min(1),
554
- label: z.string().min(1),
555
- description: z.string().optional(),
556
- });
557
- export const agentV2StructuredInputQuestionSchema = z.object({
558
- id: z.string().min(1),
559
- header: z.string().optional(),
560
- question: z.string().min(1),
561
- isOther: z.boolean().optional(),
562
- isSecret: z.boolean().optional(),
563
- selectionLimit: z.number().int().positive().optional(),
564
- options: z.array(agentV2StructuredInputOptionSchema).optional(),
565
- });
566
- export const agentV2StructuredInputSchema = z.object({
567
- requestId: z.string().min(1),
568
- questions: z.array(agentV2StructuredInputQuestionSchema).default([]),
569
- });
570
- export const agentV2SubagentRefSchema = z.object({
571
- threadId: z.string().min(1),
572
- agentId: z.string().optional(),
573
- nickname: z.string().optional(),
574
- role: z.string().optional(),
575
- model: z.string().optional(),
576
- prompt: z.string().optional(),
577
- });
578
- export const agentV2SubagentStateSchema = z.object({
579
- threadId: z.string().min(1),
580
- status: z.string().min(1),
581
- message: z.string().optional(),
582
- });
583
- export const agentV2SubagentActionSchema = z.object({
584
- tool: z.string().min(1),
585
- status: z.string().min(1),
586
- prompt: z.string().optional(),
587
- model: z.string().optional(),
588
- receiverThreadIds: z.array(z.string().min(1)).default([]),
589
- receiverAgents: z.array(agentV2SubagentRefSchema).default([]),
590
- agentStates: z.record(agentV2SubagentStateSchema).default({}),
591
- });
592
- export const agentV2TimelineItemSchema = z.object({
593
- id: z.string().min(1),
594
- conversationId: z.string().min(1),
595
- type: z.enum(["message", "tool_call", "plan", "permission", "status", "error"]),
596
- kind: agentV2TimelineKindSchema.optional(),
597
- turnId: z.string().optional(),
598
- itemId: z.string().optional(),
599
- role: z.enum(["user", "assistant", "system"]).optional(),
600
- content: z.array(agentContentBlockSchema).optional(),
601
- text: z.string().optional(),
602
- toolCall: agentToolCallSchema.optional(),
603
- commandExecution: agentV2CommandExecutionSchema.optional(),
604
- fileChange: agentV2FileChangeSchema.optional(),
605
- subagent: agentV2SubagentActionSchema.optional(),
606
- structuredInput: agentV2StructuredInputSchema.optional(),
607
- plan: z.array(z.object({
608
- id: z.string().min(1),
609
- text: z.string().min(1),
610
- status: z.enum(["pending", "in_progress", "completed"]),
611
- })).optional(),
612
- permission: agentPermissionSchema.optional(),
613
- status: agentV2StatusSchema.optional(),
614
- error: z.string().optional(),
615
- metadata: z.record(z.unknown()).optional(),
616
- createdAt: z.number(),
617
- updatedAt: z.number().optional(),
618
- isStreaming: z.boolean().optional(),
619
- });
620
- // Token / context usage + cost for a conversation. Both Claude (result.usage +
621
- // total_cost_usd) and Codex (thread/tokenUsage/updated) expose this; we carry a
622
- // normalized snapshot on the conversation so web/mobile can show context-window
623
- // occupancy and cost like Claude Code's /context and Codex's /status. All
624
- // fields optional — providers populate what they have.
625
- export const agentV2UsageSchema = z.object({
626
- inputTokens: z.number().optional(),
627
- outputTokens: z.number().optional(),
628
- cacheReadTokens: z.number().optional(),
629
- totalTokens: z.number().optional(),
630
- /** Model's max context window (tokens), when known — denominator for "% used". */
631
- contextWindow: z.number().optional(),
632
- /** Cumulative session cost in USD (Claude reports this; Codex usually omits). */
633
- totalCostUsd: z.number().optional(),
634
- updatedAt: z.number().optional(),
635
- });
636
- export const agentV2ConversationSchema = z.object({
637
- id: z.string().min(1),
638
- agentSessionId: z.string().optional(),
639
- provider: agentProviderSchema.default("codex"),
640
- cwd: z.string(),
641
- /** Codex multi-repo workspace; a session is not owned by a single folder. */
642
- workspaceRoots: z.array(z.string()).optional(),
643
- /** Claude (and similar) project/group label when not 1:1 with cwd. */
644
- group: z.string().optional(),
645
- title: z.string().optional(),
646
- model: z.string().optional(),
647
- reasoningEffort: agentReasoningEffortSchema.optional(),
648
- permissionMode: agentPermissionModeSchema.optional(),
649
- collaborationMode: agentCollaborationModeSchema.optional(),
650
- /** owned = LinkShell runtime (full control). attached = same on-disk session, read-only. */
651
- control: z.enum(["owned", "attached"]).default("owned"),
652
- status: agentV2StatusSchema.default("idle"),
653
- archived: z.boolean().default(false),
654
- lastMessagePreview: z.string().optional(),
655
- lastActivityAt: z.number(),
656
- createdAt: z.number(),
657
- usage: agentV2UsageSchema.optional(),
658
- });
659
- export const agentV2CapabilitiesRequestPayloadSchema = z.object({});
660
- export const agentV2CapabilitiesPayloadSchema = agentCapabilitiesPayloadSchema.extend({
661
- workspaceProtocolVersion: z.number().int().default(2),
662
- });
663
- export const agentV2ConversationOpenPayloadSchema = z.object({
664
- conversationId: z.string().optional(),
665
- agentSessionId: z.string().optional(),
666
- cwd: z.string().optional(),
667
- provider: agentProviderSchema.optional(),
668
- model: z.string().optional(),
669
- reasoningEffort: agentReasoningEffortSchema.optional(),
670
- permissionMode: agentPermissionModeSchema.optional(),
671
- collaborationMode: agentCollaborationModeSchema.optional(),
672
- title: z.string().optional(),
673
- // Fork: create a NEW conversation seeded from an existing one's transcript,
674
- // truncated at forkFromTurnId (omitted → full clone from the end). Claude only
675
- // in v1 — the CLI falls back to a plain new conversation for other providers.
676
- forkFromConversationId: z.string().optional(),
677
- forkFromTurnId: z.string().optional(),
678
- });
679
- export const agentV2ConversationOpenedPayloadSchema = z.object({
680
- conversation: agentV2ConversationSchema,
681
- snapshot: z.array(agentV2TimelineItemSchema).default([]),
682
- requestedConversationId: z.string().min(1).optional(),
683
- });
684
- export const agentV2ConversationListPayloadSchema = z.object({
685
- includeArchived: z.boolean().optional().default(false),
686
- });
687
- export const agentV2ConversationListResultPayloadSchema = z.object({
688
- conversations: z.array(agentV2ConversationSchema),
689
- });
690
- export const agentV2PromptPayloadSchema = z.object({
691
- conversationId: z.string().min(1),
692
- clientMessageId: z.string().min(1),
693
- contentBlocks: z.array(agentContentBlockSchema).min(1),
694
- delivery: z.enum(["auto", "new_turn", "steer"]).optional().default("auto"),
695
- targetTurnId: z.string().min(1).optional(),
696
- model: z.string().min(1).optional(),
697
- reasoningEffort: agentReasoningEffortSchema.optional(),
698
- permissionMode: agentPermissionModeSchema.optional(),
699
- collaborationMode: agentCollaborationModeSchema.optional(),
700
- });
701
- export const agentV2CommandExecutePayloadSchema = z.object({
702
- conversationId: z.string().min(1),
703
- commandId: z.string().min(1),
704
- rawText: z.string().optional(),
705
- args: z.string().optional(),
706
- clientMessageId: z.string().min(1),
707
- });
708
- export const agentV2CancelPayloadSchema = z.object({
709
- conversationId: z.string().min(1),
710
- });
711
- export const agentV2PermissionRespondPayloadSchema = z.object({
712
- conversationId: z.string().min(1),
713
- requestId: z.string().min(1),
714
- outcome: z.enum(["allow", "deny", "cancelled"]),
715
- optionId: z.string().optional(),
716
- });
717
- export const agentV2StructuredInputRespondPayloadSchema = z.object({
718
- conversationId: z.string().min(1),
719
- requestId: z.string().min(1),
720
- answers: z.record(z.array(z.string())),
721
- });
722
- export const agentV2SnapshotRequestPayloadSchema = z.object({
723
- conversationId: z.string().optional(),
724
- });
725
- export const agentV2SnapshotPayloadSchema = z.object({
726
- conversations: z.array(agentV2ConversationSchema).default([]),
727
- activeConversationId: z.string().optional(),
728
- items: z.array(agentV2TimelineItemSchema).default([]),
729
- machineId: z.string().min(1).optional(),
730
- });
731
- export const agentV2EventPayloadSchema = z.object({
732
- conversationId: z.string().min(1),
733
- conversation: agentV2ConversationSchema.optional(),
734
- item: agentV2TimelineItemSchema.optional(),
735
- patch: z.object({
736
- itemId: z.string().min(1),
737
- kind: agentV2TimelineKindSchema.optional(),
738
- role: z.enum(["user", "assistant", "system"]).optional(),
739
- content: z.array(agentContentBlockSchema).optional(),
740
- text: z.string().optional(),
741
- textDelta: z.string().optional(),
742
- status: agentV2StatusSchema.optional(),
743
- toolCall: agentToolCallSchema.optional(),
744
- commandExecution: agentV2CommandExecutionSchema.optional(),
745
- fileChange: agentV2FileChangeSchema.optional(),
746
- subagent: agentV2SubagentActionSchema.optional(),
747
- structuredInput: agentV2StructuredInputSchema.optional(),
748
- plan: z.array(z.object({
749
- id: z.string().min(1),
750
- text: z.string().min(1),
751
- status: z.enum(["pending", "in_progress", "completed"]),
752
- })).optional(),
753
- permission: agentPermissionSchema.optional(),
754
- error: z.string().optional(),
755
- metadata: z.record(z.unknown()).optional(),
756
- updatedAt: z.number().optional(),
757
- isStreaming: z.boolean().optional(),
758
- }).optional(),
759
- });
760
- export const agentV2PermissionRequestPayloadSchema = agentPermissionSchema.extend({
761
- conversationId: z.string().min(1),
762
- item: agentV2TimelineItemSchema.optional(),
763
- });
764
- // Lightweight one-shot notification from CLI to mobile (toast-style).
765
- // Used to confirm model switches, signal unsupported native commands, etc.
766
- export const agentV2NoticePayloadSchema = z.object({
767
- conversationId: z.string().optional(),
768
- kind: z.enum([
769
- "model_changed",
770
- "effort_changed",
771
- "permission_changed",
772
- "native_unsupported",
773
- "info",
774
- "warning",
775
- ]),
776
- title: z.string().min(1),
777
- detail: z.string().optional(),
778
- durationMs: z.number().int().positive().optional(),
779
- });
780
- // History pagination: client requests OLDER timeline items for a conversation
781
- // (scrolling up). cursor is opaque (passed back from a prior result); omit for
782
- // the first older page. The host pages the provider transcript via its cursor.
783
- export const agentV2HistoryRequestPayloadSchema = z.object({
784
- conversationId: z.string().min(1),
785
- cursor: z.string().optional(),
786
- limit: z.number().int().positive().max(200).optional().default(50),
787
- });
788
- export const agentV2HistoryResultPayloadSchema = z.object({
789
- conversationId: z.string().min(1),
790
- // Older items, chronologically ascending; the client prepends them.
791
- items: z.array(agentV2TimelineItemSchema).default([]),
792
- // Opaque cursor for the NEXT (even older) page; absent when no more history.
793
- nextCursor: z.string().optional(),
794
- hasMore: z.boolean().default(false),
795
- });
796
- // Usage dashboard. The host aggregates ALL on-disk agent transcripts
797
- // (~/.claude/projects + ~/.codex/sessions) — decoupled from any live LinkShell
798
- // turn, so history + externally-started sessions all count. Token figures are
799
- // per-call sums (ccusage convention); the client renders an activity heatmap +
800
- // summary cards (cumulative / peak / streaks / longest task) + breakdowns.
801
- export const agentV2UsageTotalsSchema = z.object({
802
- inputTokens: z.number().default(0),
803
- outputTokens: z.number().default(0),
804
- cacheReadTokens: z.number().default(0),
805
- cacheWriteTokens: z.number().default(0),
806
- totalTokens: z.number().default(0),
807
- calls: z.number().default(0),
808
- });
809
- export const agentV2UsageBucketSchema = agentV2UsageTotalsSchema.extend({
810
- key: z.string(),
811
- });
812
- export const agentV2UsageRequestPayloadSchema = z.object({});
813
- export const agentV2UsageReportPayloadSchema = z.object({
814
- totals: agentV2UsageTotalsSchema,
815
- sessions: z.number().default(0),
816
- peakDayTokens: z.number().default(0),
817
- longestTaskMs: z.number().default(0),
818
- currentStreakDays: z.number().default(0),
819
- longestStreakDays: z.number().default(0),
820
- byDay: z.array(agentV2UsageBucketSchema).default([]), // key=YYYY-MM-DD, ascending
821
- byHourWeekday: z
822
- .array(z.object({ weekday: z.number(), hour: z.number(), tokens: z.number() }))
823
- .default([]),
824
- byTool: z.array(agentV2UsageBucketSchema).default([]),
825
- byModel: z.array(agentV2UsageBucketSchema).default([]),
826
- byProject: z.array(agentV2UsageBucketSchema).default([]),
827
- generatedAt: z.number(),
828
- });
829
- // Mutate a conversation's user-facing metadata (rename / archive toggle).
830
- // Fields are optional: send only what changes. The host applies the patch to
831
- // its tracked conversation and echoes the updated record back via agent.v2.event.
832
- export const agentV2ConversationUpdatePayloadSchema = z.object({
833
- conversationId: z.string().min(1),
834
- title: z.string().optional(),
835
- archived: z.boolean().optional(),
836
- // Immediate settings — applied on the host now, not only on the next prompt.
837
- model: z.string().optional(),
838
- reasoningEffort: agentReasoningEffortSchema.optional(),
839
- permissionMode: agentPermissionModeSchema.optional(),
840
- collaborationMode: agentCollaborationModeSchema.optional(),
841
- });
842
- // Gateway → list-page watchers. One envelope per session whose visible
843
- // agent/host summary changed. sessionId on the envelope is the LinkShell
844
- // session, not a conversation id.
845
- export const sessionPresencePayloadSchema = z.object({
846
- hasHost: z.boolean(),
847
- agentStatus: agentV2StatusSchema.optional().nullable(),
848
- agentProvider: z.string().optional().nullable(),
849
- agentConversationId: z.string().optional().nullable(),
850
- agentTitle: z.string().optional().nullable(),
851
- // Short "what it's doing / asking" line for the session list. Permission
852
- // requests stash the tool+target here so the list can say "运行命令 · pnpm test"
853
- // instead of a bare 等待授权.
854
- agentDetail: z.string().optional().nullable(),
855
- agentLastActivity: z.number().optional().nullable(),
856
- lastActivity: z.number().optional(),
857
- agentUsage: agentV2UsageSchema.optional().nullable(),
858
- });
859
- // "Delete" a conversation. Semantics: FORGET it from the workspace's tracked
860
- // set — it does NOT delete the agent's on-disk transcript/session file (that's
861
- // destructive and irreversible). The host drops it from its in-memory map and
862
- // tombstones the id so syncProviderSessions can't resurrect it on the next list.
863
- export const agentV2ConversationDeletePayloadSchema = z.object({
864
- conversationId: z.string().min(1),
865
- });
866
- // Host → clients: a conversation was forgotten; clients remove it from their list.
867
- export const agentV2ConversationDeletedPayloadSchema = z.object({
868
- conversationId: z.string().min(1),
869
- });
870
- // Client asks the host to start MCP OAuth for a server that reported needs_auth.
871
- export const agentV2McpLoginPayloadSchema = z.object({
872
- provider: agentProviderSchema.optional(),
873
- serverName: z.string().min(1),
874
- });
875
- // Host returns a browser URL (or an error the console can show inline).
876
- export const agentV2McpLoginResultPayloadSchema = z.object({
877
- provider: agentProviderSchema.optional(),
878
- serverName: z.string().min(1),
879
- authorizationUrl: z.string().min(1).optional(),
880
- error: z.string().optional(),
881
- });
882
- // ── Protocol message type registry ──────────────────────────────────
883
- export const protocolMessageSchemas = {
884
- "session.connect": sessionConnectPayloadSchema,
885
- "session.ack": sessionAckPayloadSchema,
886
- "session.resume": sessionResumePayloadSchema,
887
- "session.heartbeat": sessionHeartbeatPayloadSchema,
888
- "session.error": errorPayloadSchema,
889
- "terminal.output": terminalOutputPayloadSchema,
890
- "terminal.input": terminalInputPayloadSchema,
891
- "terminal.resize": terminalResizePayloadSchema,
892
- "terminal.exit": terminalExitPayloadSchema,
893
- "pairing.created": pairingCreatedPayloadSchema,
894
- "pairing.claim": sessionClaimPayloadSchema,
895
- "pairing.claimed": sessionClaimedPayloadSchema,
896
- "control.claim": controlClaimPayloadSchema,
897
- "control.grant": controlGrantPayloadSchema,
898
- "control.reject": controlRejectPayloadSchema,
899
- "control.release": controlReleasePayloadSchema,
900
- "session.host_disconnected": sessionHostDisconnectedPayloadSchema,
901
- "session.host_reconnected": sessionHostReconnectedPayloadSchema,
902
- "session.presence": sessionPresencePayloadSchema,
903
- "screen.start": screenStartPayloadSchema,
904
- "screen.stop": screenStopPayloadSchema,
905
- "screen.frame": screenFramePayloadSchema,
906
- "screen.status": screenStatusPayloadSchema,
907
- "screen.offer": screenOfferPayloadSchema,
908
- "screen.answer": screenAnswerPayloadSchema,
909
- "screen.ice": screenIcePayloadSchema,
910
- "file.upload": fileUploadPayloadSchema,
911
- "terminal.spawn": terminalSpawnPayloadSchema,
912
- "terminal.spawned": terminalSpawnedPayloadSchema,
913
- "terminal.list": terminalListPayloadSchema,
914
- "terminal.browse": terminalBrowsePayloadSchema,
915
- "terminal.browse.result": terminalBrowseResultPayloadSchema,
916
- "terminal.file.read": terminalFileReadPayloadSchema,
917
- "terminal.file.read.result": terminalFileReadResultPayloadSchema,
918
- "terminal.kill": terminalKillPayloadSchema,
919
- "terminal.mkdir": terminalMkdirPayloadSchema,
920
- "terminal.status": terminalStatusPayloadSchema,
921
- "permission.decision": permissionDecisionPayloadSchema,
922
- "permission.decision.result": permissionDecisionResultPayloadSchema,
923
- "tunnel.request": tunnelRequestPayloadSchema,
924
- "tunnel.response": tunnelResponsePayloadSchema,
925
- "tunnel.ws.data": tunnelWsDataPayloadSchema,
926
- "tunnel.ws.close": tunnelWsClosePayloadSchema,
927
- "terminal.history.request": terminalHistoryRequestPayloadSchema,
928
- "terminal.history.response": terminalHistoryResponsePayloadSchema,
929
- "agent.initialize": agentInitializePayloadSchema,
930
- "agent.capabilities": agentCapabilitiesPayloadSchema,
931
- "agent.session.new": agentSessionNewPayloadSchema,
932
- "agent.session.load": agentSessionLoadPayloadSchema,
933
- "agent.session.list": agentSessionListPayloadSchema,
934
- "agent.prompt": agentPromptPayloadSchema,
935
- "agent.cancel": agentCancelPayloadSchema,
936
- "agent.update": agentUpdatePayloadSchema,
937
- "agent.permission.request": agentPermissionRequestPayloadSchema,
938
- "agent.permission.response": agentPermissionResponsePayloadSchema,
939
- "agent.snapshot": agentSnapshotPayloadSchema,
940
- "agent.v2.capabilities.request": agentV2CapabilitiesRequestPayloadSchema,
941
- "agent.v2.capabilities": agentV2CapabilitiesPayloadSchema,
942
- "agent.v2.conversation.open": agentV2ConversationOpenPayloadSchema,
943
- "agent.v2.conversation.opened": agentV2ConversationOpenedPayloadSchema,
944
- "agent.v2.conversation.list": agentV2ConversationListPayloadSchema,
945
- "agent.v2.conversation.list.result": agentV2ConversationListResultPayloadSchema,
946
- "agent.v2.conversation.update": agentV2ConversationUpdatePayloadSchema,
947
- "agent.v2.conversation.delete": agentV2ConversationDeletePayloadSchema,
948
- "agent.v2.conversation.deleted": agentV2ConversationDeletedPayloadSchema,
949
- "agent.v2.prompt": agentV2PromptPayloadSchema,
950
- "agent.v2.command.execute": agentV2CommandExecutePayloadSchema,
951
- "agent.v2.cancel": agentV2CancelPayloadSchema,
952
- "agent.v2.permission.respond": agentV2PermissionRespondPayloadSchema,
953
- "agent.v2.permission.request": agentV2PermissionRequestPayloadSchema,
954
- "agent.v2.structured_input.respond": agentV2StructuredInputRespondPayloadSchema,
955
- "agent.v2.snapshot.request": agentV2SnapshotRequestPayloadSchema,
956
- "agent.v2.snapshot": agentV2SnapshotPayloadSchema,
957
- "agent.v2.event": agentV2EventPayloadSchema,
958
- "agent.v2.notice": agentV2NoticePayloadSchema,
959
- "agent.v2.history.request": agentV2HistoryRequestPayloadSchema,
960
- "agent.v2.history.result": agentV2HistoryResultPayloadSchema,
961
- "agent.v2.usage.request": agentV2UsageRequestPayloadSchema,
962
- "agent.v2.usage.report": agentV2UsageReportPayloadSchema,
963
- "agent.v2.mcp.login": agentV2McpLoginPayloadSchema,
964
- "agent.v2.mcp.login.result": agentV2McpLoginResultPayloadSchema,
965
- };
966
- export const agentV2HostToClientMessageTypes = [
967
- "agent.v2.capabilities",
968
- "agent.v2.conversation.opened",
969
- "agent.v2.conversation.list.result",
970
- "agent.v2.event",
971
- "agent.v2.snapshot",
972
- "agent.v2.permission.request",
973
- "agent.v2.notice",
974
- "agent.v2.history.result",
975
- "agent.v2.conversation.deleted",
976
- "agent.v2.usage.report",
977
- "agent.v2.mcp.login.result",
978
- ];
979
- export const agentV2ClientWriteMessageTypes = [
980
- "agent.v2.conversation.open",
981
- "agent.v2.conversation.update",
982
- "agent.v2.conversation.delete",
983
- "agent.v2.prompt",
984
- "agent.v2.command.execute",
985
- "agent.v2.cancel",
986
- "agent.v2.permission.respond",
987
- "agent.v2.structured_input.respond",
988
- "agent.v2.mcp.login",
989
- ];
990
- export const agentV2ClientReadMessageTypes = [
991
- "agent.v2.capabilities.request",
992
- "agent.v2.conversation.list",
993
- "agent.v2.snapshot.request",
994
- "agent.v2.history.request",
995
- "agent.v2.usage.request",
996
- ];
997
- const agentV2HostToClientSet = new Set(agentV2HostToClientMessageTypes);
998
- const agentV2ClientWriteSet = new Set(agentV2ClientWriteMessageTypes);
999
- const agentV2ClientReadSet = new Set(agentV2ClientReadMessageTypes);
1000
- export function agentV2MessageRoute(type) {
1001
- if (agentV2HostToClientSet.has(type))
1002
- return "host_to_client";
1003
- if (agentV2ClientWriteSet.has(type))
1004
- return "client_write";
1005
- if (agentV2ClientReadSet.has(type))
1006
- return "client_read";
1007
- return null;
1008
- }
1009
- export function isAgentV2HostToClientMessage(type) {
1010
- return agentV2MessageRoute(type) === "host_to_client";
1011
- }
1012
- export function isAgentV2ClientWriteMessage(type) {
1013
- return agentV2MessageRoute(type) === "client_write";
1014
- }
1015
- export function isAgentV2ClientReadMessage(type) {
1016
- return agentV2MessageRoute(type) === "client_read";
1017
- }
1018
- // ── UUID helper (works in Node, Web, and Expo) ─────────────────────
1019
- function generateId() {
1020
- if (typeof globalThis.crypto?.randomUUID === "function") {
1021
- return globalThis.crypto.randomUUID();
1022
- }
1023
- // Fallback for environments without crypto.randomUUID (older Expo native)
1024
- return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
1025
- const r = (Math.random() * 16) | 0;
1026
- return (c === "x" ? r : (r & 0x3) | 0x8).toString(16);
1027
- });
1028
- }
1029
- // ── Helpers ─────────────────────────────────────────────────────────
1030
- export function createEnvelope(input) {
1031
- return {
1032
- id: input.id ?? generateId(),
1033
- type: input.type,
1034
- sessionId: input.sessionId,
1035
- terminalId: input.terminalId,
1036
- deviceId: input.deviceId,
1037
- timestamp: new Date().toISOString(),
1038
- traceId: input.traceId,
1039
- seq: input.seq,
1040
- ack: input.ack,
1041
- payload: input.payload,
1042
- };
1043
- }
1044
- export function parseEnvelope(raw) {
1045
- return envelopeSchema.parse(JSON.parse(raw));
1046
- }
1047
- export function serializeEnvelope(message) {
1048
- return JSON.stringify(message);
1049
- }
1050
- export function parseTypedPayload(type, payload) {
1051
- // Guard against unregistered or inherited keys (e.g. "toString") so the
1052
- // lookup can never resolve to a non-schema and crash with a raw TypeError.
1053
- if (!Object.prototype.hasOwnProperty.call(protocolMessageSchemas, type)) {
1054
- throw new z.ZodError([
1055
- {
1056
- code: z.ZodIssueCode.custom,
1057
- path: ["type"],
1058
- message: `Unknown protocol message type: ${String(type)}`,
1059
- },
1060
- ]);
1061
- }
1062
- return protocolMessageSchemas[type].parse(payload);
1063
- }
1064
- //# sourceMappingURL=index.js.map