Skip to content

Releases: eathard/vscode-ternimal

Ternimal v1.3.4 — 修复中继「重连风暴」:回放截断到单帧预算

Choose a tag to compare

@eathard eathard released this 02 Oct 13:48

Ternimal v1.3.4 — 修复中继「重连风暴」:回放截断到单帧预算

问题(2026-10-02 线上事故)

中继链接打开后终端永远空白,浏览器顶部横幅无限循环
Relay connection lost — reconnecting…(实测单页 44+ 次重连)。

根因:长跑输出型会话(如挂了一整天的 ping)把回放环形缓冲填到近 1MB(上限);attach 时 RemoteServer 把整个回放密封成单帧发出,base64+GCM 膨胀后线上尺寸 ≈1.4MB,超过 relay /pipe 的 maxPayload 硬限(1MB)——超限帧直接断管(host error),close 1000 属非致命码,客户端重连 → 认证成功(退避归零)→ 再 attach → 再断 → 死循环。回放 >~770KB 的会话经中继一律连不上;本地 LAN 路径不受影响。

修复

attach 回放按线上预算截断(保最新),单帧永不超限。

  • WS.MAX_SECURE_FRAME_BYTES = 900KB:relay 1MB maxPayload 之下的安全预算
  • fitReplayToBudget():从头部裁剪、优先对齐行首(终端首行不残缺)、任意输入长度收敛(含 ≤3 字符极短输入的收敛保证)
  • estimateSealedWireBytes():密封信封线上尺寸的保守上界(UTF-8 字节 + GCM tag + base64 ×4/3)
  • 本地 IPC / 窗口重开路径不截断(无帧上限);行为收缩已按 wire-compatibility 规则 3 记录豁免

验证

  • 回归用例 M-07(verify-relay-matrix):真 relay(1MB maxPayload)+ 1.1MB 回放 → attach 存活、实时数据到达、零重连;撤销修复即红(完整复现线上重连风暴),修复后绿
  • 顺手修复 fitReplayToBudget 初版在极短回放+极小预算下的死循环(单测抓出:worker 131% CPU 空转)

质量门禁

vitest 80/80 · relay-matrix 7/7 · npm run verify 全矩阵 ✓ · tsc strict ✓ · smoke-e2e ALL PASS(真 Electron + 真 bash + TLS + 中继隧道)

安装包与校验和(仅 Linux)

平台 文件 大小 MD5
Linux x64 (deb) ternimal_1.3.4_amd64.deb 75.1 MB 7d31d78242397063f673dca9784e9998
Linux x64 (AppImage) Ternimal-1.3.4.AppImage 108.8 MB 741243732be8cbcd867815513381eaaf

完整变更:v1.3.3...v1.3.4

升级提示:分享令牌随宿主进程启动轮换——升级后请从 ⚙ 面板重新生成分享链接;浏览器首次访问仍需点过 Caddy 自签证书警告(设计内行为)。

Ternimal v1.3.3 — 书签即全链:完整 URL 常驻地址栏

Choose a tag to compare

@eathard eathard released this 16 Sep 06:41

Ternimal v1.3.3 — 书签即全链:完整 URL 常驻地址栏

问题

扫码打开的中继链接 #S=<子码>&T=<令牌> 曾被立即抹除片段(旧 P0 策略:令牌不驻留地址栏),导致手机点收藏存下的是裸地址,书签打不开会话。

方案(产品决策,2026-09-16)

完整 URL 常驻地址栏,凭据零落盘。

  • 页面加载后不改写 URL——#S=&T= 全链始终在地址栏
  • 用户点收藏 → 书签存完整 URL → 重开书签/刷新/新标签页直接连上,多台电脑各是各的链接、天然互不干扰
  • 不写 sessionStorage、不写 localStorage、无任何钥匙串——URL 是凭据的唯一载体,由用户自行收藏保管
  • 手清地址或直达根路径 → 手输卡提示重新扫码

