linkshell-cli 0.1.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.
- package/LICENSE +21 -0
- package/README.md +115 -0
- package/dist/cli/src/commands/doctor.d.ts +1 -0
- package/dist/cli/src/commands/doctor.js +112 -0
- package/dist/cli/src/commands/doctor.js.map +1 -0
- package/dist/cli/src/commands/setup.d.ts +1 -0
- package/dist/cli/src/commands/setup.js +48 -0
- package/dist/cli/src/commands/setup.js.map +1 -0
- package/dist/cli/src/config.d.ts +12 -0
- package/dist/cli/src/config.js +23 -0
- package/dist/cli/src/config.js.map +1 -0
- package/dist/cli/src/index.d.ts +2 -0
- package/dist/cli/src/index.js +108 -0
- package/dist/cli/src/index.js.map +1 -0
- package/dist/cli/src/providers.d.ts +12 -0
- package/dist/cli/src/providers.js +61 -0
- package/dist/cli/src/providers.js.map +1 -0
- package/dist/cli/src/runtime/bridge-session.d.ts +40 -0
- package/dist/cli/src/runtime/bridge-session.js +317 -0
- package/dist/cli/src/runtime/bridge-session.js.map +1 -0
- package/dist/cli/src/runtime/scrollback.d.ts +11 -0
- package/dist/cli/src/runtime/scrollback.js +33 -0
- package/dist/cli/src/runtime/scrollback.js.map +1 -0
- package/dist/cli/src/utils/lan-ip.d.ts +5 -0
- package/dist/cli/src/utils/lan-ip.js +20 -0
- package/dist/cli/src/utils/lan-ip.js.map +1 -0
- package/dist/cli/tsconfig.tsbuildinfo +1 -0
- package/dist/shared-protocol/src/index.d.ts +380 -0
- package/dist/shared-protocol/src/index.js +158 -0
- package/dist/shared-protocol/src/index.js.map +1 -0
- package/package.json +49 -0
- package/src/commands/doctor.ts +119 -0
- package/src/commands/setup.ts +65 -0
- package/src/config.ts +34 -0
- package/src/index.ts +139 -0
- package/src/providers.ts +91 -0
- package/src/runtime/bridge-session.ts +407 -0
- package/src/runtime/scrollback.ts +43 -0
- package/src/types/qrcode-terminal.d.ts +7 -0
- package/src/utils/lan-ip.ts +19 -0
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const PROTOCOL_VERSION = 1;
|
|
3
|
+
export declare const deviceRoleSchema: z.ZodEnum<["host", "client"]>;
|
|
4
|
+
export type DeviceRole = z.infer<typeof deviceRoleSchema>;
|
|
5
|
+
export declare const sessionStateSchema: z.ZodEnum<["pending_pairing", "connecting", "active", "reconnecting", "idle", "terminated"]>;
|
|
6
|
+
export type SessionState = z.infer<typeof sessionStateSchema>;
|
|
7
|
+
export declare const errorCodeSchema: z.ZodEnum<["session_not_found", "pairing_expired", "pairing_not_found", "control_conflict", "session_terminated", "ack_out_of_range", "invalid_message", "unauthorized"]>;
|
|
8
|
+
export type ErrorCode = z.infer<typeof errorCodeSchema>;
|
|
9
|
+
export declare const envelopeSchema: z.ZodObject<{
|
|
10
|
+
id: z.ZodString;
|
|
11
|
+
type: z.ZodString;
|
|
12
|
+
sessionId: z.ZodString;
|
|
13
|
+
deviceId: z.ZodOptional<z.ZodString>;
|
|
14
|
+
timestamp: z.ZodString;
|
|
15
|
+
traceId: z.ZodOptional<z.ZodString>;
|
|
16
|
+
seq: z.ZodOptional<z.ZodNumber>;
|
|
17
|
+
ack: z.ZodOptional<z.ZodNumber>;
|
|
18
|
+
payload: z.ZodUnknown;
|
|
19
|
+
}, "strip", z.ZodTypeAny, {
|
|
20
|
+
sessionId: string;
|
|
21
|
+
id: string;
|
|
22
|
+
type: string;
|
|
23
|
+
timestamp: string;
|
|
24
|
+
deviceId?: string | undefined;
|
|
25
|
+
traceId?: string | undefined;
|
|
26
|
+
seq?: number | undefined;
|
|
27
|
+
ack?: number | undefined;
|
|
28
|
+
payload?: unknown;
|
|
29
|
+
}, {
|
|
30
|
+
sessionId: string;
|
|
31
|
+
id: string;
|
|
32
|
+
type: string;
|
|
33
|
+
timestamp: string;
|
|
34
|
+
deviceId?: string | undefined;
|
|
35
|
+
traceId?: string | undefined;
|
|
36
|
+
seq?: number | undefined;
|
|
37
|
+
ack?: number | undefined;
|
|
38
|
+
payload?: unknown;
|
|
39
|
+
}>;
|
|
40
|
+
export type Envelope = z.infer<typeof envelopeSchema>;
|
|
41
|
+
export declare const terminalOutputPayloadSchema: z.ZodObject<{
|
|
42
|
+
stream: z.ZodEnum<["stdout", "stderr"]>;
|
|
43
|
+
data: z.ZodString;
|
|
44
|
+
encoding: z.ZodDefault<z.ZodLiteral<"utf8">>;
|
|
45
|
+
isReplay: z.ZodDefault<z.ZodBoolean>;
|
|
46
|
+
isFinal: z.ZodDefault<z.ZodBoolean>;
|
|
47
|
+
}, "strip", z.ZodTypeAny, {
|
|
48
|
+
stream: "stdout" | "stderr";
|
|
49
|
+
data: string;
|
|
50
|
+
encoding: "utf8";
|
|
51
|
+
isReplay: boolean;
|
|
52
|
+
isFinal: boolean;
|
|
53
|
+
}, {
|
|
54
|
+
stream: "stdout" | "stderr";
|
|
55
|
+
data: string;
|
|
56
|
+
encoding?: "utf8" | undefined;
|
|
57
|
+
isReplay?: boolean | undefined;
|
|
58
|
+
isFinal?: boolean | undefined;
|
|
59
|
+
}>;
|
|
60
|
+
export declare const terminalInputPayloadSchema: z.ZodObject<{
|
|
61
|
+
data: z.ZodString;
|
|
62
|
+
}, "strip", z.ZodTypeAny, {
|
|
63
|
+
data: string;
|
|
64
|
+
}, {
|
|
65
|
+
data: string;
|
|
66
|
+
}>;
|
|
67
|
+
export declare const terminalResizePayloadSchema: z.ZodObject<{
|
|
68
|
+
cols: z.ZodNumber;
|
|
69
|
+
rows: z.ZodNumber;
|
|
70
|
+
}, "strip", z.ZodTypeAny, {
|
|
71
|
+
cols: number;
|
|
72
|
+
rows: number;
|
|
73
|
+
}, {
|
|
74
|
+
cols: number;
|
|
75
|
+
rows: number;
|
|
76
|
+
}>;
|
|
77
|
+
export declare const sessionConnectPayloadSchema: z.ZodObject<{
|
|
78
|
+
role: z.ZodEnum<["host", "client"]>;
|
|
79
|
+
clientName: z.ZodString;
|
|
80
|
+
provider: z.ZodOptional<z.ZodEnum<["claude", "codex", "custom"]>>;
|
|
81
|
+
protocolVersion: z.ZodOptional<z.ZodNumber>;
|
|
82
|
+
hostname: z.ZodOptional<z.ZodString>;
|
|
83
|
+
}, "strip", z.ZodTypeAny, {
|
|
84
|
+
clientName: string;
|
|
85
|
+
role: "host" | "client";
|
|
86
|
+
provider?: "claude" | "codex" | "custom" | undefined;
|
|
87
|
+
protocolVersion?: number | undefined;
|
|
88
|
+
hostname?: string | undefined;
|
|
89
|
+
}, {
|
|
90
|
+
clientName: string;
|
|
91
|
+
role: "host" | "client";
|
|
92
|
+
provider?: "claude" | "codex" | "custom" | undefined;
|
|
93
|
+
protocolVersion?: number | undefined;
|
|
94
|
+
hostname?: string | undefined;
|
|
95
|
+
}>;
|
|
96
|
+
export declare const terminalExitPayloadSchema: z.ZodObject<{
|
|
97
|
+
exitCode: z.ZodNullable<z.ZodNumber>;
|
|
98
|
+
signal: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
99
|
+
}, "strip", z.ZodTypeAny, {
|
|
100
|
+
exitCode: number | null;
|
|
101
|
+
signal?: number | null | undefined;
|
|
102
|
+
}, {
|
|
103
|
+
exitCode: number | null;
|
|
104
|
+
signal?: number | null | undefined;
|
|
105
|
+
}>;
|
|
106
|
+
export declare const sessionAckPayloadSchema: z.ZodObject<{
|
|
107
|
+
seq: z.ZodNumber;
|
|
108
|
+
}, "strip", z.ZodTypeAny, {
|
|
109
|
+
seq: number;
|
|
110
|
+
}, {
|
|
111
|
+
seq: number;
|
|
112
|
+
}>;
|
|
113
|
+
export declare const sessionResumePayloadSchema: z.ZodObject<{
|
|
114
|
+
lastAckedSeq: z.ZodNumber;
|
|
115
|
+
}, "strip", z.ZodTypeAny, {
|
|
116
|
+
lastAckedSeq: number;
|
|
117
|
+
}, {
|
|
118
|
+
lastAckedSeq: number;
|
|
119
|
+
}>;
|
|
120
|
+
export declare const sessionHeartbeatPayloadSchema: z.ZodObject<{
|
|
121
|
+
ts: z.ZodNumber;
|
|
122
|
+
}, "strip", z.ZodTypeAny, {
|
|
123
|
+
ts: number;
|
|
124
|
+
}, {
|
|
125
|
+
ts: number;
|
|
126
|
+
}>;
|
|
127
|
+
export declare const pairingCreatedPayloadSchema: z.ZodObject<{
|
|
128
|
+
pairingCode: z.ZodString;
|
|
129
|
+
sessionId: z.ZodString;
|
|
130
|
+
expiresAt: z.ZodString;
|
|
131
|
+
}, "strip", z.ZodTypeAny, {
|
|
132
|
+
sessionId: string;
|
|
133
|
+
pairingCode: string;
|
|
134
|
+
expiresAt: string;
|
|
135
|
+
}, {
|
|
136
|
+
sessionId: string;
|
|
137
|
+
pairingCode: string;
|
|
138
|
+
expiresAt: string;
|
|
139
|
+
}>;
|
|
140
|
+
export declare const sessionClaimPayloadSchema: z.ZodObject<{
|
|
141
|
+
pairingCode: z.ZodString;
|
|
142
|
+
}, "strip", z.ZodTypeAny, {
|
|
143
|
+
pairingCode: string;
|
|
144
|
+
}, {
|
|
145
|
+
pairingCode: string;
|
|
146
|
+
}>;
|
|
147
|
+
export declare const sessionClaimedPayloadSchema: z.ZodObject<{
|
|
148
|
+
sessionId: z.ZodString;
|
|
149
|
+
}, "strip", z.ZodTypeAny, {
|
|
150
|
+
sessionId: string;
|
|
151
|
+
}, {
|
|
152
|
+
sessionId: string;
|
|
153
|
+
}>;
|
|
154
|
+
export declare const controlClaimPayloadSchema: z.ZodObject<{
|
|
155
|
+
deviceId: z.ZodString;
|
|
156
|
+
}, "strip", z.ZodTypeAny, {
|
|
157
|
+
deviceId: string;
|
|
158
|
+
}, {
|
|
159
|
+
deviceId: string;
|
|
160
|
+
}>;
|
|
161
|
+
export declare const controlGrantPayloadSchema: z.ZodObject<{
|
|
162
|
+
deviceId: z.ZodString;
|
|
163
|
+
}, "strip", z.ZodTypeAny, {
|
|
164
|
+
deviceId: string;
|
|
165
|
+
}, {
|
|
166
|
+
deviceId: string;
|
|
167
|
+
}>;
|
|
168
|
+
export declare const controlRejectPayloadSchema: z.ZodObject<{
|
|
169
|
+
deviceId: z.ZodString;
|
|
170
|
+
reason: z.ZodString;
|
|
171
|
+
}, "strip", z.ZodTypeAny, {
|
|
172
|
+
deviceId: string;
|
|
173
|
+
reason: string;
|
|
174
|
+
}, {
|
|
175
|
+
deviceId: string;
|
|
176
|
+
reason: string;
|
|
177
|
+
}>;
|
|
178
|
+
export declare const controlReleasePayloadSchema: z.ZodObject<{
|
|
179
|
+
deviceId: z.ZodString;
|
|
180
|
+
}, "strip", z.ZodTypeAny, {
|
|
181
|
+
deviceId: string;
|
|
182
|
+
}, {
|
|
183
|
+
deviceId: string;
|
|
184
|
+
}>;
|
|
185
|
+
export declare const sessionHostDisconnectedPayloadSchema: z.ZodObject<{
|
|
186
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
187
|
+
}, "strip", z.ZodTypeAny, {
|
|
188
|
+
reason?: string | undefined;
|
|
189
|
+
}, {
|
|
190
|
+
reason?: string | undefined;
|
|
191
|
+
}>;
|
|
192
|
+
export declare const sessionHostReconnectedPayloadSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
|
|
193
|
+
export declare const errorPayloadSchema: z.ZodObject<{
|
|
194
|
+
code: z.ZodString;
|
|
195
|
+
message: z.ZodString;
|
|
196
|
+
}, "strip", z.ZodTypeAny, {
|
|
197
|
+
message: string;
|
|
198
|
+
code: string;
|
|
199
|
+
}, {
|
|
200
|
+
message: string;
|
|
201
|
+
code: string;
|
|
202
|
+
}>;
|
|
203
|
+
export declare const protocolMessageSchemas: {
|
|
204
|
+
readonly "session.connect": z.ZodObject<{
|
|
205
|
+
role: z.ZodEnum<["host", "client"]>;
|
|
206
|
+
clientName: z.ZodString;
|
|
207
|
+
provider: z.ZodOptional<z.ZodEnum<["claude", "codex", "custom"]>>;
|
|
208
|
+
protocolVersion: z.ZodOptional<z.ZodNumber>;
|
|
209
|
+
hostname: z.ZodOptional<z.ZodString>;
|
|
210
|
+
}, "strip", z.ZodTypeAny, {
|
|
211
|
+
clientName: string;
|
|
212
|
+
role: "host" | "client";
|
|
213
|
+
provider?: "claude" | "codex" | "custom" | undefined;
|
|
214
|
+
protocolVersion?: number | undefined;
|
|
215
|
+
hostname?: string | undefined;
|
|
216
|
+
}, {
|
|
217
|
+
clientName: string;
|
|
218
|
+
role: "host" | "client";
|
|
219
|
+
provider?: "claude" | "codex" | "custom" | undefined;
|
|
220
|
+
protocolVersion?: number | undefined;
|
|
221
|
+
hostname?: string | undefined;
|
|
222
|
+
}>;
|
|
223
|
+
readonly "session.ack": z.ZodObject<{
|
|
224
|
+
seq: z.ZodNumber;
|
|
225
|
+
}, "strip", z.ZodTypeAny, {
|
|
226
|
+
seq: number;
|
|
227
|
+
}, {
|
|
228
|
+
seq: number;
|
|
229
|
+
}>;
|
|
230
|
+
readonly "session.resume": z.ZodObject<{
|
|
231
|
+
lastAckedSeq: z.ZodNumber;
|
|
232
|
+
}, "strip", z.ZodTypeAny, {
|
|
233
|
+
lastAckedSeq: number;
|
|
234
|
+
}, {
|
|
235
|
+
lastAckedSeq: number;
|
|
236
|
+
}>;
|
|
237
|
+
readonly "session.heartbeat": z.ZodObject<{
|
|
238
|
+
ts: z.ZodNumber;
|
|
239
|
+
}, "strip", z.ZodTypeAny, {
|
|
240
|
+
ts: number;
|
|
241
|
+
}, {
|
|
242
|
+
ts: number;
|
|
243
|
+
}>;
|
|
244
|
+
readonly "session.error": z.ZodObject<{
|
|
245
|
+
code: z.ZodString;
|
|
246
|
+
message: z.ZodString;
|
|
247
|
+
}, "strip", z.ZodTypeAny, {
|
|
248
|
+
message: string;
|
|
249
|
+
code: string;
|
|
250
|
+
}, {
|
|
251
|
+
message: string;
|
|
252
|
+
code: string;
|
|
253
|
+
}>;
|
|
254
|
+
readonly "terminal.output": z.ZodObject<{
|
|
255
|
+
stream: z.ZodEnum<["stdout", "stderr"]>;
|
|
256
|
+
data: z.ZodString;
|
|
257
|
+
encoding: z.ZodDefault<z.ZodLiteral<"utf8">>;
|
|
258
|
+
isReplay: z.ZodDefault<z.ZodBoolean>;
|
|
259
|
+
isFinal: z.ZodDefault<z.ZodBoolean>;
|
|
260
|
+
}, "strip", z.ZodTypeAny, {
|
|
261
|
+
stream: "stdout" | "stderr";
|
|
262
|
+
data: string;
|
|
263
|
+
encoding: "utf8";
|
|
264
|
+
isReplay: boolean;
|
|
265
|
+
isFinal: boolean;
|
|
266
|
+
}, {
|
|
267
|
+
stream: "stdout" | "stderr";
|
|
268
|
+
data: string;
|
|
269
|
+
encoding?: "utf8" | undefined;
|
|
270
|
+
isReplay?: boolean | undefined;
|
|
271
|
+
isFinal?: boolean | undefined;
|
|
272
|
+
}>;
|
|
273
|
+
readonly "terminal.input": z.ZodObject<{
|
|
274
|
+
data: z.ZodString;
|
|
275
|
+
}, "strip", z.ZodTypeAny, {
|
|
276
|
+
data: string;
|
|
277
|
+
}, {
|
|
278
|
+
data: string;
|
|
279
|
+
}>;
|
|
280
|
+
readonly "terminal.resize": z.ZodObject<{
|
|
281
|
+
cols: z.ZodNumber;
|
|
282
|
+
rows: z.ZodNumber;
|
|
283
|
+
}, "strip", z.ZodTypeAny, {
|
|
284
|
+
cols: number;
|
|
285
|
+
rows: number;
|
|
286
|
+
}, {
|
|
287
|
+
cols: number;
|
|
288
|
+
rows: number;
|
|
289
|
+
}>;
|
|
290
|
+
readonly "terminal.exit": z.ZodObject<{
|
|
291
|
+
exitCode: z.ZodNullable<z.ZodNumber>;
|
|
292
|
+
signal: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
293
|
+
}, "strip", z.ZodTypeAny, {
|
|
294
|
+
exitCode: number | null;
|
|
295
|
+
signal?: number | null | undefined;
|
|
296
|
+
}, {
|
|
297
|
+
exitCode: number | null;
|
|
298
|
+
signal?: number | null | undefined;
|
|
299
|
+
}>;
|
|
300
|
+
readonly "pairing.created": z.ZodObject<{
|
|
301
|
+
pairingCode: z.ZodString;
|
|
302
|
+
sessionId: z.ZodString;
|
|
303
|
+
expiresAt: z.ZodString;
|
|
304
|
+
}, "strip", z.ZodTypeAny, {
|
|
305
|
+
sessionId: string;
|
|
306
|
+
pairingCode: string;
|
|
307
|
+
expiresAt: string;
|
|
308
|
+
}, {
|
|
309
|
+
sessionId: string;
|
|
310
|
+
pairingCode: string;
|
|
311
|
+
expiresAt: string;
|
|
312
|
+
}>;
|
|
313
|
+
readonly "pairing.claim": z.ZodObject<{
|
|
314
|
+
pairingCode: z.ZodString;
|
|
315
|
+
}, "strip", z.ZodTypeAny, {
|
|
316
|
+
pairingCode: string;
|
|
317
|
+
}, {
|
|
318
|
+
pairingCode: string;
|
|
319
|
+
}>;
|
|
320
|
+
readonly "pairing.claimed": z.ZodObject<{
|
|
321
|
+
sessionId: z.ZodString;
|
|
322
|
+
}, "strip", z.ZodTypeAny, {
|
|
323
|
+
sessionId: string;
|
|
324
|
+
}, {
|
|
325
|
+
sessionId: string;
|
|
326
|
+
}>;
|
|
327
|
+
readonly "control.claim": z.ZodObject<{
|
|
328
|
+
deviceId: z.ZodString;
|
|
329
|
+
}, "strip", z.ZodTypeAny, {
|
|
330
|
+
deviceId: string;
|
|
331
|
+
}, {
|
|
332
|
+
deviceId: string;
|
|
333
|
+
}>;
|
|
334
|
+
readonly "control.grant": z.ZodObject<{
|
|
335
|
+
deviceId: z.ZodString;
|
|
336
|
+
}, "strip", z.ZodTypeAny, {
|
|
337
|
+
deviceId: string;
|
|
338
|
+
}, {
|
|
339
|
+
deviceId: string;
|
|
340
|
+
}>;
|
|
341
|
+
readonly "control.reject": z.ZodObject<{
|
|
342
|
+
deviceId: z.ZodString;
|
|
343
|
+
reason: z.ZodString;
|
|
344
|
+
}, "strip", z.ZodTypeAny, {
|
|
345
|
+
deviceId: string;
|
|
346
|
+
reason: string;
|
|
347
|
+
}, {
|
|
348
|
+
deviceId: string;
|
|
349
|
+
reason: string;
|
|
350
|
+
}>;
|
|
351
|
+
readonly "control.release": z.ZodObject<{
|
|
352
|
+
deviceId: z.ZodString;
|
|
353
|
+
}, "strip", z.ZodTypeAny, {
|
|
354
|
+
deviceId: string;
|
|
355
|
+
}, {
|
|
356
|
+
deviceId: string;
|
|
357
|
+
}>;
|
|
358
|
+
readonly "session.host_disconnected": z.ZodObject<{
|
|
359
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
360
|
+
}, "strip", z.ZodTypeAny, {
|
|
361
|
+
reason?: string | undefined;
|
|
362
|
+
}, {
|
|
363
|
+
reason?: string | undefined;
|
|
364
|
+
}>;
|
|
365
|
+
readonly "session.host_reconnected": z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
|
|
366
|
+
};
|
|
367
|
+
export type ProtocolMessageType = keyof typeof protocolMessageSchemas;
|
|
368
|
+
export declare function createEnvelope<T>(input: {
|
|
369
|
+
type: ProtocolMessageType;
|
|
370
|
+
sessionId: string;
|
|
371
|
+
payload: T;
|
|
372
|
+
id?: string;
|
|
373
|
+
seq?: number;
|
|
374
|
+
ack?: number;
|
|
375
|
+
deviceId?: string;
|
|
376
|
+
traceId?: string;
|
|
377
|
+
}): Envelope;
|
|
378
|
+
export declare function parseEnvelope(raw: string): Envelope;
|
|
379
|
+
export declare function serializeEnvelope(message: Envelope): string;
|
|
380
|
+
export declare function parseTypedPayload<TType extends ProtocolMessageType>(type: TType, payload: unknown): z.infer<(typeof protocolMessageSchemas)[TType]>;
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
// ── Protocol version ────────────────────────────────────────────────
|
|
3
|
+
export const PROTOCOL_VERSION = 1;
|
|
4
|
+
// ── Device & Session enums ──────────────────────────────────────────
|
|
5
|
+
export const deviceRoleSchema = z.enum(["host", "client"]);
|
|
6
|
+
export const sessionStateSchema = z.enum([
|
|
7
|
+
"pending_pairing",
|
|
8
|
+
"connecting",
|
|
9
|
+
"active",
|
|
10
|
+
"reconnecting",
|
|
11
|
+
"idle",
|
|
12
|
+
"terminated",
|
|
13
|
+
]);
|
|
14
|
+
export const errorCodeSchema = z.enum([
|
|
15
|
+
"session_not_found",
|
|
16
|
+
"pairing_expired",
|
|
17
|
+
"pairing_not_found",
|
|
18
|
+
"control_conflict",
|
|
19
|
+
"session_terminated",
|
|
20
|
+
"ack_out_of_range",
|
|
21
|
+
"invalid_message",
|
|
22
|
+
"unauthorized",
|
|
23
|
+
]);
|
|
24
|
+
// ── Envelope ────────────────────────────────────────────────────────
|
|
25
|
+
export const envelopeSchema = z.object({
|
|
26
|
+
id: z.string().min(1),
|
|
27
|
+
type: z.string().min(1),
|
|
28
|
+
sessionId: z.string().min(1),
|
|
29
|
+
deviceId: z.string().min(1).optional(),
|
|
30
|
+
timestamp: z.string().datetime(),
|
|
31
|
+
traceId: z.string().min(1).optional(),
|
|
32
|
+
seq: z.number().int().nonnegative().optional(),
|
|
33
|
+
ack: z.number().int().nonnegative().optional(),
|
|
34
|
+
payload: z.unknown(),
|
|
35
|
+
});
|
|
36
|
+
// ── Payload schemas ─────────────────────────────────────────────────
|
|
37
|
+
export const terminalOutputPayloadSchema = z.object({
|
|
38
|
+
stream: z.enum(["stdout", "stderr"]),
|
|
39
|
+
data: z.string(),
|
|
40
|
+
encoding: z.literal("utf8").default("utf8"),
|
|
41
|
+
isReplay: z.boolean().default(false),
|
|
42
|
+
isFinal: z.boolean().default(false),
|
|
43
|
+
});
|
|
44
|
+
export const terminalInputPayloadSchema = z.object({
|
|
45
|
+
data: z.string(),
|
|
46
|
+
});
|
|
47
|
+
export const terminalResizePayloadSchema = z.object({
|
|
48
|
+
cols: z.number().int().positive(),
|
|
49
|
+
rows: z.number().int().positive(),
|
|
50
|
+
});
|
|
51
|
+
export const sessionConnectPayloadSchema = z.object({
|
|
52
|
+
role: deviceRoleSchema,
|
|
53
|
+
clientName: z.string().min(1),
|
|
54
|
+
provider: z.enum(["claude", "codex", "custom"]).optional(),
|
|
55
|
+
protocolVersion: z.number().int().optional(),
|
|
56
|
+
hostname: z.string().optional(),
|
|
57
|
+
});
|
|
58
|
+
export const terminalExitPayloadSchema = z.object({
|
|
59
|
+
exitCode: z.number().int().nullable(),
|
|
60
|
+
signal: z.number().int().nullable().optional(),
|
|
61
|
+
});
|
|
62
|
+
export const sessionAckPayloadSchema = z.object({
|
|
63
|
+
seq: z.number().int().nonnegative(),
|
|
64
|
+
});
|
|
65
|
+
export const sessionResumePayloadSchema = z.object({
|
|
66
|
+
lastAckedSeq: z.number().int().nonnegative(),
|
|
67
|
+
});
|
|
68
|
+
export const sessionHeartbeatPayloadSchema = z.object({
|
|
69
|
+
ts: z.number(), // unix ms
|
|
70
|
+
});
|
|
71
|
+
export const pairingCreatedPayloadSchema = z.object({
|
|
72
|
+
pairingCode: z.string().length(6),
|
|
73
|
+
sessionId: z.string().min(1),
|
|
74
|
+
expiresAt: z.string().datetime(),
|
|
75
|
+
});
|
|
76
|
+
export const sessionClaimPayloadSchema = z.object({
|
|
77
|
+
pairingCode: z.string().length(6),
|
|
78
|
+
});
|
|
79
|
+
export const sessionClaimedPayloadSchema = z.object({
|
|
80
|
+
sessionId: z.string().min(1),
|
|
81
|
+
});
|
|
82
|
+
export const controlClaimPayloadSchema = z.object({
|
|
83
|
+
deviceId: z.string().min(1),
|
|
84
|
+
});
|
|
85
|
+
export const controlGrantPayloadSchema = z.object({
|
|
86
|
+
deviceId: z.string().min(1),
|
|
87
|
+
});
|
|
88
|
+
export const controlRejectPayloadSchema = z.object({
|
|
89
|
+
deviceId: z.string().min(1),
|
|
90
|
+
reason: z.string().min(1),
|
|
91
|
+
});
|
|
92
|
+
export const controlReleasePayloadSchema = z.object({
|
|
93
|
+
deviceId: z.string().min(1),
|
|
94
|
+
});
|
|
95
|
+
export const sessionHostDisconnectedPayloadSchema = z.object({
|
|
96
|
+
reason: z.string().optional(),
|
|
97
|
+
});
|
|
98
|
+
export const sessionHostReconnectedPayloadSchema = z.object({});
|
|
99
|
+
export const errorPayloadSchema = z.object({
|
|
100
|
+
code: z.string().min(1),
|
|
101
|
+
message: z.string().min(1),
|
|
102
|
+
});
|
|
103
|
+
// ── Protocol message type registry ──────────────────────────────────
|
|
104
|
+
export const protocolMessageSchemas = {
|
|
105
|
+
"session.connect": sessionConnectPayloadSchema,
|
|
106
|
+
"session.ack": sessionAckPayloadSchema,
|
|
107
|
+
"session.resume": sessionResumePayloadSchema,
|
|
108
|
+
"session.heartbeat": sessionHeartbeatPayloadSchema,
|
|
109
|
+
"session.error": errorPayloadSchema,
|
|
110
|
+
"terminal.output": terminalOutputPayloadSchema,
|
|
111
|
+
"terminal.input": terminalInputPayloadSchema,
|
|
112
|
+
"terminal.resize": terminalResizePayloadSchema,
|
|
113
|
+
"terminal.exit": terminalExitPayloadSchema,
|
|
114
|
+
"pairing.created": pairingCreatedPayloadSchema,
|
|
115
|
+
"pairing.claim": sessionClaimPayloadSchema,
|
|
116
|
+
"pairing.claimed": sessionClaimedPayloadSchema,
|
|
117
|
+
"control.claim": controlClaimPayloadSchema,
|
|
118
|
+
"control.grant": controlGrantPayloadSchema,
|
|
119
|
+
"control.reject": controlRejectPayloadSchema,
|
|
120
|
+
"control.release": controlReleasePayloadSchema,
|
|
121
|
+
"session.host_disconnected": sessionHostDisconnectedPayloadSchema,
|
|
122
|
+
"session.host_reconnected": sessionHostReconnectedPayloadSchema,
|
|
123
|
+
};
|
|
124
|
+
// ── UUID helper (works in Node, Web, and Expo) ─────────────────────
|
|
125
|
+
function generateId() {
|
|
126
|
+
if (typeof globalThis.crypto?.randomUUID === "function") {
|
|
127
|
+
return globalThis.crypto.randomUUID();
|
|
128
|
+
}
|
|
129
|
+
// Fallback for environments without crypto.randomUUID (older Expo native)
|
|
130
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
131
|
+
const r = (Math.random() * 16) | 0;
|
|
132
|
+
return (c === "x" ? r : (r & 0x3) | 0x8).toString(16);
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
// ── Helpers ─────────────────────────────────────────────────────────
|
|
136
|
+
export function createEnvelope(input) {
|
|
137
|
+
return {
|
|
138
|
+
id: input.id ?? generateId(),
|
|
139
|
+
type: input.type,
|
|
140
|
+
sessionId: input.sessionId,
|
|
141
|
+
deviceId: input.deviceId,
|
|
142
|
+
timestamp: new Date().toISOString(),
|
|
143
|
+
traceId: input.traceId,
|
|
144
|
+
seq: input.seq,
|
|
145
|
+
ack: input.ack,
|
|
146
|
+
payload: input.payload,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
export function parseEnvelope(raw) {
|
|
150
|
+
return envelopeSchema.parse(JSON.parse(raw));
|
|
151
|
+
}
|
|
152
|
+
export function serializeEnvelope(message) {
|
|
153
|
+
return JSON.stringify(message);
|
|
154
|
+
}
|
|
155
|
+
export function parseTypedPayload(type, payload) {
|
|
156
|
+
return protocolMessageSchemas[type].parse(payload);
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../shared-protocol/src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "linkshell-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Remote terminal bridge for Claude Code / Codex — control from your phone",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"linkshell": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"src",
|
|
13
|
+
"README.md",
|
|
14
|
+
"LICENSE"
|
|
15
|
+
],
|
|
16
|
+
"keywords": [
|
|
17
|
+
"terminal",
|
|
18
|
+
"remote",
|
|
19
|
+
"claude",
|
|
20
|
+
"codex",
|
|
21
|
+
"pty",
|
|
22
|
+
"bridge",
|
|
23
|
+
"mobile",
|
|
24
|
+
"websocket"
|
|
25
|
+
],
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "https://github.com/user/linkshell"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"commander": "^13.1.0",
|
|
33
|
+
"node-pty": "^1.0.0",
|
|
34
|
+
"qrcode-terminal": "^0.12.0",
|
|
35
|
+
"ws": "^8.18.1",
|
|
36
|
+
"zod": "^3.24.3",
|
|
37
|
+
"@linkshell/protocol": "0.1.0",
|
|
38
|
+
"@linkshell/gateway": "0.1.0"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@types/ws": "^8.5.14",
|
|
42
|
+
"tsx": "^4.19.3"
|
|
43
|
+
},
|
|
44
|
+
"scripts": {
|
|
45
|
+
"build": "tsc -p tsconfig.json",
|
|
46
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
47
|
+
"dev": "tsx src/index.ts"
|
|
48
|
+
}
|
|
49
|
+
}
|