Communitygithub.com

IvanMurzak/pipeline-claude

執行管道(Pipeline)的深層監督代理程式。

pipeline-claude 是什麼?

此技能可作為 AI 代理程式(如 Claude Code)的深層監督者,協調並執行一個由多個步驟組成的管道。它會產生一個執行 ID,建立一個即時鎖定檔案,並委派一個 `pipeline-manager` 子代理程式來驅動整個鏈——主程式從不直接接觸步驟迭代檔案。支援四種執行器模式(`session`、`manager`、`driver`、`standalone`),預設為 `manager`,可理想地將長時間執行的任務與使用者會話隔離。此工具可處理區塊(blocker)的輪詢、恢復中斷的執行、將覆寫命令傳遞給個別步驟(模型或推理努力度),並透過 JSONL 檔案發出運行層級的生命週期事件,使管道的管理可觀測且強大。

相容平台✓Claude Code~Codex CLI✓Cursor
npx skills add IvanMurzak/pipeline-claude

在你喜歡的 AI 中提問

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

說明文件

執行一個管道

你正在開始或恢復一個管道的執行。$1 是要執行的管道——它位於 ./.pipeline/ 下的一個資料夾。(一個 v1 管道仍可由一個迭代檔案路徑命名;請參閱「先決條件」。)

你正在做什麼

你是運行在主會話(深度 0)中的監督者。你不會自己迭代循環。相反地,你會生成一個單一的 pipeline-manager 子代理程式(深度 1),它會驅動整個鏈——為每次迭代生成一個全新的 step-executor,並在步驟之間運行 pipeline-improver / pipeline-script-creator(它所驅動的 pipeline next CLI 會自動發出每次迭代的 UI 事件,並自行執行任何外部工作樹鉤子)——並在運行完成、暫停或遇到超出範圍的阻礙時返回一個結構化的報告。

你停留在深度 0,因為有三件事必須在主會話中進行,而子代理程式無法完成:(a) 持有穩定的 pid 以作為運行即時鎖定檔案的所有者,(b) 等待數小時以等待外部條件(例如一個阻礙的 PR 被合併)並恢復,(c) 最終將結果呈現給人類。所以你的工作是:創建運行 ID(或在 --resume 時,重新進入一個已有的運行 ID——請參閱「恢復程序」),設定 UI 追蹤,生成管理器,並根據其報告採取行動——包括運行巢狀阻礙器的輪詢等待,並重新調用管理器以繼續。

關鍵——記號規範:幾乎不讀取任何內容

