Communitygithub.com

miaoermua/artcraft-cli

驅動 ArtCraft 套件桌面應用(LightCraft RAW 修圖 / FilmCraft 影片剪輯 / PhotoCraft 點陣圖編輯)的通用 agent skill,涵蓋 JSON-lines 控制通道、命令列 CLI 與 MCP 伺服器三種入口。

artcraft-cli 是什麼?

此 skill 為 ArtCraft 系列軟體(LightCraft、FilmCraft、PhotoCraft)的 AI agent 驅動工具,提供三種等價的控制入口:TCP 控制通道(JSON-lines 協議)、獨立的 CLI 工具(lightcraft-cli、filmcraft-cli、photocraft-cli)以及 MCP 伺服器。它能讓 AI agent 像操作 GUI 一樣執行命令,包括點擊選單、調整滑桿、拖曳、截圖,以及無頭批次處理媒體檔案。支援的平台包括 Claude Desktop、Cursor、Codex 等 MCP 客戶端。核心工作流程為「發現(查詢命令註冊表)→ 執行 → 驗證 → 回退(支援 undo)」,並強調運行時發現優先(不憑記憶硬編碼命令 ID),且三應用的認證機制不同(無認證、token 字段、auth 首幀)。安全方面限制通道僅監聽 127.0.0.1,PhotoCraft 有 fail-closed 檔案系統限制。

相容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/miaoermua/artcraft-skill/tree/HEAD/skills/artcraft-cli

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

ArtCraft 自動化:控制通道、CLI 與 MCP

聲明

本 skill 是針對 ArtCraft 系列軟體的 agent skill,並非 ArtCraft 官方倉庫。 ArtCraft / LightCraft / FilmCraft / PhotoCraft 的著作權與官方文件歸 storyteller(github.com/storytold)所有;本倉庫只是把官方公開的協定與 CLI 整理成給 AI agent 用的操作手冊與工具腳本,與官方無隸屬、無背書關係。上游文件與本倉庫內容衝突時以官方為準。

官方倉庫:lightcraft · filmcraft · photocraft

這套東西是什麼

ArtCraft 套件(github.com/storytold)的每個桌面應用都把 UI 裡能點的每個選單項、滑桿、筆觸實作成帶穩定 id 和 JSON 參數的命令,並透過三個等價入口開放:

入口長什麼樣適合什麼
控制通道應用開一個 TCP 埠,說 JSON 行操控使用者正在看的視窗
CLIlightcraft-cli / filmcraft-cli / photocraft-cli無介面批處理
MCPxxx-cli mcp讓 Claude 等用戶端來使喚

三者排程同一套命令註冊表,所以腳本和 agent 能像人一樣操作,而且編輯可 undo。

四條鐵律(先記住這四條,再看別的)

  1. 執行時期發現優先。本 skill 裡的參考文件是某個版本時點的快照,只用來導航和兜底;事實以執行中實例為準:engine.commands(命令註冊表)、methods(方法表)、CLI 的 --help / commands / controls。禁止憑記憶寫命令 id——各家各版本註冊表都不一樣。
  2. 認證三家不同,且會變。動手前先跑 scripts/craft_env.py 看本機的 auth 欄位,別照抄任何部落格裡的埠命令。已知的三態:
    • LightCraft:通道無認證(任何本機行程都能驅動,用完即關)
    • FilmCraft:憑證放在每個請求的頂層 token 欄位(較新版本強制;已發佈的 0.9.0 實測並不強制)
    • PhotoCraft:每個連線首幀必須是 auth;檔案存取被 automation 讀寫根目錄 fail-closed 限制 scripts/craft_ctl.py --app <light|film|photo> 會自動套用對應方式;缺憑證時它不擅自失敗,而是交給伺服端判定並把錯誤原樣讀出來。
  3. 憑證不進命令列、不進日誌、不進倉庫。用 token 檔案(Unix mode 0600)或環境變數;不要在共享機器上把 token 明文傳給行程。
  4. 編輯前先說影響。動使用者的真實圖庫/專案前,講清楚會改哪些東西、是否可 undo、匯出到哪;不確定範圍就問。

起步:先做環境自檢

