Repository navigation
Releases: CarlOpenLab/beacon
Release list
v0.7.2
Beacon 0.7.2: Windows 的卡片保留圆角 — Windows keeps its card corners
- A card never goes square. 0.7.1 made the card
window − 8, which is exactly parallel; on Windows the window rounds at 8, so that is 0 — a square card inside a rounded window, which reads as no card at all and pinches the wash at the corner instead of widening it. The card now keeps a floor of 8: as round as the window itself, with the frame widening by a little over a pixel at the corner rather than the card losing its shape. Linux (12 − 8 = 4) comes up to the same floor.
— 0.7.1 让卡片取窗口 − 8,严格平行;Windows 的窗口圆角是 8,于是算出 0 —— 圆角窗口里一张方角卡片,看着像没有卡片,而且转角处的留白被挤窄而不是变宽。现在卡片有 8 的下限:和窗口本身一样圆,角上的留白只宽一像素多一点,而不是把卡片的形状去掉。Linux(12 − 8 = 4)同样抬到这条下限。 - macOS is asked which version it is. The window corner moved from 10 (macOS 15 and earlier) to 28 (26, Tahoe); 0.7.1 hard-coded the modern one, which would over-round the card on an older Mac. The version is read from the kernel at startup, so Tahoe still gets 20 and older releases get the floor of 8 instead of a card rounder than its window.
— macOS 的窗口圆角从 10(15 及更早)变成了 28(26,Tahoe);0.7.1 写死的是新值,在旧系统上会把卡片做得比窗口还圆。现在启动时向内核读系统版本:Tahoe 仍是 20,旧版本落到 8 的下限,而不是一张比窗口更圆的卡片。
v0.7.1
Beacon 0.7.1: 卡片重新圆回来,并按窗口的圆角对齐 — Cards keep their rounding, sized to the window's corner
- The workspace card's corner is the window's minus the frame, at the window's real radius. 0.7.0 fixed the alignment by assuming the window corner was 10 and shrinking the card to 4 — which is what a 10px window needs, and macOS 26 is not that window: it rounds at about 28. The card is 20 now (28 − 8), so it is rounder than the 14 it started with and the 8px wash keeps one width all the way round. Windows 11 (8) puts the card at 0 and Linux (12) at 4; the arithmetic is the same rule in all three. The card radius is no longer a standalone token, it is derived — so a future system change moves it instead of silently pinching the corner.
— 0.7.0 把窗口圆角当成 10、把卡片缩到 4,那是 10px 窗口该有的答案;macOS 26 不是那个窗口,它是约 28。现在卡片是 20(28 − 8),比最初的 14 还圆,同时 8px 留白在角上和边上一样宽。Windows 11(8)算出 0,Linux(12)算出 4,三处是同一条规则。卡片圆角不再是一个独立 token,而是推导出来的——系统以后变圆,它跟着走,而不是悄悄把角挤薄。 - A light card gets a 1px hard edge. The window's own edge is a hard system line; a card lifted only by shadows reads as a soft grey smudge at the corner — right curve, wrong material. It is drawn as a zero-blur shadow rather than a border so it cannot take a pixel out of the card's inside.
— 浅色卡片补了 1px 硬边。窗口那圈是系统画的硬线,只靠阴影浮起来的卡片在角上是一团软灰——弧度对了、质感不对。用零模糊阴影而不是 Border,避免它像内边距一样把卡片内容挤进去 1px。
v0.7.0
Beacon 0.7.0: 远程更接近本地 — paste images across machines, compress the wire, name every build — Beacon:图片能粘到对面,链路会压缩,每台机器的版本都看得见
- An image or a file on the clipboard becomes a file on the machine the shell runs on. The terminal used to hand a paste to the program as text, which is nothing at all when the clipboard holds a screenshot: a shell does not read the clipboard protocol, so the paste silently died. Both clients now take an image or a file, upload it over
file.put/file.chunk/file.doneinto a private temp directory on that machine (32 MB ceiling, name sanitized, one upload in flight), and paste the returned path quoted for that machine's shell — POSIX or PowerShell. The desktop hooks the terminal'sOnPaste; the browser reads clipboard files. A read-only pane says why instead of swallowing the paste.
— 剪贴板里是截图时,终端原来把粘贴当文本交给程序,而普通 shell 不读剪贴板协议,于是这次粘贴静悄悄地消失了。现在两端都会取出图片或文件,用file.put/file.chunk/file.done传到那台机器的私有临时目录(上限 32 MB、文件名清洗、同一时刻一个上传),再把返回的路径按那台机器的 shell 加引号粘进去(POSIX 或 PowerShell);桌面端挂在终端OnPaste上,浏览器读取剪贴板文件;只读窗格会说明原因,而不是吞掉。 - The wire is compressed when both ends know how. Every Data field worth more than a few hundred bytes is zlib-compressed, negotiated in the hello and only ever sent to a peer that named
deflate. Terminal output is the bulk of a fleet's traffic and it repeats itself; a megabyte replay that used to cost about 1.8× its bytes after two layers of base64 now costs a fraction of that. An old hub and an old client keep the exact wire they had.
— 超过几百字节的 Data 现在都做 zlib 压缩,在 hello 里协商,且只发给声明了deflate的对端。终端输出是流量的大头且高度重复,一次原本因两层 base64 膨胀到约 1.8 倍的重放,现在只占其中一小部分;旧 hub 与旧客户端仍然走完全相同的帧。 - Every machine says which build it runs, and the same daemon enrolled twice is refused. The handshake, the relay roster and the machine tooltip now carry the version and an instance id (hostname, pid, start). A machine that is behind is visible where you act on it; a second enrollment of the same running daemon is rejected at the relay with the id it duplicates, instead of showing one machine's sessions twice.
— 握手、中继名册和机器提示现在都带版本与实例 id(hostname、pid、启动时间)。落后的机器在你要动手的地方就能看见;同一个运行中的 daemon 被登记两次时,中继会用已在线的那台机器的 id 拒绝第二条链路,而不是把一台机器的会话列两遍。 tfd service installregisters the daemon with the OS, and one line installs it. systemd user unit on Linux (with linger), a launchd agent on macOS, a logon task on Windows;uninstall,restartandstatusalongside.scripts/install-member.sh/.ps1download the latestbeacon-clirelease and run it, so a machine joins in one command and updates by running the same one again. Released binaries now carry their version (tfd version).
— Linux 用 systemd 用户单元(并开启 linger),macOS 用 launchd agent,Windows 用登录任务;另有uninstall、restart、status。scripts/install-member.sh/.ps1下载最新beacon-cli后调用它,一台机器一条命令加入,重跑同一条命令即更新;发行二进制现在带有版本号(tfd version)。- The scrollback a reconnecting client replays is four times larger, and truncation is said out loud. The per-session ring is 1 MiB; when a client was away longer than it holds, the desktop now says the screen may be incomplete instead of leaving a full-screen program looking merely broken (the browser already said so). The relay client also has one bounded writer queue: the window's thread never waits on a relay that stopped reading, and a queue that fills ends the link so the next one resumes from the cursor rather than losing bytes silently.
— 每个会话的环形缓冲提升到 1 MiB;离开太久时桌面端现在会提示画面可能不完整,而不是让全屏程序看起来只是坏了(浏览器端原本就会提示)。中继客户端也只有一个有界发送队列:窗口线程不再等待一个停止读取的中继;队列满时结束链路,让下一条从游标续上,而不是静默丢字节。 - Tokens for people, scoped to machines and expiring on their own. The relay can mint a named credential limited to a few machine ids with a lifetime, list it in the admin panel, and revoke just that one — so a phone or a colleague no longer needs the fleet-wide token, and taking access back does not sign everyone else out.
— 中继可以签发限定到几台机器、带有效期的具名凭据,在管理页列出、单独撤销——手机或同事不必再共用一个全舰队令牌,收回权限也不会把其他人一起踢下线。 - Corner radii line up at the window edge, and a remote notification names its machine. Workspace cards inset 8 px from a window whose corner is the system's now use a radius concentric with it, so the frame between the two curves keeps the same width at the corners as along the edges. A notification about a shell on another machine says which one, so a remote program cannot read as a local one.
— 距离窗口边缘 8 px、而窗口圆角由系统绘制的工作区卡片,现在改用与窗口同心的半径,两条弧之间的留白在转角处和边上一样宽。来自另一台机器的通知会写明是哪台,远端程序无法冒充本机。 - Not in this release. A member is not updated automatically — run the install line again, or
tfd service installwith the new binary (its sessions end with it). The reattach fix for a truncated replay is a bigger ring and an honest sentence, not a server-side screen snapshot; remote paths still open on the machine you are sitting at, not on the far machine.
— 本版不含:成员不会自动更新(重跑安装命令,或用新二进制再执行tfd service install,会话会随之结束);截断重放的修法是更大的环形缓冲加一句实话,而不是服务端画面快照;远端路径仍在本地机器打开,而不是在那台远端机器上。
v0.6.8
Beacon: a tab for a session that is gone is closed, not called exited — Beacon:会话已经不在了的标签,直接关掉,而不是说它「已退出」
- A tab opened on a session the hub no longer has is closed, with a sentence. The panel draws the last session list its machine pushed, so a row can outlive its shell; clicking one opened a tab, the attach was answered
no_session, and the window read the attach that never came as an exit — "会话已退出,最后几行仍可读取" over a blank pane, a sentence about a final line that does not exist. That tab is removed now, the stale row goes with it, the machine's list is asked for again, and the status bar says the session is gone. A tab that did watch a shell end keeps its banner and its output.
— 「会话」面板画的是一台机器最后一次推来的列表,所以一行可能比它的 shell 活得久:点它会开出一个标签,attach 得到no_session,而窗口把「没有 attach」读成了「已经退出」,于是在一个空面板上写「会话已退出,最后几行仍可读取」——一句最后一行为空的话。现在这种标签会被关掉,过期的行也一起消失,并重新向那台机器要一次会话列表,状态栏说明这个会话已经不在了;真正看着 shell 结束的标签仍然保留横幅和最后输出。 - Session lists are counted in the diagnostic log. Every list a machine pushes logs its machine and size, so a row that will not go can be told apart from a list that never arrived.
— 机器每次推来的会话列表都会在诊断日志里记下机器与条数,于是「行不肯消失」和「列表根本没来」可以区分开。
v0.6.7
Beacon: a close closes the tab, even from an older client — Beacon:旧客户端发出的关闭,也不会再留下「已退出」
- A close dismisses the tab unless it says it is 结束. 0.6.6 put "this is a tab close" on the close frame, and that only worked when the device that closed it was already on 0.6.6: a device still on 0.6.5 sent the same bare frame for 关闭标签 and 结束, so its closes reached the hub with nothing on them and every other client kept a 已退出 pane. The hub now takes a bare close as a tab close; 结束 sends
keep, and that is the only close that leaves the tab showing the final output. One consequence, for one release: a 0.6.6 client's 结束 arrives bare, so its watchers drop the tab — the client that pressed it keeps its own.
— 0.6.6 让 close 帧带上「这是关标签」,但只对已经在 0.6.6 上的设备生效:还停在 0.6.5 的设备,关闭标签与结束发出的是同一帧不带任何标记的 close,于是别的客户端照样留下「已退出」的面板。现在 hub 把不带标记的 close 当作关标签处理,只有明确带keep的结束才保留标签继续显示最后输出(0.6.7 的客户端会发)。过渡期有一个代价:0.6.6 客户端按「结束」时发的是不带标记的 close,观看端会关掉标签——按下的那一端自己的标签仍然保留。 - Every close says what it meant, in the diagnostic log. A close now logs its session,
keepanddismiss, so a tab that outlives its shell can be traced to the side that sent the frame — a stale client, or a daemon on a machine that has not been updated.
— 每次 close 现在都会在诊断日志里记下 session、keep与dismiss,于是「标签比 shell 活得久」可以直接追到发帧的那一侧:是没更新的客户端,还是某台机器上的旧 daemon。
v0.6.6
Beacon: a closed tab is closed everywhere — Beacon:关掉的标签,每台设备上一起关掉
- Closing a tab takes the tab with it on every client. The × and ⌘W ended the shell and then left a 已退出 tab on the machine the shell runs on, and on every phone or browser watching it — a close and an exit were the same frame on the wire, and an exit is deliberately kept so its last lines can be read. A close now says it is a tab being closed, and the hub repeats that on the exit frame: each client drops its tab with the process, so the machine that hosted the shell does not keep a dead pane nobody there closed. 结束 sends the same close without the flag, and that is still the act that leaves the tab holding the final output.
— 桌面端 × 与 ⌘W 结束进程后,会在运行这个 shell 的机器和其他正在观看的手机/浏览器上留下一枚「已退出」标签:close 与 exit 在协议上是同一帧,而 exit 是刻意保留的,好让最后几行还能读。现在关闭标签会带上「这是关标签」的标记,hub 把它带在 exit 帧里广播,各客户端随进程一起移除自己的标签,主机上不会再留一个没人关的死面板;「结束」仍发送不带该标记的 close,也就是保留标签读最后输出的那个动作。 - The browser's × now ends the session too, after asking. The mobile and web clients read a tab close as "stop watching", so closing there left the shell running and the desktop's tab alive. Closing a tab now means what it means on the desktop — the pane and the shell go together, everywhere — and it asks first, because the kill is irreversible for every other client and a thumb is easy to misplace. A tab whose shell has already exited is still only a view to dismiss.
— 浏览器/手机端此前把关闭标签当作「停止观看」,关掉后 shell 继续跑、桌面端的标签也还在。现在点 × 与桌面端同义(窗格和 shell 一起走,且对所有客户端生效),并且会先确认——对其他人不可恢复,手指又容易点偏。已经退出的 shell 仍只是关掉视图。
v0.6.5
Beacon: a remote paste is this keyboard's, and a watched screen fits — Beacon:远程粘贴用本机剪贴板,观看屏幕适配窗格
- Ctrl+V at another machine's shell pastes this machine's clipboard. The terminal used to send
^Vto the far end, where a Windows console or Claude Code read it as "paste the clipboard here" — the panel that opened belonged to the other machine, not the person typing. Remote tabs now bindCtrl+V/Ctrl+Shift+Vto the local clipboard (a performable binding: an empty clipboard still reaches the program as^V), and local shells keep their platform's keys untouched. The browser client also routes a paste made over the terminal into the composer instead of losing it in xterm's display-only textarea.
— 控制其他机器时按 Ctrl+V 现在粘贴的是本机剪贴板。之前远端标签会把^V发给对端,Windows 控制台或 Claude Code 会把它当成“粘贴那边的剪贴板”,弹出的面板属于另一台机器。远程标签现在把 Ctrl+V / Ctrl+Shift+V 绑成本机粘贴(剪贴板为空时仍把^V交给程序),本机 shell 的按键不变;浏览器端在终端上粘贴也会进入 composer,不再被 xterm 的只读输入框吞掉。 - A watched shell lays out at its own size, and can be scaled to fit the pane. A viewer used to fit the replay to its own pane, so a full-screen program's lines wrapped here and not on the machine that wrote them, and every later cursor move landed a row off. Both clients now keep the shell's reported columns and rows (the replay is written for that screen) and, with the new 观看时缩放适配 / “Fit while watching” switch, shrink the text just enough to put the whole screen inside the pane; controlling is never scaled. The switch is on by default, skips screens that almost fit (under ~10% off), and stops at a readable 7.5 pt — a pane smaller than that still clips. Desktop: 设置 → 终端; browser: the gear's popover, remembered per device.
— 观看端现在按远端 shell 上报的行列排版(重放就是按那块屏幕写的),并用新增的「观看时缩放适配」开关把字号缩到整屏刚好放进窗格;控制时永不缩放。开关默认开启,差距小于约 10% 时不缩,字号下限 7.5 pt,再小仍会裁切。桌面端在设置 → 终端,浏览器在齿轮菜单里,按设备记住选择。此前按本机窗格重排会导致全屏程序换行位置不同、之后每次光标移动都偏一行。 - The read-only sentence lives in the card's header. On the desktop, taking or releasing the lease used to add a 34 px strip under the header; the strip took its height out of the terminal, so the same shell lost its last rows just because control had moved. The sentence and its button now share the header row — replacing the descriptive chips while it shows — and the terminal keeps the same rectangle in both states.
— 桌面端把只读横幅并进卡片头,替代原来的 34px 独立横条;控制/释放不再改变终端高度,同一块屏幕不会因为控制权变化而少掉最后几行。
v0.6.4
Beacon: the session list is dragged like a sortable list — Beacon:侧栏会话改成 sortable 式拖动
- A dragged row now previews the order it is making. The row picked up leaves an empty slot where it would land, a copy follows the pointer, and the rows it passes slide out of the way; dropping writes the order, while Escape or letting go outside the rows puts it back. The browser client draws the same interaction with pointer events and a 160 ms FLIP instead of the browser's drag image, and decides the landing place from layout positions, so a list that is still sliding cannot change its mind under a pointer that has not moved.
— 拖动的会话行现在就是新顺序的预览:原位置留出空槽,副本跟着指针,被经过的行滑开让位;松手才写入顺序,Esc 或丢在列表外则原样退回。浏览器端改用 Pointer Events 与 160ms FLIP 画同一套交互(浏览器自带的拖拽图像跟不上实时重排的列表),落点按布局坐标判定 —— 正在滑动的列表不会在指针不动时自己改主意。 - The motion no longer bounces, and the list stays quiet under the pointer. Rows move with a short spring that does not overshoot, a dragged row's copy is a lifted card rather than another row passing through, and hover backgrounds and the close × are suppressed while rows slide under the pointer. A drag that is cancelled or dropped outside leaves no trace in the saved order.
— 动画不再弹:行用一段不回弹的短弹簧让位,被拖那枚的副本有卡片底和阴影,不再像另一行从列表里飘过;行从指针下经过时不闪 hover 与关闭 ×。取消或丢在列表外的拖动不会在保存的顺序里留下痕迹。
v0.6.3
Beacon: drag the fleet into your order, and let the terminal name itself — Beacon:把会话拖成自己的顺序,让标题自己说话
- The project is called Beacon. The window, the browser page, the relay's admin panel and the docs now say Beacon throughout, the desktop bundle is
dev.carl.beacon, and the service files follow the new name. A settings directory that already exists underterm-fleetis still the one used — an update is not a reason to lose a font, a relay or a shortcut — andTERM_FLEET_CONFIG_HOMEstill works beside the newBEACON_CONFIG_HOME. README has a Simplified Chinese edition.
— 项目正式改名为 Beacon:窗口、浏览器页面、中继管理页和文档统一换名,桌面 bundle 标识为dev.carl.beacon,服务文件也跟着改。已有的term-fleet设置目录仍继续使用——升级不该弄丢字体、中继或快捷键;TERM_FLEET_CONFIG_HOME与新的BEACON_CONFIG_HOME并存。README 补了简体中文版。 - Drag a session row into the order you want. The sidebar of both clients was fixed to the daemon's oldest-first list; now the desktop and the browser each remember their own arrangement, per machine. A row dragged over another lands above or below it by which half of the row the pointer is on, with an accent line marking where it will go; dragging never picks the row, and a shell the order has not seen yet joins at the end. The desktop keeps it in
settings.json, the browser inlocalStorage, and a filtered list moves rows without disturbing the ones it is hiding.
— 侧栏会话现在可以拖动排序:两个客户端原先都固定按 daemon 的最早优先顺序,现在桌面端和浏览器各自、按机器记住自己的排列。拖到另一行上半段就插在它前面、下半段插在它后面,强调色横线标出落点;拖动不会选中该行,顺序里没见过的会话排在末尾。桌面端写进settings.json,浏览器写进localStorage;筛选状态下拖动也不会打乱被隐藏的行。 - An agent names the shell by naming its terminal. The daemon now reads the title a program sets with
OSC 0/OSC 2and uses it as the session's name when nobody has renamed the shell — which is how Claude Code and other AI CLIs say which task they are on. The animated spinner in front is taken off, so the name does not flicker with every frame; an explicit rename still wins, and a program that clears its title gives the name back to the program and directory. A set title is broadcast like any other state change, so the phone, the browser and the desktop change together.
— AI 用「给终端起标题」来命名自己的任务:daemon 现在解析程序写入的OSC 0/OSC 2标题,在没人手动重命名时把它作为会话名——Claude Code 这类 AI CLI 正是这样说明当前任务的。标题前面的动画 spinner 会被去掉,名字不再逐帧闪动;显式重命名仍然优先,程序清空标题后名字回落到程序名与目录。标题变化会像状态一样广播,手机、浏览器和桌面一起更新。 - The browser client speaks the protocol the daemon speaks again. 0.6.2's browser bundle still announced version 1 to a daemon that requires version 2, so the page could load and then fail to show a single session. It now sends 2 and names both versions if they ever disagree. While fixing the title feed, the scanner also stopped treating the byte
0x9Das a C1 control: it is the middle byte of❯, so a prompt drawn with that arrow used to swallow every title and status report after it.
— 浏览器客户端重新说对协议版本:0.6.2 的前端仍向要求版本 2 的 daemon 声明版本 1,页面能加载却看不到任何会话。现在发送 2,真不一致时会把双方版本都写出来。修标题链路时也修了扫描器:它把字节0x9D当成 C1 控制符,而0x9D正是❯的中间字节,于是带这个提示符的终端会吞掉之后所有标题和状态报告。 - A shell started by the desktop has a UTF-8 locale. A window-server launch passes no
LANG, so zsh came up in the C locale: a Chinese name was echoed as reverse-video bytes andcd 中文said the directory did not exist. Sessions now name the user's own UTF-8 locale from the system preference, oren_US.UTF-8/C.UTF-8when the system has one; an environment that already names a locale — including an explicitC— is left alone, and Windows, whose console has no locale, is unchanged.
— 桌面端启动的 shell 现在有 UTF-8 locale:从窗口服务器启动时环境里没有LANG,zsh 会进 C locale——中文文件名被回显成反色的字节串,cd 中文还会说目录不存在。会话现在按系统偏好选择用户自己的 UTF-8 locale,系统没有时退到en_US.UTF-8/C.UTF-8;环境里已经写明 locale(包括显式C)就不覆盖,Windows 控制台没有 locale 概念,行为不变。 - macOS draws its own traffic lights. The three dots are AppKit's now, on the same 30px line as the rest of the chrome, so they keep the system's shapes, spacing, inactive-window grey, double-click and window menu; full screen collapses them and the header around them. Windows and Linux keep the controls the view draws, now covered by tests that run on every platform.
— macOS 改用系统自己的红绿灯:三颗圆点由 AppKit 绘制,与其余 chrome 落在同一条 30px 线上,形状、间距、失焦灰色、双击与窗口菜单都是系统的;全屏时它们和围绕它们的标题区一起收起。Windows / Linux 继续使用界面绘制的按钮,并补上了在三大平台都运行的测试。
v0.6.2
Desktop: the window's controls in the platform's corner, and a settings window that floats — 桌面端:窗口按钮回到平台该在的一角,设置改成浮窗
- Minimize, maximize and close at the top right on Windows and Linux. The view used to draw macOS's three dots at the top-left on every platform. Windows and Linux now get Windows 11's flat minimize, maximize or restore, and close at the right end of the card header, the close one turning red under the pointer; macOS keeps its traffic lights. The top-right pane's header keeps the room the buttons take, the maximize button carries the system's snap-layout hit target on Windows 11, and with the sidebar folded away the card title no longer leaves the traffic lights' 58 pixels on platforms that have none.
— 桌面端窗口按钮按平台分角:Windows / Linux 原先也画在左上角的三颗 macOS 圆点,现在换成右上角 Windows 11 风格的最小化 / 最大化或还原 / 关闭(关闭悬停红底白字),macOS 保持红绿灯。占住窗口右上角的那个窗格,其卡片头给按钮留出位置;最大化按钮在 Windows 11 上仍能唤出贴靠布局;侧栏收起时,卡片标题也不再为不存在的红绿灯空出 58px。 - The settings window floats, and does not cover the page. Opening settings used to lay the window's wash over every shell, so the appearance settings could not be tried against what they change. The dialog is now a floating card with no backdrop at all: the shells stay visible behind it, the pointer drags it aside by its title bar (it stays inside the window, a margin from the edges, and remembers where it was put for the session), and its title bar no longer drags the whole window.
— 设置不再盖住整页:原先打开设置会用窗口 wash 覆盖所有 shell,改外观时看不到实际效果。现在是一块没有任何幕布的浮动卡片——底下的 shell 一直可见,按住标题栏即可拖开(限制在窗口内、离边留 12px,并在本次运行内记住位置),标题栏也不再拖动整个窗口。