npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@fengye404/termpilot

v0.6.10

Published

一个基于 tmux 的终端会话跨端查看与控制原型。

Downloads

4,121

Readme

TermPilot

English | 简体中文

npm version npm downloads GitHub Actions

让同一条受管理终端会话在电脑和手机之间持续可见、可控制。

TermPilot 是一个本地优先的终端会话共享工具,方便你从手机继续访问电脑上已经运行中的受管理会话,同时把会话内容保留在本机。

[!TIP] 文档站: TermPilot Docs · 快速开始 · 部署指南 · Agent 运维 · 故障排查 · CLI 参考

[!IMPORTANT] TermPilot 不会自动导入任意 Terminal 或 iTerm 标签页。只有由 TermPilot 创建或管理的会话,才能在手机端继续访问。

它是什么

TermPilot 围绕一条很明确的主路径设计:

  • 电脑上已经有一条受管理会话在运行
  • 你离开了工位
  • 你仍然想在手机上继续接入这条原会话

这条会话可以是 Claude Code、部署流程、迁移任务,或者任何长期运行的终端任务。整个产品围绕同一条会话在多端之间持续可达来设计。

架构

手机浏览器 / PWA  -- https / wss -->  relay  <-- ws / wss -- 电脑上的 agent
                                                   |
                                                   +-- 配对、授权路由、
                                                       审计元数据、Web UI

运行时由三部分组成:

  • relay: HTTP + WebSocket 入口,负责 Web UI 托管、配对、权限控制和加密信封转发
  • agent: 跑在电脑上的守护进程,负责管理本地会话,并把敏感会话数据留在端侧
  • app: 由 relay 提供的移动端 Web UI

当前模型

  • 一个统一 CLI,同时提供 relay、agent 和会话管理命令
  • 基于 tmux 的受管理会话,输出回放由 agent 提供
  • 本地优先的会话状态模型,会话标题、cwd、状态细节和终端输出保留在 agent 所在电脑
  • 设备级配对与授权模型,用于浏览器与 agent 之间的加密通信
  • relay 持久化默认只保留配对、grant 与审计元数据,长期运行默认使用 SQLite,也可通过 DATABASE_URL 切换到 PostgreSQL
  • 一个面向移动端的 Web UI,聚焦查看、轻输入和快捷控制
  • 页面在后台时,浏览器可对设备离线、会话退出和疑似残留会话发出提醒
  • 输出同步采用自适应轮询:活跃会话保持更快刷新,长期无人附着的托管命令会话会自动降频
  • 托管命令会话带有轻量残留治理,会自动回收长期无人附着且无输出的会话

这是一条刻意收窄的产品边界,重点放在会话连续性和多端接入体验上。

如果你是从旧版本升级、且本地绑定里还没有本地密钥,需要重新配对一次。

快速开始

如果你更希望按文档站的分层路径阅读,而不是直接从仓库首页一路往下看,可以从这里进入:

环境要求

服务器和电脑都需要:

  • Node.js 22+
  • @fengye404/termpilot

电脑还需要:

  • tmux

安装:

npm install -g @fengye404/termpilot

1. 启动 relay

在服务器或一台手机可访问的机器上执行:

termpilot relay

常用变体:

termpilot relay start
termpilot relay stop
termpilot relay run

默认情况下,relay 会后台启动,监听 0.0.0.0:8787,同时提供 Web UI 和 /ws,并把 relay 元数据持久化到 ~/.termpilot/relay.db

2. 启动 agent

在你的电脑上执行:

termpilot agent

首次运行时,agent 会询问 relay 主机和端口,然后:

  • 保存本地配置
  • 启动后台守护进程
  • 打印一次性配对码

如果你希望 agent 长期常驻,更推荐交给系统进程管理器托管:

termpilot agent --foreground --relay wss://your-domain.com/ws

3. 手机完成配对

在手机浏览器打开:

  • http://your-domain.com:8787
  • 或反向代理后的 https://your-domain.com

输入电脑端打印出来的配对码,随后进入该设备的会话列表。

4. 启动受管理会话

如果你主要跑 Claude Code:

termpilot claude code

如果你要跑其他托管命令:

termpilot run -- opencode

如果你想先创建一条普通 shell 会话:

termpilot create --name my-task --cwd /path/to/project

然后再显式接入它:

termpilot list
termpilot attach --sid <sid>

如果你只记一条规则,记这个就够了:

  • termpilot run -- <command> 表示“围绕这个命令启动一条受管理会话”
  • termpilot create + termpilot attach 表示“先建一条普通 shell 会话,再按需回到它”

本地开发测试流程

如果你是在当前仓库里迭代开发,最好不要把本地开发运行和全局 npm 安装的 termpilot、以及默认的 ~/.termpilot 状态目录混在一起。

先把下面这段加到 ~/.zshrc

tpdev() {
  local root="/Users/fengye/workspace/TermPilot"
  local home="/tmp/termpilot-local"
  local cmd="${1:-help}"

  if [ "$#" -gt 0 ]; then
    shift
  fi

  case "$cmd" in
    help|-h|--help)
      cat <<'EOF'
tpdev build
tpdev reset
tpdev fresh
tpdev refresh
tpdev relay ...
tpdev agent ...
tpdev claude code
tpdev run -- <command>
EOF
      ;;
    build)
      (cd "$root" && pnpm build)
      ;;
    reset)
      (cd "$root" && TERMPILOT_HOME="$home" pnpm local:reset)
      ;;
    fresh|refresh)
      (cd "$root" && pnpm build && TERMPILOT_HOME="$home" pnpm local:reset)
      ;;
    *)
      (cd "$root" && TERMPILOT_HOME="$home" node dist/cli.js "$cmd" "$@")
      ;;
  esac
}

