@wendongfly/myhi
v1.0.120
Published
Web-based terminal sharing with chat UI — control your terminal from phone via LAN/Tailscale
Maintainers
Readme
myhi
基于 Web 的终端共享工具 —— 通过局域网或 Tailscale 在手机、平板等设备上安全访问和控制你的终端,无需中继服务器。
特性
- 双前端界面 —— 聊天对话式 UI(适合手机触屏)和 xterm.js 全功能终端
- 设备控制权切换 —— 多设备同时观看,单设备独占输入,支持接管与释放
- AI Agent 集成 —— 内置 Claude Code CLI,Web 界面中直接与 AI 对话编程、审批文件变更
- 角色权限管理 —— admin / operator / viewer 三级角色,多种认证模式
- 多用户隔离 —— 独立用户目录、独立 Git 配置,支持独占模式
- SSH 开发账号 —— 为每个用户创建独立的 SSH 账号,VS Code Remote-SSH 远程开发
- Git 一键提交 —— 内置 Git 提交推送功能,支持每个项目独立的 GitLab 账号
- 自动更新 —— Web 界面检测新版本,一键更新服务器
- 会话持久化 —— 会话断线重连、服务重启自动恢复
- 零配置启动 —— 一条命令启动,自动创建会话并附加终端
- 局域网 / Tailscale —— 自动检测网络,点对点直连,QR 码快速连接
- PWA 支持 —— 可添加到手机主屏幕,原生应用体验
安装
npm install -g @wendongfly/myhi需要 Node.js >= 18。
快速开始
# 前台启动(自动创建会话并附加终端)
myhi
# 后台守护进程模式
myhi -d
# 指定端口
myhi -p 8080启动后,终端会输出访问地址和 QR 码。在同一局域网内的手机浏览器扫码或输入 http://<你的IP>:12300 即可访问。
首次启动会在 ~/.myhi/password 生成一个 4 位数默认密码,终端中会显示。
CLI 命令
服务器管理
myhi # 前台启动服务器
myhi -d / --daemon # 后台守护进程启动
myhi -p 8080 # 指定端口
myhi stop # 停止后台进程
myhi restart # 重启后台进程
myhi status # 查看运行状态
myhi log [N] # 查看最近 N 行日志(默认 50)会话操作
myhi attach # 交互式选择会话并附加
myhi attach <id> # 附加到指定会话
myhi attach --new # 创建新会话并附加
myhi kick # 交互式踢出用户附加会话后按 Ctrl+] 可安全断开。
用户管理
myhi user list # 列出所有用户
myhi user add <密码> <名称> <目录> # 添加用户
myhi user remove <密码> # 删除用户
myhi exclusive on|off # 开启/关闭独占模式SSH 开发账号
为 myhi 用户创建系统 SSH 账号,员工可通过 VS Code Remote-SSH 远程开发,每人只能访问自己的项目目录(支持 Windows 和 Ubuntu)。
myhi ssh add <用户名> [密码] # 创建 SSH 账号(绑定到 myhi 用户的项目目录)
myhi ssh list # 列出所有 SSH 账号
myhi ssh remove <用户名> # 删除 SSH 账号(保留项目目录)示例:
# 1. 先添加 myhi 用户
myhi user add 1234 张三 /data/projects/zhangsan
# 2. 为他创建 SSH 账号
myhi ssh add 张三 sshpass123
# 输出:
# ✓ SSH 账号创建成功!
# │ SSH 用户名: myhi-zhangsan
# │ SSH 密码: sshpass123
# │ 项目目录: /data/projects/zhangsan目录隔离:
| 平台 | 隔离方式 |
|------|---------|
| Windows | NTFS 权限:上级目录仅允许穿越,子目录完全控制 |
| Ubuntu | chmod 711 上级目录 + chmod 700 用户目录 + chown |
员工在 VS Code 中连接后打开 ~/project 即可开发,无法查看其他用户的文件。
远程附加
# 连接到远程服务器的会话
MYHI_SERVER=http://192.168.1.100:12300 myhi attach环境变量
| 变量 | 默认值 | 说明 |
|------|--------|------|
| PORT | 12300 | 监听端口 |
| HOST | 0.0.0.0 | 监听地址 |
| MYHI_AUTO_ATTACH | 1 | 启动时自动打开本地终端窗口并附加会话 |
| MYHI_CWD | 当前目录 | 新建会话的工作目录 |
| MYHI_SERVER | http://localhost:PORT | attach 客户端连接的服务器地址 |
界面说明
仪表盘(/)
会话列表页面,显示所有终端和 Agent 会话:
- 实时状态(运行中 / 已退出 / 模式)
- 在线观看人数
- 控制权状态指示
- 快捷操作:打开、删除、重命名、踢出用户
- 新建 PTY 会话或 AI Agent 会话(支持文件夹选择器)
- 用量统计(7 天活动数据)
- 版本更新提示 —— 检测到新版本时显示更新横幅,一键更新
聊天模式(/terminal/:id)
对话式界面,主要为手机优化:
- 用户消息 vs AI 回复的对话气泡
- ANSI 48 色彩色终端输出渲染
- Markdown 渲染(加粗、代码块、列表)
- 工具调用可视化(可折叠分组,支持一键展开/收起全部)
- AI 思考过程(可展开查看)
- 文件差异查看器
- 权限请求卡片(允许 / 拒绝按钮)
- 图片上传(粘贴或选择,最大 20MB)
- 实时消息流式显示
- ESC 取消 —— Agent 处理中按 ESC 或点击停止按钮中断操作
- Git 提交 —— 快捷按钮一键提交代码到 GitLab,每个项目独立凭据
终端模式(/terminal-raw/:id)
完整的 xterm.js 终端:
- 全键盘操作支持
- 自动适配窗口大小
- 可点击的 URL 链接
- 完整的终端色彩和格式
登录页(/login)
- 密码输入认证
- 登录失败计数与锁定倒计时
- 独占模式下显示占用状态
认证系统
myhi 支持三种认证模式,按优先级依次检查:
1. 用户模式(users.json)
每个用户拥有独立密码、名称和工作目录:
// ~/.myhi/users.json
{
"users": {
"alice123": { "name": "Alice", "dir": "/home/alice/projects" },
"bob456": { "name": "Bob", "dir": "/home/bob/work" }
},
"exclusive": false
}通过 CLI 管理:myhi user add <密码> <名称> <目录>
独占模式(exclusive: true):同一时间只允许一个用户登录,其他用户需等待当前用户退出(2 分钟无连接自动释放)。
2. 角色模式(roles.json)
不同密码映射到不同角色:
// ~/.myhi/roles.json
{
"passwords": {
"1234": { "name": "管理员", "role": "admin" },
"5678": { "name": "开发者", "role": "operator" },
"0000": { "name": "观察者", "role": "viewer" }
}
}3. 默认密码模式
无配置文件时,使用 ~/.myhi/password 中的 4 位数密码,所有登录用户获得 admin 角色。
认证流程
- 浏览器访问 → 重定向到
/login - 输入密码 → 服务器验证(5 次失败锁定 IP 5 分钟)
- 验证通过 → 设置 HttpOnly Cookie(
myhi_sid,SameSite=Strict) - 后续请求自动携带 Cookie,7 天无活动自动过期
设备控制模型
每个会话同一时间只允许一个设备进行输入操作,其余设备为只读观察模式。
| 操作 | 说明 | |------|------| | 获取控制权 | 点击按钮或发送消息时自动获取 | | 释放控制权 | 主动释放或 5 分钟无输入自动释放 | | 强制接管 | admin 角色可强制从其他设备接管 | | 断线释放 | 控制者断开连接后立即释放 |
权限等级:admin(3) > operator(2) > viewer(1)
- admin:创建/删除会话、强制接管、浏览目录、踢出用户
- operator:获取控制权、输入命令
- viewer:只读观看
AI Agent 会话
myhi 集成了 Claude Code CLI,可以在 Web 界面中直接与 AI 进行编程协作。
工作方式
- 在仪表盘点击"新建 Agent 会话"
- 选择工作目录,创建 Agent 会话
- 在聊天界面中输入自然语言指令
- AI 以流式方式返回回复,包括:
- 文本回复 —— Markdown 格式
- 工具调用 —— 文件读写、命令执行等(可折叠查看,支持一键展开全部)
- 思考过程 —— AI 的推理过程(可展开)
- 权限请求 —— 需要你批准的操作(允许/拒绝按钮)
- 文件差异 —— 代码变更的 diff 视图
权限模式
Agent 会话支持三种权限模式,可在界面中切换:
| 模式 | 说明 |
|------|------|
| acceptEdits | 默认,自动批准文件编辑,其他操作需确认 |
| plan | 规划模式,AI 只分析不执行 |
| bypassPermissions | 信任模式,自动批准所有操作 |
中断与取消
- ESC 键 —— 在 Agent 处理中按 ESC 中断当前操作
- 停止按钮 —— Agent 忙时发送按钮自动变为红色停止按钮,点击取消
会话恢复
Agent 会话支持断线重连,重新打开时自动加载最近的对话历史(最多 500 条消息)。
Git 提交推送
聊天界面的快捷键栏提供**"提交"**按钮,一键将代码提交并推送到 GitLab/GitHub。
功能特点
- 每个项目独立凭据 —— 不同项目可使用不同的 GitLab 账号,互不干扰
- 凭据记忆 —— 勾选"记住"后自动回填仓库地址和用户名
- 自动初始化 —— 目录未初始化时自动执行
git init - 分支管理 —— 支持指定推送分支(默认 main)
凭据存储
每个项目的 Git 凭据存储在项目目录下,与系统全局 Git 配置隔离:
~/myhi/张三/
├── .gitconfig # 项目级 Git 配置(credential helper + user)
├── .git-credentials # 项目级凭据文件(仅本人可读)
└── ...自动更新
myhi 支持在 Web 界面中检测和执行版本更新。
- 仪表盘:页面加载时和每 10 分钟检查 npm 最新版本,有新版本时显示黄色更新横幅,点击"更新"按钮自动执行
npm install -g @wendongfly/myhi@latest - 聊天页:状态栏显示"有更新"提示,点击跳转到仪表盘执行更新
- 更新完成后服务器自动重启,页面自动刷新
安全特性
| 特性 | 说明 |
|------|------|
| HttpOnly Cookie | 防止 XSS 窃取会话 |
| SameSite=Strict | 防止 CSRF 攻击 |
| 一次性 Token | QR 码使用一次性 token,扫码后立即失效 |
| 登录限速 | 5 次失败锁定 IP 5 分钟 |
| Referrer-Policy | 防止 token 通过 Referer 头泄漏 |
| CORS 限制 | 仅允许局域网 (RFC1918) 和 Tailscale 网段 |
| 路径遍历防护 | 目录浏览接口阻止 .. 路径穿越 |
| 进程隔离 | 每个用户独立 Git 配置,防止凭据交叉 |
| SSH 目录隔离 | NTFS/chmod 权限确保用户只能访问自己的项目目录 |
| 环境变量清理 | PTY 进程剥离 Claude Code 相关变量,防止嵌套 |
网络与连接
局域网
启动后自动检测本机局域网 IP,在终端输出访问地址。同一 Wi-Fi / 有线网络下的设备直接访问。
Tailscale
自动检测 Tailscale IP(100.x.x.x),优先使用。通过 Tailscale 组网的设备可安全访问,无需端口转发或公网暴露。
QR 码
仪表盘页面提供 QR 码生成,手机扫码即可打开会话。QR 码中包含一次性认证 token,无需再次输入密码。
自动附加终端
启动时(MYHI_AUTO_ATTACH=1)会自动打开一个本地终端窗口并附加到会话:
- Windows:优先使用 Windows Terminal (wt.exe)
- macOS:通过 osascript 打开 Terminal.app
- Linux:依次尝试 gnome-terminal / xterm / konsole
数据目录
所有运行时数据存储在 ~/.myhi/,可跨重启持久化:
~/.myhi/
├── token # 主认证 token(32 位十六进制)
├── password # 默认 4 位数登录密码
├── users.json # 用户账号配置(可选,含 SSH 账号映射)
├── roles.json # 角色权限配置(可选)
├── sessions.json # 会话持久化(重启后自动恢复)
├── uploads/ # 通过 Web 上传的图片
├── daemon.pid # 守护进程 PID
└── daemon.log # 守护进程日志API 参考
HTTP 接口
| 路由 | 方法 | 认证 | 说明 |
|------|------|------|------|
| /login | GET | 否 | 登录页面 |
| /login | POST | 否 | 密码认证(有限速) |
| /logout | POST | 否 | 退出登录 |
| /api/status | GET | 否 | 登录状态查询 |
| / | GET | 是 | 仪表盘 |
| /terminal/:id | GET | 是 | 聊天式界面 |
| /terminal-raw/:id | GET | 是 | xterm.js 终端 |
| /api/sessions | GET | 是 | 会话列表 |
| /api/sessions | POST | 是 | 创建会话 |
| /api/sessions/:id | DELETE | 是 | 删除会话 |
| /api/claude-sessions | GET | 是 | 可导入的 Claude 会话列表 |
| /api/dirs | GET | 是 | 目录浏览(仅 admin) |
| /api/me | GET | 是 | 当前用户信息 |
| /api/usage | GET | 否 | AI 用量统计 |
| /api/version | GET | 是 | 版本信息(当前版本 + 最新版本) |
| /api/update | POST | 是 | 触发自动更新(仅 admin) |
| /api/git/info | GET | 是 | 获取项目 Git remote 信息 |
| /api/git/push | POST | 是 | Git 提交并推送 |
| /upload | POST | 是 | 图片上传(最大 20MB) |
| /qr/:sessionId | GET | 是 | QR 码 SVG(一次性 token) |
Socket.IO 事件
会话管理
| 事件 | 方向 | 说明 |
|------|------|------|
| join(sessionId) | 客户端→服务器 | 加入会话,接收历史和滚动缓冲区 |
| joined(data) | 服务器→客户端 | 加入确认,返回会话数据和用户角色 |
| create(opts, ack) | 客户端→服务器 | 创建 PTY 会话 |
| create-agent(opts, ack) | 客户端→服务器 | 创建 Agent 会话 |
| kill(sessionId) | 客户端→服务器 | 删除会话(仅 admin) |
| rename({sessionId, title}) | 客户端→服务器 | 重命名会话 |
| sessions(list) | 服务器→客户端 | 会话列表广播 |
终端 I/O
| 事件 | 方向 | 说明 |
|------|------|------|
| input(data) | 客户端→服务器 | PTY 输入(需控制权) |
| output(data) | 服务器→客户端 | PTY 输出 |
| resize({cols, rows}) | 客户端→服务器 | 终端尺寸调整 |
| session-exit({code}) | 服务器→客户端 | 会话进程退出 |
AI Agent
| 事件 | 方向 | 说明 |
|------|------|------|
| agent:query({prompt}) | 客户端→服务器 | 发送 AI 查询(需控制权) |
| agent:message(msg) | 服务器→客户端 | 流式消息(文本/工具/思考/权限) |
| agent:busy(bool) | 服务器→客户端 | AI 处理状态 |
| agent:history([msgs]) | 服务器→客户端 | 历史消息回放 |
| agent:interrupt() | 客户端→服务器 | 中断当前 AI 操作 |
| agent:permission({requestId, allow}) | 客户端→服务器 | 批准/拒绝权限请求 |
| agent:error({message}) | 服务器→客户端 | 错误通知 |
控制权
| 事件 | 方向 | 说明 |
|------|------|------|
| take-control | 客户端→服务器 | 请求控制权 |
| release-control | 客户端→服务器 | 释放控制权 |
| control-changed | 服务器→客户端 | 控制权变更广播 |
| control-denied({reason}) | 服务器→客户端 | 控制权被拒绝 |
| set-mode({mode}) | 客户端→服务器 | 设置 Agent 权限模式 |
| kick-user({socketId}) | 客户端→服务器 | 强制断开用户 |
| list-viewers(ack) | 客户端→服务器 | 获取在线用户列表 |
使用场景
远程终端访问
开发者在电脑上启动 myhi,用手机在任何地方查看和控制终端。适合:
- 离开工位时查看长时间运行的任务
- 在沙发上用手机 review 日志
- 通过 Tailscale 安全地远程操作服务器
多人协作
团队成员共同查看同一个终端会话:
- Pair programming:一人输入,多人观看
- 演示和教学:admin 控制,学员观看
- 故障排查:多人同时查看错误日志,按需切换控制权
AI 辅助编程
在手机上通过 Agent 会话与 Claude 协作:
- 用自然语言描述需求,AI 自动编写代码
- 查看文件差异,审批变更
- 随时随地进行代码审查和修改
团队服务器管理
为团队提供受控的服务器访问:
- 每人独立账号和工作目录
- SSH 账号支持 VS Code Remote-SSH 远程开发
- 权限分级(admin 全权限,viewer 只读)
- 独占模式防止操作冲突
- admin 可审计在线用户并踢出
- 每个项目独立的 Git 凭据,一键提交到 GitLab
技术架构
┌──────────────────────────────────────────────────┐
│ 客户端(浏览器 / CLI attach) │
│ ┌────────────┐ ┌─────────────┐ ┌────────────┐ │
│ │ chat.html │ │terminal.html│ │ attach.js │ │
│ │ (ansi_up) │ │ (xterm.js) │ │ (raw tty) │ │
│ └─────┬──────┘ └──────┬──────┘ └──────┬─────┘ │
└────────┼────────────────┼────────────────┼───────┘
│ Socket.IO │ │
┌────────┼────────────────┼────────────────┼───────┐
│ 服务器 (Express + Socket.IO) │
│ ┌─────┴────────────────┴────────────────┴─────┐ │
│ │ server.js │ │
│ │ HTTP 路由 · 认证中间件 · 事件处理 │ │
│ └──────┬──────────────────────────┬───────────┘ │
│ ┌──────┴──────┐ ┌──────┴──────┐ │
│ │ sessions.js │ │ agent.js │ │
│ │ PTY 会话 │ │ Claude CLI │ │
│ │ node-pty │ │ stream-json │ │
│ └─────────────┘ └─────────────┘ │
└──────────────────────────────────────────────────┘- 运行时:Node.js >= 18(ES Modules)
- 后端:Express.js HTTP 服务 + Socket.IO 实时通信
- 终端:node-pty 创建伪终端进程,100KB 循环滚动缓冲区
- 前端:原生 JavaScript(无框架),xterm.js + ansi_up 双渲染引擎
- AI:Claude Code CLI
--output-format stream-json模式,惰性启动进程 - 构建:ncc 打包 + esbuild 压缩 → 单文件
dist/index.js
开发
git clone <repo-url>
cd myhi
npm install
npm run dev # 开发模式,文件变更自动重载
npm run build # 构建到 dist/
npm start # 运行构建产物项目结构
myhi/
├── bin/myhi.js # CLI 入口:命令解析与分发(含 ssh 子命令)
├── src/
│ ├── server.js # 主服务器:路由、Socket.IO、认证、Git API
│ ├── sessions.js # 会话管理:PTY、Agent、持久化
│ ├── agent.js # Claude Code CLI 集成
│ ├── roles.js # 角色与用户管理
│ └── attach.js # CLI 附加客户端
├── public/
│ ├── index.html # 仪表盘(含版本更新检测)
│ ├── chat.html # 聊天式界面(含 Git 提交、ESC 取消)
│ ├── terminal.html # xterm.js 终端
│ ├── login.html # 登录页
│ └── lib/ # xterm.js 等前端库
├── scripts/build.js # 构建脚本
└── dist/ # 构建产物许可证
MIT