python3 scripts/craft_env.py --table     # 裝了什麼版本、CLI 在哪、通道開了沒、憑證在哪
python3 scripts/craft_env.py             # 同樣內容的 JSON

這一步取代「我記得我裝了 X 版本」。它唯讀不寫。

入口決策

使用者想要選一句話理由
「我現在開著這個軟體,你幫我點/看」控制通道唯一能看見真實視窗狀態的入口
「把這 200 張批次處理掉」CLI headless不依賴視窗渲染,跑得更快更穩
「以後我直接跟 AI 說這件事」MCP一次接線,長期使用
「現在到底能點什麼命令」任一入口的 engine.commands / command_list唯一權威清單

A. 控制通道

啟動

三個應用都用 --control PORT 開通道,但啟動 flag 和憑證要求不同,先查 craft_env.py 與 references/app-matrix.md:

# LightCraft:一次性記憶體工作階段,測試首選,不寫碟
nohup "/Applications/LightCraft.app/Contents/MacOS/LightCraft" --control 7980 --memory > /tmp/lc.log 2>&1 & disown

# FilmCraft:需要先匯出憑證,否則不監聽
export FILMCRAFT_CONTROL_TOKEN="$(python3 -c 'import secrets; print(secrets.token_hex(32))')"
nohup "/Applications/FilmCraft.app/Contents/MacOS/FilmCraft" --control 9876 > /tmp/fc.log 2>&1 & disown

# PhotoCraft:token 檔案(應用首次啟動時自動建立,mode 0600)
nohup "/Applications/PhotoCraft.app/Contents/MacOS/PhotoCraft" --control 7878 \
      --control-token-file ~/.photocraft/control.token > /tmp/pc.log 2>&1 & disown

行程保活:裸 & 啟動的 GUI 會隨啟動它的 shell 退出被回收,之後連線一律被拒。用 nohup ... & disown,或把「啟動→操控→退出」寫在同一條命令裡。

操控

用自帶的用戶端,別每次重寫 socket 程式碼:

# 通用形式:--app 決定認證方式,--port 給埠
python3 scripts/craft_ctl.py --app light --port 7980 engine.commands
python3 scripts/craft_ctl.py --app film  --port 9876 --method engine.execute --params '{"command":"sequence.inspect"}'
python3 scripts/craft_ctl.py --app photo --port 7878 --token-file ~/.photocraft/control.token '{"method":"ui.inspect"}'

# 條件發現:命令註冊表精簡表(--filter 過濾,避免上千行刷屏)
python3 scripts/craft_ctl.py --app light --port 7980 --discover --filter develop

# 腳本模式:stdin 每行一個請求,'#' 開頭為註解
echo '{"method":"engine.commands"}' | python3 scripts/craft_ctl.py --app light --port 7980

退出碼:0 全部 ok / 1 有 ok=false / 2 用法或連線錯誤。

B. CLI(無頭批次處理)

CLI 是獨立 release 資產,不在 .app 裡,ArtCraft Launcher 也不裝它。取得與安裝見 references/cli-reference.md。

lightcraft-cli run --import in.dng develop.set control=light.exposure value=0.7 app.export path=out.jpg longEdge=2048
lightcraft-cli render in.dng -o out.jpg --set light.exposure=0.5
lightcraft-cli commands --json                 # 命令註冊表(等價於通道的 engine.commands)
lightcraft-cli controls --json                 # develop 滑桿 id 與範圍

photocraft-cli run wave.psd --cmd filter.sharpen.smartSharpen --params '{"amount":80}' --out out.png
photocraft-cli batch --actions grade.json --in ./raw --out ./graded

filmcraft-cli commands razor                   # 按關鍵字找命令 id
filmcraft-cli describe timeline.razor          # 單命令的選單/快速鍵/參數/當前啟用態
filmcraft-cli --project p.fcproj --save exec timeline.razor seconds=3.5
filmcraft-cli --bridge 127.0.0.1:9876 exec window.workspace.color   # 反控執行中的應用

通用規則:選項位置任意;輸出 JSON;退出碼 0=成功 / 1=命令失敗 / 2=用法錯誤;key=value 能解析成 JSON 就按 JSON 解析,否則當字串;點號鍵表示巢狀(color.r=1)。

