Cline desktop v0.0.22-beta.1 拆解:你按的 Stop 停得掉子 agent 嗎?
上禮拜有人在我旁邊按 Stop 按了三次,然後抱怨「Cline 停不下來」。實際情況是:主 session 確實停了,但它派出去的子 agent 還在後台跑,繼續燒 token、繼續改檔案。你在畫面上看不到它,因為那顆 Stop 按鈕早就換回送出鍵了。
這不是誰家的 bug,是所有支援「agent 派 agent」的工具都會踩的同一個坑:取消是一個需要一路傳遞下去的訊號,而多數實作只在最上層做對了。
Cline 在 desktop-v0.0.22-beta.1(2026-09-01 發布,commit 6b40621)這個 beta 裡,把這條鏈路補完了,同時還夾帶兩個對日常使用影響更大的改動:web search 在桌面版變成預設開啟,以及 Composio 連接器改用完全不同的方式把工具送進 session。
這三件事表面上是 changelog 三行字,拆開看其實是三堂課:取消訊號怎麼傳、全域設定怎麼外溢、工具怎麼註冊才不會在打包版靜默失效。 這篇就照著原始 PR 一條一條拆,順便給你可以照做的檢查步驟。
本文大綱
這個 beta 到底改了什麼
官方 release note 只有兩行:Composio 連接器改為「直接在打包後的桌面 runtime 註冊工具」,以及「web search 對新的桌面 session 預設開啟」。另外它把 v0.0.21 的穩定改動一起帶進來,其中包含「可靠取消子 agent 與隊友」。
但 release note 不會告訴你機制。真正的資訊在四個 PR 裡:
| PR | 作者 | 合併時間 | 內容 |
|---|---|---|---|
| #13647 | johnwschoi | 2026-08-28 | 把 session abort 傳給隊友(teammates) |
| #13677 | johnwschoi | 2026-08-31 | 把父層 abort 傳給委派出去的子 agent |
| #13678 | johnwschoi | 2026-08-31 | 子 agent 執行中時,Desktop 保留 Stop 按鈕 |
| #13725 | saoudrizwan | 2026-09-01 | 桌面版預設開啟 web search |
| #13739 | abeatrix | 2026-09-01 | Composio 連接器改為 core 內建 extension |
以下按「對你影響由大到小」的順序講。
一、web search 預設開啟:一個會外溢到其他 host 的設定
先講最容易在你不知情下改變行為的那個。
機制
Cline 的 web search 不是一個本地執行的工具,而是由 provider 執行的 model tool。這個架構是 abeatrix 在 #13075 建立的:Anthropic、OpenAI、Gemini、Vertex 各自有原生 search API,Cline 和 ClinePass 則走 Cline 自己的 web-search endpoint。這類工具不進 AgentRuntime 的本地審批與執行迴圈,所以你不會看到「是否允許執行」的提示。
開關寫在共用的全域設定裡,路徑是 ~/.cline/data/settings/global-settings.json:
{
"tools": {
"web_search": {
"enabled": true
}
}
}
原本這個 key 在全新安裝時根本不存在,等同關閉。#13725 做的事很小(+16/-0,只動 apps/examples/desktop-app/sidecar/index.ts):桌面版 sidecar 啟動時,只在這個設定從未被寫過的情況下,把它種成 true。你如果曾經手動關掉,那是一筆持久化的 enabled: false,不會被覆蓋。
這裡有個你該知道的副作用
PR 作者 saoudrizwan 自己在描述裡寫得很清楚:因為這是共用的全域設定檔,桌面版種下去之後,同一台機器上的 VS Code 擴充套件與 CLI 讀到的也會是「已開啟」。
換句話說:你只是開了一次 Cline Desktop,你的 CLI session 從此就帶著 web search 工具了。 這不是 bug,是設定本來就是全域的必然結果(桌面版原本的 Settings 開關也是寫全域),但值得你知道。
照著做:檢查與關閉
# 看目前實際值(沒有 tools key = 從未寫過 = 關閉)
cat ~/.cline/data/settings/global-settings.json | jq '.tools'
要關掉,三個地方擇一,寫的是同一個 key:
- Desktop:Settings → General → Web search
- VS Code:Settings → Features → Agent 群組下的 Web Search 開關(#13245 加的)
- CLI:config 的 Tools 分頁
開了不一定會生效
這是最多人誤會的一點。saoudrizwan 在 #13328 的描述裡直接點名這個回饋來源:使用者在 OpenRouter 上把開關打開,什麼都沒發生,而且沒有任何提示告訴他為什麼——runtime 只是靜默地跳過這個工具。
依該 PR 的說明,目前宣告支援原生 web search 的 provider 是:Anthropic、OpenAI、OpenAI ChatGPT Subscription、Gemini、Vertex、Cline、ClinePass。用其他 provider(包含 OpenRouter)時,開關無效。現在桌面版 Settings 會在開關底下直接顯示狀態行,例如「Ready to use with Anthropic」,沒有支援的 provider 則顯示琥珀色警告。
還有一個容易漏的組合限制:依 Cline 官方文件,子 agent 不能做 web search。所以你把 web search 開起來,並不會讓「派子 agent 去查最新文件」這種用法變成可行——子 agent 只能讀檔、搜尋、跑唯讀指令、用 skill。
二、取消鏈路:三個 PR 才補完一顆 Stop 按鈕

這段是我覺得最值得任何在做 agent 產品的人讀一遍的。三個 PR,剛好對應取消訊號的三個斷點。
斷點一:訊號沒傳給隊友(#13647)
Cline 的 agent teams 是一個協調者 agent 帶著若干專才 agent,狀態存在 ~/.cline/data/teams/[team-name]/,包含任務板、agent 之間的信箱、任務日誌。原本根 session 中止時,隊友的工作不受影響。
#13647 的做法值得抄:沿用既有的 session.abort 路徑,不新增命令通道,然後把行為切得很細——
- 只中止正在執行的隊友
- 保留隊友定義與對話(取消不等於刪除)
- 排隊中的 async run 取消掉、執行中的結算為 cancelled,且只結算一次
- 閒置隊友與不相關的 team runtime 完全不動
這個「只碰正在跑的、其餘一律不動」的原則,是取消語意設計的關鍵。取消不該順手清掉狀態。
斷點二:子 runtime 沒去監聽那個訊號(#13677)
這個最陰險。spawn_agent 與 configured-agent 工具是透過一個子 SessionRuntime 執行委派工作的,而父層的 abort signal 早就已經以 AgentConfig.abortSignal 傳下去了。
問題是:SessionRuntime 根本沒有去觀察這個既有的取消契約。訊號傳到了,沒人聽。
修法很克制:只在子 runtime 存活期間監聽那個外部 signal、重用既有的 SessionRuntime.abort()、在啟動階段收到的 abort 會保留到 run-started 邊界才生效、run 收尾時把 listener 解除。作者 johnwschoi 明確寫了什麼不在範圍內:不改 spawn-executor、Hub 命令、transport、team-runtime 或 plugin 生命週期契約;任意 plugin 初始化仍然不可中斷。
這種「明確宣告 out of scope」的 PR 描述,本身就是好範本。
斷點三:UI 上根本沒得按(#13678)
前兩個修好了,還有一個純前端問題:父 session 可能顯示為閒置,但子 agent 還在跑,這時 Desktop 會把 Stop 換回送出鍵——你得自己點進子 session 才能取消。
#13678 的處理:只要還有 child 活著就持續輪詢那份持久化的 child-agent 名冊(並且避免慢輪詢重疊)、在 composer 顯示 Stop、abort 請求送出但尚未回應時保留權威狀態、失敗就還原、中止後把持久化的工具活動對帳一次,讓被打斷的 spawn_agent 那一列不會視覺上還在轉圈。
照著做:驗證你的版本修好了沒
作者自己的手動測試步驟可以直接拿來用:
- 跟 agent 說:「開一個子 agent,讓它 sleep 兩分鐘」
- 確認父 session 的 Stop 按鈕還在(沒有變回送出鍵)
- 按下 Stop
- 檢查子 agent 是否轉為 cancelled,且行內的 spawn 列不再顯示執行中
如果你用的是別的工具(Claude Code、Codex、Cursor),同一套步驟照樣能測。這是我目前判斷一個 coding agent 的多 agent 功能「有沒有做完」最快的方式。
順便:關掉子 agent 的方式
依 Cline 文件,子 agent 預設啟用,由 Cline 自己決定何時值得平行探索。要關掉,在 Settings → Features → Agent 把 use_subagents 工具停用,這個設定跨 VS Code / JetBrains / CLI 生效。CLI 的 agent teams 則是 cline --no-teams "your prompt"。
子 agent 的啟動沿用 Read project files 的自動核准權限——如果你沒開自動核准,Cline 會先把它打算派出去的 prompt 給你看再問你要不要放行。這其實是個好習慣:看一眼 Cline 打算怎麼拆問題,比看它拆完的結果更有資訊量。
三、Composio 連接器:一個很典型的打包陷阱

先講清楚你現在多半用不到這個功能:依 PR #13684 的描述,連接器目前是內部限定,用一個 SDK 層的內部功能閘門擋著,只對 @cline.bot 網域的帳號開放(精確網域比對,子網域與相似網域一律拒絕,email 缺失或格式異常時 fail closed)。閘門值同時是一個 PostHog feature flag key(internal-composio-connectors,預設 false),所以他們可以不發版就把特定外部帳號放進來。
即使如此,這個 PR 的內容值得讀,因為它踩到的坑非常普遍。
那個 beta blocker
在打包後的 beta 版裡,連接器顯示「已連線」,但 session 從來沒拿到工具。
根因在 #13739 寫得非常清楚:工具原本是透過一個生成出來的 drop-in plugin 送達的,檔案落在 ~/.cline/plugins/composio-tools.ts。而載入任何 drop-in plugin 都會 spawn 一個 plugin-sandbox 子行程,那個子行程需要磁碟上有 JS runtime 執行檔、以及編譯好的 plugin-sandbox-bootstrap.js。npm 版 CLI 兩者都有;.app bundle 兩者都沒有。於是 session bootstrap 吞掉了 plugin-sandbox process is not available,然後不帶任何 plugin 繼續跑。
作者是用一個 bun 編譯出來的探針執行檔重現的。
修法:連接器工具改成核心內建的 extension,session bootstrap 直接讀 <cline-data>/settings/composio.json,在行程內註冊那些以 fetch 為基礎的工具。沒有外掛檔、沒有沙箱子行程、沒有「runtime 必須在磁碟上」的要求,dev、打包桌面版、CLI 託管的 hub 行為一致。sidecar 還會主動刪除遺留的 composio-tools.ts,避免舊安裝重複註冊。
PR 也誠實地留了一句:打包後的桌面版「載不了任何 drop-in 檔案外掛」這個底層缺口仍然存在,其他 plugin 功能還是會中招,值得另開 issue。
授權生命週期的幾個設計,值得抄
這部分是我認為整個 PR 最有價值的地方,因為 OAuth 連接器的錯誤處理幾乎每家都做得不夠硬:
取消要能持久地撤銷。 取消一次 OAuth 嘗試(或在流程進行中斷線、輪替金鑰),會為該次嘗試的 connected-account id 寫下一個 tombstone,並遠端刪除該帳號。對帳時拒絕匯入被 tombstone 標記的帳號,並重試刪除。關鍵設計:tombstone 不以數量或時間上限淘汰——一個被放棄的瀏覽器流程可能任意晚才完成——只有在遠端「確認」刪除後才清除。所以被取消的連接器永遠不會復活。
斷開連線要誠實且 fail closed。 只有真正的「已不存在」訊號(結構化 HTTP 404,或 SDK 那個開頭是 404 的訊息形狀)才會繼續執行本地移除。其他任何失敗——包括一個 body 裡寫著 "not found" 的 500——都會保留連接器並把錯誤呈現出來,而不是回報「已解除安裝」但帳號其實還被授權著。
寫入序列化。 每一次 composio.json 的變更都走單一同步的 read → mutate → write 路徑,這樣就不會有卡在網路 I/O 上的 writer 蓋掉並行寫入的 tombstone 或連線。
差異對帳配 CAS。 狀態刷新以刷新起點為基準做逐 slug 的增刪,並用 compare-and-swap,所以刷新途中完成的連線(或並行的 disconnect / cancel)不會被對帳寫入吃掉。
如果你正在做任何「使用者授權第三方帳號給 agent 用」的功能,上面四條可以直接當 checklist。
金鑰的處理方式
也值得一提:Composio 的金鑰刻意不嵌進出貨的 build。理由 PR 寫得很直白——嵌在 client 的密鑰,任何拿到 artifact 的人都能取出,不管你走哪個發布通道。sidecar 是在 runtime 從環境變數讀 COMPOSIO_API_KEY,沒有這個變數的安裝就整個功能隱藏。目前內部測試者是在啟動 app 的 shell 裡自己 export;後續計畫是由 Cline 平台端的 proxy 持有金鑰、依已認證的 Cline 帳號做 scope。
原因是 Composio 的工具執行接受 client 提供的 user_id,所以那把金鑰是專案層級的憑證,PR 直接說要「當作可容忍外洩」來處理(專用專案、隨時可輪替)。
數據與限制:哪些數字可以信,哪些有前提
誠實標註一下我查到的數字與它們的前提:
- ~500 個可連接的 toolkit:來自 PR #13684 描述。注意這是 Cline 端過濾過的數字(只留 Composio 託管憑證或有 project auth config 的、可連接的 toolkit),UI 預設只顯示使用量排名前 24 個。Composio 官方行銷數字是 1000+ toolkit,兩者不衝突但不是同一個母體。
- Google Calendar 連上後 materialize 出 20 個工具:這是 PR 作者對一個真實 Composio 專案做端對端驗證時回報的數字,不是通則。
- 測試數:#13739 回報 6 個 shared internal-features + 7 個 core composio-extension + 60 個 desktop 測試全綠;#13677 回報 orchestrator 測試 65 個通過。這些是作者在自己 checkout 上跑的結果,兩個 PR 都註明本地有不相關的既存失敗,CI 才是權威。
- #13739 的規模是
+2771/-925,因為它是「revert 掉 8/30 的快照,再把 #13684 目前已審核的狀態重貼上去」,不是全新功能量體。 - 我沒有實際跑過這個 beta。以上全部來自 release note 與 PR 描述、程式碼路徑與官方文件。想自己驗證取消行為,用上面那個 sleep 兩分鐘的步驟最快。
另外,#13684 到現在仍是 open 狀態(尚未併入 main)。這個 beta 拿到的是透過 #13739 同步到 desktop-experimental 分支的版本。所以你在 main 的程式碼裡不一定找得到對應狀態。
什麼時候該關心這些、什麼時候別
該關心的情境:
- 你在用(或在做)任何會派子 agent 的工具,尤其是會跑長時間指令的。取消鏈路沒補完=你的成本上限沒有煞車。
- 你在同一台機器上混用 desktop / VS Code / CLI。全域設定外溢會讓你「在 A 改的東西影響到 B」,web search 只是第一個,不會是最後一個。
- 你在做需要打包成桌面 app 的 agent 產品。「dev 能跑、打包後靜默失效」這條路徑值得你現在就去測一次。
別浪費時間的情境:
- 你只用 VS Code 擴充套件、也不用多 agent:這版對你唯一的實質影響就是 web search 那顆開關可能被種成開啟。
- 你想馬上用 Composio 連接器:現在還進不去,除非你有
@cline.bot帳號或被放進那個 PostHog flag。等平台 proxy 落地再說。 - 你的 provider 不在支援清單上:把 web search 開關打開對你完全沒有作用,不用花時間研究。
對工程團隊的意義
如果要從這個 beta 帶三件事回去,我會選這三件:
一、把「取消」當成一條需要端到端測試的路徑,不是一個按鈕。 你的 agent 系統裡,取消訊號要經過幾層?每一層都有人在聽嗎?#13677 的教訓是:訊號有傳下去,不代表有人監聽。寫一個 e2e 測試:派一個長時間子任務、送出取消、斷言子任務在 N 秒內轉為 cancelled。這比任何 code review 都可靠。
二、靜默失敗是最貴的失敗。 連接器那個 bug 的本質不是 sandbox 缺 runtime,而是錯誤被吞掉之後流程若無其事地繼續。UI 顯示已連線、agent 手上零個工具、沒有任何錯誤訊息。去 grep 你自己的 codebase,看有幾個 catch block 是把錯誤吃掉然後 continue 的。
三、能力的「遞送方式」會綁定一整條環境假設。 把功能做成「生成一個外掛檔讓外掛系統載入」,感覺很優雅、很解耦,但你同時繼承了那條載入路徑對執行環境的所有要求。改成核心內建 extension 之後,dev / 打包 / CLI 三個環境行為才一致。做技術選型時,多問一句:這條路徑在我所有的出貨形態下都成立嗎?
來源
- Cline Desktop v0.0.22-beta.1 release notes — https://github.com/cline/cline/releases/tag/desktop-v0.0.22-beta.1
- Cline Desktop v0.0.21 release notes — https://github.com/cline/cline/releases/tag/desktop-v0.0.21
- PR #13684
feat(desktop): Composio connectors(abeatrix,open)— https://github.com/cline/cline/pull/13684 - PR #13739
fix(desktop): sync reviewed Composio connectors onto desktop-experimental(abeatrix)— https://github.com/cline/cline/pull/13739 - PR #13725
Default web search on for the desktop app(saoudrizwan)— https://github.com/cline/cline/pull/13725 - PR #13075
feat(core, llms): add provider-aware web search tools(abeatrix)— https://github.com/cline/cline/pull/13075 - PR #13328
feat(desktop): show provider web-search support under the settings toggle(saoudrizwan)— https://github.com/cline/cline/pull/13328 - PR #13245
feat: add web search settings toggle to VS Code extension and desktop app(saoudrizwan)— https://github.com/cline/cline/pull/13245 - PR #13647
ENG-2490: Propagate session aborts to teammates(johnwschoi)— https://github.com/cline/cline/pull/13647 - PR #13677
fix(core): propagate parent aborts to delegated subagents(johnwschoi)— https://github.com/cline/cline/pull/13677 - PR #13678
fix(desktop): keep Stop available for running child agents(johnwschoi)— https://github.com/cline/cline/pull/13678 - Cline 官方文件 — Subagents:https://docs.cline.bot/features/subagents;Agent Teams:https://docs.cline.bot/cli/agent-teams
整理:DataAgent · Coding Agent 實戰教學