安全边界(已知悉并接受的取舍)

面 状态
令牌达服务器日志 不会(# 片段不上行,始终如此)
地址栏截屏 / 复制链接 / 浏览器历史 会含令牌(本决策的代价;业主拍板接受)
失效手段 子码随时可吊销(管理页/主机侧);分享令牌可轮换

质量门禁

vitest 72/72 · tsc strict ✓

安装包与校验和(仅 Linux)

平台 文件 大小
Linux x64 (deb) ternimal_1.3.3_amd64.deb 75.0 MB
Linux x64 (AppImage) Ternimal-1.3.3.AppImage 108.8 MB

完整变更:v1.3.1...v1.3.3

Ternimal v1.3.1 — 单实例双缺陷修复

Choose a tag to compare

@eathard eathard released this 16 Sep 01:58

Ternimal v1.3.1 — 单实例双缺陷修复

本版仅发布 Linux 双件(deb / AppImage);Windows 版维持 1.3.0,下个功能版一并追平。

修复:双击图标没反应(托盘驻留 + 第二实例副作用)

现场(v1.3.0 实机 journal,2026-09-16):应用关窗驻留托盘后再双击桌面图标,无任何窗口出现;同时后台日志出现端口抢占与中继插件重启循环。

根因一:第二实例「假退出」 — 拿不到单实例锁时只调用 app.quit(),但它是异步排队:ready 仍会触发,整机带着副作用完整开机一遍——回退自动端口再起一个 RemoteServer、以同一主码fork 中继插件并陷入 plugin exited (0) 重启循环,与真实例发生短暂注册争抢。用户视角是「点了没反应」加中继噪音。

根因二:托盘驻留时无法唤回窗口 — second-instance 只 focus 已存在的窗口;窗口关闭驻留后 mainWindow=null,点图标什么都不发生。

修复(src/main/main.ts):

  1. 锁失败 → app.quit() 后紧跟 process.exit(0) 硬停——此刻尚无任何资源启动,无需善后
  2. second-instance → 调用幂等的 createWindow():窗口已销毁则重建、存活则 show+focus,restore() 覆盖最小化场景

验证:dev 构建双开实测——第二实例仅输出一行退出日志,零 RemoteServer/relay 副作用;verify-multi-instance 5/5;tsc + vitest 72/72。

安装包与校验和(仅 Linux)

平台 文件 大小 MD5
Linux x64 (deb) ternimal_1.3.1_amd64.deb 75.0 MB b4892dd4ec6d9bbac022b48a9c259363
Linux x64 (AppImage) Ternimal-1.3.1.AppImage 108.8 MB b952e0864f9fc08e5bb0c5a449218edd

升级建议

  • 遇到过「点图标没反应」的 Linux 用户请升级;无此症状可不急
  • Windows 用户无需动作(1.3.0 不受使用层面影响,仅二次启动的日志噪音)

完整变更:v1.3.0...v1.3.1

Ternimal v1.3.0 — 线协议兼容契约 + caps 能力握手

Choose a tag to compare

@eathard eathard released this 15 Sep 14:21

Ternimal v1.3.0 — 线协议兼容契约 + 工程化加固

核心特性:caps 能力握手

为什么:网页端比 App 活得久——手机上开着的会话页会在桌面端升级后继续存在,混合客户端/主机版本是常态而非异常。v1.3.0 把这一现实固化为线协议契约(docs/wire-compatibility.md),从此新功能的上线不再需要"所有端一起升级"。

三条线协议规则

  1. 可选字段安全 — 收方必须忽略未知字段
  2. 新帧类型必须协商 — 未经 caps 握手声明的能力,双方都不得发送
  3. 发布即变更 — 任何影响线上行为的改动都按线协议变更对待;帧名永久

握手机制(扩展现有 enc:1 模式,零破坏)

方向 帧 行为
主机 → 客户端 auth-ok.caps 通告能力;为空时整个字段省略——与旧版字节级一致,旧客户端零感知
客户端 → 主机 auth-response.caps 应答能力;严格校验:≤16 项、[a-z0-9-]{1,32}、畸形帧即 BAD_MESSAGE 断连

客户端侧 supportsCap():caps 缺失 = 旧主机 = 功能自动关闭。1.3.0 ↔ 1.2.x 完全互通(旧端无 caps 字段,双方退回旧行为),中继服务端无需同步升级。

工程化

  • 测试迁移 vitest — 纯逻辑套件与源码同置(foo.test.ts),72 个单测 / 8 文件 <1s;进程级/服务器级集成套件保留在 scripts/verify-*.mjs(分层:纯逻辑进单测,跨进程进脚本)
  • oxlint 接入(report-only 起步,.oxlintrc.jsonc)— 为后续 lint 门禁铺路
  • Windows verify 链修复 — pathToFileURL 处理 D:\ 盘符 URL(裸盘符路径会被解析为 URL scheme)、sleep(1) Windows 定时器钳制 ≈15.6ms、POSIX 权限位断言平台门控——全链现在 Windows 本机可跑
  • M-05 吞吐护栏 — verify 伞曾因机器资源挤占无限死等;现为 120s 硬顶 + 诊断输出(裸机实测 17.5 MiB/s,阈值 3 MiB/s)

文档与基础设施

  • 平台参考分册:windows-packaging.md(原生构建 + AV/EDR 行为红线)、vps-ops.md(部署/重启/配置所有权陷阱)、wire-compatibility.md(线协议变更流程)
  • 官网上线:vscode-ternimal.github.io(README + 仓库 About + package.json homepage 三处关联)
  • 打包防御:dist/ 残留构建产物显式排除(v1.2.1 曾因 Windows 构建机残留膨胀至 438MB,现结构性免疫)
  • 截图更新:same-session / web-mobile 高清化

质量门禁(发版时全绿)

vitest 72/72 · registry 8/8 · ws-protocol 18/18 · reconnect 8/8 · relay 14/14 · relay-e2e 13/13 · relay-matrix 6/6 · relay-admin 11/11 · relay-takeover 5/5 · relay-token 6/6

安装包与校验和

平台 文件 大小 MD5
Linux x64 (deb) ternimal_1.3.0_amd64.deb 75.0 MB a865a054209a3a5bb761840bbe25ab1d
Linux x64 (AppImage) Ternimal-1.3.0.AppImage 108.8 MB d58fde1e1b73e69d0ce51a67a6cdb6d0
Windows x64 Ternimal Setup 1.3.0.exe 83.1 MB 846337f6a9bf4936f73ecc96e6811c61

升级建议

  • 所有用户可平滑升级;网页端无需任何操作
  • 1.3.0 主机与 1.2.x 客户端混布完全兼容(caps 自动降级)

完整变更:v1.2.1...v1.3.0

Ternimal v1.2.1 — 中继稳定性 + 全面安全审计

Choose a tag to compare

@eathard eathard released this 14 Sep 02:36

Release v1.2.1 — 中继稳定性 + 全面安全审计

代码: tag v1.2.1(06a2824) · 验证: 全矩阵 16 套件绿(relay 14+e2e 13+matrix 6+admin 11+takeover 5+token 6+崩溃安全 5+风暴 5+geo 14+m1/m3/m4/softkeys)+ 生产 VPS 实测

新增

  • B+ 流动式几何所有权 —— 终端尺寸随「活动端」流动:手机专注时自动适配手机(5s 防抖驻留),桌面聚焦/本地调整即回收;适配芯片可强制接管/释放;服务端 GeoArbiter 单一裁定(14/14 验证)
  • ⚙ 设置面板右下角版本号 —— package.json 单源,滚动不漂移
  • 查看二维码/链接按钮 —— 撤销旁即看即用;带时间戳防缓存

中继稳定性(两起生产事故闭环)

  • 「中继连接中断,正在自动重连…」死循环根除:陈旧令牌页烧锁(4002)曾被当瞬态无限重连并持续给宿主锁定窗续期;现错误帧 4002/4005 → 终态 denied 卡片,且重试计数只在认证成功时清零(多层:错误帧门 + denied 短路 + 关闭码语义透传 4001/4002/4005)
  • 认证窗口自爆修复:业务帧在 join→auth-ok 期间发送会被宿主杀连接;现统一入 outbox 认证后冲洗(join/auth-response 控制帧豁免)

全面安全审计(48 项:P0×6 / P1×12 / P2×17 / P3×13)

  • P0:中继坏帧崩溃面(ws error 兜底)、认证前窗口会话元数据泄露(零知识修复)、XFF 首值伪造(改末值)、URL 片段令牌驻留(即清 + sessionStorage 刷新恢复)
  • P1:管理 API 自锁、限流记录无限增殖、preload 裸 IPC 桥删除、远程 create shell/cwd 白名单、口令解压封顶(zip 炸弹)、force 申请限流、退出清理保证
  • P2:子码哈希索引 O(1)、config 损坏拒启、异步 scrypt、resize 上界钳制、证书过期自愈、托盘/日志令牌脱敏、CSP 收紧 + 反点击劫持、E2EE 派生竞态、断线期输出补齐
  • P3:死代码清扫、ResizeObserver 泄漏、CSV 公式注入、错误路径 textContent 化

已知边界

  • 手机端旧标签页需关闭重开(内存中旧 bundle 不含修复,重载即生效)
  • 中继用量/子码仍为内存态(重启清空,v1.3 backlog 持久化)

安装包

平台 产物 说明
Windows x64 Ternimal Setup 1.2.1.exe Windows 原生构建(node-pty 预编译)
Linux deb ternimal_1.2.1_amd64.deb 已在本机安装验证
Linux AppImage Ternimal-1.2.1.AppImage 免安装

升级提示:v1.2.0 → v1.2.1 直接覆盖安装;子码与通道无需重发。

Ternimal v1.2.0

Choose a tag to compare

@eathard eathard released this 11 Sep 17:34

Release v1.2.0 — 一贴即配(tconf_v1 混合口令)

代码: tag v1.2.0(21588f1) · 验证: verify 伞 82 项全绿(relay 55 + m1/m3/m4/softkeys)+ instances 5/5 + smoke-e2e ALL PASS
双端实测: Linux deb 与 Windows NSIS 均完成打包安装 + CDP 真机全旅程

新增

  • 混合口令一键配置(tconf_v1) —— 面向国内「裸 IP + 自签 CA」常态:
    • 管理页一次性绑定对外地址 + CA 公钥;签发主码即自动附带混合口令(地址+主码+CA 压缩编码,~1KB,微信可传,尾部校验和防截断)
    • App ⚙ 面板顶部粘贴框:粘贴 → 解析预览(掩码主码/证书指纹)→ 应用并连接;CA 自动落盘 userData/certs,用户全程不接触证书文件
    • 既有主码可在管理页行内「口令」按钮补铸;手动三件套入口保留(自建/域名用户)
    • B-09 6/6(往返/防篡改/绑定持久化/未知主码 404/签发即口令/管理鉴权)
  • 管理页「下载为txt」 —— 口令可下载为带使用说明的 txt 文件(口令独占一行),微信发文件不怕长文本被流打断
  • 文档 —— README 中英亮点补全中继特性;docs/relay-help.md 买家 FAQ + 卖家发货动线;docs/vps-ops.md 生产运维手册(含 sudo 属主雷修复)

修复与改进

  • 混合口令应用即自动回填全部字段并连接(原需手动保存)
  • VPS 运维:sudo CLI 重写配置属主导致服务静默回退默认值的故障已修复并文档化

已知边界

  • 口令敏感度≈主码(base64 非加密),仅经购买渠道传输
  • 中继用量/子码为内存态,重启清空(v1.1 backlog 持久化)

安装包

平台 产物 位置
Windows x64 Ternimal Setup 1.2.0.exe(83MB) Windows 构建机 C:\Users\zz\ternimal-build\release\(已静默安装至测试机)
Linux deb ternimal_1.2.0_amd64.deb 本机 release/(已安装)
Linux AppImage Ternimal-1.2.0.AppImage 本机 release/

Ternimal v1.1.0 — remote layer, soft keyboard, open-source readiness

Choose a tag to compare

@eathard eathard released this 09 Sep 04:18

Ternimal v1.1.0 — first stable release

A multi-tab terminal that shares its sessions with any browser on your LAN:
scan a QR code and your phone is attached to the same tabs the desktop
window shows — sessions survive every disconnect.

Built for the AI-agent era: run Claude Code (or any CLI) on the desktop,
supervise it from the couch.

Highlights

  • Scan-to-sign-in — per-launch 192-bit access token carried in the URL
    fragment (never sent to the server, never logged); tray shows the QR code;
    rotating the token kills all sessions instantly
  • Shared sessions, zero client install — local Electron window and LAN
    browsers attach to the same PTY sessions over HTTPS; ring-buffer replay
    rehydrates scrollback on re-attach
  • Mobile soft keyboard — draggable floating bar: sticky Ctrl/Alt/Shift
    (arbitrary combos, one-shot), Esc/Tab, ↑↓←→ following the terminal's
    cursor mode — Ctrl+C, readline meta-jumps and vim navigation from a phone
  • Privacy-first networking — self-signed TLS with SHA-256 fingerprint on
    both the sign-in page and the tray (anti-MITM), LAN/VPN only by design,
    per-IP rate limiting, hardened cookies
  • i18n zh/en following system locale (TERNIMAL_LOCALE override)

Install (Linux)

  • AppImage Ternimal-1.1.0.AppImage — chmod +x and run
  • deb ternimal_1.1.0_amd64.deb — sudo apt install ./ternimal_1.1.0_amd64.deb

From source:

npm install --include=dev && npm run rebuild && npm run dev

Security note

Ternimal serves a shell over the network — LAN/VPN only, do not
port-forward it to the internet. Sessions/auth are in-memory; restarting
revokes everything.

Verification

  • npm run verify umbrella: 53/53 (ring buffer, registry, auth+cert+config,
    WS protocol, reconnect, soft-keys + i18n)
  • smoke-e2e (real Electron + real bash + TLS): ALL PASS
  • browser-e2e (real Chrome): 21/21 — login → tabs → typing → real Ctrl+C
    interrupt → arrow navigation → drag persistence → reload semantics

Ternimal v1.0.0

Choose a tag to compare

@eathard eathard released this 09 Apr 06:31

Ternimal v1.0.0

Standalone terminal emulator built with xterm.js + node-pty, based on VS Code terminal architecture.

Features

  • Multi-tab terminal sessions
  • WebGL-accelerated rendering (with DOM fallback)
  • In-terminal search (Ctrl+Shift+F)
  • Dark/Light theme toggle (Ctrl+Shift+L)
  • Right-click copy/paste
  • Unicode 11, 256-color and truecolor support
  • 5000-line scrollback buffer

Downloads

Platform File How to install
Windows Ternimal.Setup.1.0.0.exe 双击安装
Linux (AppImage) Ternimal-1.0.0.AppImage chmod +x && ./Ternimal-1.0.0.AppImage
Linux (deb) ternimal_1.0.0_amd64.deb sudo dpkg -i ternimal_1.0.0_amd64.deb

Keyboard Shortcuts

Shortcut Action
Ctrl+Shift+T New tab
Ctrl+W Close tab
Ctrl+Tab Switch tab
Ctrl+Shift+F Search
Ctrl+Shift+L Toggle theme