1. 项目概述:一个为“氛围编码者”打造的远程开发控制台
如果你和我一样,自诩为一名“氛围编码者”或“智能体工程师”,那你一定对下面这个场景深有体会:你正和你的AI编程伙伴(比如Claude或Codex)在终端里并肩作战,思路如泉涌,代码行云流水。突然,一个不得不离开电脑的时刻到了——可能是会议、通勤,或者只是想在沙发上换个姿势。那一刻,你看着屏幕上等待指令的AI,心里总会闪过一个念头:“要是能直接用手机接着干,该多好。”
这就是AgenticWormhole诞生的初衷。它不是一个云端SaaS,而是一个本地优先的控制平面。简单说,它在你本地开发机上运行一个轻量级服务器,然后为你提供一个可以通过手机或任何浏览器访问的Web界面。通过这个界面,你不仅能继续与Claude、Codex等AI模型对话,还能直接启动、停止、重启你的前后端应用服务,实时查看日志,甚至预览你的Web应用。你的AI智能体进程依然运行在本地真实的终端(PTY)里,这意味着所有终端特有的行为,比如ANSI彩色输出、进度条、甚至是某些依赖特定终端环境的工具(如一些MCP服务)都能完美工作。
这个项目的核心价值在于,它将你强大的本地开发环境“投射”到了一个轻便的访问层上,让你在保持本地开发全部优势(高速、无网络延迟、访问本地文件和服务)的同时,获得了前所未有的移动性和灵活性。无论是快速修复一个线上bug,还是利用碎片时间review AI生成的代码,你都不再被束缚在办公桌前。
2. 核心架构与设计哲学拆解
2.1 为什么是“本地优先”?
在云原生和SaaS大行其道的今天,AgenticWormhole坚持“本地优先”架构是一个值得深思的选择。这背后有几个关键考量:
- 数据安全与隐私:所有与AI的对话、执行的命令、产生的日志,都从未离开你的机器。这对于处理公司私有代码库或个人项目的开发者来说是底线要求。你不需要担心敏感代码片段被发送到第三方服务器。
- 极致的响应速度与零延迟:AI模型(如本地的Claude Desktop或Codex)与你的项目文件都在同一台机器上,通信是本地进程间通信,速度极快。Web UI与服务器之间在局域网内的通信延迟也远低于任何公网服务。
- 完整的本地环境访问:你的AI助手可以无缝调用你本地安装的所有CLI工具、SDK、数据库连接,就像你在本地终端里操作一样。这是云端编码环境难以比拟的优势。
- 成本与可控性:无需为云主机或容器服务付费,也无需管理复杂的网络配置。一切都在你熟悉的本地环境中。
这种设计哲学决定了它的技术栈:一个在本地运行的Node.js服务器作为中枢,一个React Web界面作为遥控器,两者通过WebSocket进行实时、双向通信。
2.2 核心组件交互解析
项目结构清晰地划分了职责:
server/(Node.js + TypeScript 运行时):这是项目的大脑。它做了三件核心事:- PTY桥接:利用
node-pty这个库,在本地创建一个“伪终端”。当你通过网页向AI发送命令时,实际上是这个PTY在模拟终端执行命令,并将输出流式传回网页。这保证了codex或claude这类CLI工具能以最自然的方式运行。 - WebSocket枢纽:所有连接的网页客户端和桥接的CLI客户端都通过WebSocket与服务器通信,实现实时消息推送(如日志、终端输出)和远程调用(如启动服务)。
- 服务运行器:根据配置文件,管理你前后端应用的启动、停止和清理命令。它本质上是一个进程管理器。
- PTY桥接:利用
web/(React + Vite UI):这是项目的脸面和控制台。它被设计为“手机优先”,意味着UI元素和交互都为大拇指操作优化。它通过WebSocket与服务器保持长连接,实时更新终端内容、日志和服务状态。- 根工作区 (npm workspaces):使用Monorepo模式管理
server和web两个包,方便共享配置和依赖,一键构建。
这种架构的精妙之处在于解耦:Web UI只负责展示和发送指令,繁重的终端执行和进程管理完全由本地Node服务承担,两者通过定义良好的协议通信。这使得Web UI可以做得非常轻量且响应迅速。
3. 从零开始部署与深度配置指南
3.1 环境准备与初次运行
假设你的开发机是macOS或Linux,并且已经安装了Node.js(建议LTS版本)和npm。Windows用户同样支持,但需确保使用PowerShell或CMD,并且node-pty原生模块能正常编译。
第一步:获取项目并安装依赖
# 克隆仓库 git clone https://github.com/schmidi000/agentic-wormhole.git cd agentic-wormhole # 安装项目依赖(利用workspace安装所有子包依赖) npm install这里有个细节:因为使用了npm workspaces,在根目录执行npm install会递归地为server和web两个子包安装它们各自的依赖。这比分别进入两个目录安装要方便得多。
第二步:核心配置文件剖析与定制配置文件是AgenticWormhole的灵魂。复制示例文件后,你需要深入理解并修改它:
cp AGENTIC_WORMHOLE_CONFIG.example.json AGENTIC_WORMHOLE_CONFIG.json用你喜欢的编辑器打开这个JSON文件。我们以一个典型的全栈Node.js项目为例,进行逐项解读:
{ “frontend”: { “cwd”: “../my-app/frontend”, // 前端项目相对路径 “startCommand”: “npm run dev -- --host 0.0.0.0 --port 5173”, // 关键:绑定到所有网络接口 “cleanCommand”: “npm ci”, // 通常用于依赖重装 “previewUrl”: “http://YOUR_LOCAL_IP:5173” // 预览地址,需替换为你的局域网IP }, “backend”: { “cwd”: “../my-app/backend”, “startCommand”: “npm run dev”, “cleanCommand”: “npm ci” }, “security”: { “listenHost”: “0.0.0.0”, // 服务器监听地址,0.0.0.0表示接受所有网络连接 “listenPort”: 8787, // 服务器端口 “accessToken”: “generate-a-very-strong-password-here!” // !!!必须修改!!! } }重要安全提示:
accessToken是你Web界面的唯一密码。绝对不要使用示例中的默认值。建议使用密码管理器生成一个高强度、随机的字符串。因为服务器监听在0.0.0.0,同一局域网内的任何设备都能尝试连接,强密码是首要防线。
关于previewUrl和startCommand的联动:这是实现手机预览Web应用的关键。前端开发服务器(如Vite、Next.js)默认通常只监听localhost或127.0.0.1,这意味着只有本机可以访问。为了让同一局域网下的手机能访问,必须在启动命令中显式指定--host 0.0.0.0。同时,previewUrl中的地址也需要从127.0.0.1改为你电脑在局域网中的实际IP地址(如192.168.1.100)。
第三步:构建与全局安装CLI
# 在项目根目录执行构建,这会编译TypeScript代码并打包Web资源 npm run build # 从npm全局安装CLI工具(推荐,最稳定) npm install -g agentic-wormhole全局安装后,你可以在任何目录使用agentic-wormhole命令。这个npm包已经包含了服务器和Web UI的所有资产。
第四步:启动服务并连接
启动服务器:首先,进入你的目标项目目录(即存放
AGENTIC_WORMHOLE_CONFIG.json的目录),然后运行:agentic-wormhole serve你会看到类似
Server listening on http://0.0.0.0:8787的输出。这意味着控制平面已经就绪。从手机访问:在你的手机浏览器中输入
http://<你的电脑局域网IP>:8787。例如http://192.168.1.100:8787。页面会提示你输入访问令牌,填入你在配置文件中设置的accessToken即可登录。桥接AI终端:这是让AI对话功能工作的关键一步。另开一个终端窗口,同样进入到你的目标项目目录,运行:
agentic-wormhole codex # 或 agentic-wormhole claude这个命令会启动一个本地进程,连接到刚才启动的WebSocket服务器,并将该终端会话“桥接”到Web界面。此时,你在手机Web界面的“Chat”标签页里,就能看到这个终端的实时输出,并可以输入命令与AI交互了。
3.2 高级配置:无缝集成到你的工作流
对于深度用户,AgenticWormhole提供了更丝滑的集成方案——终端钩子(Hooks)。
终端钩子的作用:安装钩子后,你在终端里直接输入codex或claude命令时,它会自动被agentic-wormhole桥接,而无需再手动输入agentic-wormhole codex。这极大地简化了工作流。
安装钩子(以Bash为例):
# 确保你在agentic-wormhole的项目目录下,并且已经构建过 eval “$(node server/dist/cli.js hooks bash)”这条命令会输出一些shell函数定义,eval会立即执行它们,将钩子注册到当前的shell会话中。为了方便,你通常会把这条命令加到你的~/.bashrc或~/.zshrc文件中,这样每次打开终端都会自动设置钩子。
钩子原理:它实际上为codex和claude命令创建了shell函数。当你输入codex时,这个函数会检查环境变量AGENTIC_WORMHOLE_BYPASS是否设置,如果没有,则转而执行agentic-wormhole codex,从而实现自动桥接。
临时绕过钩子:有时候你可能需要直接运行本地的codex命令(例如进行一些本地调试),这时可以:
AGENTIC_WORMHOLE_BYPASS=1 codex设置这个环境变量后,钩子函数就会跳过桥接,直接调用原始的codex命令。
4. 核心功能实战与场景化应用
4.1 服务管理:把手机变成开发运维遥控器
Web UI中的“Services”标签页是控制你应用生命周期的中枢。它的威力在于将原本需要在多个终端窗口里输入的命令,抽象成了手机上的几个按钮。
配置详解:服务管理完全依赖于配置文件中的frontend和backend区块。
startCommand:点击“Start”按钮时执行的命令。这里可以放任何启动脚本,比如npm run dev,docker-compose up,python app.py等。cleanCommand:点击“Clean”按钮时执行的命令。通常用于在启动前确保环境干净,例如npm ci(干净安装)或rm -rf node_modules && npm install(彻底重装)。cwd:命令执行的工作目录。这允许你将AgenticWormhole服务器运行在一个“控制中心”目录,而管理位于其他路径的项目。
实战场景:想象你正在户外,突然收到报警邮件说测试环境的后端服务挂了。你掏出手机,打开AgenticWormhole,进入Services页,点击后端服务的“Stop”,等待几秒确认进程终止,然后再点击“Start”。同时,你可以立刻切换到“Logs”标签页,实时观察服务启动日志,确认服务是否正常启动。整个过程无需打开电脑,也无需记忆复杂的SSH命令。
操作心得:
- 状态感知:UI上的“Start”/“Stop”按钮会根据服务的实际运行状态切换,避免误操作。
- 日志关联:在服务管理页面启动的服务,其所有标准输出和错误输出都会自动重定向到“Logs”标签页,方便集中查看。
- 谨慎使用“Clean”:“Clean”命令通常比较重(会重装依赖),可能会中断服务较长时间。建议在明确需要更新依赖或解决依赖冲突时才使用。
4.2 实时日志流:移动端的“tail -f”
“Logs”标签页提供了一个聚合的、可滚动的实时日志视图。所有通过AgenticWormhole启动的服务(前后端)以及桥接的AI终端输出,都会汇聚到这里。
技术实现:服务器端会捕获每个被管理进程的stdout和stderr流,并通过WebSocket实时推送到所有已连接的Web客户端。前端使用一个虚拟化的文本区域来渲染,即使日志量很大,也能保持流畅滚动。
使用技巧:
- 过滤与搜索:虽然当前MVP版本可能没有内置搜索过滤,但你可以利用浏览器的页面内搜索(Ctrl+F / Cmd+F)来查找关键错误信息。
- ANSI颜色支持:由于终端输出是原样传输,如果你的日志或CLI工具使用了ANSI转义码来显示颜色,那么在Web界面上也能看到彩色的输出,这对于识别错误级别(红色错误、黄色警告)非常友好。
- 清空日志:长时间运行后日志可能会很长,可以查找页面是否有“Clear”按钮,或者直接刷新页面来清空当前视图(注意:这不会停止日志流,新的日志会继续追加)。
4.3 Web应用预览:在手机上实时测试响应式布局
这是对前端开发者极具吸引力的功能。配置好frontend.previewUrl(指向你前端开发服务器的局域网可访问地址)后,Web UI的“Preview”标签页会内嵌一个iframe来加载这个URL。
关键配置步骤:
- 确保前端开发服务器监听在
0.0.0.0。以Vite为例,你的startCommand应该是:“npm run dev -- --host 0.0.0.0 --port 5173”。 - 找出你电脑的局域网IP(在macOS/Linux上可以用
ifconfig或ip addr,在Windows上用ipconfig)。 - 将配置中的
previewUrl设置为“http://<你的局域网IP>:5173”。
带来的便利:
- 真正的移动端测试:你直接在手机上操作你的Web应用,可以测试触摸交互、手势、移动端布局(CSS媒体查询)是否正常工作,这比浏览器开发者工具的模拟器要真实得多。
- 热重载同步:如果你的前端框架支持热模块替换(HMR),那么你在电脑上修改代码并保存后,手机上的预览页面也会自动刷新,实现真正的移动端实时调试。
- 脱离数据线:你不再需要将手机通过USB连接到电脑,并使用Chrome远程调试。一切都在Wi-Fi环境下完成。
4.4 AI编码会话桥接:永不间断的编程对话
这是项目的核心场景。通过“Chat”标签页,你桥接的AI终端会话会在这里显示。你可以像在本地终端一样输入命令,与Claude或Codex进行对话。
工作流程:
- 在电脑终端A运行
agentic-wormhole serve启动服务器。 - 在电脑终端B运行
agentic-wormhole claude桥接Claude会话。 - 在手机浏览器登录Web UI,进入“Chat”标签页。
- 现在,你可以在手机输入框里输入
帮我分析一下src/utils/errorHandler.js这个文件的逻辑,Claude会在你的电脑上读取该文件并生成分析,结果会实时显示在你的手机屏幕上。
优势与局限:
- 优势:会话状态完全保存在本地终端进程中。即使你关闭手机浏览器,AI对话历史依然在桥接的终端里,下次连接还能看到。
- 注意:这是一个单向桥接。Web UI是终端的一个“只读”视图加上一个输入通道。一些复杂的终端交互(如Vim的全屏编辑、需要响应特定终端序列的程序)可能无法完美呈现。但对于主要的AI对话(问答、代码生成)场景,完全足够。
5. 深入原理:PTY、WebSocket与服务管理
5.1 PTY桥接:如何在浏览器中“模拟”一个真终端
这是AgenticWormhole最具技术含量的部分。简单在子进程中运行命令(child_process.spawn)只能获取输出,但无法模拟一个完整的终端环境。许多CLI工具(包括一些AI助手)会检查它们是否运行在真正的TTY中,并据此改变行为(如输出颜色、交互式提示)。
node-pty库创建了一个“伪终端”(Pseudo Terminal, PTY)。PTY是一对主从设备:主端(我们程序控制)和从端(被启动的程序认为是它的终端)。当你在Web界面输入ls -la时:
- 字符通过WebSocket发送到服务器。
- 服务器将字符写入PTY的主端。
- PTY的从端将这些字符作为输入发送给正在运行的shell(或
claude命令)。 - Shell执行命令,将输出写入PTY的从端。
- PTY的主端读取到这些输出。
- 服务器通过WebSocket将输出推送到Web界面。
- Web界面将输出渲染到模拟的终端屏幕上。
这个过程完整地模拟了本地终端的所有特性,包括信号处理(如Ctrl+C)、终端尺寸调整等。
5.2 WebSocket通信协议:实时性的基石
HTTP协议不适合这种需要持续双向通信的场景。AgenticWormhole使用WebSocket在浏览器和服务器之间建立了一个全双工、低延迟的通信通道。
服务器维护了几个核心的WebSocket信道:
- 控制信道:用于传输UI指令,如“启动服务”、“停止服务”、“发送终端输入”。
- 数据广播信道:用于将终端输出、服务日志、系统状态等实时推送给所有已连接的客户端。
- 会话管理:管理多个桥接的终端会话,确保输入输出被路由到正确的PTY实例。
这种设计使得多个手机或浏览器可以同时连接到同一个AgenticWormhole实例,看到相同的实时日志和终端输出,非常适合团队协作或演示场景。
5.3 进程管理与状态同步
服务运行器(Service Runner)是一个小型的进程管理器。它负责:
- 启动进程:在指定的
cwd目录下,以子进程方式执行startCommand。 - 捕获输出:重定向子进程的
stdout和stderr到日志流。 - 维护状态:跟踪进程的PID,判断其是否存活。
- 优雅终止:当收到“Stop”指令时,首先发送SIGTERM信号请求进程退出,如果超时再发送SIGKILL强制终止。
状态同步是通过WebSocket实现的。当服务状态变化(如从“运行中”变为“已停止”)时,服务器会广播状态更新事件,所有在线的Web UI都会立即更新按钮状态和显示。
6. 故障排查与性能优化实战记录
即使设计再精良,在实际部署中也会遇到各种问题。以下是我在多次使用和部署AgenticWormhole后总结的常见问题与解决方案。
6.1 连接与访问问题
问题1:手机无法访问Web界面(连接被拒绝/无法连接)
- 检查防火墙:这是最常见的原因。确保你电脑的防火墙允许入站连接访问
8787端口(或你自定义的端口)。在macOS上,可以在“系统设置”->“网络”->“防火墙”中临时禁用或添加规则。在Linux上,可能需要使用ufw或iptables命令。 - 确认IP地址:确保你在手机浏览器中输入的是电脑正确的局域网IP,而不是
localhost或127.0.0.1。在电脑上使用ipconfig(Windows)或ifconfig/ip addr(Linux/macOS)查看Wi-Fi或Ethernet适配器的IPv4地址。 - 验证服务器运行:在电脑上确认
agentic-wormhole serve命令正在运行,并且没有报错退出。检查输出中是否显示Server listening on http://0.0.0.0:8787。
问题2:Web界面能打开,但终端是黑屏或没有响应
- 检查桥接会话:Web UI的“Chat”标签页内容依赖于一个活动的桥接终端会话。确保你已经在另一个终端中运行了
agentic-wormhole codex或agentic-wormhole claude。 - 切换标签页:官方文档中提到一个已知的UI渲染问题:如果终端黑屏,尝试切换到“Services”、“Logs”或“Preview”标签页,然后再切换回“Chat”,有时能触发重新渲染。
- 检查WebSocket连接:打开浏览器的开发者工具(F12),切换到“Network”标签页,过滤“WS”(WebSocket)。你应该能看到一个到
ws://your-ip:8787的连接。如果它没有建立,或者很快断开,可能是网络策略或代理问题。
6.2 服务管理与命令执行问题
问题3:服务启动失败,日志显示“命令未找到”
- 检查
cwd路径:配置文件中的cwd是相对路径,它是相对于AGENTIC_WORMHOLE_CONFIG.json文件所在目录进行解析的。确保路径正确。建议使用绝对路径以避免歧义。 - 检查命令可用性:
startCommand和cleanCommand中的命令(如npm,gradlew)必须在配置的cwd目录下可用。可以通过在对应目录下手动执行该命令来验证。 - 环境变量问题:通过
AgenticWormhole启动的进程,其环境变量继承自启动agentic-wormhole serve的那个shell环境。如果你在.bashrc中设置了PATH等变量,确保你是在登录shell中启动的服务,或者将必要的环境变量在配置中或启动脚本里显式设置。
问题4:前端预览页面无法加载(空白或连接错误)
- 确认前端服务器已监听
0.0.0.0:这是最关键的一步。检查你的前端startCommand是否包含了--host 0.0.0.0参数。不同的开发服务器参数可能不同(Vite用--host, Next.js用-H)。 - 检查端口和IP:确保
previewUrl中的IP和端口与前端开发服务器实际监听的地址一致。你可以在电脑上使用lsof -i :5173(macOS/Linux)或netstat -ano | findstr :5173(Windows)来查看哪个进程在监听该端口。 - 关闭电脑的防火墙(临时测试):有时防火墙会阻止不同设备间的访问。可以暂时关闭防火墙测试,如果成功,再配置详细的入站规则。
6.3 性能与稳定性优化建议
优化1:处理大量日志输出如果你的应用日志输出非常频繁,可能会对WebSocket传输和浏览器渲染造成压力。
- 服务器端日志限制:可以考虑修改服务器代码,为日志流添加一个缓冲区,当客户端跟不上时丢弃最旧的日志行,或者对日志进行采样。
- 客户端虚拟滚动:确保Web UI使用了虚拟滚动技术来渲染日志,只渲染可视区域内的行,这对性能提升巨大。
优化2:长时间运行的会话管理桥接的AI终端会话可能会运行很久,占用PTY资源。
- 会话保活:网络波动可能导致WebSocket断开,但PTY进程还在。服务器应实现重连机制,允许客户端重新连接到已有的PTY会话,而不是创建新的。
- 资源清理:在服务器代码中,需要监听进程退出和客户端断开事件,及时清理僵尸PTY进程,防止资源泄漏。
优化3:安全加固
- 定期更换Token:将
accessToken视为重要密码,定期更换。 - 使用HTTPS(高级):在公网或不可信网络中使用时,应考虑使用反向代理(如Nginx)为
AgenticWormhole的HTTP服务添加HTTPS加密,避免Token在传输中被窃听。 - IP白名单(可选):如果你熟悉Node.js,可以修改服务器代码,增加基于IP的简单访问控制,只允许特定IP段的设备连接。
7. 扩展思路与自定义开发
AgenticWormhole的MVP版本已经搭建了一个强大的框架,你可以基于它进行扩展,以适应更复杂的工作流。
思路1:集成更多开发工具
- 数据库客户端:桥接
psql、mysql或mongosh会话,让你能在手机上直接查询和操作开发数据库。 - 容器管理:将
docker或kubectl命令桥接进来,实现移动端的容器和集群管理。 - 系统监控:在Web UI中增加一个面板,显示系统资源(CPU、内存、磁盘)使用情况,集成
htop或glances的输出。
思路2:增强AI协作功能
- 多会话管理:当前似乎只支持一个桥接的AI会话。可以扩展为支持多个并行会话,并在UI上提供标签页切换,方便同时与Claude和Codex对话,或者进行不同的任务。
- 会话模板与上下文持久化:为常见的开发任务(如“代码审查”、“API设计”、“Debug”)创建会话模板,自动加载相关的系统提示词和上下文文件。
- 代码片段与命令收藏:将常用的AI指令或生成的代码片段保存下来,方便快速复用。
思路3:改进UI/UX
- 移动端键盘优化:为终端输入设计更友好的移动端虚拟键盘布局,增加常用符号(
/,-,*,|)和组合键(如Ctrl+C)的快捷按钮。 - 离线支持:使用Service Worker缓存Web UI的静态资源,这样即使服务器短暂中断,也能加载出界面。
- 主题与可访问性:增加深色/浅色主题切换,并确保终端色彩对比度满足可访问性标准。
参与这个项目的开发本身也很简单。项目使用TypeScript,结构清晰。在根目录运行npm run dev会同时启动开发服务器(端口8787)和带有热重载的Web UI开发服务器(端口5178)。你可以边修改代码边看效果。项目配置了基于语义化提交的自动化npm发布流程,对开源贡献者非常友好。