Beacon v0.6.3

终端编排 · 一条 WebSocket · 桌面 / Web / 手机

NO. 001 — 2026

一个终端舰队, 随处掌控。

把机器上真实的 PTY 会话,同时交给桌面、浏览器和手机。谁在写入、谁在旁观由租约决定;断线只是离开,不是结束。

同一会话 · 实时附着

zsh 1 ~/srv/atlas claude running the tests · 40%
11:26:04 [lease] controller active [epoch #6] — single-writer lease held by this window
dev@studio-mac ~/srv/atlas % git status -sb
## main...origin/main
M internal/session/session.go
M web/src/app.ts
$ grep -rn "func (e Element) Radius" ~/go/pkg/mod/github.com/egoist/mygo@v0.5.5/ui/*.go | head -5
Outputno output
Wall: 0.02s · Timeout: 300s · Exit: 1
$ go test ./internal/hub/ -run TestAttach
Outputok github.com/atelier/atlas/internal/hub 0.42s
dev@studio-mac ~/srv/atlas %
图 01 · tfdesktop — 原生 Mygo 窗口:左边是机器与会话,右边是终端卡片 图 02 · Web 客户端 — 由中继直接服务;没有标签栏,会话列表就是切换器 图 03 · 手机端 — 抽屉侧栏与修饰键条:一张卡片就是一个会话 s10 · 控制中 · 135 × 42
开放入站端口
0
条 WebSocket 承载全部会话
1
原生桌面空闲内存
~15MB
01为什么

终端应该跟着人走。

不是又一层远程桌面。Beacon 让同一组真实 shell 同时存在于三个客户端里,并且始终知道谁在写入。

  1. 01 / DETACH

    断开,不是结束。

    锁屏、合盖、Wi-Fi 闪断只是客户端离开。进程和 PTY 留在主机,重连时按字节偏移续上,不重放、不丢失。

    环形缓冲 · 增量续接
  2. 02 / LEASE

    一个 shell,一个写入者。

    一个 PTY 只有一条 stdin。纪元租约保证同一时刻只有一个控制端,其余客户端实时镜像,接管是一次明确的动作。

    纪元租约 · 一键接管
  3. 03 / OUTBOUND

    机器出门,不开门。

    受控机器主动外联中继,不需要公网 IP、入站端口或 VPN。中继只配对字节流,不接触 PTY,也不接触密钥。

    出站 WSS · 0 入站端口
02手感

规则不是口号,是能看见的手感。

下面三块都可以点,不是截图。

A / RESUME

断开,不等于结束。

点一下拔掉网线:客户端 detach,shell 继续跑。恢复时只补断线期间的那几个字节。

试一下 →
已连接 · s10 byte 41,208
dev@studio-mac ~/srv/atlas % tail -f deploy.log
14:02:11 build ✓ 42s
14:03:12 request ✓ 81ms
14:04:02 deploy ✓ 200
14:04:39 health ✓ 200
客户端离开 · shell 留下
B / WRITE

一个 shell,只有一个写入者。

两端都能看见同一屏,但只有一端能输入。在手机上接管是一次显式动作,纪元随之递增。

试一下 →
控制中 (Epoch #6) · studio-mac 单写入者租约
studio-mac 控制中 · 可输入
iPhone 只读 · 实时镜像
dev@studio-mac % echo "lease is explicit"
接管会递增纪元,旧控制端转为只读
C / RELAY

机器主动出门。

公网中继负责配对,不负责解释。受控机器只建立一条出站连接,浏览器和手机从另一侧接上。

只转发字节 · 不接触 PTY 与密钥
studio-mac tfd · 本机 build-box tfd · relay workshop-pc offline tfrelay pair · authenticate forward bytes browser relay.example.com iPhone same session outbound WSS attach
studio-mactfd · 本机 build-boxtfd · relay workshop-pcoffline
↓ outbound WSS
tfrelaypair · authenticate · forward bytes
↓ attach
browserrelay.example.com iPhonesame session
0 个入站端口 机器向外拨号,主机上不监听任何端口。
03对比

和它们比,差在哪。

SSH、tmux、tmate 各有各的解法。Beacon 把「多端附着」当成第一性问题。

Beacon 与 SSH、tmux、tmate 的能力对比
能力 Beacon SSH tmux tmate
免入站端口 ●出站中继 —需要可达主机 —随 SSH —需公网主机
单一写入者 ●租约仲裁 — — —
断线续接 ●字节偏移 —进程中止 —重新挂载 —容易断流
原生桌面端 ●Mygo · ~15 MB — — —
手机修饰键条 ●内置 — — —
每个会话在做什么 ●五态 · ⌘J — —只有响铃 —

按各方案的默认形态比较;tmux 可以借 SSH 隧道达到部分效果。

04上手

三条命令,一支舰队。

从源码构建,或直接取 Release 里的二进制。自包含,没有运行时依赖。

  1. 01
    起一个守护进程

    tfd 持有 PTY,默认监听 127.0.0.1:7678。

  2. 02
    把中继放到公网

    可选。tfrelay 只做流配对与鉴权,不持有任何 shell。

  3. 03
    打开窗口或浏览器

    tfdesktop 和 Web 客户端附着到同一批会话。

完整部署手册
# 从源码构建(Go + pnpm)
git clone https://github.com/CarlOpenLab/term-fleet.git
cd term-fleet && pnpm run build

# 起守护进程:真实 PTY,走一条 WebSocket
./bin/tfd

# → http://127.0.0.1:7678
05下载

带走它。随处接上。

每个 release 由 CI 构建,附带 SHA-256 校验和。构建未签名,首次打开需要手动放行。

macOS 右键 → 打开;Windows SmartScreen → 更多信息 → 仍要运行。

全部版本与校验和