Files
Claude-Code-Workflow/.codex/skills/codex-issue-plan-execute/phases/actions/action-list.md
catlog22 8cdd6a8b5f Add execution and planning agent prompts, specifications, and quality standards
- Created execution agent prompt for issue execution with detailed deliverables and validation criteria.
- Developed planning agent prompt to analyze issues and generate structured solution plans.
- Introduced issue handling specifications outlining the workflow and issue structure.
- Established quality standards for evaluating completeness, consistency, correctness, and clarity of solutions.
- Defined solution schema specification detailing the required structure and validation rules for solutions.
- Documented subagent roles and responsibilities, emphasizing the dual-agent strategy for improved workflow efficiency.
2026-01-29 15:15:42 +08:00

4.4 KiB
Raw Blame History

Action: List Issues

列出 issues 并支持用户交互选择。

Purpose

展示当前所有 issues 的状态,收集用户的规划/执行意图。

Preconditions

  • state.status === "running"

Execution

async function execute(state) {
  // 1. 加载或初始化 issues
  let issues = state.issues || {};

  // 2. 从 ccw issue list 或提供的参数加载 issues
  // 这取决于用户是否在命令行提供了 issue IDs
  // 示例ccw codex issue:plan-execute ISS-001,ISS-002

  // 对于本次演示,我们假设从 issues.jsonl 加载
  try {
    const issuesListOutput = Bash("ccw issue list --status registered,planned --json").output;
    const issuesList = JSON.parse(issuesListOutput);

    issuesList.forEach(issue => {
      if (!issues[issue.id]) {
        issues[issue.id] = {
          id: issue.id,
          title: issue.title,
          status: "registered",
          solution_id: null,
          planned_at: null,
          executed_at: null,
          error: null
        };
      }
    });
  } catch (error) {
    console.log("Note: Could not load issues from ccw issue list");
    // 使用来自参数的 issues或者空列表
  }

  // 3. 显示当前状态
  const totalIssues = Object.keys(issues).length;
  const registeredCount = Object.values(issues).filter(i => i.status === "registered").length;
  const plannedCount = Object.values(issues).filter(i => i.status === "planned").length;
  const completedCount = Object.values(issues).filter(i => i.status === "completed").length;

  console.log("\n=== Issue Status ===");
  console.log(`Total: ${totalIssues} | Registered: ${registeredCount} | Planned: ${plannedCount} | Completed: ${completedCount}`);

  if (totalIssues === 0) {
    console.log("\nNo issues found. Please create issues first using 'ccw issue init'");
    return {
      stateUpdates: {
        context: {
          ...state.context,
          total_issues: 0
        }
      }
    };
  }

  // 4. 显示详细列表
  console.log("\n=== Issue Details ===");
  Object.values(issues).forEach((issue, index) => {
    const status = issue.status === "completed" ? "✓" : issue.status === "planned" ? "→" : "○";
    console.log(`${status} [${index + 1}] ${issue.id}: ${issue.title} (${issue.status})`);
  });

  // 5. 询问用户下一步
  const issueIds = Object.keys(issues);
  const pendingIds = issueIds.filter(id => issues[id].status === "registered");

  if (pendingIds.length === 0) {
    console.log("\nNo unplanned issues. Ready to execute planned solutions.");
    return {
      stateUpdates: {
        context: {
          ...state.context,
          total_issues: totalIssues
        }
      }
    };
  }

  // 6. 显示选项
  console.log("\nNext action:");
  console.log("- Enter 'p' to PLAN selected issues");
  console.log("- Enter 'x' to EXECUTE planned solutions");
  console.log("- Enter 'a' to plan ALL pending issues");
  console.log("- Enter 'q' to QUIT");

  const response = await AskUserQuestion({
    questions: [{
      question: "Select issues to plan (comma-separated numbers, or 'all'):",
      header: "Selection",
      multiSelect: false,
      options: pendingIds.slice(0, 4).map(id => ({
        label: `${issues[id].id}: ${issues[id].title}`,
        description: `Current status: ${issues[id].status}`
      }))
    }]
  });

  // 7. 更新 issues 状态为 "planning"
  const selectedIds = [];
  if (response.Selection === "all") {
    selectedIds.push(...pendingIds);
  } else {
    // 解析用户选择
    selectedIds.push(response.Selection);
  }

  selectedIds.forEach(issueId => {
    if (issues[issueId]) {
      issues[issueId].status = "planning";
    }
  });

  return {
    stateUpdates: {
      issues: issues,
      context: {
        ...state.context,
        total_issues: totalIssues
      }
    }
  };
}

State Updates

return {
  stateUpdates: {
    issues: issues,
    context: {
      total_issues: Object.keys(issues).length,
      registered_count: registeredCount,
      planned_count: plannedCount,
      completed_count: completedCount
    }
  }
};

Error Handling

Error Type Recovery
Issues 加载失败 使用空列表继续
用户输入无效 要求重新选择
列表显示异常 使用 JSON 格式输出

Next Actions (Hints)

  • 有 "planning" issues执行 action-plan
  • 无 pending issues执行 action-execute
  • 用户取消:中止