返回列表

部落格

深入 Mac 伴侶應用:輕量級工作階段管理器的架構設計

Mac 伴侶應用是 Tactic Remote 默默運轉的基石——一個常駐選單列的工具程式,負責管理 tmux 工作階段、執行內嵌的 HTTP/WebSocket 伺服器,並在 AI 工作期間防止 Mac 進入睡眠。

發布於 標籤: architecture / mac / engineering
部落格

繼續查看該欄目下的產品與工程更新。

瀏覽此分類

Mac 伴侶應用是 Tactic Remote 中最不起眼的部分,但可以說是最重要的部分。它在選單列中執行,管理你機器上的每個 Claude Code 工作階段,為你的 iPhone 提供 API 服務,並負責在睡眠週期和網路變化中維持工作階段存活這項不起眼但至關重要的工作。本文將詳細說明它的運作原理以及我們做出各項架構決策的原因。

設計限制

我們在開發初期確立了三項限制:

  1. 應用在閒置時必須幾乎無感知。 開發者通常已經執行了數十個背景程序。一個在閒置狀態下消耗明顯 CPU 或記憶體的工作階段管理器是不可接受的。
  2. 必須支援多個並行工作階段。 許多開發者會同時執行兩三個 Claude Code 任務——一個用於功能分支,一個用於測試,一個用於文件。
  3. 必須優雅地應對 Mac 睡眠和網路變化。 開發者闔上筆記型電腦,走到咖啡店,重新打開,一切應該在幾秒鐘內重新連線。

這些限制塑造了架構的每一層。

內嵌伺服器模型

伴侶應用沒有執行一個獨立的伺服器程序,而是直接內嵌了一個 HTTP 和 WebSocket 伺服器。這是經過深思熟慮後做出的選擇,我們放棄了附帶一個獨立背景服務程序的方案。

為什麼選擇內嵌? 獨立的背景服務程序需要自己的生命週期管理——launchd 設定、程序監控、日誌輪替和崩潰復原。這些每一項都是潛在的故障點和維護負擔。透過將伺服器內嵌到應用本身,生命週期變得很簡單:應用執行,伺服器就執行。應用結束,一切乾淨地停止。

內嵌伺服器繫結到一個可設定的連接埠(預設 48736),可選擇僅繫結 localhost(用於區域網路模式,搭配獨立的網路代理層)或繫結所有介面。它提供用於工作階段管理和狀態查詢的 REST API,以及用於即時終端串流傳輸和審批推送的 WebSocket 端點。

在閒置狀態下,伺服器維持開啟的 socket 但不執行任何工作。在我們的基準測試中,沒有活躍工作階段時的伴侶應用大約消耗 18 MB 記憶體和可忽略不計的 CPU——與典型的選單列工具程式相當。

tmux 作為工作階段骨架

Tactic Remote 管理的每個 Claude Code 工作階段都在 tmux 工作階段內執行。我們選擇 tmux 而非 screen 或直接 PTY 管理,原因如下:

工作階段持久性。 tmux 工作階段獨立於建立它們的程序存活。如果伴侶應用崩潰並重新啟動,tmux 工作階段及其 Claude Code 程序會繼續不受干擾地執行。應用只需在啟動時重新附加到現有工作階段即可。

無干擾擷取。 tmux 的 capture-pane 命令讓我們可以在不注入輸入或修改執行中程序的情況下讀取終端內容。這至關重要——我們需要將終端輸出串流傳輸到 iPhone,同時不能有任何干擾 Claude Code 運作的風險。

具名工作階段。 每個 Claude Code 工作階段都有一個可預測的 tmux 工作階段名稱(例如 claude-remote-0、claude-remote-1),這使得列舉、附加和以程式化方式管理工作階段變得簡單。

成熟且通用。 tmux 隨 macOS 附帶,或者可以透過 Homebrew 輕鬆安裝。它擁有數十年的穩定性積累,並處理了我們否則必須自行解決的邊界情況(終端尺寸調整、Unicode、跳脫序列)。

伴侶應用以可設定的間隔(預設 200ms)輪詢活躍的 tmux 工作階段以擷取最新的終端內容。當內容發生變化時,它透過 WebSocket 將差異推送到已連線的用戶端。這種輪詢方式是刻意選擇的簡潔方案——我們評估了基於檔案系統的通知機制,發現在不同 macOS 版本上,它們不如在此間隔下進行直接輪詢可靠。

工作階段生命週期管理

Tactic Remote 中的 Claude Code 工作階段經歷一個明確的生命週期:

  1. 建立 — iPhone 發送「啟動工作階段」請求。伴侶應用建立一個新的 tmux 工作階段,並在其中以指定的工作目錄和任務描述啟動 Claude Code。
  2. 活躍監控 — 終端內容被擷取並串流傳輸。來自 Claude Code hook 系統的審批請求被攔截,並透過 WebSocket 和推播通知轉發到 iPhone。
  3. 閒置偵測 — 如果某個工作階段在可設定的時間段內沒有終端輸出變化,其輪詢頻率會降低以減少資源使用。
  4. 完成 — Claude Code 結束。伴侶應用偵測到結束,擷取最終輸出,並通知 iPhone。
  5. 清理 — tmux 工作階段在可設定的保留期(預設 30 分鐘)內被保留,以便使用者檢視輸出,然後自動清理。

