@linkshell/gateway 0.5.2 → 0.6.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 (109) hide show
  1. package/Dockerfile +8 -22
  2. package/README.md +99 -44
  3. package/dist/gateway/src/accounts.js.map +1 -0
  4. package/dist/gateway/src/index.d.ts +4 -1
  5. package/dist/gateway/src/index.js +4 -863
  6. package/dist/gateway/src/index.js.map +1 -1
  7. package/dist/gateway/src/main.js +57 -0
  8. package/dist/gateway/src/main.js.map +1 -0
  9. package/dist/gateway/src/rate-limit.d.ts +22 -0
  10. package/dist/gateway/src/rate-limit.js +66 -0
  11. package/dist/gateway/src/rate-limit.js.map +1 -0
  12. package/dist/gateway/src/relay.d.ts +84 -5
  13. package/dist/gateway/src/relay.js +402 -529
  14. package/dist/gateway/src/relay.js.map +1 -1
  15. package/dist/gateway/src/serve.d.ts +34 -0
  16. package/dist/gateway/src/serve.js +102 -0
  17. package/dist/gateway/src/serve.js.map +1 -0
  18. package/dist/{gateway-v2 → gateway}/src/store.d.ts +5 -0
  19. package/dist/{gateway-v2 → gateway}/src/store.js +7 -0
  20. package/dist/gateway/src/store.js.map +1 -0
  21. package/dist/gateway/src/subscription.d.ts +18 -0
  22. package/dist/gateway/src/subscription.js +46 -0
  23. package/dist/gateway/src/subscription.js.map +1 -0
  24. package/dist/gateway/tsconfig.tsbuildinfo +1 -1
  25. package/dist/wire/src/direct.d.ts +22 -0
  26. package/dist/wire/src/direct.js +37 -0
  27. package/dist/wire/src/direct.js.map +1 -0
  28. package/dist/wire/src/index.d.ts +1 -0
  29. package/dist/wire/src/index.js +1 -0
  30. package/dist/wire/src/index.js.map +1 -1
  31. package/dist/wire/src/model.d.ts +387 -6
  32. package/dist/wire/src/model.js +74 -0
  33. package/dist/wire/src/model.js.map +1 -1
  34. package/dist/wire/src/relay.d.ts +8 -8
  35. package/dist/wire/src/rpc.d.ts +2524 -200
  36. package/dist/wire/src/rpc.js +77 -4
  37. package/dist/wire/src/rpc.js.map +1 -1
  38. package/dist/wire/src/updates.d.ts +390 -34
  39. package/dist/wire/src/updates.js +11 -1
  40. package/dist/wire/src/updates.js.map +1 -1
  41. package/package.json +12 -12
  42. package/src/accounts.ts +32 -0
  43. package/src/index.ts +4 -997
  44. package/src/main.ts +65 -0
  45. package/src/rate-limit.ts +72 -0
  46. package/src/relay.ts +435 -620
  47. package/src/serve.ts +130 -0
  48. package/src/store.ts +135 -0
  49. package/src/subscription.ts +51 -0
  50. package/dist/gateway/src/auth-middleware.d.ts +0 -44
  51. package/dist/gateway/src/auth-middleware.js +0 -204
  52. package/dist/gateway/src/auth-middleware.js.map +0 -1
  53. package/dist/gateway/src/cors.d.ts +0 -2
  54. package/dist/gateway/src/cors.js +0 -7
  55. package/dist/gateway/src/cors.js.map +0 -1
  56. package/dist/gateway/src/embedded.d.ts +0 -21
  57. package/dist/gateway/src/embedded.js +0 -438
  58. package/dist/gateway/src/embedded.js.map +0 -1
  59. package/dist/gateway/src/host-auth.d.ts +0 -32
  60. package/dist/gateway/src/host-auth.js +0 -78
  61. package/dist/gateway/src/host-auth.js.map +0 -1
  62. package/dist/gateway/src/pairings.d.ts +0 -38
  63. package/dist/gateway/src/pairings.js +0 -119
  64. package/dist/gateway/src/pairings.js.map +0 -1
  65. package/dist/gateway/src/presence.d.ts +0 -28
  66. package/dist/gateway/src/presence.js +0 -92
  67. package/dist/gateway/src/presence.js.map +0 -1
  68. package/dist/gateway/src/sessions.d.ts +0 -113
  69. package/dist/gateway/src/sessions.js +0 -352
  70. package/dist/gateway/src/sessions.js.map +0 -1
  71. package/dist/gateway/src/state-store.d.ts +0 -21
  72. package/dist/gateway/src/state-store.js +0 -103
  73. package/dist/gateway/src/state-store.js.map +0 -1
  74. package/dist/gateway/src/static-web.d.ts +0 -15
  75. package/dist/gateway/src/static-web.js +0 -129
  76. package/dist/gateway/src/static-web.js.map +0 -1
  77. package/dist/gateway/src/tokens.d.ts +0 -19
  78. package/dist/gateway/src/tokens.js +0 -151
  79. package/dist/gateway/src/tokens.js.map +0 -1
  80. package/dist/gateway/src/tunnel.d.ts +0 -61
  81. package/dist/gateway/src/tunnel.js +0 -576
  82. package/dist/gateway/src/tunnel.js.map +0 -1
  83. package/dist/gateway-v2/src/accounts.js.map +0 -1
  84. package/dist/gateway-v2/src/index.d.ts +0 -3
  85. package/dist/gateway-v2/src/index.js +0 -4
  86. package/dist/gateway-v2/src/index.js.map +0 -1
  87. package/dist/gateway-v2/src/main.js +0 -17
  88. package/dist/gateway-v2/src/main.js.map +0 -1
  89. package/dist/gateway-v2/src/server.d.ts +0 -84
  90. package/dist/gateway-v2/src/server.js +0 -426
  91. package/dist/gateway-v2/src/server.js.map +0 -1
  92. package/dist/gateway-v2/src/store.js.map +0 -1
  93. package/dist/shared-protocol/src/index.d.ts +0 -17029
  94. package/dist/shared-protocol/src/index.js +0 -1064
  95. package/dist/shared-protocol/src/index.js.map +0 -1
  96. package/src/auth-middleware.ts +0 -266
  97. package/src/cors.ts +0 -8
  98. package/src/embedded.ts +0 -526
  99. package/src/host-auth.ts +0 -88
  100. package/src/pairings.ts +0 -133
  101. package/src/presence.ts +0 -118
  102. package/src/sessions.ts +0 -432
  103. package/src/state-store.ts +0 -140
  104. package/src/static-web.ts +0 -133
  105. package/src/tokens.ts +0 -159
  106. package/src/tunnel.ts +0 -644
  107. /package/dist/{gateway-v2 → gateway}/src/accounts.d.ts +0 -0
  108. /package/dist/{gateway-v2 → gateway}/src/accounts.js +0 -0
  109. /package/dist/{gateway-v2 → gateway}/src/main.d.ts +0 -0
