mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-28 09:23:08 +08:00
- Implemented exportSettings and importSettings APIs for CLI settings. - Added hooks useExportSettings and useImportSettings for managing export/import operations in the frontend. - Updated SettingsPage to include buttons for exporting and importing CLI settings. - Enhanced backend to handle export and import requests, including validation and conflict resolution. - Introduced new data structures for exported settings and import options. - Updated localization files to support new export/import features. - Refactored CLI tool configurations to remove hardcoded model defaults, allowing dynamic model retrieval.
12 KiB
12 KiB
name, description, agents, phases
| name | description | agents | phases |
|---|---|---|---|
| issue-devpipeline | Plan-and-Execute pipeline with per-issue beat pattern. Orchestrator coordinates planner (Deep Interaction) and executors (Parallel Fan-out). Planner outputs per-issue solutions, executors implement solutions concurrently. | 3 | 4 |
Issue DevPipeline
边规划边执行流水线。编排器通过逐 Issue 节拍流水线协调 planner 和 executor(s):planner 每完成一个 issue 的规划后立即输出,编排器即时为该 issue 派发 executor agent,同时 planner 继续规划下一 issue。
Architecture Overview
┌─────────────────────────────────────────────────────────────┐
│ Orchestrator (this file) │
│ → Parse input → Manage planner → Dispatch executors │
└───────────┬──────────────────────────────────────┬──────────┘
│ │
┌──────┴──────┐ ┌──────────┴──────────┐
│ Planner │ │ Executors (N) │
│ (Deep │ │ (Parallel Fan-out) │
│ Interaction│ │ │
│ per-issue) │ │ exec-1 exec-2 ... │
└──────┬──────┘ └──────────┬──────────┘
│ │
┌──────┴──────┐ ┌──────────┴──────────┐
│ issue-plan │ │ code-developer │
│ (existing) │ │ (role reference) │
└─────────────┘ └─────────────────────┘
Per-Issue Beat Pipeline Flow:
Planner → Issue 1 solution → ISSUE_READY
↓ (spawn executor for issue 1)
↓ send_input → Planner → Issue 2 solution → ISSUE_READY
↓ (spawn executor for issue 2)
...
↓ Planner outputs "all_planned"
↓ wait for all executor agents
↓ Aggregate results → Done
Agent Registry
| Agent | Role File | Responsibility | New/Existing |
|---|---|---|---|
planex-planner |
~/.codex/agents/planex-planner.md |
需求拆解 → issue 创建 → 方案设计 → 冲突检查 → 逐 issue 输出 | New |
planex-executor |
~/.codex/agents/planex-executor.md |
加载 solution → 代码实现 → 测试 → 提交 | New |
issue-plan-agent |
~/.codex/agents/issue-plan-agent.md |
Closed-loop: ACE 探索 + solution 生成 | Existing |
Input Types
支持 3 种输入方式(通过 orchestrator 参数传入):
| 输入类型 | 格式 | 示例 |
|---|---|---|
| Issue IDs | 直接传入 ID | ISS-20260215-001 ISS-20260215-002 |
| 需求文本 | --text '...' |
--text '实现用户认证模块' |
| Plan 文件 | --plan path |
--plan plan/2026-02-15-auth.md |
Phase Execution
Phase 1: Input Parsing (Orchestrator Inline)
// Parse input arguments
const args = orchestratorInput
const issueIds = args.match(/ISS-\d{8}-\d{6}/g) || []
const textMatch = args.match(/--text\s+['"]([^'"]+)['"]/)
const planMatch = args.match(/--plan\s+(\S+)/)
let inputType = 'unknown'
if (issueIds.length > 0) inputType = 'issue_ids'
else if (textMatch) inputType = 'text'
else if (planMatch) inputType = 'plan_file'
else inputType = 'text_from_description'
const inputPayload = {
type: inputType,
issueIds: issueIds,
text: textMatch ? textMatch[1] : args,
planFile: planMatch ? planMatch[1] : null
}
// Initialize session directory for artifacts
const slug = (issueIds[0] || 'batch').replace(/[^a-zA-Z0-9-]/g, '')
const dateStr = new Date().toISOString().slice(0,10).replace(/-/g,'')
const sessionId = `PEX-${slug}-${dateStr}`
const sessionDir = `.workflow/.team/${sessionId}`
shell(`mkdir -p "${sessionDir}/artifacts/solutions"`)
Phase 2: Planning (Deep Interaction with Planner — Per-Issue Beat)
// Track all agents for cleanup
const allAgentIds = []
// Spawn planner agent
const plannerId = spawn_agent({
message: `
## TASK ASSIGNMENT
### MANDATORY FIRST STEPS (Agent Execute)
1. **Read role definition**: ~/.codex/agents/planex-planner.md (MUST read first)
2. Read: .workflow/project-tech.json
3. Read: .workflow/project-guidelines.json
---
Goal: 分析需求并逐 issue 输出规划结果。每完成一个 issue 立即输出。
Input:
${JSON.stringify(inputPayload, null, 2)}
Session Dir: ${sessionDir}
Scope:
- Include: 需求分析、issue 创建、方案设计、inline 冲突检查、写中间产物
- Exclude: 代码实现、测试执行、git 操作
Deliverables:
每个 issue 输出严格遵循以下 JSON 格式:
\`\`\`json
{
"status": "issue_ready" | "all_planned",
"issue_id": "ISS-xxx",
"solution_id": "SOL-xxx",
"title": "描述",
"priority": "normal",
"depends_on": [],
"solution_file": "${sessionDir}/artifacts/solutions/ISS-xxx.json",
"remaining_issues": ["ISS-yyy", ...],
"summary": "本 issue 规划摘要"
}
\`\`\`
Quality bar:
- 每个 issue 必须有绑定的 solution
- Solution 写入中间产物文件
- Inline 冲突检查标记 depends_on
`
})
allAgentIds.push(plannerId)
// Wait for planner first issue output
let plannerResult = wait({ ids: [plannerId], timeout_ms: 900000 })
if (plannerResult.timed_out) {
send_input({ id: plannerId, message: "请尽快输出当前已完成的规划结果。" })
plannerResult = wait({ ids: [plannerId], timeout_ms: 120000 })
}
// Parse planner output
let issueData = parseIssueOutput(plannerResult.status[plannerId].completed)
Phase 3: Per-Issue Execution Loop
const executorResults = []
let issueCount = 0
while (true) {
issueCount++
// ─── Dispatch executor for current issue (if valid) ───
if (issueData && issueData.issue_id) {
const executorId = spawn_agent({
message: `
## TASK ASSIGNMENT
### MANDATORY FIRST STEPS (Agent Execute)
1. **Read role definition**: ~/.codex/agents/planex-executor.md (MUST read first)
2. Read: .workflow/project-tech.json
3. Read: .workflow/project-guidelines.json
---
Goal: 实现 ${issueData.issue_id} 的 solution
Issue: ${issueData.issue_id}
Solution: ${issueData.solution_id}
Title: ${issueData.title}
Priority: ${issueData.priority}
Dependencies: ${issueData.depends_on?.join(', ') || 'none'}
Solution File: ${issueData.solution_file}
Session Dir: ${sessionDir}
Scope:
- Include: 加载 solution plan、代码实现、测试运行、git commit
- Exclude: issue 创建、方案修改
Deliverables:
输出严格遵循以下格式:
\`\`\`json
{
"issue_id": "${issueData.issue_id}",
"status": "success" | "failed",
"files_changed": ["path/to/file", ...],
"tests_passed": true | false,
"committed": true | false,
"commit_hash": "abc123" | null,
"error": null | "错误描述",
"summary": "实现摘要"
}
\`\`\`
Quality bar:
- solution plan 中的所有任务必须实现
- 现有测试不能 break
- 遵循项目编码规范
- 每个变更必须 commit
`
})
allAgentIds.push(executorId)
executorResults.push({
id: executorId,
issueId: issueData.issue_id,
index: issueCount
})
}
// ─── Check if all planned ───
if (issueData?.status === 'all_planned') {
break
}
// ─── Request next issue from planner ───
send_input({
id: plannerId,
message: `Issue ${issueData?.issue_id || 'unknown'} dispatched. Continue to next issue.`
})
// ─── Wait for planner next issue ───
const nextResult = wait({ ids: [plannerId], timeout_ms: 900000 })
if (nextResult.timed_out) {
send_input({ id: plannerId, message: "请尽快输出当前已完成的规划结果。" })
const retryResult = wait({ ids: [plannerId], timeout_ms: 120000 })
if (retryResult.timed_out) break
issueData = parseIssueOutput(retryResult.status[plannerId].completed)
} else {
issueData = parseIssueOutput(nextResult.status[plannerId].completed)
}
}
// ─── Wait for all executor agents ───
const executorIds = executorResults.map(e => e.id)
if (executorIds.length > 0) {
const execResults = wait({ ids: executorIds, timeout_ms: 1200000 })
// Handle timeouts
if (execResults.timed_out) {
const pending = executorIds.filter(id => !execResults.status[id]?.completed)
pending.forEach(id => {
send_input({ id, message: "Please finalize current task and output results." })
})
wait({ ids: pending, timeout_ms: 120000 })
}
// Collect results
executorResults.forEach(entry => {
entry.result = execResults.status[entry.id]?.completed || 'timeout'
})
}
Phase 4: Aggregation & Cleanup
// ─── Aggregate results ───
const succeeded = executorResults.filter(r => {
try {
const parsed = JSON.parse(r.result)
return parsed.status === 'success'
} catch { return false }
})
const failed = executorResults.filter(r => {
try {
const parsed = JSON.parse(r.result)
return parsed.status === 'failed'
} catch { return true }
})
// ─── Output final report ───
const report = `
## PlanEx Pipeline Complete
**Total Issues**: ${executorResults.length}
**Succeeded**: ${succeeded.length}
**Failed**: ${failed.length}
### Results
${executorResults.map(r => `- ${r.issueId} | ${(() => {
try { return JSON.parse(r.result).status } catch { return 'error' }
})()}`).join('\n')}
${failed.length > 0 ? `### Failed Issues
${failed.map(r => `- ${r.issueId}: ${(() => {
try { return JSON.parse(r.result).error } catch { return r.result?.slice(0, 200) || 'unknown' }
})()}`).join('\n')}` : ''}
`
console.log(report)
// ─── Lifecycle cleanup ───
allAgentIds.forEach(id => {
try { close_agent({ id }) } catch { /* already closed */ }
})
Helper Functions
function parseIssueOutput(output) {
// Extract JSON block from agent output
const jsonMatch = output.match(/```json\s*([\s\S]*?)```/)
if (jsonMatch) {
try { return JSON.parse(jsonMatch[1]) } catch {}
}
// Fallback: try parsing entire output as JSON
try { return JSON.parse(output) } catch {}
// Last resort: return empty with all_planned
return { status: 'all_planned', issue_id: null, remaining_issues: [], summary: 'Parse failed' }
}
Configuration
const CONFIG = {
sessionDir: ".workflow/.team/PEX-{slug}-{date}/",
artifactsDir: ".workflow/.team/PEX-{slug}-{date}/artifacts/",
issueDataDir: ".workflow/issues/",
plannerTimeout: 900000, // 15 min
executorTimeout: 1200000, // 20 min
maxIssues: 50
}
Lifecycle Management
Timeout Handling
| Scenario | Action |
|---|---|
| Planner issue timeout | send_input 催促收敛,retry wait 120s |
| Executor timeout | 标记为 failed,继续其他 executor |
| Batch wait partial timeout | 收集已完成结果,继续 pipeline |
| Pipeline stall (> 3 issues timeout) | 中止 pipeline,输出部分结果 |
Cleanup Protocol
// All agents tracked in allAgentIds
// Final cleanup at end or on error
allAgentIds.forEach(id => {
try { close_agent({ id }) } catch { /* already closed */ }
})
Error Handling
| Scenario | Resolution |
|---|---|
| Planner output parse failure | Retry with send_input asking for strict JSON |
| No issues created | Report error, abort pipeline |
| Solution planning failure | Skip issue, report in final results |
| Executor implementation failure | Mark as failed, continue with other executors |
| Inline conflict check failure | Use empty depends_on, continue |
| Planner exits early | Treat as all_planned, finish current executors |