team-planex

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Team PlanEx

Team PlanEx

2 成员边规划边执行团队。通过 Wave Pipeline(波次流水线)实现 planner 和 executor 并行工作:planner 完成一个 wave 的 queue 后立即创建 EXEC-* 任务,同时进入下一 wave 规划。所有成员通过
--role=xxx
路由。
由Planner(规划者)和Executor(执行者)组成的双人团队,支持边规划边执行。通过Wave Pipeline(波次流水线)实现Planner与Executor的并行协作:Planner完成一个Wave的任务队列后,立即创建EXEC-*任务,同时启动下一个Wave的规划工作。所有角色通过
--role=xxx
参数进行路由。

Architecture Overview

架构概述

┌──────────────────────────────────────────────┐
│  Skill(skill="team-planex", args="--role=xxx") │
└────────────────┬─────────────────────────────┘
                 │ Role Router
         ┌───────┴───────┐
         ↓               ↓
    ┌─────────┐    ┌──────────┐
    │ planner │    │ executor │
    │ PLAN-*  │    │ EXEC-*   │
    └─────────┘    └──────────┘
设计原则: 只有 2 个角色,没有独立 coordinator。SKILL.md 入口承担轻量编排(创建团队、派发初始任务链),然后 planner 担任 lead 角色持续推进。
┌──────────────────────────────────────────────┐
│  Skill(skill="team-planex", args="--role=xxx") │
└────────────────┬─────────────────────────────┘
                 │ Role Router
         ┌───────┴───────┐
         ↓               ↓
    ┌─────────┐    ┌──────────┐
    │ planner │    │ executor │
    │ PLAN-*  │    │ EXEC-*   │
    └─────────┘    └──────────┘
设计原则:仅包含两个角色,无独立协调者(Coordinator)角色。SKILL.md入口承担轻量编排职责(创建团队、派发初始任务链),后续由Planner担任主导角色持续推进工作。

Role Router

角色路由

Input Parsing

输入解析

javascript
const args = "$ARGUMENTS"
const roleMatch = args.match(/--role[=\s]+(\w+)/)

if (!roleMatch) {
  // No --role: orchestration mode (lightweight coordinator)
  // → See "Orchestration Mode" section below
}

const role = roleMatch[1]
const teamName = args.match(/--team[=\s]+([\w-]+)/)?.[1] || "planex"
javascript
const args = "$ARGUMENTS"
const roleMatch = args.match(/--role[=\s]+(\w+)/)

if (!roleMatch) {
  // 未传入--role:进入编排模式(轻量协调器)
  // → 详见下方「编排模式」章节
}

const role = roleMatch[1]
const teamName = args.match(/--team[=\s]+([\w-]+)/)?.[1] || "planex"

Role Dispatch

角色分发

javascript
const VALID_ROLES = {
  "planner":  { file: "roles/planner.md",  prefix: "PLAN" },
  "executor": { file: "roles/executor.md", prefix: "EXEC" }
}

if (!VALID_ROLES[role]) {
  throw new Error(`Unknown role: ${role}. Available: ${Object.keys(VALID_ROLES).join(', ')}`)
}

// Read and execute role-specific logic
Read(VALID_ROLES[role].file)
// → Execute the 5-phase process defined in that file
javascript
const VALID_ROLES = {
  "planner":  { file: "roles/planner.md",  prefix: "PLAN" },
  "executor": { file: "roles/executor.md", prefix: "EXEC" }
}

if (!VALID_ROLES[role]) {
  throw new Error(`Unknown role: ${role}. Available: ${Object.keys(VALID_ROLES).join(', ')}`)
}

// 读取并执行角色专属逻辑
Read(VALID_ROLES[role].file)
// → 执行该文件中定义的5阶段流程

Available Roles

可用角色