@@ -17,6 +17,12 @@ export declare const agentCapabilitiesSchema: z.ZodObject<{
17
17
  steer: z.ZodBoolean;
18
18
  permissions: z.ZodBoolean;
19
19
  images: z.ZodBoolean;
20
+ /**
21
+ * The agent forks sessions itself, keeping everything it knew. Every agent's
22
+ * sessions can be forked: without this (or from a single reply, where the
23
+ * agent only forks whole sessions) LinkShell makes the fork — the new session
24
+ * shows the conversation and its agent is told it as text.
25
+ */
20
26
  fork: z.ZodBoolean;
21
27
  models: z.ZodBoolean;
22
28
  modes: z.ZodBoolean;
@@ -88,6 +94,12 @@ export declare const agentInfoSchema: z.ZodObject<{
88
94
  steer: z.ZodBoolean;
89
95
  permissions: z.ZodBoolean;
90
96
  images: z.ZodBoolean;
97
+ /**
98
+ * The agent forks sessions itself, keeping everything it knew. Every agent's
99
+ * sessions can be forked: without this (or from a single reply, where the
100
+ * agent only forks whole sessions) LinkShell makes the fork — the new session
101
+ * shows the conversation and its agent is told it as text.
102
+ */
91
103
  fork: z.ZodBoolean;
92
104
  models: z.ZodBoolean;
93
105
  modes: z.ZodBoolean;
@@ -192,6 +204,80 @@ export declare const sessionActivitySchema: z.ZodObject<{
192
204
  }>;
193
205
  export type SessionActivity = z.infer<typeof sessionActivitySchema>;
194
206
  /** The oldest unanswered permission request, so lists can offer approval inline. Live only. */
207
+ /**
208
+ * Something the agent asks the user rather than asks permission for: a choice
209
+ * among options, several of them, or something to type (Claude's
210
+ * AskUserQuestion, Codex's request_user_input, an MCP server's form).
211
+ */
212
+ export declare const questionSchema: z.ZodObject<{
213
+ id: z.ZodString;
214
+ /** A short label for the question ("Auth method"). */
215
+ header: z.ZodOptional<z.ZodString>;
216
+ text: z.ZodString;
217
+ /** `choice`: one of `options`; `choices`: any number of them; `text`: typed. */
218
+ kind: z.ZodEnum<["choice", "choices", "text"]>;
219
+ options: z.ZodOptional<z.ZodArray<z.ZodObject<{
220
+ value: z.ZodString;
221
+ label: z.ZodString;
222
+ description: z.ZodOptional<z.ZodString>;
223
+ }, "strip", z.ZodTypeAny, {
224
+ value: string;
225
+ label: string;
226
+ description?: string | undefined;
227
+ }, {
228
+ value: string;
229
+ label: string;
230
+ description?: string | undefined;
231
+ }>, "many">>;
232
+ /** With options: an answer of the user's own can be typed instead of, or beside, a pick. */
233
+ other: z.ZodOptional<z.ZodBoolean>;
234
+ /** What is typed shouldn't be shown (a token). */
235
+ secret: z.ZodOptional<z.ZodBoolean>;
236
+ required: z.ZodOptional<z.ZodBoolean>;
237
+ }, "strip", z.ZodTypeAny, {
238
+ id: string;
239
+ kind: "text" | "choice" | "choices";
240
+ text: string;
241
+ options?: {
242
+ value: string;
243
+ label: string;
244
+ description?: string | undefined;
245
+ }[] | undefined;
246
+ other?: boolean | undefined;
247
+ header?: string | undefined;
248
+ secret?: boolean | undefined;
249
+ required?: boolean | undefined;
250
+ }, {
251
+ id: string;
252
+ kind: "text" | "choice" | "choices";
253
+ text: string;
254
+ options?: {
255
+ value: string;
256
+ label: string;
257
+ description?: string | undefined;
258
+ }[] | undefined;
259
+ other?: boolean | undefined;
260
+ header?: string | undefined;
261
+ secret?: boolean | undefined;
262
+ required?: boolean | undefined;
263
+ }>;
264
+ export type Question = z.infer<typeof questionSchema>;
265
+ export declare const questionAnswerSchema: z.ZodObject<{
266
+ id: z.ZodString;
267
+ /** The values picked (`choice`: at most one), or what was typed for a `text` question. */
268
+ values: z.ZodArray<z.ZodString, "many">;
269
+ /** The user's own answer beside the options. */
270
+ other: z.ZodOptional<z.ZodString>;
271
+ }, "strip", z.ZodTypeAny, {
272
+ values: string[];
273
+ id: string;
274
+ other?: string | undefined;
275
+ }, {
276
+ values: string[];
277
+ id: string;
278
+ other?: string | undefined;
279
+ }>;
280
+ export type QuestionAnswer = z.infer<typeof questionAnswerSchema>;
195
281
  export declare const pendingPermissionSchema: z.ZodObject<{
196
282
  requestId: z.ZodString;
197
283
  toolCallId: z.ZodOptional<z.ZodString>;
@@ -210,6 +296,59 @@ export declare const pendingPermissionSchema: z.ZodObject<{
210
296
  name: string;
211
297
  kind: "allow_once" | "allow_always" | "reject_once" | "reject_always";
212
298
  }>, "many">;
299
+ /** Set when this is a question to answer (`sessions.answer`) rather than a permission to give. */
300
+ questions: z.ZodOptional<z.ZodArray<z.ZodObject<{
301
+ id: z.ZodString;
302
+ /** A short label for the question ("Auth method"). */
303
+ header: z.ZodOptional<z.ZodString>;
304
+ text: z.ZodString;
305
+ /** `choice`: one of `options`; `choices`: any number of them; `text`: typed. */
306
+ kind: z.ZodEnum<["choice", "choices", "text"]>;
307
+ options: z.ZodOptional<z.ZodArray<z.ZodObject<{
308
+ value: z.ZodString;
309
+ label: z.ZodString;
310
+ description: z.ZodOptional<z.ZodString>;
311
+ }, "strip", z.ZodTypeAny, {
312
+ value: string;
313
+ label: string;
314
+ description?: string | undefined;
315
+ }, {
316
+ value: string;
317
+ label: string;
318
+ description?: string | undefined;
319
+ }>, "many">>;
320
+ /** With options: an answer of the user's own can be typed instead of, or beside, a pick. */
321
+ other: z.ZodOptional<z.ZodBoolean>;
322
+ /** What is typed shouldn't be shown (a token). */
323
+ secret: z.ZodOptional<z.ZodBoolean>;
324
+ required: z.ZodOptional<z.ZodBoolean>;
325
+ }, "strip", z.ZodTypeAny, {
326
+ id: string;
327
+ kind: "text" | "choice" | "choices";
328
+ text: string;
329
+ options?: {
330
+ value: string;
331
+ label: string;
332
+ description?: string | undefined;
333
+ }[] | undefined;
334
+ other?: boolean | undefined;
335
+ header?: string | undefined;
336
+ secret?: boolean | undefined;
337
+ required?: boolean | undefined;
338
+ }, {
339
+ id: string;
340
+ kind: "text" | "choice" | "choices";
341
+ text: string;
342
+ options?: {
343
+ value: string;
344
+ label: string;
345
+ description?: string | undefined;
346
+ }[] | undefined;
347
+ other?: boolean | undefined;
348
+ header?: string | undefined;
349
+ secret?: boolean | undefined;
350
+ required?: boolean | undefined;
351
+ }>, "many">>;
213
352
  }, "strip", z.ZodTypeAny, {
214
353
  options: {
215
354
  optionId: string;
@@ -220,6 +359,20 @@ export declare const pendingPermissionSchema: z.ZodObject<{
220
359
  requestId: string;
221
360
  toolCallId?: string | undefined;
222
361
  detail?: string | undefined;
362
+ questions?: {
363
+ id: string;
364
+ kind: "text" | "choice" | "choices";
365
+ text: string;
366
+ options?: {
367
+ value: string;
368
+ label: string;
369
+ description?: string | undefined;
370
+ }[] | undefined;
371
+ other?: boolean | undefined;
372
+ header?: string | undefined;
373
+ secret?: boolean | undefined;
374
+ required?: boolean | undefined;
375
+ }[] | undefined;
223
376
  }, {
224
377
  options: {
225
378
  optionId: string;
@@ -230,6 +383,20 @@ export declare const pendingPermissionSchema: z.ZodObject<{
230
383
  requestId: string;
231
384
  toolCallId?: string | undefined;
232
385
  detail?: string | undefined;
386
+ questions?: {
387
+ id: string;
388
+ kind: "text" | "choice" | "choices";
389
+ text: string;
390
+ options?: {
391
+ value: string;
392
+ label: string;
393
+ description?: string | undefined;
394
+ }[] | undefined;
395
+ other?: boolean | undefined;
396
+ header?: string | undefined;
397
+ secret?: boolean | undefined;
398
+ required?: boolean | undefined;
399
+ }[] | undefined;
233
400
  }>;
234
401
  export type PendingPermissionSummary = z.infer<typeof pendingPermissionSchema>;
235
402
  export declare const queuedMessageSchema: z.ZodObject<{
@@ -239,12 +406,12 @@ export declare const queuedMessageSchema: z.ZodObject<{
239
406
  images: z.ZodNumber;
240
407
  }, "strip", z.ZodTypeAny, {
241
408
  images: number;
242
- clientMessageId: string;
243
409
  text: string;
410
+ clientMessageId: string;
244
411
  }, {
245
412
  images: number;
246
- clientMessageId: string;
247
413
  text: string;
414
+ clientMessageId: string;
248
415
  }>;
249
416
  export type QueuedMessage = z.infer<typeof queuedMessageSchema>;
250
417
  /** A sub-agent a session started: the tool call it runs under, and how it is doing. */
@@ -323,6 +490,59 @@ export declare const sessionSummarySchema: z.ZodObject<{
323
490
  name: string;
324
491
  kind: "allow_once" | "allow_always" | "reject_once" | "reject_always";
325
492
  }>, "many">;
493
+ /** Set when this is a question to answer (`sessions.answer`) rather than a permission to give. */
494
+ questions: z.ZodOptional<z.ZodArray<z.ZodObject<{
495
+ id: z.ZodString;
496
+ /** A short label for the question ("Auth method"). */
497
+ header: z.ZodOptional<z.ZodString>;
498
+ text: z.ZodString;
499
+ /** `choice`: one of `options`; `choices`: any number of them; `text`: typed. */
500
+ kind: z.ZodEnum<["choice", "choices", "text"]>;
501
+ options: z.ZodOptional<z.ZodArray<z.ZodObject<{
502
+ value: z.ZodString;
503
+ label: z.ZodString;
504
+ description: z.ZodOptional<z.ZodString>;
505
+ }, "strip", z.ZodTypeAny, {
506
+ value: string;
507
+ label: string;
508
+ description?: string | undefined;
509
+ }, {
510
+ value: string;
511
+ label: string;
512
+ description?: string | undefined;
513
+ }>, "many">>;
514
+ /** With options: an answer of the user's own can be typed instead of, or beside, a pick. */
515
+ other: z.ZodOptional<z.ZodBoolean>;
516
+ /** What is typed shouldn't be shown (a token). */
517
+ secret: z.ZodOptional<z.ZodBoolean>;
518
+ required: z.ZodOptional<z.ZodBoolean>;
519
+ }, "strip", z.ZodTypeAny, {
520
+ id: string;
521
+ kind: "text" | "choice" | "choices";
522
+ text: string;
523
+ options?: {
524
+ value: string;
525
+ label: string;
526
+ description?: string | undefined;
527
+ }[] | undefined;
528
+ other?: boolean | undefined;
529
+ header?: string | undefined;
530
+ secret?: boolean | undefined;
531
+ required?: boolean | undefined;
532
+ }, {
533
+ id: string;
534
+ kind: "text" | "choice" | "choices";
535
+ text: string;
536
+ options?: {
537
+ value: string;
538
+ label: string;
539
+ description?: string | undefined;
540
+ }[] | undefined;
541
+ other?: boolean | undefined;
542
+ header?: string | undefined;
543
+ secret?: boolean | undefined;
544
+ required?: boolean | undefined;
545
+ }>, "many">>;
326
546
  }, "strip", z.ZodTypeAny, {
327
547
  options: {
328
548
  optionId: string;
@@ -333,6 +553,20 @@ export declare const sessionSummarySchema: z.ZodObject<{
333
553
  requestId: string;
334
554
  toolCallId?: string | undefined;
335
555
  detail?: string | undefined;
556
+ questions?: {
557
+ id: string;
558
+ kind: "text" | "choice" | "choices";
559
+ text: string;
560
+ options?: {
561
+ value: string;
562
+ label: string;
563
+ description?: string | undefined;
564
+ }[] | undefined;
565
+ other?: boolean | undefined;
566
+ header?: string | undefined;
567
+ secret?: boolean | undefined;
568
+ required?: boolean | undefined;
569
+ }[] | undefined;
336
570
  }, {
337
571
  options: {
338
572
  optionId: string;
@@ -343,6 +577,20 @@ export declare const sessionSummarySchema: z.ZodObject<{
343
577
  requestId: string;
344
578
  toolCallId?: string | undefined;
345
579
  detail?: string | undefined;
580
+ questions?: {
581
+ id: string;
582
+ kind: "text" | "choice" | "choices";
583
+ text: string;
584
+ options?: {
585
+ value: string;
586
+ label: string;
587
+ description?: string | undefined;
588
+ }[] | undefined;
589
+ other?: boolean | undefined;
590
+ header?: string | undefined;
591
+ secret?: boolean | undefined;
592
+ required?: boolean | undefined;
593
+ }[] | undefined;
346
594
  }>>;
347
595
  /**
348
596
  * Live only: messages waiting for the current turn to end, when the host
@@ -355,13 +603,29 @@ export declare const sessionSummarySchema: z.ZodObject<{
355
603
  images: z.ZodNumber;
356
604
  }, "strip", z.ZodTypeAny, {
357
605
  images: number;
358
- clientMessageId: string;
359
606
  text: string;
607
+ clientMessageId: string;
360
608
  }, {
361
609
  images: number;
362
- clientMessageId: string;
363
610
  text: string;
611
+ clientMessageId: string;
364
612
  }>, "many">>;
613
+ /**
614
+ * The session works in a git worktree LinkShell made for it: its own
615
+ * checkout and branch, so it can't disturb the project's working directory.
616
+ * `cwd` is inside the worktree; `source` is the directory it was made from
617
+ * (the project the session belongs to).
618
+ */
619
+ worktree: z.ZodOptional<z.ZodObject<{
620
+ branch: z.ZodString;
621
+ source: z.ZodString;
622
+ }, "strip", z.ZodTypeAny, {
623
+ branch: string;
624
+ source: string;
625
+ }, {
626
+ branch: string;
627
+ source: string;
628
+ }>>;
365
629
  /** Live only, for sessions that started sub-agents: how many, and how many are working now (`sessions.subagents` lists them). */
366
630
  subagents: z.ZodOptional<z.ZodObject<{
367
631
  total: z.ZodNumber;
@@ -403,12 +667,30 @@ export declare const sessionSummarySchema: z.ZodObject<{
403
667
  requestId: string;
404
668
  toolCallId?: string | undefined;
405
669
  detail?: string | undefined;
670
+ questions?: {
671
+ id: string;
672
+ kind: "text" | "choice" | "choices";
673
+ text: string;
674
+ options?: {
675
+ value: string;
676
+ label: string;
677
+ description?: string | undefined;
678
+ }[] | undefined;
679
+ other?: boolean | undefined;
680
+ header?: string | undefined;
681
+ secret?: boolean | undefined;
682
+ required?: boolean | undefined;
683
+ }[] | undefined;
406
684
  } | undefined;
407
685
  queue?: {
408
686
  images: number;
409
- clientMessageId: string;
410
687
  text: string;
688
+ clientMessageId: string;
411
689
  }[] | undefined;
690
+ worktree?: {
691
+ branch: string;
692
+ source: string;
693
+ } | undefined;
412
694
  subagents?: {
413
695
  running: number;
414
696
  total: number;
@@ -443,12 +725,30 @@ export declare const sessionSummarySchema: z.ZodObject<{
443
725
  requestId: string;
444
726
  toolCallId?: string | undefined;
445
727
  detail?: string | undefined;
728
+ questions?: {
729
+ id: string;
730
+ kind: "text" | "choice" | "choices";
731
+ text: string;
732
+ options?: {
733
+ value: string;
734
+ label: string;
735
+ description?: string | undefined;
736
+ }[] | undefined;
737
+ other?: boolean | undefined;
738
+ header?: string | undefined;
739
+ secret?: boolean | undefined;
740
+ required?: boolean | undefined;
741
+ }[] | undefined;
446
742
  } | undefined;
447
743
  queue?: {
448
744
  images: number;
449
- clientMessageId: string;
450
745
  text: string;
746
+ clientMessageId: string;
451
747
  }[] | undefined;
748
+ worktree?: {
749
+ branch: string;
750
+ source: string;
751
+ } | undefined;
452
752
  subagents?: {
453
753
  running: number;
454
754
  total: number;
@@ -460,21 +760,79 @@ export declare function parseSessionId(id: string): {
460
760
  agent: string;
461
761
  nativeId: string;
462
762
  } | null;
763
+ /** What git says about a directory, to offer starting a session in a worktree of it. */
764
+ export declare const gitInfoSchema: z.ZodObject<{
765
+ /** The repository's top directory. */
766
+ root: z.ZodString;
767
+ /** The branch checked out; absent on a detached HEAD. */
768
+ branch: z.ZodOptional<z.ZodString>;
769
+ /** The commit checked out, abbreviated; absent before the first commit. */
770
+ head: z.ZodOptional<z.ZodString>;
771
+ /** Uncommitted changes in the working directory (a new worktree starts from the last commit, without them). */
772
+ dirty: z.ZodBoolean;
773
+ }, "strip", z.ZodTypeAny, {
774
+ dirty: boolean;
775
+ root: string;
776
+ branch?: string | undefined;
777
+ head?: string | undefined;
778
+ }, {
779
+ dirty: boolean;
780
+ root: string;
781
+ branch?: string | undefined;
782
+ head?: string | undefined;
783
+ }>;
784
+ export type GitInfo = z.infer<typeof gitInfoSchema>;
785
+ /** A worktree LinkShell made for sessions. */
786
+ export declare const worktreeEntrySchema: z.ZodObject<{
787
+ /** The worktree's top directory. */
788
+ path: z.ZodString;
789
+ branch: z.ZodString;
790
+ /** The repository it belongs to. */
791
+ source: z.ZodString;
792
+ createdAt: z.ZodNumber;
793
+ /** Sessions working in it. */
794
+ sessions: z.ZodArray<z.ZodString, "many">;
795
+ /** Uncommitted changes in it. */
796
+ dirty: z.ZodBoolean;
797
+ /** Commits made in it since it was created. */
798
+ ahead: z.ZodNumber;
799
+ }, "strip", z.ZodTypeAny, {
800
+ dirty: boolean;
801
+ path: string;
802
+ createdAt: number;
803
+ branch: string;
804
+ source: string;
805
+ sessions: string[];
806
+ ahead: number;
807
+ }, {
808
+ dirty: boolean;
809
+ path: string;
810
+ createdAt: number;
811
+ branch: string;
812
+ source: string;
813
+ sessions: string[];
814
+ ahead: number;
815
+ }>;
816
+ export type WorktreeEntry = z.infer<typeof worktreeEntrySchema>;
463
817
  export declare const projectSummarySchema: z.ZodObject<{
464
818
  cwd: z.ZodString;
465
819
  name: z.ZodString;
466
820
  lastActiveAt: z.ZodNumber;
467
821
  sessionCount: z.ZodNumber;
822
+ /** For a git repository: the branch checked out there now (or the abbreviated commit, on a detached HEAD). */
823
+ branch: z.ZodOptional<z.ZodString>;
468
824
  }, "strip", z.ZodTypeAny, {
469
825
  name: string;
470
826
  cwd: string;
471
827
  lastActiveAt: number;
472
828
  sessionCount: number;
829
+ branch?: string | undefined;
473
830
  }, {
474
831
  name: string;
475
832
  cwd: string;
476
833
  lastActiveAt: number;
477
834
  sessionCount: number;
835
+ branch?: string | undefined;
478
836
  }>;
479
837
  export type ProjectSummary = z.infer<typeof projectSummarySchema>;
480
838
  export declare const machineInfoSchema: z.ZodObject<{
@@ -513,6 +871,12 @@ export declare const machineInfoSchema: z.ZodObject<{
513
871
  steer: z.ZodBoolean;
514
872
  permissions: z.ZodBoolean;
515
873
  images: z.ZodBoolean;
874
+ /**
875
+ * The agent forks sessions itself, keeping everything it knew. Every agent's
876
+ * sessions can be forked: without this (or from a single reply, where the
877
+ * agent only forks whole sessions) LinkShell makes the fork — the new session
878
+ * shows the conversation and its agent is told it as text.
879
+ */
516
880
  fork: z.ZodBoolean;
517
881
  models: z.ZodBoolean;
518
882
  modes: z.ZodBoolean;
@@ -576,6 +940,17 @@ export declare const machineInfoSchema: z.ZodObject<{
576
940
  hint?: string | undefined;
577
941
  } | undefined;
578
942
  }>, "many">;
943
+ /**
944
+ * The host can send bulk streams peer to peer (`direct.offer`); `iceServers`
945
+ * are the STUN servers both sides use to find a path.
946
+ */
947
+ direct: z.ZodOptional<z.ZodObject<{
948
+ iceServers: z.ZodArray<z.ZodString, "many">;
949
+ }, "strip", z.ZodTypeAny, {
950
+ iceServers: string[];
951
+ }, {
952
+ iceServers: string[];
953
+ }>>;
579
954
  }, "strip", z.ZodTypeAny, {
580
955
  machineId: string;
581
956
  hostname: string;
@@ -604,6 +979,9 @@ export declare const machineInfoSchema: z.ZodObject<{
604
979
  } | undefined;
605
980
  }[];
606
981
  home?: string | undefined;
982
+ direct?: {
983
+ iceServers: string[];
984
+ } | undefined;
607
985
  }, {
608
986
  machineId: string;
609
987
  hostname: string;
@@ -632,6 +1010,9 @@ export declare const machineInfoSchema: z.ZodObject<{
632
1010
  } | undefined;
633
1011
  }[];
634
1012
  home?: string | undefined;
1013
+ direct?: {
1014
+ iceServers: string[];
1015
+ } | undefined;
635
1016
  }>;
636
1017
  export type MachineInfo = z.infer<typeof machineInfoSchema>;
637
1018
  /** A server listening on the host, which a device can preview through the encrypted channel. */
@@ -16,6 +16,12 @@ export const agentCapabilitiesSchema = z.object({
16
16
  steer: z.boolean(),
17
17
  permissions: z.boolean(),
18
18
  images: z.boolean(),
19
+ /**
20
+ * The agent forks sessions itself, keeping everything it knew. Every agent's
21
+ * sessions can be forked: without this (or from a single reply, where the
22
+ * agent only forks whole sessions) LinkShell makes the fork — the new session
23
+ * shows the conversation and its agent is told it as text.
24
+ */
19
25
  fork: z.boolean(),
20
26
  models: z.boolean(),
21
27
  modes: z.boolean(),
@@ -72,12 +78,40 @@ export const sessionActivitySchema = z.object({
72
78
  toolKind: toolKindSchema.optional(),
73
79
  });
74
80
  /** The oldest unanswered permission request, so lists can offer approval inline. Live only. */
81
+ /**
82
+ * Something the agent asks the user rather than asks permission for: a choice
83
+ * among options, several of them, or something to type (Claude's
84
+ * AskUserQuestion, Codex's request_user_input, an MCP server's form).
85
+ */
86
+ export const questionSchema = z.object({
87
+ id: z.string(),
88
+ /** A short label for the question ("Auth method"). */
89
+ header: z.string().optional(),
90
+ text: z.string(),
91
+ /** `choice`: one of `options`; `choices`: any number of them; `text`: typed. */
92
+ kind: z.enum(["choice", "choices", "text"]),
93
+ options: z.array(z.object({ value: z.string(), label: z.string(), description: z.string().optional() })).optional(),
94
+ /** With options: an answer of the user's own can be typed instead of, or beside, a pick. */
95
+ other: z.boolean().optional(),
96
+ /** What is typed shouldn't be shown (a token). */
97
+ secret: z.boolean().optional(),
98
+ required: z.boolean().optional(),
99
+ });
100
+ export const questionAnswerSchema = z.object({
101
+ id: z.string(),
102
+ /** The values picked (`choice`: at most one), or what was typed for a `text` question. */
103
+ values: z.array(z.string().max(20_000)).max(50),
104
+ /** The user's own answer beside the options. */
105
+ other: z.string().max(20_000).optional(),
106
+ });
75
107
  export const pendingPermissionSchema = z.object({
76
108
  requestId: z.string(),
77
109
  toolCallId: z.string().optional(),
78
110
  title: z.string(),
79
111
  detail: z.string().optional(),
80
112
  options: z.array(permissionOptionSchema).min(1),
113
+ /** Set when this is a question to answer (`sessions.answer`) rather than a permission to give. */
114
+ questions: z.array(questionSchema).optional(),
81
115
  });
82
116
  export const queuedMessageSchema = z.object({
83
117
  clientMessageId: z.string(),
@@ -120,6 +154,13 @@ export const sessionSummarySchema = z.object({
120
154
  * holds them (agents that can't take input mid-turn). Oldest first.
121
155
  */
122
156
  queue: z.array(queuedMessageSchema).optional(),
157
+ /**
158
+ * The session works in a git worktree LinkShell made for it: its own
159
+ * checkout and branch, so it can't disturb the project's working directory.
160
+ * `cwd` is inside the worktree; `source` is the directory it was made from
161
+ * (the project the session belongs to).
162
+ */
163
+ worktree: z.object({ branch: z.string(), source: z.string() }).optional(),
123
164
  /** Live only, for sessions that started sub-agents: how many, and how many are working now (`sessions.subagents` lists them). */
124
165
  subagents: z.object({ total: z.number().int(), running: z.number().int() }).optional(),
125
166
  });
@@ -132,11 +173,39 @@ export function parseSessionId(id) {
132
173
  return null;
133
174
  return { agent: id.slice(0, index), nativeId: id.slice(index + 1) };
134
175
  }
176
+ /** What git says about a directory, to offer starting a session in a worktree of it. */
177
+ export const gitInfoSchema = z.object({
178
+ /** The repository's top directory. */
179
+ root: z.string(),
180
+ /** The branch checked out; absent on a detached HEAD. */
181
+ branch: z.string().optional(),
182
+ /** The commit checked out, abbreviated; absent before the first commit. */
183
+ head: z.string().optional(),
184
+ /** Uncommitted changes in the working directory (a new worktree starts from the last commit, without them). */
185
+ dirty: z.boolean(),
186
+ });
187
+ /** A worktree LinkShell made for sessions. */
188
+ export const worktreeEntrySchema = z.object({
189
+ /** The worktree's top directory. */
190
+ path: z.string(),
191
+ branch: z.string(),
192
+ /** The repository it belongs to. */
193
+ source: z.string(),
194
+ createdAt: z.number(),
195
+ /** Sessions working in it. */
196
+ sessions: z.array(z.string()),
197
+ /** Uncommitted changes in it. */
198
+ dirty: z.boolean(),
199
+ /** Commits made in it since it was created. */
200
+ ahead: z.number().int().nonnegative(),
201
+ });
135
202
  export const projectSummarySchema = z.object({
136
203
  cwd: z.string(),
137
204
  name: z.string(),
138
205
  lastActiveAt: z.number(),
139
206
  sessionCount: z.number().int().nonnegative(),
207
+ /** For a git repository: the branch checked out there now (or the abbreviated commit, on a detached HEAD). */
208
+ branch: z.string().optional(),
140
209
  });
141
210
  export const machineInfoSchema = z.object({
142
211
  machineId: z.string().min(1),
@@ -146,6 +215,11 @@ export const machineInfoSchema = z.object({
146
215
  /** The host user's home directory, so apps can show paths as `~/…`. */
147
216
  home: z.string().optional(),
148
217
  agents: z.array(agentInfoSchema),
218
+ /**
219
+ * The host can send bulk streams peer to peer (`direct.offer`); `iceServers`
220
+ * are the STUN servers both sides use to find a path.
221
+ */
222
+ direct: z.object({ iceServers: z.array(z.string()) }).optional(),
149
223
  });
150
224
  /** A server listening on the host, which a device can preview through the encrypted channel. */
151
225
  export const portInfoSchema = z.object({