然后重新加载 shell:

source ~/.zshrc

之后就按这套本地专用链路跑:

tpdev fresh
tpdev relay run
tpdev agent --relay ws://127.0.0.1:8787/ws --pair
tpdev claude code

如果你改了代码,推荐先跑 tpdev fresh,因为 tpdev relay ...tpdev agent ... 走的仍然是已经构建好的 dist/cli.js

tpdev refresh 也可以用,它是 tpdev fresh 的别名。

如果本地调试过程中 relay、agent、tmux 会话或者状态目录已经变乱了,可以直接一键重置:

tpdev reset

这条命令会停止 /tmp/termpilot-local 这套本地开发环境里的 agent 和 relay,清掉该状态目录里记录的 tmux 会话,并删除整个目录本身。

这套方式的好处是:

  • 使用的是当前仓库构建出来的 CLI,而不是全局 npm 安装版本
  • 本地状态目录固定隔离在 /tmp/termpilot-local
  • 可以直接对着 http://127.0.0.1:8787 做浏览器测试,不用先发 npm 包

如果你要启动别的托管命令,也可以直接:

tpdev run -- <command>

CLI 参考

termpilot relay
termpilot relay stop
termpilot relay run

termpilot agent
termpilot agent --pair
termpilot agent status
termpilot agent stop

termpilot pair
termpilot create --name my-task --cwd /path/to/project
termpilot list
termpilot attach --sid <sid>
termpilot kill --sid <sid>
termpilot grants
termpilot audit --limit 20
termpilot revoke --token <accessToken>
termpilot doctor

termpilot claude code
termpilot run -- <command>

配置

默认本地状态目录:

~/.termpilot

常见文件:

  • config.json: agent 保存的 relay 配置
  • agent-runtime.json: 后台 agent 运行状态
  • relay-runtime.json: 后台 relay 运行状态
  • state.json: 本地受管理会话状态
  • device-key.json: agent 本地设备密钥
  • agent.log / relay.log: 日志

常用环境变量:

  • TERMPILOT_HOME
  • TERMPILOT_RELAY_URL
  • TERMPILOT_DEVICE_ID
  • TERMPILOT_AGENT_TOKEN
  • TERMPILOT_RELAY_STORE
  • TERMPILOT_SQLITE_PATH
  • TERMPILOT_ORPHAN_WARNING_MS
  • TERMPILOT_MANAGED_SESSION_AUTOCLEANUP_MS
  • HOST
  • PORT
  • DATABASE_URL
  • TERMPILOT_PAIRING_TTL_MINUTES

托管命令自动治理默认值:

  • TERMPILOT_ORPHAN_WARNING_MS: detached 且无输出的预警阈值,默认 3600000(1 小时)
  • TERMPILOT_MANAGED_SESSION_AUTOCLEANUP_MS: detached 且无输出的自动清理阈值,默认 43200000(12 小时)

relay 存储默认值:

  • TERMPILOT_RELAY_STORE: 默认 sqlite,可显式设成 memory
  • TERMPILOT_SQLITE_PATH: SQLite 文件路径,默认 ~/.termpilot/relay.db

示例:

TERMPILOT_HOME=/data/termpilot termpilot agent
TERMPILOT_RELAY_URL=wss://your-domain.com/ws termpilot agent
HOST=0.0.0.0 PORT=8787 termpilot relay

部署说明

如果只是快速试通:

  • 在一台可访问机器上直接运行 termpilot relay
  • 手机上打开 http://your-ip:8787
  • 让 agent 连接 ws://your-ip:8787/ws

如果准备长期使用:

  • 在服务器上运行 termpilot relay
  • 前面放一个反向代理
  • 手机上使用 https://your-domain.com
  • agent 使用 wss://your-domain.com/ws
  • relay 元数据尽量放在 SQLite 或 PostgreSQL 上,而不是易失的内存存储

最小 Caddy 示例:

your-domain.com {
    reverse_proxy 127.0.0.1:8787
}

如果你想继续看更细的部署、运维和排障文档,可以直接进入:

relay Docker 镜像

直接使用已经发布好的 relay 镜像:

docker pull fengye404/termpilot-relay:latest

使用持久化卷启动:

docker run -d \
  --name termpilot-relay \
  -p 8787:8787 \
  -e TERMPILOT_AGENT_TOKEN=change-me \
  -v termpilot-relay-data:/var/lib/termpilot \
  fengye404/termpilot-relay:latest

容器内默认把 relay 元数据持久化到 /var/lib/termpilot/relay.db。如果你希望固定版本,可以改成 fengye404/termpilot-relay:0.3.9 这样的 tag。

非目标

TermPilot 明确不打算变成:

  • 远程桌面
  • 图形界面控制层
  • 任意现有终端标签页导入器
  • 完整终端日志归档系统
  • 通用型多租户运维平台

如果一个任务希望在手机端持续可见、可控制,就应该从一开始运行在 TermPilot 管理的会话里。

仓库结构

这个仓库是一个 pnpm workspace monorepo:

开发

本地运行:

pnpm install
pnpm dev:relay
pnpm dev:app
pnpm dev:agent

常用检查:

pnpm typecheck
pnpm build
pnpm test:ui-smoke
pnpm check:stability
pnpm test:isolation

文档