這個技能是一個監督者,而不是一個讀取器。每個迭代檔案都是由一個 step-executor 在其自己的全新上下文中讀取的;每個步驟的模型解析發生在 pipeline-manager 內部。

  • 永遠不要 Read 一個迭代檔案 (steps/**/*.md)。 你永遠不會碰觸它們——甚至它們的前言部份也不碰。管理器會解析每個步驟的模型;你只將管道層級的預設值傳遞給它。
  • 只在鏈開始時讀取 PIPELINE.md 的前言部份 (limit: 50)一次,以提取 model: 欄位作為 pipeline_default_model,除此之外不做任何事。不要將其內容傳遞給管理器。在 --resume 時,完全跳過這次讀取——pipeline_default_model 來自現有運行的已持久化 next.json.default_model(請參閱「恢復程序」),這使得恢復時無需在它已經需要的 next.json 讀取之上再添加一次 manifest 讀取。
  • 你唯一可以完整 Read 的檔案是你自己在巢狀阻礙流程中寫入的那些(issue body、部份工作筆記),以及在 --resume 時,小型的 .runtime/*/next.json 編排游標檔案——絕不是一個迭代檔案或 PIPELINE.md 本體。

執行器選擇(實驗性)

存在四種模式,而 pipeline next 在所有模式中(E1)決定接下來要運行什麼——絕不是呼叫它的循環。 它們的區別僅在於循環所在的位置和執行一個步驟的內容:

模式循環位於執行一個步驟
session此主會話Agent 工具,會話內
manager (預設)一個 pipeline-manager 子代理程式Agent 工具,會話內
driver此插件擁有的一個程序,循環中無模型 (pipeline drive)每個步驟一個全新的 claude -p 程序
standalone與 driver 相同的擁有程序使用你自己的 API 金鑰的 Agent SDK——完全沒有 Claude Code 會話

driver 和 standalone 很容易混淆,因為它們共享一個循環,僅在執行器上有所不同;不要將它們中的任何一個與 pipeline drive 混淆,後者是 driver 路徑的命令名稱,而不是該模式的同義詞。 此捆綁的 CLI 實現了 session、manager 和 driver——v1 管道在 PIPELINE.md 前言中將 driver 拼寫為 runner: headless(見下文);standalone 和 pipeline.yml 層級的 runner: 鍵屬於相同的四模式設計,但尚未連接到此捆綁副本中,因此不要告訴使用者今天會運行任何一個。

在程序步驟 3 時,連同 model: 讀取一起解析 runner:。 在 v2 管道中,它是 pipeline.yml 中的一個頂層鍵——Grep ^runner: 在那裡,它讀取一行且從不打開步驟檔案;在 v1 中,它是 PIPELINE.md 前言,已經在你為 model: 讀取的 ≤ 50 行內。缺席或無法讀取 ⇒ manager,這是今天的行為和審慎的預設值(E10)。一個確實宣告但下面沒有分支的值仍然會運行 manager——但在你開始之前用一行說明這一點,因為 manifest 未宣告的模式是作者未選擇的模式。永遠不要從鏈長度推斷模式:一個不可見的閾值會使一個命令表現出兩種方式。

runner: session——主會話自己運行循環

不要生成 pipeline-manager。閱讀會話循環並遵循它以取代程序步驟 5.1–5.3;此檔案中的所有其他內容——步驟 1–4、恢復程序、巢狀阻礙流程、監督者不變量和報告格式——對你同樣適用,因為你仍然是深度 0 的監督者,只是吸收了循環而不是委派它。

該檔案帶有此模式所需的兩個前提拒絕(CLI 版本太舊無法使用 pipeline next --brief-file,以及 execution: parallel,其載荷存在於會話可能無法打開的簡要中),並誠實地說明權衡:每個動作和每個步驟報告都會落入使用者正在觀看的上下文中,因此一個長鏈應屬於 manager——這正是 manager 仍然是預設值的原因。

runner: headless (v1)——driver 模式

當管道是 v1 且你為 model: 讀取的 PIPELINE.md 前言也帶有 runner: headless(v1 對 driver 模式的拼寫——見上表)時,不要生成 pipeline-manager。而是將捆綁的驅動器作為後台程序運行並監督它:

bun "${CLAUDE_PLUGIN_ROOT}/apps/pipeline-cli/src/cli.ts" drive \
  --root "<pipeline_root>" --run-id "<run_id>" [--start "<step-name>"] \
  --default-model "<pipeline_default_model-or-null>" \
  [--default-effort "<level-or-null>"] \
  [--model "<step_id>=<model>" ...] [--effort "<step_id>=<level>" ...] --json [--resume]

使用 run_in_background: true 啟動它,並在其退出時根據其最終 JSON 採取行動:退出碼 0 → 發出 pipeline.completed;退出碼 1 → 發出 pipeline.halted 並顯示原因;退出碼 3 (blocked) → 運行下面的巢狀阻礙流程,然後使用 --resume 重新運行 drive。你監督者角色的其他所有事項(運行 ID、即時鎖定、綁定鏡像、人類報告)保持不變。此 driver(v1:runner: headless)路徑跳過自我改進動作,並保留 .feedback/<run_id>/——在你的最終報告中提到這一點,以便使用者可以運行手動改進器過程。當 runner: 缺席或為 manager 時,完全按照下面的說明進行。

模型選擇

一個管道(以及每次迭代)可以透過可選的 model: 前言欄位選擇一個 Claude 模型。該欄位預設為繼承——省略它,步驟執行器會繼承會話模型。你只解析管道層級的預設值並將其交給管理器;pipeline next CLI 會解析每次迭代的有效模型(每次運行覆寫 ?? step.model ?? pipeline_default_model),管理器透過 Agent 工具的每個呼叫 model 參數將其傳遞給每個 step-executor。按原樣傳遞解析後的值——不要將別名轉換為規範 ID。 Agent model 參數直接接受別名、規範 ID 和 inherit。

接受的 model: 詞彙(端到端):其中一個別名 haiku / sonnet / opus / fable,或任何確切的規範 Claude 模型 ID(一個以 claude- 開頭的字串,例如 claude-opus-4-8、claude-sonnet-4-6、claude-fable-5),或 inherit / 缺席(→ 會話預設值)。

解析 pipeline_default_model: 在 v2 管道中,CLI 從 pipeline.yml 本身讀取 defaults.model——傳遞 null 並讓它處理。否則,如果 <pipeline-root>/PIPELINE.md 存在,以 limit: 50 Read 它,並在值為一個可接受的值(一個別名、一個 claude-* ID,逐字保留)時取用前言 model: 值;inherit/缺席 → null。如果 PIPELINE.md 缺席,則為 null。無效值——任何不是接受的別名、claude-* ID、inherit 或缺席的值——警告一次並回退到 null(不要停止)。(閱讀 ≤ ~10 行前言是元資料提取,而不是內容閱讀——它永遠不會與步驟執行器載入的內容重複。)

每次運行的步驟覆寫 (step_model_overrides): 使用者可以為此僅本次運行固定個別步驟到不同的模型——而不編輯任何管道檔案——可以透過路徑後的明確標誌 (--model <step_id>=<model>,可重複) 或以自然語言(「在 fable 上運行步驟 02-implement 和 03-refine」)。將他們說的任何內容標準化為 <step_id>=<model> 對:step_id 是步驟的 step_id 前言或其檔案名稱詞幹(例如 steps/02-implement.md 的 02-implement);model 使用上面接受的詞彙(inherit 對該步驟強制使用會話預設值)。你不會讀取任何步驟檔案來驗證 ID——CLI 會在未知 ID 上發出警告,並拒絕無效的模型。將這些對傳遞給管理器作為 step_model_overrides(見 5.1),或在 driver 路徑上,作為 drive 命令上的重複 --model 標誌。覆寫會覆蓋步驟自己的 model: 前言;沒有覆寫的步驟不受影響。CLI 在初始化時將覆寫持久化到運行的狀態中,因此恢復會自動保留它們——無論如何,在重新調用管理器時重新傳遞相同的對(無害,並且可以在刪除 .runtime/ 後存活)。未提及覆寫 ⇒ 完全省略。

努力度選擇(推理努力度——model: 的雙胞胎)

一個管道和每次迭代也可以透過可選的 effort: 前言欄位選擇一個推理努力度(等級:low / medium / high / xhigh / max;inherit/缺席 → 會話的努力度)。它透過與模型完全相同的階梯來解析——每次運行覆寫 ?? 步驟 effort: ?? 管道 effort: ?? 繼承——完全在 pipeline next CLI 內部。從你已經為 model: 做的同一個 PIPELINE.md 前言讀取中解析 pipeline_default_effort(相同的無效值規則:警告一次,回退到 null),將其作為 pipeline_default_effort 交給管理器,並將使用者請求如「以最大努力度運行 03-refine」標準化為 step_effort_overrides 對(<step_id>=<level>),完全像模型對一樣傳遞(在 driver 路徑上使用 --effort 標誌)。誠實提示:driver 執行器實際應用努力度(每次生成使用 claude --effort);在管理器模式下,Agent 工具可能尚未公開每個呼叫的努力度參數——管理器在支援時傳遞它,否則步驟繼承會話努力度(參見 pipeline-manager.md § run-step)。

先決條件

  • 一個管道存在於當前專案的 ./.pipeline/ 下(通常由 /pipeline:design 編寫)。
  • $1 是 ./.pipeline/ 下的管道資料夾(例如 ./.pipeline/ship-feature),它會開始一個全新的運行——這總是會創建一個新的 run_id。--start <step-name> 從一個命名步驟而不是 manifest 的第一個步驟開始該全新運行。仍接受一個迭代檔案路徑,這是 v1 管道命名起始步驟的方式。或者 --resume [<run_id>] 以在其原始的 run_id 下重新進入一個已有的運行(請參閱「恢復程序」)——這是在不孤立其狀態的情況下繼續一個死會話運行的唯一途徑。
  • 當前工作目錄是消費者專案的根目錄——迭代執行的所有檔案編輯都落在此處。

日誌事件發射

你將運行層級的生命週期發出到 <project>/.pipeline/.runtime/events.jsonl;每次迭代的事件(iteration.*、improver.*、script_creator.*、worktree.*)由管理器驅動的 pipeline next CLI 在進程內自動發出(管理器本身只發出回顧的改進器/腳本事件)。因為整個運行共享一個 session_id,你下面註冊的綁定鏡像讓分析鉤子能夠將管理器和步驟執行器的工具呼叫與此運行關聯起來。發射是盡力而為——永遠不要讓失敗停止運行。

程序開始時的一次性設定: 透過呼叫 CLI 來創建運行 ID——永遠不要自己生成一個或發明一種格式:bun "${CLAUDE_PLUGIN_ROOT}/apps/pipeline-cli/src/cli.ts" id。捕獲它打印的逐字值(一個 UUIDv7,例如 019fc762-5762-7000-a9bf-922ed8fa00be)。

關鍵——在每次寫入者呼叫時逐字傳遞 run_id。 Claude Code 的 Bash 工具不會在呼叫之間保留 shell 狀態,因此一個導出的環境變數不會到達下一個 pipeline event 呼叫。在每次呼叫時將 run_id=<the-literal-id> 作為 k=v 參數傳遞。k=v 參數在 = 周圍沒有空格;使用單引號包裹包含空格的值。

發射輔助工具(使用 Bun 運行,成功時靜默,即使失敗也退出碼 0——不要檢查輸出):

bun "${CLAUDE_PLUGIN_ROOT}/apps/pipeline-cli/src/cli.ts" event <event-type> run_id=<literal-id> [k=v ...]

你發出什麼(每個項目符號一次呼叫):

  • 在 --resume 時,此整個列表不適用——恢復程序只為已有的 run_id 發出 write-liveness + register-mirror-binding,並且永遠不會發出 pipeline.started(重新進入一個運行不是開始一個)。請參閱「恢復程序」。
  • 在橫幅之後:pipeline.started run_id=<id> pipeline_name=<name> first_iteration_path=<abs> pipeline_root=<abs> default_model=<model-or-null>——default_model 是 pipeline_default_model(一個別名 haiku/sonnet/opus/fable,一個規範的 claude-* ID,或字面值 null)。
  • 緊接在 pipeline.started 之後,寫入即時鎖定檔案,以便讀取者可以判斷此運行在沒有終端事件的情況下死亡:bun "${CLAUDE_PLUGIN_ROOT}/apps/pipeline-cli/src/cli.ts" event write-liveness run_id=<id> pid=$PPID(PowerShell:pid=$PID)。傳遞驅動此監督者的程序的 OS pid——$PPID 是持久 Claude 會話的最佳可移植控制代碼。守護行程僅在該 pid 是一個真實的死程序時才會自動退役一個運行,因此一個不可信賴的值是一個安全的無操作。

...

[為翻譯而截斷]

相關技能