C. MCP(接入 Claude 等用戶端)

claude mcp add lightcraft     -- lightcraft-cli mcp ~/Pictures/shoot
claude mcp add lightcraft-app -- lightcraft-cli mcp --connect 127.0.0.1:7980
claude mcp add filmcraft      -- filmcraft-cli mcp --bridge 127.0.0.1:9876
claude mcp add photocraft     -- photocraft-cli mcp --bridge 127.0.0.1:7878 --control-token-file /path/token

headless(行程內引擎,無視窗)與 bridge(驅動已啟動的應用)兩種模式,憑證要求見 references/mcp-servers.md。

核心工作流程:發現 → 執行 → 驗證 → 回退

  1. 發現:engine.commands / command_list 拿註冊表,按 label/menu 找目標命令 id 與參數文件。
  2. 執行:engine.execute {command, params}。注意語義差別——ui.menu.invoke 是「選單點擊」(無參數時會打開命令的對話框),engine.execute 直接以預設參數執行、不開對話框。
  3. 驗證:讀狀態而不是猜。ui.inspect 是通用 UI 狀態;各應用另有領域狀態方法(LightCraft library.state / photo.inspect / develop.get,FilmCraft sequence.inspect,PhotoCraft document.inspect)。
  4. 看結果:ui.screenshot {path} 抓視窗(渲染完成後才抓;視窗不繪製幀時用 headless 截圖)。
  5. 回退:edit.undo / edit.redo。agent 的編輯同樣進 undo 堆疊。

協定鐵律(三家一致的部分):

  • 一行一個 JSON 請求、一行一個回覆,按序對應:{"id":N,"method":...,"params":{...}} → {"id":N,"ok":true,"result":...} 或 {"id":N,"ok":false,"error":"..."}。
  • 無事件推送:通道只回請求。想知道 GUI 側發生了什麼,輪詢 inspect 方法比對快照。
  • 每次請求是獨立快照:換了物件必須重讀狀態,別拿快取的 id 推斷當前狀態。
  • 伺服端回覆上限 60s;逾時的命令可能仍在跑,重試前先查狀態。長任務用 wait:false 再輪詢 jobs.list。

安全邊界

  • 所有通道只監聽 127.0.0.1,協定不加密——不要 tunnel 或代理到不可信主機。loopback 只擋遠端,擋不住同機其他行程。
  • LightCraft 通道無認證:按需開啟,用 LIGHTCRAFT_CONFIG_DIR 隔離設定做自動化,不用時關掉。
  • PhotoCraft 檔案系統 fail-closed:自動化讀寫限制在 --automation-read-root / --automation-write-root 之內,未授權即拒絕;file.open / file.save 被通道拒絕,改用 app.open / app.save。
  • FilmCraft 的 FILMCRAFT_CONTROL_TOKEN 等同於全部控制權限:保密、不要進命令列歷史或 MCP 設定。
  • 預設不碰使用者既有資料(例如 LightCraft 的 ~/Pictures/LightCraft Library),除非使用者明確要求。

出問題先查這裡

references/known-pitfalls.md 收錄了實測踩過的坑(連線被拒、無幀逾時、PhotoCraft 沒有 --help、匯出原子儲存被系統策略攔截、圖層原點偏移、quad 相對座標等)。先查表,別重複試同一個錯命令。

參考文件索引

檔案內容
references/app-matrix.md三應用差異速查(啟動 flag、憑證、沙箱、狀態方法、CLI/MCP 入口)——先看這個
references/control-protocols.md控制通道協定:通用機制 + 各家方法表 + 認證三態
references/cli-reference.md三個 CLI 的取得、子命令、參數語義、退出碼
references/mcp-servers.mdMCP 伺服器工具清單、兩種模式、接入方式
references/known-pitfalls.md實測坑位與排障路徑
references/upstream-sources.md上游文件地址、快照日期、怎麼重新整理這份參考
scripts/craft_ctl.py控制通道用戶端(三家認證差異已內建)
scripts/craft_env.py環境自檢:應用、版本、CLI、通道、憑證

相關技能