Loading...
Loading...
Execute all solutions from issue queue with git commit after each solution. Supports batch processing and execution control.
npx skill4agent add catlog22/claude-code-workflow issue-executeccw issue next.workflow/project-tech.json.workflow/project-guidelines.json~/.ccw/workflows/cli-templates/schemas/solution-schema.json--queue=<id>--worktree=<path|new>--skip-tests--skip-build--dry-run--queue <queue-id>List queues → Output options → Stop and wait for userccw issue queue list --brief --jsoncodex -p "@.codex/prompts/issue-execute.md --queue QUE-xxx"--worktree--worktree--worktree <existing-path>ccw issue# Step 0: Setup worktree before starting (run from MAIN REPO)
# Use absolute paths to avoid issues when running from subdirectories
REPO_ROOT=$(git rev-parse --show-toplevel)
WORKTREE_BASE="${REPO_ROOT}/.ccw/worktrees"
# Check if existing worktree path was provided
EXISTING_WORKTREE="${1:-}" # Pass as argument or empty
if [[ -n "${EXISTING_WORKTREE}" && -d "${EXISTING_WORKTREE}" ]]; then
# Resume mode: Use existing worktree
WORKTREE_PATH="${EXISTING_WORKTREE}"
WORKTREE_NAME=$(basename "${WORKTREE_PATH}")
# Verify it's a valid git worktree
if ! git -C "${WORKTREE_PATH}" rev-parse --is-inside-work-tree &>/dev/null; then
echo "Error: ${EXISTING_WORKTREE} is not a valid git worktree"
exit 1
fi
echo "Resuming in existing worktree: ${WORKTREE_PATH}"
else
# Create mode: New worktree with timestamp
WORKTREE_NAME="issue-exec-$(date +%Y%m%d-%H%M%S)"
WORKTREE_PATH="${WORKTREE_BASE}/${WORKTREE_NAME}"
# Ensure worktree base directory exists (gitignored)
mkdir -p "${WORKTREE_BASE}"
# Prune stale worktrees from previous interrupted executions
git worktree prune
# Create worktree from current branch
git worktree add "${WORKTREE_PATH}" -b "${WORKTREE_NAME}"
echo "Created new worktree: ${WORKTREE_PATH}"
fi
# Setup cleanup trap for graceful failure handling
cleanup_worktree() {
echo "Cleaning up worktree due to interruption..."
cd "${REPO_ROOT}" 2>/dev/null || true
git worktree remove "${WORKTREE_PATH}" --force 2>/dev/null || true
# Keep branch for debugging failed executions
echo "Worktree removed. Branch '${WORKTREE_NAME}' kept for inspection."
}
trap cleanup_worktree EXIT INT TERM
# Change to worktree directory
cd "${WORKTREE_PATH}"
# ccw issue commands auto-detect worktree and use main repo's .workflow/
# So you can run ccw issue next/done directly from worktree0. [MAIN REPO] Validate queue ID (--queue required, or prompt user to select)
1. [WORKTREE] ccw issue next --queue <queue-id> → auto-redirects to main repo's .workflow/
2. [WORKTREE] Implement all tasks, run tests, git commit
3. [WORKTREE] ccw issue done <item_id> → auto-redirects to main repo
4. Repeat from step 1.ccw/worktrees/.gitignore# List existing worktrees to find interrupted execution
git worktree list
# Resume in existing worktree (pass path as argument)
# The worktree path will be used instead of creating a new one
codex -p "@.codex/prompts/issue-execute.md --worktree /path/to/existing/worktree"All solutions completed in worktree. Choose next action:
1. Merge to main - Merge worktree branch into main and cleanup
2. Create PR - Push branch and create pull request (Recommended for parallel execution)
3. Keep branch - Keep branch for manual handling, cleanup worktree only
Please respond with: 1, 2, or 3# Disable cleanup trap before intentional cleanup
trap - EXIT INT TERM
# Return to main repo first (use REPO_ROOT from setup)
cd "${REPO_ROOT}"
# Validate main repo state before merge (prevents conflicts)
validate_main_clean() {
if [[ -n $(git status --porcelain) ]]; then
echo "⚠️ Warning: Main repo has uncommitted changes."
echo "Cannot auto-merge. Falling back to 'Create PR' option."
return 1
fi
return 0
}
# Option 1: Merge to main (only if main is clean)
if validate_main_clean; then
git merge "${WORKTREE_NAME}" --no-ff -m "Merge issue queue execution: ${WORKTREE_NAME}"
git worktree remove "${WORKTREE_PATH}"
git branch -d "${WORKTREE_NAME}"
else
# Fallback to PR if main is dirty
git push -u origin "${WORKTREE_NAME}"
gh pr create --title "Issue Queue: ${WORKTREE_NAME}" --body "Automated issue queue execution (main had uncommitted changes)"
git worktree remove "${WORKTREE_PATH}"
fi
# Option 2: Create PR (Recommended for parallel execution)
git push -u origin "${WORKTREE_NAME}"
gh pr create --title "Issue Queue: ${WORKTREE_NAME}" --body "Automated issue queue execution"
git worktree remove "${WORKTREE_PATH}"
# Branch kept on remote
# Option 3: Keep branch
git worktree remove "${WORKTREE_PATH}"
# Branch kept locally for manual handling
echo "Branch '${WORKTREE_NAME}' kept. Merge manually when ready."STEP 0: Validate queue ID (--queue required, or prompt user to select)
INIT: Fetch first solution via ccw issue next --queue <queue-id>
WHILE solution exists:
1. Receive solution JSON from ccw issue next --queue <queue-id>
2. Execute all tasks in solution.tasks sequentially:
FOR each task:
- IMPLEMENT: Follow task.implementation steps
- TEST: Run task.test commands
- VERIFY: Check task.acceptance criteria
3. COMMIT: Stage all files, commit once with formatted summary
4. Report completion via ccw issue done <item_id>
5. Fetch next solution via ccw issue next --queue <queue-id>
WHEN queue empty:
Output final summary--queue// ccw auto-detects worktree and uses main repo's .workflow/
// QUEUE_ID is required - obtained from --queue argument or user selection
const result = shell_command({ command: `ccw issue next --queue ${QUEUE_ID}` })item_idissue_idsolution_idsolutionexecution_hints{ "status": "empty" }{
"item_id": "S-1",
"issue_id": "ISS-20251227-001",
"solution_id": "SOL-ISS-20251227-001-1",
"status": "pending",
"solution": {
"id": "SOL-ISS-20251227-001-1",
"description": "Description of solution approach",
"tasks": [
{
"id": "T1",
"title": "Task title",
"scope": "src/module/",
"action": "Create|Modify|Fix|Refactor|Add",
"description": "What to do",
"modification_points": [
{ "file": "path/to/file.ts", "target": "function name", "change": "description" }
],
"implementation": [
"Step 1: Do this",
"Step 2: Do that"
],
"test": {
"commands": ["npm test -- --filter=xxx"],
"unit": ["Unit test requirement 1", "Unit test requirement 2"]
},
"regression": ["Verify existing tests still pass"],
"acceptance": {
"criteria": ["Criterion 1: Must pass", "Criterion 2: Must verify"],
"verification": ["Run test command", "Manual verification step"]
},
"commit": {
"type": "feat|fix|test|refactor",
"scope": "module",
"message_template": "feat(scope): description"
},
"depends_on": [],
"estimated_minutes": 30,
"priority": 1
}
],
"exploration_context": {
"relevant_files": ["path/to/reference.ts"],
"patterns": "Follow existing pattern in xxx",
"integration_points": "Used by other modules"
},
"analysis": {
"risk": "low|medium|high",
"impact": "low|medium|high",
"complexity": "low|medium|high"
},
"score": 0.95,
"is_bound": true
},
"execution_hints": {
"executor": "codex",
"estimated_minutes": 180
}
}solution.strategy_typetask.actionsolution.descriptiontask.title| Strategy Type | Match Keywords | Description |
|---|---|---|
| Debug, Diagnose, Trace, Investigate | Bug diagnosis with logging and debugging |
| Fix, Patch, Resolve, Correct | Bug fixing with root cause analysis |
| Feature, Add, Implement, Create, Build | New feature development with full testing |
| Refactor, Restructure, Optimize, Cleanup | Code restructuring with behavior preservation |
| Test, Coverage, E2E, Integration | Test implementation with coverage checks |
| Performance, Optimize, Speed, Memory | Performance optimization with benchmarking |
| Security, Vulnerability, CVE, Audit | Security fixes with vulnerability checks |
| Hotfix, Urgent, Critical, Emergency | Urgent fixes with minimal changes |
| Documentation, Docs, Comment, README | Documentation updates with example validation |
| Chore, Dependency, Config, Maintenance | Maintenance tasks with compatibility checks |
| (default) | Standard implementation without extra steps |
REPRODUCE → INSTRUMENT → DIAGNOSE → IMPLEMENT → TEST → VERIFY → CLEANUPROOT_CAUSE → IMPLEMENT → TEST → EDGE_CASES → REGRESSION → VERIFYDESIGN_REVIEW → UNIT_TESTS → IMPLEMENT → INTEGRATION_TESTS → TEST → CODE_REVIEW → DOCS → VERIFYBASELINE_TESTS → IMPLEMENT → TEST → BEHAVIOR_PRESERVATION → PERFORMANCE_CMP → VERIFYCOVERAGE_BASELINE → TEST_DESIGN → IMPLEMENT → COVERAGE_CHECK → VERIFYPROFILING → BOTTLENECK → IMPLEMENT → BENCHMARK → TEST → VERIFYVULNERABILITY_SCAN → IMPLEMENT → SECURITY_TEST → PENETRATION_TEST → VERIFYIMPACT_ASSESSMENT → IMPLEMENT → TEST → QUICK_VERIFY → VERIFYIMPLEMENT → EXAMPLE_VALIDATION → FORMAT_CHECK → LINK_VALIDATION → VERIFYIMPLEMENT → COMPATIBILITY_CHECK → TEST → CHANGELOG → VERIFYIMPLEMENT → TEST → VERIFYfunction determineStrategy(solution) {
// Priority 1: Explicit strategy type
if (solution.strategy_type) {
return solution.strategy_type
}
// Priority 2: Infer from task actions
const actions = solution.tasks.map(t => t.action.toLowerCase())
const titles = solution.tasks.map(t => t.title.toLowerCase())
const description = solution.description.toLowerCase()
const allText = [...actions, ...titles, description].join(' ')
// Match keywords (order matters - more specific first)
if (/hotfix|urgent|critical|emergency/.test(allText)) return 'hotfix'
if (/debug|diagnose|trace|investigate/.test(allText)) return 'debug'
if (/security|vulnerability|cve|audit/.test(allText)) return 'security'
if (/performance|optimize|speed|memory|benchmark/.test(allText)) return 'performance'
if (/refactor|restructure|cleanup/.test(allText)) return 'refactor'
if (/test|coverage|e2e|integration/.test(allText)) return 'test'
if (/documentation|docs|comment|readme/.test(allText)) return 'documentation'
if (/chore|dependency|config|maintenance/.test(allText)) return 'chore'
if (/fix|patch|resolve|correct/.test(allText)) return 'bugfix'
if (/feature|add|implement|create|build/.test(allText)) return 'feature'
// Default
return 'standard'
}// After parsing solution (Step 2)
const strategy = determineStrategy(solution)
console.log(`Strategy selected: ${strategy}`)
// During task execution (Step 3), follow strategy-specific phases
for (const task of solution.tasks) {
executeTaskWithStrategy(task, strategy)
}update_plan// Initialize plan with all tasks from solution
update_plan({
explanation: `Starting solution ${item_id}`,
plan: solution.tasks.map(task => ({
step: `${task.id}: ${task.title}`,
status: "pending"
}))
})update_plansolution.tasks// Update current task status
update_plan({
explanation: `Working on ${task.id}: ${task.title}`,
plan: tasks.map(t => ({
step: `${t.id}: ${t.title}`,
status: t.id === task.id ? "in_progress" : (t.completed ? "completed" : "pending")
}))
})// Mark task as completed (commit happens at solution level)
update_plan({
explanation: `Completed ${task.id}: ${task.title}`,
plan: tasks.map(t => ({
step: `${t.id}: ${t.title}`,
status: t.id === task.id ? "completed" : t.status
}))
})multi_tool_use.parallel// Read all relevant files in parallel for context
multi_tool_use.parallel({
tool_uses: solution.exploration_context.relevant_files.map(file => ({
recipient_name: "functions.read_file",
parameters: { path: file }
}))
})task.implementationtask.modification_pointssolution.exploration_context.patternstask.regression## Implementing: [task.title] (Task [N]/[Total])
**Scope**: [task.scope]
**Action**: [task.action]
**Steps**:
1. ✓ [implementation step 1]
2. ✓ [implementation step 2]
...
**Files Modified**:
- path/to/file1.ts
- path/to/file2.tstask.test.commandstask.test.unittask.test.integration## Testing: [task.title]
**Test Results**:
- [x] Unit tests: PASSED
- [x] Integration tests: PASSED (or N/A)task.acceptance.criteriatask.acceptance.verification## Verifying: [task.title]
**Acceptance Criteria**:
- [x] Criterion 1: Verified
- [x] Criterion 2: Verified
...
**Verification Steps**:
- [x] Run test command
- [x] Manual verification step
All criteria met: YESsolution.tasks# Stage all modified files from all tasks
git add path/to/file1.ts path/to/file2.ts ...
# Commit with clean, standard format (NO solution metadata)
git commit -m "[commit_type](scope): [brief description of changes]"
# Example commits:
# feat(auth): add token refresh mechanism
# fix(payment): resolve timeout handling in checkout flow
# refactor(api): simplify error handling logicfeatfixrefactortestdocschoreCLAUDE.md## Solution Committed: [solution_id]
**Commit**: [commit hash]
**Type**: [commit_type]([scope])
**Changes**:
- [Feature/Fix/Improvement]: [What functionality was added/fixed/improved]
- [Specific change 1]
- [Specific change 2]
**Files Modified**:
- path/to/file1.ts - [Brief description of changes]
- path/to/file2.ts - [Brief description of changes]
- path/to/file3.ts - [Brief description of changes]
**Solution**: [solution_id] ([N] tasks completed)// ccw auto-detects worktree and uses main repo's .workflow/
// Record ALL solution context here (NOT in git commit)
shell_command({
command: `ccw issue done ${item_id} --result '${JSON.stringify({
solution_id: solution.id,
issue_id: issue_id,
commit: {
hash: commit_hash,
type: commit_type,
scope: commit_scope,
message: commit_message
},
analysis: {
risk: solution.analysis.risk,
impact: solution.analysis.impact,
complexity: solution.analysis.complexity
},
tasks_completed: solution.tasks.map(t => ({
id: t.id,
title: t.title,
action: t.action,
scope: t.scope
})),
files_modified: ["path1", "path2", ...],
tests_passed: true,
verification: {
all_tests_passed: true,
acceptance_criteria_met: true,
regression_checked: true
},
summary: "[What was accomplished - brief description]"
})}'`
})shell_command({
command: `ccw issue done S-1 --result '${JSON.stringify({
solution_id: "SOL-ISS-20251227-001-1",
issue_id: "ISS-20251227-001",
commit: {
hash: "a1b2c3d4",
type: "feat",
scope: "auth",
message: "feat(auth): add token refresh mechanism"
},
analysis: {
risk: "low",
impact: "medium",
complexity: "medium"
},
tasks_completed: [
{ id: "T1", title: "Implement refresh token endpoint", action: "Add", scope: "src/auth/" },
{ id: "T2", title: "Add token rotation logic", action: "Create", scope: "src/auth/services/" }
],
files_modified: [
"src/auth/routes/token.ts",
"src/auth/services/refresh.ts",
"src/auth/middleware/validate.ts"
],
tests_passed: true,
verification: {
all_tests_passed: true,
acceptance_criteria_met: true,
regression_checked: true
},
summary: "Implemented token refresh mechanism with automatic rotation"
})}'`
})shell_command({
command: `ccw issue done ${item_id} --fail --reason '${JSON.stringify({
task_id: "TX",
error_type: "test_failure",
message: "Integration tests failed: timeout in token validation",
files_attempted: ["path1", "path2"],
commit: null
})}'`
})// ccw auto-detects worktree
// Continue using the same QUEUE_ID throughout execution
const result = shell_command({ command: `ccw issue next --queue ${QUEUE_ID}` })✓ [N/M] Completed: [item_id] - [solution.description]
Commit: [commit_hash] ([commit_type])
Tasks: [task_count] completed
→ Fetching next solution...ccw issue next{ "status": "empty" }## Issue Queue Execution Complete
**Total Solutions Executed**: N
**Total Tasks Executed**: M
**Total Commits**: N (one per solution)
**Solution Commits**:
| # | Solution | Tasks | Commit | Type |
|---|----------|-------|--------|------|
| 1 | SOL-xxx-1 | T1, T2 | abc123 | feat |
| 2 | SOL-xxx-2 | T1 | def456 | fix |
| 3 | SOL-yyy-1 | T1, T2, T3 | ghi789 | refactor |
**Files Modified**:
- path/to/file1.ts
- path/to/file2.ts
**Summary**:
[Overall what was accomplished]ccw issue doneccw issue done --failccw issue| Situation | Action |
|---|---|
| All done - output final summary |
| Tests fail | Fix code, re-run tests |
| Verification fails | Go back to implement phase |
| Solution commit fails | Check staging, retry commit |
| Log error, continue to next solution |
| Any task unrecoverable | Call |
| Command | Purpose |
|---|---|
| List all queues (for queue selection) |
| Fetch next solution from specified queue (--queue required) |
| Mark solution complete with result (auto-detects queue) |
| Mark solution failed with structured reason |
| Reset failed items in specific queue |
--queueccw issue queue list --brief --json--queue QUE-xxxccw issue next --queue <queue-id>