Repository navigation
Expand file tree
/
Copy pathcontent.json
More file actions
1239 lines (1239 loc) · 61 KB
/
Copy pathcontent.json
File metadata and controls
1239 lines (1239 loc) · 61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
{
"version": "0.25.0",
"pages": {
"docs": {
"eyebrow": "Quick start",
"title": "Your terminal. Open anywhere.",
"intro": "Start a session on your computer, then open it in any browser. Watch your agent, reply to a prompt, or bring in a teammate. No account needed.",
"seo": {
"description": "Start a session on your computer, then open it in any browser. Watch your agent, reply to a prompt, or bring in a teammate. No account needed.",
"socialTitle": "Your terminal. Open anywhere. | shell.online",
"socialDescription": "Start a session on your computer, then open it in any browser. Watch your agent, reply to a prompt, or bring in a teammate. No account needed."
},
"cards": [
[
"1. Install on your computer",
"Use the computer where your agent or command will run. Choose the command for its operating system.",
[
[
"curl -fsSL https://shell.online/install | sh",
"macOS, Linux, BSD or Solaris. Run in a terminal."
],
[
"irm https://shell.online/install.ps1 | iex",
"Windows. Run in PowerShell."
]
]
],
[
"2. Start something to share",
"Put `shell` before the command you normally use. Your agent must already be installed and signed in. This starts a new process; it does not attach to one that is already running.",
[
[
"shell claude",
"Start Claude Code."
],
[
"shell codex",
"Start Codex."
],
[
"shell opencode",
"Start OpenCode."
],
[
"shell muse",
"Start Muse Code."
],
[
"shell -- npm run dev",
"Or share another terminal command."
]
]
],
[
"3. Open the link",
"The terminal prints a link, password and QR code. Scan the QR code on your phone, or open the full link in another browser and enter the password.\n\nYou should see the same terminal output. You can type unless the session is read-only. Keep the host computer awake and connected to the internet."
],
[
"Leave the tab. Keep the work.",
"Closing the browser does not stop the process. Normal sessions run in the background. Reopen the link to return, or attach on the host computer.",
[
[
"shell list",
"Find your local sessions and their IDs."
],
[
"shell attach <ID>",
"Return to a local session. Press Ctrl-X, then D to detach without stopping it."
],
[
"shell kill -- <ID>",
"Stop that process and close its share."
]
]
],
[
"Share only what you mean to",
"An interactive link and its password let someone type with the process’s permissions. Give them only to people you trust. For watching without typing, start a read-only session.",
[
[
"shell --read-only claude",
"Watch-only browser access. Choose this when creating the session."
]
]
],
[
"Ready for more?",
"[Link your machines](/app/) to find sessions in one app. [Connect another agent](/agents/) with a separate MCP grant. If the view is blank or offline, [start here](/reliability/)."
]
]
},
"platforms": {
"eyebrow": "Install & update",
"title": "Get shell.online on your computer.",
"intro": "Install the CLI on the machine doing the work. Phones and other viewing devices need only a browser. Choose an install method, then start a session.",
"seo": {
"description": "Install the CLI on the machine doing the work. Phones and other viewing devices need only a browser. Choose an install method, then start a session.",
"socialTitle": "Get shell.online on your computer. | shell.online",
"socialDescription": "Install the CLI on the machine doing the work. Phones and other viewing devices need only a browser. Choose an install method, then start a session."
},
"cards": [
[
"Install on macOS, Linux, BSD or Solaris",
"The installer selects the right binary and checks its SHA-256 checksum. It does not run sudo or silently change your PATH.",
[
[
"curl -fsSL https://shell.online/install | sh",
"If the installer prints PATH instructions, follow them before opening a session."
]
]
],
[
"Install on Windows",
"Open PowerShell and run the installer. The CLI uses Windows’ native ConPTY terminal support.",
[
[
"irm https://shell.online/install.ps1 | iex",
"Works with the published x86, x64 and ARM64 builds."
]
]
],
[
"Prefer Homebrew?",
"Use the project’s tap. The tap can lag behind the direct installer; check `shell --version` when you need a particular release.",
[
[
"brew tap teoslayer/shell-online https://github.com/TeoSlayer/shell.online",
"Add the project’s tap."
],
[
"brew trust --tap teoslayer/shell-online",
"Approve the tap if your Homebrew version requires it."
],
[
"brew install shell-online",
"Install the CLI."
]
]
],
[
"Build the CLI from source",
"Install Git and Go 1.26.9 first. Clone the release tag, not an unpinned development branch. This builds the CLI only: you do not need Node.js or a local web server to use the hosted service. The Go build downloads the dependencies pinned by go.mod and go.sum.\n\nThe commands below assume a new checkout directory. On macOS, Linux and other Unix systems:",
[
[
"git clone --depth 1 --branch v0.25.0 https://github.com/TeoSlayer/shell.online.git\ncd shell.online\ngo build -buildvcs=false -trimpath -ldflags=\"-X main.version=0.25.0\" -o shell ./cmd/shell\n./shell --version",
"Expect version 0.25.0. Then use ./shell codex, ./shell claude, or your own command from this directory."
],
[
"git clone --depth 1 --branch v0.25.0 https://github.com/TeoSlayer/shell.online.git\ncd shell.online\ngo build -buildvcs=false -trimpath -ldflags=\"-X main.version=0.25.0\" -o shell.exe ./cmd/shell\n.\\shell.exe --version",
"Windows PowerShell: run these instead. Then use .\\shell.exe codex or another installed command."
],
[
"Make it available elsewhere",
"Move the built binary into a directory on your PATH if you want to type shell from anywhere. No sudo is needed when you choose a user-owned directory. Existing sessions are not restarted by a build."
],
[
"Develop the website too?",
"That is a separate build using Node.js and npm. See the repository’s [development instructions](https://github.com/TeoSlayer/shell.online#development). On MIPS64, keep Go 1.26.9: the repository documents a Go 1.27 runtime regression."
]
]
],
[
"Check or update your version",
"Run the same installer again to update an installer-managed copy. For Homebrew, use `brew upgrade shell-online`.\n\nUpdating the binary does not update hosts that are already running. Save your agent’s work and restart its Shell host when safe to use new host features. Do not stop an active task just to update.",
[
[
"shell --version",
"Check the executable your terminal is using."
]
]
],
[
"Supported host systems",
"These are release targets, not a promise that every device or agent runs on every architecture. Published checksums are in [SHA256SUMS](/downloads/SHA256SUMS).",
[
[
"macOS",
"amd64, arm64. Build-verified."
],
[
"Windows",
"386, amd64, arm64. Native runtime checks on amd64; other targets build-verified."
],
[
"Linux",
"386, amd64, armv5/6/7, arm64, loong64, mips, mipsle, mips64, mips64le, ppc64, ppc64le, riscv64, s390x. Runtime checks under QEMU."
],
[
"FreeBSD",
"386, amd64, armv7, arm64. Build-verified."
],
[
"OpenBSD",
"386, amd64, armv7, arm64, ppc64, riscv64. Build-verified."
],
[
"NetBSD",
"386, amd64, armv7, arm64. Build-verified."
],
[
"DragonFly BSD",
"amd64. Build-verified."
],
[
"Solaris",
"amd64. Build-verified."
]
]
],
[
"Routers, small computers and ROS",
"A supported binary still needs a working PTY and outbound HTTPS/WebSockets. Vendor firmware, kernel restrictions and storage can affect small Linux devices; QEMU checks do not cover those hardware differences.\n\nFor ROS, first load your usual ROS environment, then put `shell` before its command. Shell’s platform support does not extend ROS’s own support."
],
[
"If the command is not found",
"Follow the installer’s PATH instructions, open a new terminal, and try `shell --version`. Make sure you installed on the host computer—not on the phone you use to view it. Then [start your first session](/docs/)."
]
]
},
"mobile": {
"eyebrow": "Use your phone",
"title": "Keep work moving from your phone.",
"intro": "Open the share link in your phone’s browser. Read output, scroll back, and reply to your agent without moving its work off your computer.",
"seo": {
"description": "Open the share link in your phone’s browser. Read output, scroll back, and reply to your agent without moving its work off your computer.",
"socialTitle": "Keep work moving from your phone. | shell.online",
"socialDescription": "Open the share link in your phone’s browser. Read output, scroll back, and reply to your agent without moving its work off your computer."
},
"cards": [
[
"Open your session",
"Scan the QR code printed by the CLI. Or open the complete link and enter its password. A signed-in session listing is not a substitute for its terminal password."
],
[
"Type and use terminal keys",
"Tap the terminal to open your keyboard. Use the terminal key controls for keys your phone keyboard lacks. Ctrl-C interrupts the running command; it is not a copy shortcut here.\n\nCtrl-D can end a shell. The browser warns on the first press; repeating it within three seconds deliberately sends EOF."
],
[
"Scroll without losing your place",
"Drag with one finger to scroll terminal history. In full-screen programs that handle mouse input, gestures are sent as terminal wheel input instead. How that program scrolls depends on the program itself.\n\nIf rendering or input looks wrong, select the default xterm.js renderer and [check the recovery steps](/reliability/)."
],
[
"Paste carefully",
"Pasting sends text to the terminal; it may contain commands. Check what you are sending. Paste input is split into bounded 16 KiB frames and waits when the connection is busy."
],
[
"Why the screen changes size",
"Everyone sees one shared terminal grid. Any connected phone selects the portrait grid, including a read-only phone. The grid returns to desktop size when the last phone leaves.",
[
[
"Desktop only",
"120 columns × 36 rows."
],
[
"Phone connected",
"80 columns × 40 rows with a current host; older hosts use 80 × 24."
],
[
"Resizing the browser",
"Fits the shared grid to your screen. It does not give each viewer a separate terminal size."
]
]
],
[
"Choose light or dark",
"On a shared link, open Controls → Appearance and choose Light, Dark or System. The sun/moon button switches quickly. In the app, use Account → Appearance. Each site remembers your choice in this browser. System follows your device’s appearance; switching themes does not restart your terminal."
],
[
"Paste on a phone",
"Tap Paste in the terminal controls. Review the text, then choose Insert into terminal. If your browser cannot read the clipboard, touch and hold inside the text box and choose Paste. No Enter is added, but line breaks in the text can still run commands. You need input access; read-only viewers cannot paste."
],
[
"Keep active sessions together",
"On a shared link, open Controls and choose Sign up. Create an account and link your computer to find its sessions in the app. This does not share the current session’s password or automatically import someone else’s session."
],
[
"Close the browser when you’re done",
"Closing the tab leaves the task running. Keep the host computer awake and online. A sleeping laptop cannot be controlled until it reconnects. The session ends when its process exits."
]
]
},
"app": {
"eyebrow": "Sessions & teammates",
"title": "Find your work in one place.",
"intro": "The optional app brings sessions from linked computers into one list. Open a terminal, invite a teammate, and keep control of who gets access.",
"seo": {
"description": "The optional app brings sessions from linked computers into one list. Open a terminal, invite a teammate, and keep control of who gets access.",
"socialTitle": "Find your work in one place. | shell.online",
"socialDescription": "The optional app brings sessions from linked computers into one list. Open a terminal, invite a teammate, and keep control of who gets access."
},
"cards": [
[
"1. Link your computer",
"Create or sign into your account at [app.shell.online](https://app.shell.online/), then run this on the host computer. Complete the approval in your browser.",
[
[
"shell auth",
"Link this machine. Remote start is a separate choice during setup."
],
[
"shell whoami",
"Check the linked account."
]
]
],
[
"2. Open a session",
"Sessions started on linked machines appear in the app. Open one to view the same terminal. Tabs stay connected while you switch between them.\n\nTo decrypt a session, unlock your personal vault if it contains the password, or enter the session password. Seeing a listing alone does not reveal its encrypted contents.",
[
[
"shell password <ID>",
"Recover an active session password on its host computer. Treat the printed value as a secret."
]
]
],
[
"3. Bring in a teammate",
"Invite the person to your organization, then assign or share the session as appropriate. Session responsibility, terminal passwords and MCP grants are different kinds of access.\n\nFor a plain browser share, give your teammate the complete link and password. If someone should only watch, create a [read-only session](/security/)."
],
[
"Start sessions from the browser",
"Only an approved, online machine can accept a browser-start request. The process runs on that machine—not on an app server. Enabling this grants remote execution authority; choose it deliberately.",
[
[
"shell auth --allow-remote-start",
"Allow your signed-in browser to start sessions on this machine."
],
[
"shell auth --no-remote-start",
"Link the account without allowing remote start, or withdraw that permission."
],
[
"shell daemon status",
"Check the local listener."
],
[
"shell daemon stop",
"Pause the listener. A later Shell command can start it again."
],
[
"shell service uninstall",
"Remove the installed background service. This is separate from account access."
]
]
],
[
"Use your personal vault",
"The vault is per account, not per organization. It stores encrypted password copies and unlocks in your browser with its password or a supported PRF passkey. Keep your recovery key somewhere safe.\n\nA teammate does not automatically receive your vault. If every owner-held password and recovery copy is lost, the service cannot recover them."
],
[
"Understand the session state",
"A session’s status describes reachability, not whether an agent completed its task.",
[
[
"Online / Starting",
"The host is connected or starting."
],
[
"Offline / Unavailable",
"The app cannot currently reach a usable host. Check the machine before assuming the process stopped."
],
[
"Finished",
"A known process exit. It is not proof that the requested work succeeded."
]
]
],
[
"Automation is a separate permission",
"Owners can set team MCP, daily-briefing and briefing-sharing preferences in the app or CLI. The switches are independent.\n\nIn this release, daily-briefing consent can allow an updated host to publish an owner-encrypted title and existing response excerpt for a supported, explicitly resumed OpenCode conversation. It does not prompt an agent or generate a new summary. Team delivery and a team MCP gateway are not implemented. [See the exact limits](https://github.com/TeoSlayer/shell.online/blob/main/docs/session-content.md).",
[
[
"shell permissions <ID>",
"Read the session’s automation preferences."
],
[
"shell permissions <ID> --daily-briefing=true",
"Change only daily-briefing consent."
],
[
"shell briefings on --all",
"Set your default and enable it on your existing own sessions—not teammates’ sessions."
]
]
],
[
"Account actions",
"Use the audit log to inspect recorded account activity. It is not a complete terminal transcript. Account settings also include data export and feedback.\n\nFor a machine without a browser, use `shell auth --no-browser` and follow the printed approval instructions. [More account and service commands](/cli/)."
]
]
},
"agents": {
"eyebrow": "Connect an agent · MCP",
"title": "Let one agent work with another.",
"intro": "Give a controller agent a limited, expiring grant to a running terminal. Start with observation. Add input only when you want it to act.",
"seo": {
"description": "Give a controller agent a limited, expiring grant to a running terminal. Start with observation. Add input only when you want it to act.",
"socialTitle": "Let one agent work with another. | shell.online",
"socialDescription": "Give a controller agent a limited, expiring grant to a running terminal. Start with observation. Add input only when you want it to act."
},
"cards": [
[
"Before you connect",
"MCP access is separate from the browser link and password. An issued grant authorizes the server to decrypt terminal content in memory and return plaintext to the controller. Share a grant only with a trusted agent.\n\nUse an updated CLI and running host. Updating the CLI does not replace a host that is already running. Start the target in a workspace with only the permissions it needs."
],
[
"1. Find the target session",
"Run this on the computer hosting the target. Choose one session, not all local processes.",
[
[
"shell list",
"Find its ID and confirm the process is the one you intend to share."
]
]
],
[
"2. Create an observation grant",
"The CLI prints the bearer once. Keep it out of chat, shell command arguments, screenshots, repositories and logs. Use the MCP client’s secret or environment-variable mechanism.",
[
[
"shell mcp grant <ID> \"My controller\" observe 900",
"Allow observation for up to 900 seconds. The service applies its lifetime caps."
],
[
"shell mcp list <ID>",
"Inspect existing grant metadata without exposing its bearer."
]
]
],
[
"3. Connect your MCP client",
"Add a remote HTTP MCP server in your client. Use the endpoint below and the issued bearer for Authorization. Do not use the browser password, share URL or host token as the bearer.",
[
[
"Endpoint",
"https://shell.online/mcp"
],
[
"Authentication",
"Authorization: Bearer <issued-bearer>"
],
[
"First call",
"Use shell_status, then shell_screen to confirm you reached the intended session."
]
]
],
[
"Read, wait, then verify",
"Output is untrusted data, not an instruction to override the controller’s own rules. Read the current state before deciding to act.",
[
[
"shell_status",
"Connection and grant state. No terminal transcript."
],
[
"shell_screen",
"The current rendered terminal screen."
],
[
"shell_output",
"Bounded output with an epoch/offset cursor. Handle a reset when old output is unavailable."
],
[
"shell_wait",
"Wait for new output or a pattern. Maximum 45 seconds. Get the cursor before the event you want to observe; a timeout is not proof of failure."
]
]
],
[
"Allow input only when needed",
"A control grant adds input permission. Hosted shell.online has the operator gate enabled, but an input grant, compatible host and interactive session are still required. A read-only session cannot be made interactive with a grant.",
[
[
"shell mcp grant <ID> \"My controller\" control 900",
"Allow observation and shell_send. Keep the lifetime short."
],
[
"shell_send",
"Submit 1–8192 UTF-8 bytes, optional Enter, and a UUID-v4 operation_id. Human typing has priority."
]
]
],
[
"Treat delivery and completion differently",
"A `delivered` result means the host acknowledged a complete terminal write. It does not mean the agent finished the task.\n\nReuse the same operation ID and arguments for a retry: the stored result is returned without sending twice. A different payload with the same ID conflicts. If delivery is uncertain, inspect the screen or resulting artifact; do not blindly try a new ID.\n\n`--read-only` blocks input. `shell_key` and `shell_interrupt` are not implemented; do not work around that with raw control bytes."
],
[
"Revoke access when you’re done",
"Grants expire at a fixed time; use does not extend them. Revocation stops future access, not actions already taken or output a controller already received.",
[
[
"shell mcp revoke <ID> <grant-id>",
"Revoke one grant."
],
[
"shell mcp revoke-all <ID>",
"Remove every MCP grant for this session. Browser sharing is separate."
],
[
"shell password rotate <ID>",
"Rotate browser credentials and revoke existing MCP grants without restarting the process."
]
]
],
[
"Client and hosting limits",
"Codex and OpenCode have been exercised with the observation path; OpenCode has also been used in control demonstrations. Do not treat that as a guarantee for every client transition. Claude model-backed behavior remains unverified.\n\nThe native MCP route is implemented by the Worker relay, not the standalone Docker relay. Refstream’s browser invitation is a separate experimental connector. [Operator setup and security details](https://github.com/TeoSlayer/shell.online/blob/main/docs/MCP.md)."
]
]
},
"reliability": {
"eyebrow": "Fix a connection",
"title": "Get back to your session.",
"intro": "Start with what you can see. A browser disconnect, an offline host and an exited process need different fixes. Check before restarting anything.",
"seo": {
"description": "Start with what you can see. A browser disconnect, an offline host and an exited process need different fixes. Check before restarting anything.",
"socialTitle": "Get back to your session. | shell.online",
"socialDescription": "Start with what you can see. A browser disconnect, an offline host and an exited process need different fixes. Check before restarting anything."
},
"cards": [
[
"The page says offline",
"Check that the host computer is awake, online and still running the process. The CLI and browser retry temporary connection failures automatically.\n\nOn the host, use the local session list. A stale app row is not proof that a process is still alive.",
[
[
"shell list",
"Check local process and relay state separately."
],
[
"shell attach <ID>",
"If the local session is alive, inspect it without relying on the browser. Detach with Ctrl-X, then D."
]
]
],
[
"The terminal is blank or looks wrong",
"Wait for the reconnect snapshot, then try reopening the view. If you selected Refstream, switch back to xterm.js. Check whether the running host predates your installed CLI.\n\nInstalling an update does not restart hosts. Save work and arrange a safe restart if a host update is needed. Never kill all sessions to fix one view."
],
[
"The password no longer works",
"Use the complete link, including its `#salt=` fragment, and the current password. Password rotation changes both the salt and password and disconnects old viewers.\n\nIf the app has a sealed copy, unlock your personal vault. Otherwise recover the password on the host.",
[
[
"shell password <ID>",
"Print the active password locally. Do not put it in a bug report."
]
]
],
[
"You cannot type",
"Check whether the session was created read-only or another person currently holds input. A read-only session requires a new interactive share if its owner wants typing enabled.\n\nFor MCP, check the grant scope, expiry and host version. [MCP setup](/agents/) explains the additional input requirements."
],
[
"A command exits before you get a link",
"Very short tasks may finish during startup. The CLI reports their exit status instead of printing a dead link. Try a longer-running process or start a fresh shell.",
[
[
"shell",
"Start an interactive shell to test the share path."
]
]
],
[
"What survives a disconnect",
"The process runs on your computer. A temporary browser or network failure does not intentionally stop it. Current hosts keep bounded screen state and restore the screen when viewers return.\n\nAn ordinary disconnected share can recover its link for 12 hours. A known task exit closes the ordinary share. A persistent identity can be reused, but it is not a process checkpoint."
],
[
"High output and nested terminals",
"Display queues are bounded. When output outruns the connection or renderer, stale display work may be replaced by a fresh screen snapshot rather than an unlimited transcript.\n\nCurrent snapshot handling suppresses replies to old terminal queries. It is designed for full-screen programs, tmux and nested terminal use, but a specific application can still expose a compatibility bug."
],
[
"Report a useful bug",
"Use Report in the shared terminal, or [send feedback](https://app.shell.online/feedback). No account is required. Signed-in users can choose to send without their account or email; anonymous reports cannot receive replies. Terminal text, passwords and sharing links are not attached automatically.\n\nInclude your CLI version, operating system, browser, renderer and a small reproduction that contains no private work. Say whether the problem happens locally, in a browser, or only after reconnecting. Remove share links, passwords, tokens and raw terminal logs before sending feedback or [opening an issue](https://github.com/TeoSlayer/shell.online/issues)."
]
]
},
"security": {
"eyebrow": "Share safely",
"title": "Choose who can watch. Choose who can type.",
"intro": "A shared terminal gives real access to a process on your computer. Keep credentials private, use read-only when possible, and understand the MCP boundary.",
"seo": {
"description": "A shared terminal gives real access to a process on your computer. Keep credentials private, use read-only when possible, and understand the MCP boundary.",
"socialTitle": "Choose who can watch. Choose who can type. | shell.online",
"socialDescription": "A shared terminal gives real access to a process on your computer. Keep credentials private, use read-only when possible, and understand the MCP boundary."
},
"cards": [
[
"Start with the access you need",
"Interactive access is the default. Anyone with the complete link and password can view and type with the wrapped process’s operating-system permissions.\n\nFor demos, reviews or a second screen that only needs to watch, create a read-only session.",
[
[
"shell --read-only claude",
"Input is rejected by both the relay and the CLI. A modified browser cannot turn this into an interactive session."
]
]
],
[
"Keep the link, password and QR private",
"The QR code includes the password for one-scan access. Treat it like the link and password together. Do not put it in a public screenshot.\n\nRemoving someone from an account cannot erase a password they already know. Rotate active session credentials when that access must end.",
[
[
"shell password rotate <ID>",
"Disconnect old viewers, change the password and salt, and revoke existing MCP grants. The process keeps running."
]
]
],
[
"Files require their own opt-in",
"Files are not shared by default. `--files` exposes regular files under the working directory; `--files-root` chooses a root. Requests are checked on the host, including traversal and symlink-escape checks.\n\nRead-only terminal access does not cancel file access you explicitly enabled. Choose the root carefully."
],
[
"What the service can see",
"With default E2EE, the host encrypts terminal payloads before the relay forwards them. The relay carries authenticated ciphertext, plus visible connection metadata.",
[
[
"Visible metadata",
"Connection IPs, timing, encrypted sizes, frame types, labels, access mode, lifecycle and terminal grid dimensions."
],
[
"MCP exception",
"Issuing a grant authorizes server-side, in-memory decryption. The controller receives plaintext results. The browser disclosure remains for the grant’s lifetime."
],
[
"No-E2EE exception",
"An explicit --no-e2ee session exposes terminal contents to the relay. HTTPS/WSS still protects the network hop."
]
]
],
[
"What is retained",
"The host keeps bounded screen/replay state. The hosted relay also keeps a bounded last-screen cache for offline viewing: ciphertext in E2EE mode, potentially plaintext with `--no-e2ee`.\n\nMCP’s durable records contain bearer hashes, grant metadata and operation fingerprints/outcomes—not plaintext terminal contents, bearers or frame keys. Ordinary task exit deletes its relay session state. This is not a full-history archive."
],
[
"Encryption does not remove every trust",
"The browser code served by the website is trusted while you view a terminal or unlock your vault. E2EE does not protect against malicious code on either endpoint, or hide traffic timing.\n\nBrowser-started processes also trust the account service after you explicitly enable remote start. Use a restricted workspace and local permissions appropriate to the task."
],
[
"If you shared too much",
"Rotate a leaked browser password; revoke a leaked MCP grant. Stop the specific target if its actions are unsafe. These actions cannot undo earlier commands or remove copies someone already made.\n\n[Encryption details](/e2ee/) explain key derivation and replay protection. [MCP access](/agents/) explains grants and uncertain delivery."
]
]
},
"e2ee": {
"eyebrow": "Passwords & encryption",
"title": "Keep terminal contents private.",
"intro": "Encryption is on by default. Your computer encrypts terminal data and authorized browsers decrypt it. MCP grants deliberately add a separate decryption path.",
"seo": {
"description": "Encryption is on by default. Your computer encrypts terminal data and authorized browsers decrypt it. MCP grants deliberately add a separate decryption path.",
"socialTitle": "Keep terminal contents private. | shell.online",
"socialDescription": "Encryption is on by default. Your computer encrypts terminal data and authorized browsers decrypt it. MCP grants deliberately add a separate decryption path."
},
"cards": [
[
"Use the generated password",
"A normal session generates a random ten-character base64url password. The CLI prints it with the share link. The QR code includes it for one-scan access.\n\nFor sensitive or longer-lived work, use a longer unique password through `SHELL_ONLINE_E2EE_PASSWORD`. Do not reuse an account password or put the value in logs."
],
[
"Recover an active password",
"On the host computer, retrieve the password from its local session record. If you enabled your account’s personal vault, a sealed copy may also be available there.",
[
[
"shell password <ID>",
"Reveal one session password deliberately. The service has no recovery backdoor if all owner-held copies are lost."
]
]
],
[
"Rotate without restarting the task",
"Rotation changes the password, URL salt and cipher generation. Current viewers disconnect, old MCP grants are revoked, and persistent state and the owner’s vault copy are updated.",
[
[
"shell password rotate <ID>",
"Share the new complete link and password only with people who should retain access."
]
]
],
[
"How keys are made",
"The link’s `#salt=` fragment contains a random salt. The host and browser derive the AES-256-GCM frame key locally using PBKDF2-HMAC-SHA256 with 600,000 iterations.\n\nURL fragments are not part of HTTP requests. The QR’s password remains sensitive to anyone who sees the QR. Ten random base64url characters provide 60 bits of randomness; a longer unique password is preferable for sensitive, long-lived sessions."
],
[
"Encrypted content and visible metadata",
"Terminal input, output, snapshots and latency probes are authenticated ciphertext. Current envelope-v2 frames bind direction, sender stream and sequence so receivers reject duplicate or stale frames.\n\nThe relay can still delay or drop traffic. It sees timing, addresses, encrypted sizes, labels and lifecycle metadata. Grid dimensions travel in plaintext control messages: `terminal_size` to viewers, the host's own `terminal_grid`, and a viewer's `grid_request`."
],
[
"MCP changes who can decrypt",
"A host-issued MCP grant supplies the server with the authority to decrypt in memory for that grant’s lifetime. The controller receives plaintext output. This is why the browser visibly says server-side decryption is authorized.\n\nRevoking grants removes future MCP access; it does not erase results already received. [Create or revoke a grant](/agents/)."
],
[
"Vault and browser storage",
"The optional vault keeps encrypted password copies per account. Unlocking happens in the browser. A vault password, supported PRF passkey or recovery key is needed; team membership alone is not enough.\n\nThe current browser password cache is memory-only. A reload needs the vault or password again. A legacy password blob may remain as a read-only migration source until it can be migrated safely; this does not mean new passwords are written there."
],
[
"Turning encryption off",
"`--no-e2ee` is an explicit compatibility/debugging choice, not the default. The relay can then read terminal contents. It conflicts with password overrides and persistence. Avoid it for private work."
]
]
},
"docker": {
"eyebrow": "Keep a Docker workspace",
"title": "A workspace with a link you can reuse.",
"intro": "Run a shared terminal in a container. Named volumes keep its workspace and session identity across container restarts—not the memory of a running process.",
"seo": {
"description": "Run a shared terminal in a container. Named volumes keep its workspace and session identity across container restarts—not the memory of a running process.",
"socialTitle": "A workspace with a link you can reuse. | shell.online",
"socialDescription": "Run a shared terminal in a container. Named volumes keep its workspace and session identity across container restarts—not the memory of a running process."
},
"cards": [
[
"1. Get the project",
"You need Docker with Compose. Clone the project and use the Compose file in its root. This runs a client of the hosted relay, not your own relay.",
[
[
"git clone https://github.com/TeoSlayer/shell.online.git\ncd shell.online",
"Open the repository directory."
]
]
],
[
"2. Start the container",
"The first launch prints the browser link and generated password. The logs contain credentials: read them privately, not in a shared report.",
[
[
"docker compose up --build -d",
"Build and start the container."
],
[
"docker compose logs shell-online",
"Read the session link and password."
]
]
],
[
"3. Open the session",
"Open the printed link in your browser and enter the password. The default configuration keeps state and workspace in separate named volumes.",
[
[
"shell-online-state",
"Host identity, browser password and encryption material. Protect this volume and its backups as secrets."
],
[
"shell-online-workspace",
"The files you work on inside the container."
]
]
],
[
"What a restart preserves",
"The container reuses its saved link and password, then starts a new terminal process. It does not restore an agent’s in-memory conversation or a running job.\n\nA saved identity can be revived from its state volume after the relay’s offline retention expires. Deleting that volume loses the saved identity. Do not use volume deletion as a routine restart step."
],
[
"Choose or rotate a password",
"You may set a longer `SHELL_ONLINE_E2EE_PASSWORD` before first launch. Restarts reuse saved credentials. To change an active password, run `shell password rotate <ID>` inside the running container; an environment change alone does not rotate stored state."
],
[
"Want your own server instead?",
"The root Compose file connects to hosted shell.online. To run your own relay and domain, follow [Run your own relay](/self-hosting/)."
]
]
},
"refstream": {
"eyebrow": "Try Refstream · alpha",
"title": "An optional terminal view.",
"intro": "xterm.js is the default. Refstream adds experimental terminal tools and a browser-mediated agent connector. Switch back if your program does not behave correctly.",
"seo": {
"description": "xterm.js is the default. Refstream adds experimental terminal tools and a browser-mediated agent connector. Switch back if your program does not behave correctly.",
"socialTitle": "An optional terminal view. | shell.online",
"socialDescription": "xterm.js is the default. Refstream adds experimental terminal tools and a browser-mediated agent connector. Switch back if your program does not behave correctly."
},
"cards": [
[
"Choose a renderer",
"Open Terminal controls and select Refstream (unstable alpha), or use the Renderer selector in an app terminal tab. The choice is saved for that browser.\n\nSwitching changes the browser view. It does not restart the process, change encryption or grant extra permissions. This build includes Refstream v0.1.0-alpha.5."
],
[
"Search and inspect output",
"Refstream offers literal search, text sizing, themes, a back-to-live shortcut and retained-output download. Command inspection needs OSC 133 shell markers from the program; it cannot reliably infer commands or exit status from arbitrary text."
],
[
"Connect an agent from the browser",
"The Connect agent invitation is private, short-lived and revocable. Choose read access or read-and-control. Reuse the returned connector session for follow-ups instead of pairing again each time.\n\nThis is not the native `/mcp` bearer channel. Its invitation and tools are different. For the host-managed MCP route, use [Connect an agent](/agents/)."
],
[
"Know when a task is really done",
"A stable task ID protects a retry from submitting the same prompt twice. A delivery acknowledgement, output burst or quiet terminal is not proof of completion.\n\nA generic terminal view cannot safely infer an agent’s editor state. Local keyboard activity and stale sequence guards can block remote input; do not bypass them."
],
[
"Files and saved output",
"File access still needs an explicit host `--files` or `--files-root` setting. A filename printed in terminal output does not grant access to it.\n\nCurrent Shell integration keeps terminal recovery state in memory, not new localStorage/sessionStorage snapshots, and purges legacy Refstream cache entries. Reload re-syncs from the host’s live screen. Exported output is a separate copy you must protect."
],
[
"If something looks wrong",
"Switch back to xterm.js. Refstream does not implement every xterm behavior or addon. For a report, include a minimal reproduction without private output or credentials.\n\n[Upstream release](https://github.com/TeoSlayer/refstream.js/releases/tag/v0.1.0-alpha.5) · [Connector protocol](https://github.com/TeoSlayer/refstream.js/blob/v0.1.0-alpha.5/docs/agents.md)."
]
]
},
"self-hosting": {
"eyebrow": "Run your own relay",
"title": "Use your own server and domain.",
"intro": "The standalone relay runs with Docker and Caddy on one host. Your CLI stays the same; point it at your server. Accounts and native MCP are separate deployments.",
"seo": {
"description": "The standalone relay runs with Docker and Caddy on one host. Your CLI stays the same; point it at your server. Accounts and native MCP are separate deployments.",
"socialTitle": "Use your own server and domain. | shell.online",
"socialDescription": "The standalone relay runs with Docker and Caddy on one host. Your CLI stays the same; point it at your server. Accounts and native MCP are separate deployments."
},
"cards": [
[
"Before you start",
"You need Docker with Compose, a domain pointing at the server, and ports 80/443 reachable for HTTPS. The standalone relay is single-node. It is not the optional accounts app or the native Worker MCP implementation."
],
[
"1. Get the standalone deployment",
"Use the `standalone` directory, not the root Compose file. The root file starts a terminal client; this one runs a relay.",
[
[
"git clone https://github.com/TeoSlayer/shell.online.git\ncd shell.online/standalone",
"Prepare the relay on your server."
]
]
],
[
"2. Set your public domain",
"Replace the example domain with your own. Caddy obtains HTTPS certificates when DNS and ports are ready.",
[
[
"SHELL_ONLINE_PUBLIC_URL=https://relay.example.com SHELL_ONLINE_SITE=relay.example.com docker compose up -d --build",
"Start the relay and HTTPS proxy."
]
]
],
[
"3. Start a session through it",
"On the computer doing the work, select your relay. Keep HTTPS for a real deployment.",
[
[
"shell --server https://relay.example.com claude",
"The generated link points at your server."
]
]
],
[
"Try it locally first",
"For a loopback-only trial, the default Compose settings use HTTP localhost. This is not a public deployment configuration.",
[
[
"docker compose up -d --build",
"Run from the standalone directory."
],
[
"curl http://localhost/api/health",
"Check the local relay response."
]
]
],
[
"Protect state and keep one replica",
"The `relay-state` volume contains session metadata and host-token hashes, not browser passwords or E2EE frame keys. Back it up. Do not run multiple relay replicas against the same state file.\n\nLive sockets reconnect after a restart. The standalone relay stores metadata, not a terminal transcript. Default E2EE still happens between the host and browser."
],
[
"Configuration reference",
"Trust forwarded addresses only when the relay is behind your own trusted proxy.",
[
[
"SHELL_ONLINE_PUBLIC_URL",
"Exact public origin used in links and browser-origin checks."
],
[
"SHELL_ONLINE_SITE",
"Caddy hostname for HTTPS; http://localhost for local tests."
],
[
"SHELL_ONLINE_STATE_FILE",
"Metadata file path. Default /var/lib/shell-online/relay.json."
],
[
"SHELL_ONLINE_TRUST_PROXY",
"Enabled by the supplied proxy deployment. Do not expose that trust directly to untrusted clients."
]
]
],
[
"Cloudflare and accounts",
"The Worker deployment is also available and provides the native MCP channel with its required bindings and keys. An accounts app needs its own identity provider and PostgreSQL.\n\nFollow the [operator guide](https://github.com/TeoSlayer/shell.online/blob/main/docs/self-hosting.md) for these deployments. The terminal relay works without an account."
]
]
},
"cli": {
"eyebrow": "Command reference",
"title": "Find the command you need.",
"intro": "A task-first reference for the Shell CLI. Start with the common commands below; flags and technical details follow. Commands run on the host computer.",
"seo": {
"description": "A task-first reference for the Shell CLI. Start with the common commands below; flags and technical details follow. Commands run on the host computer.",
"socialTitle": "Find the command you need. | shell.online",
"socialDescription": "A task-first reference for the Shell CLI. Start with the common commands below; flags and technical details follow. Commands run on the host computer."
},
"cards": [
[
"Start a session",
"`shell` starts a process in a local terminal and shares it. Use `--` to separate Shell options from the program’s arguments.",
[
[
"shell <command> [arguments...]",
"Share a new process in the background."
],
[
"shell",
"Start your default shell. On Windows, PowerShell is preferred, then COMSPEC."
],
[
"shell --foreground claude",
"Keep local foreground interaction while sharing."
],
[
"shell --read-only claude",
"Allow browser viewing, not input."
],
[
"shell --name \"Review\" -- codex",
"Give the session a readable name."
]
]
],
[
"Find, attach and stop",
"Local and account lists are different. Use a full ID or an unambiguous local prefix of at least six characters.",
[
[
"shell list",
"Local sessions and relay state."
],
[
"shell list --json",
"Local JSON on stdout. Can contain e2ee_password; treat it as secret."
],
[
"shell ls",
"Open sessions in your linked account."
],
[
"shell ls --all",
"Include ended account sessions."
],
[
"shell ls --json",
"Account metadata as JSON, without session passwords."
],
[
"shell attach <ID>",
"Attach locally. Ctrl-X, then D detaches; Ctrl-] is a legacy alternative."
],
[
"shell kill -- <ID>",
"Stop one session. The -- also handles IDs beginning with a dash."
],
[
"shell kill --all",
"Stops every locally managed session. Do not use it to clean up a single test."
]
]
],
[
"Passwords",
"The complete share link and password grant browser access. Do not print them into shared logs.",
[
[
"shell password <ID>",
"Reveal the active browser password locally."
],
[
"shell password rotate <ID>",
"Change password, salt and cipher generation; disconnect viewers and revoke MCP grants without restarting the task."
]
]
],
[
"Account and remote start",
"Account linking is optional. Remote start grants additional authority to run commands on this machine.",
[
[
"shell auth",
"Link your machine through browser approval."
],
[
"shell auth --no-browser",
"Print the approval URL and follow the callback instructions."
],
[
"shell auth --allow-remote-start",
"Enable browser-started sessions deliberately."
],
[
"shell auth --no-remote-start",
"Disable that capability."
],
[
"shell whoami",
"Show the linked account."
],
[