RoleTask PrefixResponsibilityReuses AgentRole File
planner
PLAN-*需求拆解 → issue 创建 → 方案设计 → 队列编排 → EXEC 任务派发issue-plan-agent, issue-queue-agentroles/planner.md
executor
EXEC-*加载 solution → 代码实现 → 测试 → 提交code-developerroles/executor.md
角色任务前缀职责复用Agent角色文件
planner
PLAN-*需求拆解→创建Issue→方案设计→队列编排→派发EXEC-*任务issue-plan-agent, issue-queue-agentroles/planner.md
executor
EXEC-*加载方案→代码实现→测试验证→提交代码code-developerroles/executor.md

Input Types

输入类型

支持 3 种输入方式(通过 args 传入 planner):
输入类型格式示例
Issue IDs直接传入 ID
--role=planner ISS-20260215-001 ISS-20260215-002
需求文本
--text '...'
--role=planner --text '实现用户认证模块'
Plan 文件
--plan path
--role=planner --plan plan/2026-02-15-auth.md
支持3种输入方式(通过参数传递给Planner):
输入类型格式示例
Issue ID直接传入ID
--role=planner ISS-20260215-001 ISS-20260215-002
需求文本
--text '...'
--role=planner --text '实现用户认证模块'
规划文件
--plan path
--role=planner --plan plan/2026-02-15-auth.md

Shared Infrastructure

共享基础设施

Role Isolation Rules

角色隔离规则

Output Tagging(强制)

输出标记(强制)

javascript
SendMessage({ content: `## [${role}] ...`, summary: `[${role}] ...` })
mcp__ccw-tools__team_msg({ summary: `[${role}] ...` })
javascript
SendMessage({ content: `## [${role}] ...`, summary: `[${role}] ...` })
mcp__ccw-tools__team_msg({ summary: `[${role}] ...` })

Planner 边界

Planner 角色边界

允许禁止
需求拆解 (issue 创建)❌ 直接编写/修改代码
方案设计 (issue-plan-agent)❌ 调用 code-developer
队列编排 (issue-queue-agent)❌ 运行测试
创建 EXEC-* 任务❌ git commit
监控进度 (消息总线)
允许操作禁止操作
需求拆解(创建Issue)❌ 直接编写/修改代码
方案设计(调用issue-plan-agent)❌ 调用code-developer
队列编排(调用issue-queue-agent)❌ 运行测试
创建EXEC-*任务❌ Git提交
通过消息总线监控进度

Executor 边界

Executor 角色边界

允许禁止
处理 EXEC-* 前缀的任务❌ 创建 issue
调用 code-developer 实现❌ 修改 solution/queue
运行测试验证❌ 为 planner 创建 PLAN-* 任务
git commit 提交❌ 直接与用户交互 (AskUserQuestion)
SendMessage 给 planner
允许操作禁止操作
处理带EXEC-*前缀的任务❌ 创建Issue
调用code-developer实现功能❌ 修改方案/任务队列
运行测试验证❌ 为Planner创建PLAN-*任务
Git提交代码❌ 直接与用户交互(调用AskUserQuestion)
向Planner发送消息

Team Configuration

团队配置

javascript
const TEAM_CONFIG = {
  name: "planex",
  sessionDir: ".workflow/.team/PEX-{slug}-{date}/",
  msgDir: ".workflow/.team-msg/planex/",
  issueDataDir: ".workflow/issues/"
}
javascript
const TEAM_CONFIG = {
  name: "planex",
  sessionDir: ".workflow/.team/PEX-{slug}-{date}/",
  msgDir: ".workflow/.team-msg/planex/",
  issueDataDir: ".workflow/issues/"
}

Message Bus

消息总线

javascript
mcp__ccw-tools__team_msg({
  operation: "log",
  team: teamName,
  from: role,
  to: role === "planner" ? "executor" : "planner",
  type: "<type>",
  summary: `[${role}] <summary>`,
  ref: "<file_path>"
})
Message types by role:
RoleTypes
planner
wave_ready
,
queue_ready
,
all_planned
,
error
executor
impl_complete
,
impl_failed
,
wave_done
,
error
javascript
mcp__ccw-tools__team_msg({
  operation: "log",
  team: teamName,
  from: role,
  to: role === "planner" ? "executor" : "planner",
  type: "<type>",
  summary: `[${role}] <summary>`,
  ref: "<file_path>"
})
各角色的消息类型:
角色消息类型
Planner
wave_ready
,
queue_ready
,
all_planned
,
error
Executor
impl_complete
,
impl_failed
,
wave_done
,
error

