最近發現一個有趣的開源專案 lunel,使用者可以透過手機連到電腦,然後直接運行 Codex、OpenCode、Claude Code,重點是免費且公網可用。
它的核心技術原理其實是「手機作為純 UI 用戶端」,然後本地機器透過 WebSocket 閘道實現中繼連線,電腦端的 CLI 透過服務與 AI 終端互動,專案主要分三部分:

lunel-cli,負責所有實際操作:


另外目前有兩種模式:
這裡面一個核心之一是「中繼轉發(Relay)」,Lunel 包含了一個名為 Proxy 的 Bun 服務端,作為行動端 App 與本地 CLI 之間的 WebSocket 橋梁,App 只做聊天與審核,邏輯和執行都在電腦端的 Lunel CLI。

CLI 會呼叫一個用 Rust 撰寫的 pty 執行檔,pty 是基於 wezterm 開發,當你在手機 App 的終端機或 AI 聊天輸入內容時,App 不會直接發送原始文本,而是會封裝為標準化的 Message 物件:
pty 代表終端機操作,ai 代表 AI 指令)input 或 ask
本地 CLI 接收到訊息後,會根據 ns 將輸入分發到不同的執行器:
如果 ns 為終端機相關,CLI 會將 payload 中的字元透過 stdin(標準輸入)寫入 Rust PTY 程序,就類似你在電腦鍵盤上打字一樣,本地的 Bash 或 Zsh 接收到字元並執行。

如果輸入來自 AI 面板,CLI 會轉給 AI 代理模組(如 cli/src/ai/opencode.ts):

而在呼叫方式上,不同 AI 終端也不一樣。例如對於 OpenCode,Lunel CLI 並不是直接執行外部命令,而是利用 SDK 在本地程序做管理:
@opencode-ai/sdk 裡的 createOpencodeServer,在本地隨機埠啟動一個 OpenCode 伺服器Authorization 請求標頭與該本地伺服器通訊server.heartbeat 或 session.updated),並將其轉發給手機端 App而對於 Codex 的呼叫方式則是 JSON-RPC,互動相對複雜一些:
spawn("codex", ["app-server"], ...) 在背景啟動一個 codex 程序,這個程序對使用者是不可見的prompt 指令,CLI 會轉化為 turn/start 的 JSON 請求發送給背景程序
基於這個流程,Lunel CLI 可以在過程中精準識別和控制整個流程,例如當 AI 嘗試執行危險命令或修改敏感檔案時,CLI 可以捕捉到 requestApproval 請求,並暫停執行,直到你在手機上點選「批准」。
Claude Code 也是採用類似方式,它會啟動一個
codex app-server背景程序來處理攔截,在codex.ts的prompt方法中,可以透過參數指定model。

另外 Lunel Cloud 模式尚未完成,其目標看起來是在你需要時,透過 GitHub OAuth 登入後,直接在雲端 VM 啟動一個服務,然後運行預裝了 Lunel 的 VM,這點也很有意思,值得期待。

這個專案的思路還不錯,例如透過手機你就可以直接監控和管理你的 Codex 或 Claude Code,當然 Claude Code 本身也支援 mobile 遠端指令,但 Lunel 支援多個不同的 CLI 場景,更靈活、功能也更多,目前仍免費,重點是開源,自己弄一套感覺比龍蝦有趣多了。