Agent规划
- 作者仓库星标 435
- 作者更新于 实时读取
- 作者仓库 nvim
- 领域
- 工程开发
- 兼容 Agent
-
- Claude Code
- Cursor
- Cline
- Codex
- Windsurf
- Gemini CLI
- +20
- 信任分
- 88 / 100 · 社区维护
- 作者 / 版本 / 许可
- @benbrastmckie · 未声明 license
- Token 消耗评级
- 较高消耗
- 接入复杂程度
- 需简单配置
- 是否需要外部 API Key
- 不需要
- 兼容的系统
- 未声明(默认跨平台)
- 底层运行要求
- 无特殊要求
- 文件与系统权限
-
- 只读
- 允许写入 / 修改
- Shell 执行
- 网络行为
- 仅限本地
- 安装命令数
- 26 条
档案由构建时根据 SKILL.md 与安装命令自动衍生,可能与作者实际意图存在差异。
需要注意: 未限定 allowed-tools,默认拥有全部工具权限。
---
name: skill-orchestrate
description: Autonomous state machine that drives a task through its full lifecycle (research -> plan -> impl…
category: 工程开发
runtime: 无特殊运行时
---
# skill-orchestrate 输出预览
## PART A: 任务判断
- 适用问题:代码实现、重构、调试或代码审查。
- 输入要求:目标材料、限制条件、期望输出和验收方式。
- 证据边界:围绕“Context References / Execution Flow / Stage 1: Input Validation”读取原文规则,不把推断写成作者承诺。
## PART B: 执行结果
- **01** 任务判断:确认你的需求是否属于代码实现、重构、调试或代码审查,并标出输入、限制和预期结果。
- **02** 执行计划:优先按“Context References / Execution Flow / Stage 1: Input Validation”拆成步骤,说明每一步会读取什么、修改什么、产出什么。
- **03** 交付结果:给出可复制的命令、文件改动、检查清单或内容草稿,并说明如何继续迭代。
- **04** 风险边界:结合 读取文件、写入/修改文件、执行终端命令、主要在本地完成、通常不需要额外 API Key 给出执行前确认项。
## Running Rules
- 读取文件、写入/修改文件、执行终端命令;主要在本地完成;通常不需要额外 API Key。
- 先小样例验证,再放大到真实任务。
- 交付时同时给结果、检查口径和下一步迭代建议。 原文出现了 `/orchestrate`、`/implement`、`/research`、`/revise` 这类斜杠命令;如果你的 Agent 支持命令触发,优先用命令开场,再补充目标和边界。
告诉 Agent 目标文件或材料、期望结果、不可改范围、是否允许联网或执行命令。本 Skill 的权限画像是:读取文件、写入/修改文件、执行终端命令。
先用一个小任务确认它会围绕“Context References / Execution Flow / Stage 1: Input Validation”工作;涉及文件或命令时,先看 diff、日志、预览或测试结果。
检查最终产物是否包含明确结果、必要证据和下一步动作;如果输出泛泛而谈,就补充输入、边界和验收标准后重跑。
---
name: skill-orchestrate
description: Autonomous state machine that drives a task through its full lifecycle (research -> plan -> impl…
category: 工程开发
source: benbrastmckie/nvim
---
# skill-orchestrate
## 什么时候使用
- 把工程方向的常用动作沉淀成 Agent 可调用的技能 适合处理工程开发场景下的代码实现、调试、重构、测试或代码审查,核心价值是把输入、判断、执行、验证和交付边界固定下来,避免 Agent 泛泛回答。 把任务拆成可执行、可检查、可继续迭代…
- 面向代码实现、重构、调试或代码审查,优先处理能明确输入、步骤和验收标准的工作。
## 需要提供什么
- 目标材料、目录范围、期望结果和不可改动内容。
- 是否允许联网、执行命令、读写文件或调用外部服务。
## 执行规则
- 围绕「Context References / Execution Flow / Stage 1: Input Validation」组织步骤,不把推断写成作者事实。
- 读取文件、写入/修改文件、执行终端命令;主要在本地完成;通常不需要额外 API Key。
- 先跑小样例,确认结果可检查后再扩大任务范围。
## 输出要求
- 给出最终产物、关键证据、验证方式和下一步动作。
- 信息不足时标记 unknown,不编造命令、平台或依赖。 作者原文负责流程事实;仓库文件负责来源和命令;流狐只补充适用场景、限制和质量判断。
skill "skill-orchestrate" {
输入层 -> 用户目标 + 目标文件 + 禁止范围 + 验收标准
上下文层 -> Context References / Execution Flow / Stage 1: Input Validation
规则层 -> SKILL.md 触发条件 / 执行顺序 / 输出格式
运行层 -> 无特殊运行时 | 读取文件、写入/修改文件、执行终端命令 | 主要在本地完成
安全层 -> 通常不需要额外 API Key + 小任务验证 + diff / 日志复核
输出层 -> 可复制结果 + 检查清单 + 下一步迭代
} Orchestrate Skill
Fire-and-forget autonomous loop implementing the 10-state task lifecycle state machine. Drives research, planning, implementation, and blocker escalation without user interaction.
Context References
Architecture documentation (load as needed):
.claude/docs/architecture/orchestrate-state-machine.md- Complete state table and transition diagram.claude/docs/architecture/handoff-schema.md- Orchestrator handoff JSON schema.claude/docs/architecture/dispatch-agent-spec.md- Fork vs. named subagent dispatch spec
Infrastructure (source as needed):
.claude/scripts/skill-base.sh- Shared skill lifecycle functions.claude/scripts/dispatch-agent.sh- Fork vs. named subagent dispatch functions
Execution Flow
Stage 1: Input Validation
source .claude/scripts/skill-base.sh
task_number=$(echo "$delegation_context" | jq -r '.task_context.task_number')
session_id=$(echo "$delegation_context" | jq -r '.session_id')
# Read task state without blocking on terminal states (orchestrate handles them gracefully)
PADDED_NUM=$(printf "%03d" "$task_number")
TASK_DATA=$(jq -r --argjson num "$task_number" \
'.active_projects[] | select(.project_number == $num)' \
specs/state.json)
if [ -z "$TASK_DATA" ]; then
echo "ERROR: Task $task_number not found in state.json" >&2
exit 1
fi
PROJECT_NAME=$(echo "$TASK_DATA" | jq -r '.project_name')
TASK_TYPE=$(echo "$TASK_DATA" | jq -r '.task_type // "general"')
DESCRIPTION=$(echo "$TASK_DATA" | jq -r '.description // ""')
TASK_DIR="specs/${PADDED_NUM}_${PROJECT_NAME}"
Stage 2: Preflight — Loop Guard
Create or read the loop guard file. This tracks cycle count across conversational turns.
MAX_CYCLES=5
loop_guard_file="${TASK_DIR}/.orchestrator-loop-guard"
handoff_file="${TASK_DIR}/.orchestrator-handoff.json"
mkdir -p "$TASK_DIR"
if [ -f "$loop_guard_file" ] && jq empty "$loop_guard_file" 2>/dev/null; then
# Resume: read existing guard
cycle_count=$(jq -r '.cycle_count // 0' "$loop_guard_file")
echo "[orchestrate] Resuming — cycle $cycle_count of $MAX_CYCLES"
else
# Fresh start: create guard
cycle_count=0
jq -n \
--arg session_id "$session_id" \
--argjson max_cycles "$MAX_CYCLES" \
--arg started "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
'{
"session_id": $session_id,
"cycle_count": 0,
"max_cycles": $max_cycles,
"current_state": "reading",
"started": $started,
"last_updated": $started
}' > "$loop_guard_file"
echo "[orchestrate] Starting fresh — MAX_CYCLES=$MAX_CYCLES"
fi
# Blocker escalation counter (reset each /orchestrate invocation)
blocker_escalation_count=0
MAX_BLOCKER_ESCALATIONS=2
Stage 3: State Machine Loop
The loop runs until a terminal condition is reached or MAX_CYCLES is hit.
while [ "$cycle_count" -lt "$MAX_CYCLES" ]; do
At the top of each iteration:
3a. Read current task status
current_status=$(jq -r --argjson num "$task_number" \
'.active_projects[] | select(.project_number == $num) | .status' \
specs/state.json)
echo "[orchestrate] Cycle $((cycle_count + 1))/$MAX_CYCLES — status: $current_status"
3b. Update loop guard with current state
jq --arg state "$current_status" \
--arg updated "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
--argjson count "$cycle_count" \
'.current_state = $state | .last_updated = $updated | .cycle_count = $count' \
"$loop_guard_file" > "${loop_guard_file}.tmp" && mv "${loop_guard_file}.tmp" "$loop_guard_file"
3c. Dispatch by state (see State Handlers in Stage 4)
Stage 4: State Handlers
State: not_started or not started
Dispatch research via named subagent.
dispatch_instructions = dispatch_agent "general-research-agent" \
"Research task $task_number: $DESCRIPTION" \
'{"task_number": N, "task_type": "T", "session_id": "S", "orchestrator_mode": false}' \
"false"
Invoke the Agent tool per dispatch_instructions (subagent_type: general-research-agent).
After Agent tool returns: read handoff (Stage 5). Increment cycle_count.
State: researching
In-flight state (another session is actively researching). Exit with warning.
echo "[orchestrate] WARNING: Task $task_number is currently being researched in another session."
echo "Wait for the research to complete, then run /orchestrate $task_number again."
EXIT (partial)
State: researched
Dispatch planning via named subagent.
research_artifacts=$(jq -c '[.active_projects[] | select(.project_number == N) | .artifacts // [] | .[] | select(.type == "report")] | .[0].path // ""' specs/state.json)
dispatch_instructions = dispatch_agent "planner-agent" \
"Create implementation plan for task $task_number" \
'{"task_number": N, "task_type": "T", "session_id": "S", "research_artifacts": [...], "orchestrator_mode": false}' \
"false"
Invoke the Agent tool per dispatch_instructions (subagent_type: planner-agent).
After Agent tool returns: read handoff. Increment cycle_count.
State: planning
In-flight state. Exit with warning (same pattern as researching).
State: planned or implementing
Dispatch implement via named subagent with orchestrator_mode: true.
plan_path=$(ls -1 "${TASK_DIR}/plans/"*.md 2>/dev/null | sort -V | tail -1)
dispatch_instructions = dispatch_agent "general-implementation-agent" \
"Implement task $task_number following the plan" \
'{"task_number": N, "task_type": "T", "session_id": "S", "orchestrator_mode": true,
"plan_path": "$plan_path"}' \
"false"
Invoke the Agent tool per dispatch_instructions (subagent_type: general-implementation-agent).
After Agent tool returns: read handoff. Increment cycle_count.
State: partial
Read .orchestrator-handoff.json to determine sub-state:
handoff=$(cat "$handoff_file" 2>/dev/null || echo '{}')
blockers=$(echo "$handoff" | jq -c '.blockers // []')
continuation=$(echo "$handoff" | jq -c '.continuation_context // null')
blocker_count=$(echo "$blockers" | jq 'length')
Sub-state: continuation available (continuation != null AND has handoff_path):
Dispatch implement with continuation context.
dispatch_instructions = dispatch_agent "general-implementation-agent" \
"Resume implementation for task $task_number from continuation handoff" \
'{"task_number": N, ..., "orchestrator_mode": true,
"plan_path": "$plan_path",
"continuation_context": {continuation_context_object}}' \
"false"
Sub-state: blockers present (blocker_count > 0):
Invoke blocker escalation (Stage 6). Increment cycle_count after escalation.
Sub-state: no handoff, no blockers (cycle limit or stuck):
echo "[orchestrate] Task $task_number in partial state with no continuation and no blockers."
echo "Cycle $cycle_count/$MAX_CYCLES consumed. Run /orchestrate $task_number to retry or /implement $task_number for manual resume."
EXIT (partial, cycle_count)
State: blocked
Read blockers from state.json (not handoff — task was blocked outside orchestrator context):
blocker_desc=$(jq -r --argjson num "$task_number" \
'.active_projects[] | select(.project_number == $num) | .blockers // "Unspecified blocker"' \
specs/state.json)
Invoke blocker escalation (Stage 6) with blocker_desc.
State: completed
echo "[orchestrate] Task $task_number completed successfully."
# Clean up loop guard
rm -f "$loop_guard_file"
EXIT (success)
States: abandoned, expanded
echo "[orchestrate] Task $task_number is in terminal state [$current_status]. No action taken."
EXIT (no-op)
Unknown state
echo "[orchestrate] WARNING: Unrecognized state '$current_status' for task $task_number."
EXIT (partial)
Stage 5: Handoff Reading (after each dispatch)
After every Agent tool invocation, read the orchestrator handoff to learn the outcome. Never read the full research report, plan, or implementation summary — only the handoff.
if [ ! -f "$handoff_file" ]; then
echo "[orchestrate] ERROR: Skill did not write orchestrator handoff."
echo "This may mean orchestrator_mode was not propagated correctly."
# Increment cycle and continue — state.json may still have been updated
else
handoff=$(cat "$handoff_file")
dispatch_status=$(echo "$handoff" | jq -r '.status')
dispatch_summary=$(echo "$handoff" | jq -r '.summary // ""')
blockers=$(echo "$handoff" | jq -c '.blockers // []')
continuation=$(echo "$handoff" | jq -c '.continuation_context // null')
next_hint=$(echo "$handoff" | jq -r '.next_action_hint // "none"')
echo "[orchestrate] Dispatch result: $dispatch_status — $dispatch_summary"
fi
# Increment cycle_count
cycle_count=$((cycle_count + 1))
Stage 6: Blocker Escalation (5-Step Sequence)
Called when: partial state with non-empty blockers, or blocked state.
Capped at MAX_BLOCKER_ESCALATIONS=2 per /orchestrate invocation.
blocker_escalation() {
local blocker_desc="$1"
local task_number="$2"
local session_id="$3"
if [ "$blocker_escalation_count" -ge "$MAX_BLOCKER_ESCALATIONS" ]; then
echo "[orchestrate] ERROR: Blocker escalation cap ($MAX_BLOCKER_ESCALATIONS) reached."
echo "Manual intervention required. Blocker: $blocker_desc"
echo "Suggested actions:"
echo " 1. Run /research $task_number to research the blocker manually"
echo " 2. Run /revise $task_number to update the plan"
echo " 3. Run /implement $task_number to re-attempt implementation"
return 1
fi
blocker_escalation_count=$((blocker_escalation_count + 1))
echo "[orchestrate] Blocker escalation attempt $blocker_escalation_count/$MAX_BLOCKER_ESCALATIONS"
echo " Blocker: $blocker_desc"
# Step 1: DETECT (already done by caller; blocker_desc passed in)
# Step 2: RESEARCH FORK (cache-warm, is_blocker_escalation=true)
source .claude/scripts/dispatch-agent.sh
blocker_research_prompt="Research this specific blocker for task $task_number: $blocker_desc. Find the root cause and a concrete solution path."
fork_context=$(jq -n \
--argjson num "$task_number" \
--arg session_id "$session_id" \
--arg blocker "$blocker_desc" \
'{"task_number": $num, "session_id": $session_id, "blocker": $blocker, "orchestrator_mode": false}')
dispatch_agent "" "$blocker_research_prompt" "$fork_context" "true"
# SKILL.md reads this output and invokes the Agent tool as a fork (omitting subagent_type)
# After Agent tool returns: read handoff for research findings
# Step 3: READ FINDINGS (from handoff)
findings_summary=$(jq -r '.summary // "No findings"' "$handoff_file" 2>/dev/null)
findings_artifact=$(jq -r '.artifacts[0].path // ""' "$handoff_file" 2>/dev/null)
echo "[orchestrate] Research findings: $findings_summary"
# Step 4: REVISE PLAN (named reviser-agent)
plan_path=$(ls -1 "${TASK_DIR}/plans/"*.md 2>/dev/null | sort -V | tail -1)
revise_context=$(jq -n \
--argjson num "$task_number" \
--arg session_id "$session_id" \
--arg findings "$findings_summary" \
--arg plan_path "${plan_path:-}" \
'{"task_number": $num, "session_id": $session_id,
"research_findings": $findings,
"plan_path": $plan_path,
"orchestrator_mode": false}')
dispatch_agent "reviser-agent" \
"Revise the implementation plan for task $task_number to address this blocker: $blocker_desc. Research findings: $findings_summary" \
"$revise_context" "false"
# SKILL.md invokes the Agent tool (subagent_type: reviser-agent)
# After Agent tool returns: read handoff to confirm revision
# Step 5: RE-DISPATCH IMPLEMENT (orchestrator_mode=true)
revised_plan_path=$(ls -1 "${TASK_DIR}/plans/"*.md 2>/dev/null | sort -V | tail -1)
implement_context=$(jq -n \
--argjson num "$task_number" \
--arg session_id "$session_id" \
--arg plan_path "${revised_plan_path:-}" \
'{"task_number": $num, "session_id": $session_id,
"orchestrator_mode": true,
"plan_path": $plan_path}')
dispatch_agent "general-implementation-agent" \
"Implement task $task_number following the revised plan" \
"$implement_context" "false"
# SKILL.md invokes the Agent tool (subagent_type: general-implementation-agent)
# After Agent tool returns: read handoff
return 0
}
Stage 7: Loop Guard Update (end of each cycle)
After each cycle (whether dispatch succeeded or failed):
jq --arg state "$current_status" \
--arg updated "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
--argjson count "$cycle_count" \
'.current_state = $state | .last_updated = $updated | .cycle_count = $count' \
"$loop_guard_file" > "${loop_guard_file}.tmp" && mv "${loop_guard_file}.tmp" "$loop_guard_file"
If MAX_CYCLES reached (cycle_count >= MAX_CYCLES):
echo "[orchestrate] MAX_CYCLES ($MAX_CYCLES) reached for task $task_number."
echo "Current state: $current_status. Run /orchestrate $task_number to continue."
EXIT (partial)
Stage 8: Postflight
On clean exit (task completed or terminal state):
# Remove loop guard on success
rm -f "$loop_guard_file"
echo "[orchestrate] Task $task_number: orchestration complete."
echo "Final status: $current_status | Cycles used: $cycle_count/$MAX_CYCLES"
On partial exit (MAX_CYCLES, in-flight warning, escalation cap):
# Preserve loop guard for next /orchestrate invocation
echo "[orchestrate] Task $task_number: orchestration paused."
echo "Status: $current_status | Cycles: $cycle_count/$MAX_CYCLES | Run /orchestrate $task_number to continue."
Write metadata file:
mkdir -p "${TASK_DIR}/summaries"
jq -n \
--arg status "implemented" \
--argjson cycles "$cycle_count" \
--arg final_state "$current_status" \
'{
"status": $status,
"metadata": {
"cycles_used": $cycles,
"final_state": $final_state
}
}' > "${TASK_DIR}/.return-meta.json"
MUST NOT (Context Flatness Constraint)
This skill MUST NOT:
- Read research reports (
reports/*.md) during the state machine loop - Read plan files (
plans/*.md) during the state machine loop - Read implementation summaries (
summaries/*.md) during the state machine loop - Read continuation handoff files (
handoffs/*.md) — pass the path, not the content
The ONLY file read after each dispatch is .orchestrator-handoff.json (≤400 tokens).
This ensures context grows by only ~450 tokens per cycle regardless of artifact complexity.
Skill-to-Agent Mapping
| Operation | Agent Type | Mode |
|---|---|---|
| Research dispatch | general-research-agent |
Named subagent |
| Plan dispatch | planner-agent |
Named subagent |
| Implement dispatch | general-implementation-agent |
Named subagent, orchestrator_mode=true |
| Blocker research | (no type — fork inherits parent) | Fork (cache-warm) |
| Plan revision | reviser-agent |
Named subagent |
先判断是否适合
作者设计意图
作者的方法与取舍
边界和复核