CLI Fallback

CLI 降级方案

javascript
Bash(`ccw team log --team "${teamName}" --from "${role}" --to "${role === 'planner' ? 'executor' : 'planner'}" --type "<type>" --summary "<summary>" --json`)
javascript
Bash(`ccw team log --team "${teamName}" --from "${role}" --to "${role === 'planner' ? 'executor' : 'planner'}" --type "<type>" --summary "<summary>" --json`)

Task Lifecycle (Both Roles)

任务生命周期(所有角色)

javascript
const tasks = TaskList()
const myTasks = tasks.filter(t =>
  t.subject.startsWith(`${VALID_ROLES[role].prefix}-`) &&
  t.owner === role &&
  t.status === 'pending' &&
  t.blockedBy.length === 0
)
if (myTasks.length === 0) return // idle
const task = TaskGet({ taskId: myTasks[0].id })
TaskUpdate({ taskId: task.id, status: 'in_progress' })
// Phase 2-4: Role-specific (see roles/{role}.md)
// Phase 5: Report + Loop
javascript
const tasks = TaskList()
const myTasks = tasks.filter(t =>
  t.subject.startsWith(`${VALID_ROLES[role].prefix}-`) &&
  t.owner === role &&
  t.status === 'pending' &&
  t.blockedBy.length === 0
)
if (myTasks.length === 0) return // 无待处理任务,进入空闲状态
const task = TaskGet({ taskId: myTasks[0].id })
TaskUpdate({ taskId: task.id, status: 'in_progress' })
// 阶段2-4:角色专属流程(详见roles/{role}.md)
// 阶段5:结果上报+循环执行

Wave Pipeline

Wave Pipeline(波次流水线)

Wave 1:  planner 创建 issues + 规划 solutions + 形成 queue
                ↓ (queue ready → 创建 EXEC-* 任务)
Wave 1 执行:  executor 开始实现  ←→  planner 继续规划 Wave 2
Wave 2 执行:  executor 实现 Wave 2  ←→  planner 规划 Wave 3
                ...
Final:   planner 发送 all_planned → executor 完成剩余 EXEC-* → 结束
波次规则:
  • planner 每完成一个 wave 的 queue 后,立即创建 EXEC-* 任务供 executor 消费
  • planner 不等待 executor 完成当前 wave,直接进入下一 wave
  • executor 持续轮询并消费可用的 EXEC-* 任务
  • 当 planner 发送
    all_planned
    消息后,executor 完成所有剩余任务即可结束
Wave 1:Planner创建Issue+规划方案+形成任务队列
                ↓(队列就绪→创建EXEC-*任务)
Wave 1执行:Executor开始实现 ←→ Planner继续规划Wave 2
Wave 2执行:Executor实现Wave2任务 ←→ Planner规划Wave3
                ...
最终阶段:Planner发送all_planned消息→Executor完成剩余EXEC-*任务→流程结束
波次规则
  • Planner完成一个Wave的任务队列后,立即创建EXEC-*任务供Executor处理
  • Planner无需等待Executor完成当前Wave,直接启动下一个Wave的规划
  • Executor持续轮询并处理可用的EXEC-*任务
  • 当Planner发送
    all_planned
    消息后,Executor完成所有剩余任务即可结束流程

Execution Method Selection

执行方式选择

在编排模式或直接调用 executor 前,必须先确定执行方式。支持 3 种执行后端:
Executor后端适用场景
agent
code-developer subagent简单任务、同步执行
codex
ccw cli --tool codex --mode write
复杂任务、后台执行
gemini
ccw cli --tool gemini --mode write
分析类任务、后台执行
在编排模式或直接调用Executor前,必须先确定执行方式。支持3种执行后端:
执行器后端适用场景
agent
code-developer子Agent简单任务、同步执行
codex
ccw cli --tool codex --mode write
复杂任务、后台执行
gemini
ccw cli --tool gemini --mode write
分析类任务、后台执行

