這篇要介紹 OpenCLI 這個工具,順便講一下我怎麼用它把 Substack 發布這件事自動化。
簡單說,我現在發 Ravan AI 週報的流程是:寫完文章之後,跟 Claude Code 說「發到 Substack」,剩下的事 Claude Code 會透過 OpenCLI 自己去操作我登入過的 Chrome,把標題、封面、內文、標籤、排程時間全部填好,最後排程在下週二早上 10 點公開。我中間不用碰滑鼠。
OpenCLI 是什麼
作者是 jackwener,npm 套件名 @jackwener/opencli,需要 Node.js 21 以上。
它解決的事情是:讓 AI agent(像 Claude Code、Cursor)可以操作你電腦上的瀏覽器、桌面 App、本地 CLI 工具。整個工具大概分三塊。
第一塊是瀏覽器自動化的低階指令。
像 opencli browser open、opencli browser state、opencli browser click、opencli browser type、opencli browser eval 這些。
你不會自己手動敲,這是設計給 AI agent 在背後用的。
它透過一個 Chrome extension 加一個本地 daemon,連到你已經登入過的 Chrome session,所以 cookie、登入狀態完全沿用,密碼不會離開瀏覽器。
第二塊是內建的網站 adapter。
OpenCLI 把 100 多個網站的常用功能寫成 deterministic 的 CLI 指令,像 opencli hackernews top、opencli bilibili hot、opencli reddit hot、opencli twitter trending、opencli xiaohongshu search "AI"、opencli 1688 search "皮夾"。
每次跑同樣指令、同樣輸出格式,0 token 成本。
第三塊是 CLI Hub。
你本機裝過的 gh、docker、vercel、obsidian 等 CLI,OpenCLI 可以統一接過來用 opencli gh pr list、opencli docker ps 這種方式呼叫。
也可以用 opencli external register mycli 把自己寫的本地 CLI 註冊進去。
對 AI agent 來說,OpenCLI 等於把「這台機器有什麼能力」這件事整合成一個統一介面,agent 透過 opencli list 就知道能用什麼。
我用 Claude Code 操作 OpenCLI 做了什麼
我把 Substack 後台發布文章的整套動作,交給 Claude Code 用 opencli browser 系列指令去操作。
我打開 Claude Code,跟它說「我要做一個自動發布到 Substack 的流程,請你用 OpenCLI 操作 Chrome 來實作」。
Claude Code 接著用 opencli browser open 打開 Substack 後台,用 opencli browser state 抓頁面結構,找到標題框、副標題框、封面圖 input、編輯器內文區、標籤 combobox、排程設定面板各自的 ref,再用 opencli browser click、opencli browser type、opencli browser fill 把每個欄位該做的事跑一遍。
過程中我們踩到三個 Substack 前端框架的雷,這些雷都不是 OpenCLI 的問題,是現代前端框架本身的特性。
但因為這些雷的解法後來變成這套技能能不能跑通的關鍵,我把它寫下來給後人參考。
第一個雷:ProseMirror 編輯器塞不進內文。
Substack 的編輯器是 ProseMirror。Claude Code 一開始試 opencli browser keys "Meta+v" 想模擬貼上,跑完發現編輯器內文 length 還是 1,沒有任何反應。換成先 navigator.clipboard.writeText 寫入剪貼簿、再按 Meta+v 也是一樣。
後來才搞清楚,ProseMirror 不接收系統剪貼簿的鍵盤事件,它只接 ClipboardEvent 物件 dispatch 進來的 paste 事件。解法是用 opencli browser eval 注入一段 JavaScript,前端組一個 new ClipboardEvent('paste', { clipboardData }) 物件,直接 dispatch 到編輯器元素上。這才把內文塞進去。
第二個雷:HeadlessUI combobox 打字進去沒反應。
Substack 的文章標籤用的是 HeadlessUI 的 combobox。Claude Code 試 opencli browser type 把標籤名稱打進去,畫面完全沒反應,下拉選單也不出現。
原因是 HeadlessUI 用 React 控制 input 的 value,模擬鍵盤打字不會觸發 React 的 state 更新。解法是用 opencli browser eval 跑一段 JS,先用 Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set 拿到 React 認得的原生 setter,把值塞進去後再 dispatch 一個 input 事件,combobox 才會開始搜尋並顯示對應選項,後面才能 click 選中。
第三個雷:datetime-local 排程時間選不了。
Substack 排程介面用的是 datetime-local input。opencli browser type 打 2026-05-12T10:00 進去,框框完全空白,跟 combobox 一樣的問題。
解法也一樣:用 opencli browser eval 拿原生 value setter 塞值,但 datetime-local 必須同時 dispatch input 和 change 兩個事件,Substack 才會把這個時間記下來。
三個雷踩完之後,Claude Code 把整套流程寫成了一個技能檔,存在 .claude/skills/publish-to-substack/SKILL.md。下次要發文,我只要說「發到 Substack」,Claude Code 就會讀那個技能檔,照著步驟跑一次。
結論
OpenCLI 在這個流程裡扮演的角色,是「讓 AI agent 能精確操作真實網頁」的橋。
全程我都只要透過 Claude Code 去下指令,然後讓 Claude Code 去操作 OpenCLI 這個工具。
完全解放你的雙手。
如果你也在嘗試把自己的工作流自動化、想知道 Claude Code 加上這類工具能做到什麼程度、不知道從哪裡開始,可以聊聊。我有開一對一的 AI 一人公司啟動諮詢,幫你把方向定下來。