管理多個並行工作階段意味著獨立地多工處理這些生命週期。每個工作階段有自己的擷取迴圈、自己的 WebSocket 頻道和自己的狀態機。伴侶應用目前最多支援 8 個並行工作階段,這一限制是基於實際資源測試而非架構限制。

防止 Mac 睡眠

這是不太顯而易見的工程挑戰之一。macOS 在偵測到不活動時會積極進入睡眠狀態,而在 tmux 中執行的 Claude Code 任務不會產生 macOS 辨識為「活動」的使用者輸入。

伴侶應用在至少有一個 Claude Code 工作階段活躍執行時,使用 IOPMAssertionCreateWithName API 來持有電源宣告。宣告類型為 kIOPMAssertPreventUserIdleSystemSleep,它可以防止系統睡眠,同時仍允許螢幕關閉。當所有工作階段完成或被終止時,宣告會立即釋放。

我們考慮過使用 caffeinate 作為外部程序,但出於與拒絕獨立背景服務程序相同的理由放棄了它——它增加了生命週期複雜性。IOKit 宣告 API 給予我們精確的控制,並能與應用自身的工作階段追蹤乾淨地整合。

選單列整合

伴侶應用以選單列圖示和一個簡潔的下拉介面呈現。選單顯示:

  • 連線狀態 — 伺服器是否在執行、繫結到哪個連接埠、Cloudflare Tunnel 是否處於活躍狀態。
  • 活躍工作階段 — 正在執行的 Claude Code 工作階段數量及簡要狀態指示。
  • QR Code 存取 — 一鍵顯示包含連線 URL 和認證權杖的 QR Code,用於 iPhone 配對。
  • 快捷操作 — 啟動/停止伺服器、開啟設定、複製連線 URL。

我們刻意避免建構完整的視窗化介面。伴侶應用的職責是充當基礎設施,而非互動目的地。開發者透過 iPhone 與 Tactic Remote 互動;Mac 應用只應在初始設定和偶爾的設定變更時才需要關注。

Cloudflare Tunnel 整合

啟用 Cloudflare Tunnel 模式後,伴侶應用以子程序方式管理 cloudflared 程序。它使用設定好的隧道憑證啟動 cloudflared,透過本機指標端點監控其健康狀態,並在隧道斷開時自動重新啟動。

此整合處理了一個微妙的時序問題:隧道必須完全建立後,iPhone 才能透過它進行連線。伴侶應用會等待 cloudflared 回報連線健康(通常在啟動後 1-3 秒)後,才將隧道 URL 標記為可用。在此期間,選單列圖示會顯示獨特的「正在連線」狀態。

如果隧道程序崩潰,伴侶應用會以指數退避方式(2 秒、4 秒、8 秒)嘗試最多 3 次重新啟動,然後將隧道模式標記為失敗,並通知已連線的用戶端回退到本機模式(如果可用)。

認證

每個 API 請求和 WebSocket 連線都需要 Bearer Token。該權杖在首次啟動時產生,並儲存在 macOS 鑰匙圈中。它包含在設定過程中顯示的 QR Code 中,因此配對只需掃描一次,無需手動複製權杖。

該權杖是一個 256 位元隨機值,使用 SecRandomCopyBytes 產生。我們選擇靜態權杖模型而非基於工作階段的認證,因為主要威脅模型是未經授權的網路存取,而非多使用者存取控制。對於需要按使用者認證的團隊,我們建議在隧道前部署 Cloudflare Access。

我們考慮過但放棄的方案

完整的 Electron 應用。 僅記憶體開銷就否決了這個方案——Electron 的基線是 80-150 MB,大約是我們原生 Swift 應用閒置時的 5-8 倍。

獨立的 CLI 背景服務程序。 初期建構更簡單,但對非技術使用者來說更難管理,且無法整合 macOS 選單列規範。

直接 PTY 管理取代 tmux。 控制力更強,但我們將不得不重新實作工作階段持久性、終端模擬邊界情況以及程序生命週期管理——這些 tmux 已經可靠地處理了。

用 LaunchAgent 實現自動啟動。 我們實作了這個功能,但將其設為可選而非預設。開發者對登入時執行什麼有強烈的偏好,我們尊重這一點。

效能概況

在典型負載下(2 個活躍工作階段,1 部已連線的 iPhone),伴侶應用的資源使用:

指標數值
記憶體 (RSS)22-35 MB
CPU(閒置,無輸出變化)< 0.1%
CPU(活躍串流傳輸,2 個工作階段)1-3%
磁碟 I/O可忽略不計(預設不寫入磁碟日誌)
網路(本機模式,活躍串流傳輸)10-50 KB/s

這些數據在執行 macOS 14 的 MacBook Pro M2 上測量。Intel Mac 上的效能相當,在活躍串流傳輸時 CPU 使用率略高。

展望未來

伴侶應用的架構設計旨在支援超出當前已發佈功能的能力。工作階段管理層可以容納工作階段共享(多部 iPhone 監控同一工作階段)、工作階段錄製(擷取完整終端歷史用於回放),以及隨著 Claude Code 可擴展性 API 的演進與之更深度地整合。

有關設定說明,請參閱快速入門。有關 Mac 伴侶應用的疑難排解,請參閱常見問題。

立即體驗 Tactic Remote

用手機遠端操作程式開發 Agent

連線到 Mac、Windows 或 Linux 電腦上的 Claude Code、Codex 等 Agent,在 iPhone 或 iPad 上查看進度並傳送下一個請求。