选择逻辑

选择逻辑

javascript
// ★ 统一 auto mode 检测:-y/--yes 从 $ARGUMENTS 或 ccw 传播
const autoYes = /\b(-y|--yes)\b/.test(args)
const explicitExec = args.match(/--exec[=\s]+(agent|codex|gemini|auto)/i)?.[1]

let executionConfig

if (explicitExec) {
  // 显式指定
  executionConfig = {
    executionMethod: explicitExec.charAt(0).toUpperCase() + explicitExec.slice(1),
    codeReviewTool: "Skip"
  }
} else if (autoYes) {
  // Auto 模式:默认 Agent + Skip review
  executionConfig = { executionMethod: "Auto", codeReviewTool: "Skip" }
} else {
  // 交互选择
  executionConfig = AskUserQuestion({
    questions: [
      {
        question: "选择执行方式:",
        header: "Execution",
        multiSelect: false,
        options: [
          { label: "Agent", description: "code-developer agent(同步,适合简单任务)" },
          { label: "Codex", description: "Codex CLI(后台,适合复杂任务)" },
          { label: "Gemini", description: "Gemini CLI(后台,适合分析类任务)" },
          { label: "Auto", description: "根据任务复杂度自动选择" }
        ]
      },
      {
        question: "执行后是否进行代码审查?",
        header: "Code Review",
        multiSelect: false,
        options: [
          { label: "Skip", description: "不审查" },
          { label: "Gemini Review", description: "Gemini CLI 审查" },
          { label: "Codex Review", description: "Git-aware review(--uncommitted)" },
          { label: "Agent Review", description: "当前 agent 审查" }
        ]
      }
    ]
  })
}

// Auto 解析:根据 solution task_count 决定
function resolveExecutor(taskCount) {
  if (executionConfig.executionMethod === 'Auto') {
    return taskCount <= 3 ? 'agent' : 'codex'
  }
  return executionConfig.executionMethod.toLowerCase()
}
javascript
// ★ 自动模式统一检测:-y/--yes参数从$ARGUMENTS或ccw工具传播
const autoYes = /\b(-y|--yes)\b/.test(args)
const explicitExec = args.match(/--exec[=\s]+(agent|codex|gemini|auto)/i)?.[1]

let executionConfig

if (explicitExec) {
  // 显式指定执行方式
  executionConfig = {
    executionMethod: explicitExec.charAt(0).toUpperCase() + explicitExec.slice(1),
    codeReviewTool: "Skip"
  }
} else if (autoYes) {
  // 自动模式:默认使用Agent+跳过审查
  executionConfig = { executionMethod: "Auto", codeReviewTool: "Skip" }
} else {
  // 交互模式:让用户选择
  executionConfig = AskUserQuestion({
    questions: [
      {
        question: "选择执行方式:",
        header: "Execution",
        multiSelect: false,
        options: [
          { label: "Agent", description: "code-developer Agent(同步执行,适合简单任务)" },
          { label: "Codex", description: "Codex CLI(后台执行,适合复杂任务)" },
          { label: "Gemini", description: "Gemini CLI(后台执行,适合分析类任务)" },
          { label: "Auto", description: "根据任务复杂度自动选择" }
        ]
      },
      {
        question: "执行后是否进行代码审查?",
        header: "Code Review",
        multiSelect: false,
        options: [
          { label: "Skip", description: "不审查" },
          { label: "Gemini Review", description: "Gemini CLI审查" },
          { label: "Codex Review", description: "Git感知审查(--uncommitted)" },
          { label: "Agent Review", description: "当前Agent审查" }
        ]
      }
    ]
  })
}

// Auto模式解析:根据方案中的任务数量决定执行方式
function resolveExecutor(taskCount) {
  if (executionConfig.executionMethod === 'Auto') {
    return taskCount <= 3 ? 'agent' : 'codex'
  }
  return executionConfig.executionMethod.toLowerCase()
}

通过 args 指定

通过参数指定

bash
undefined
bash
undefined

显式指定

显式指定执行方式

Skill(skill="team-planex", args="--exec=codex ISS-xxx") Skill(skill="team-planex", args="--exec=agent --text '简单功能'")
Skill(skill="team-planex", args="--exec=codex ISS-xxx") Skill(skill="team-planex", args="--exec=agent --text '简单功能'")

Auto 模式(跳过交互,-y 或 --yes)

自动模式(跳过交互,使用-y或--yes参数)

Skill(skill="team-planex", args="-y --text '添加日志'")
undefined
Skill(skill="team-planex", args="-y --text '添加日志'")
undefined

Orchestration Mode

编排模式

当不带
--role
调用时,SKILL.md 进入轻量编排模式:
javascript
// 1. 创建团队
TeamCreate({ team_name: teamName })

// 2. 解析输入参数
const issueIds = args.match(/ISS-\d{8}-\d{6}/g) || []
const textMatch = args.match(/--text\s+['"]([^'"]+)['"]/)
const planMatch = args.match(/--plan\s+(\S+)/)

let plannerInput = args  // 透传给 planner

// 3. 执行方式选择(见上方 Execution Method Selection)
// executionConfig 已确定: { executionMethod, codeReviewTool }

// 4. 创建初始 PLAN-* 任务
TaskCreate({
  subject: "PLAN-001: 初始规划",
  description: `规划任务。输入: ${plannerInput}`,
  activeForm: "规划中",
  owner: "planner"
})

// 5. Spawn planner agent
Task({
  subagent_type: "general-purpose",
  team_name: teamName,
  name: "planner",
  prompt: `你是 team "${teamName}"PLANNER当你收到 PLAN-* 任务时,调用 Skill(skill="team-planex", args="--role=planner") 执行。
当前输入: ${plannerInput}
当不带
--role
参数调用时,SKILL.md将进入轻量编排模式:
javascript
// 1. 创建团队
TeamCreate({ team_name: teamName })

// 2. 解析输入参数
const issueIds = args.match(/ISS-\d{8}-\d{6}/g) || []
const textMatch = args.match(/--text\s+['"]([^'"]+)['"]/)
const planMatch = args.match(/--plan\s+(\S+)/)

let plannerInput = args  // 直接透传给Planner

// 3. 确定执行方式(详见上方「执行方式选择」章节)
// executionConfig已确定: { executionMethod, codeReviewTool }

// 4. 创建初始PLAN-*任务
TaskCreate({
  subject: "PLAN-001: 初始规划",
  description: `规划任务。输入参数: ${plannerInput}`,
  activeForm: "规划中",
  owner: "planner"
})

// 5. 启动Planner Agent
Task({
  subagent_type: "general-purpose",
  team_name: teamName,
  name: "planner",
  prompt: `你是团队"${teamName}"PLANNER当你收到PLAN-*任务时,调用Skill(skill="team-planex", args="--role=planner")执行。
当前输入参数: ${plannerInput}

执行配置

执行配置

executor 的执行方式已确定: ${executionConfig.executionMethod} 创建 EXEC-* 任务时,在 description 中包含: execution_method: ${executionConfig.executionMethod} code_review: ${executionConfig.codeReviewTool}
Executor的执行方式已确定: ${executionConfig.executionMethod} 创建EXEC-*任务时,需在描述中包含: execution_method: ${executionConfig.executionMethod} code_review: ${executionConfig.codeReviewTool}

角色准则(强制)

角色准则(强制)

  • 你只能处理 PLAN-* 前缀的任务
  • 所有输出必须带 [planner] 标识前缀
  • 完成每个 wave 后立即创建 EXEC-* 任务供 executor 消费
  • EXEC-* 任务 description 中必须包含 execution_method 字段
  • 你只能处理带PLAN-*前缀的任务
  • 所有输出必须带有[planner]标识前缀
  • 完成每个Wave后立即创建EXEC-*任务供Executor处理
  • EXEC-*任务的描述中必须包含execution_method字段

消息总线(必须)

消息总线要求(必须遵守)

每次 SendMessage 前,先调用 mcp__ccw-tools__team_msg 记录。
工作流程:
  1. TaskList → 找到 PLAN-* 任务
  2. Skill(skill="team-planex", args="--role=planner") 执行
  3. team_msg log + SendMessage
  4. TaskUpdate completed → 检查下一个任务` })
// 6. Spawn executor agent Task({ subagent_type: "general-purpose", team_name: teamName, name: "executor", prompt: `你是 team "${teamName}" 的 EXECUTOR。 当你收到 EXEC-* 任务时,调用 Skill(skill="team-planex", args="--role=executor") 执行。
每次调用SendMessage前,需先调用mcp__ccw-tools__team_msg记录消息。
工作流程:
  1. 调用TaskList→找到PLAN-*任务
  2. 调用Skill(skill="team-planex", args="--role=planner")执行
  3. 调用team_msg记录日志+发送消息
  4. 更新任务状态为completed→检查下一个任务` })
// 6. 启动Executor Agent Task({ subagent_type: "general-purpose", team_name: teamName, name: "executor", prompt: `你是团队"${teamName}"的EXECUTOR。 当你收到EXEC-*任务时,调用Skill(skill="team-planex", args="--role=executor")执行。

执行配置

执行配置

默认执行方式: ${executionConfig.executionMethod} 代码审查: ${executionConfig.codeReviewTool} (每个 EXEC-* 任务 description 中可能包含 execution_method 覆盖)
默认执行方式: ${executionConfig.executionMethod} 代码审查配置: ${executionConfig.codeReviewTool} (每个EXEC-*任务的描述中可能包含execution_method字段以覆盖默认配置)

角色准则(强制)

角色准则(强制)

  • 你只能处理 EXEC-* 前缀的任务
  • 所有输出必须带 [executor] 标识前缀
  • 根据 execution_method 选择执行后端(Agent/Codex/Gemini)
  • 每个 solution 完成后通知 planner
  • 你只能处理带EXEC-*前缀的任务
  • 所有输出必须带有[executor]标识前缀
  • 根据execution_method选择对应的执行后端(Agent/Codex/Gemini)
  • 完成每个方案后通知Planner

消息总线(必须)

消息总线要求(必须遵守)

每次 SendMessage 前,先调用 mcp__ccw-tools__team_msg 记录。
工作流程:
  1. TaskList → 找到 EXEC-* 任务(等待 planner 创建)
  2. Skill(skill="team-planex", args="--role=executor") 执行
  3. team_msg log + SendMessage
  4. TaskUpdate completed → 检查下一个任务` })
undefined
每次调用SendMessage前,需先调用mcp__ccw-tools__team_msg记录消息。
工作流程:
  1. 调用TaskList→找到EXEC-*任务(等待Planner创建)
  2. 调用Skill(skill="team-planex", args="--role=executor")执行
  3. 调用team_msg记录日志+发送消息
  4. 更新任务状态为completed→检查下一个任务` })
undefined

Error Handling

错误处理

ScenarioResolution
Unknown --role valueError with available role list
Missing --role argEnter orchestration mode
Role file not foundError with expected path (roles/{name}.md)
Planner wave failureRetry once, then report error and halt pipeline
Executor impl failureReport to planner, continue with next EXEC-* task
No EXEC-* tasks yetExecutor idles, polls for new tasks
Pipeline stallPlanner monitors — if executor blocked > 2 tasks, escalate to user
场景处理方式
传入未知的--role值抛出错误并列出可用角色
未传入--role参数进入编排模式
角色文件未找到抛出错误并提示预期路径(roles/{name}.md)
Planner波次规划失败重试一次,若仍失败则上报错误并终止流水线
Executor任务实现失败向Planner上报错误,继续处理下一个EXEC-*任务
暂无EXEC-*任务Executor进入空闲状态,持续轮询新任务
流水线停滞Planner监控:若Executor阻塞任务超过2个,则升级通知用户