mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-05 01:50:27 +08:00
12 KiB
12 KiB
name, description, argument-hint, allowed-tools
| name | description | argument-hint | allowed-tools |
|---|---|---|---|
| queue | Form execution queue from bound solutions using issue-queue-agent (solution-level) | [--rebuild] [--issue <id>] | TodoWrite(*), Task(*), Bash(*), Read(*), Write(*) |
Issue Queue Command (/issue:queue)
Overview
Queue formation command using issue-queue-agent that analyzes all bound solutions, resolves inter-solution conflicts, and creates an ordered execution queue at solution level.
Design Principle: Queue items are solutions, not individual tasks. Each executor receives a complete solution with all its tasks.
Output Requirements
Generate Files:
.workflow/issues/queues/{queue-id}.json- Full queue with solutions, conflicts, groups.workflow/issues/queues/index.json- Update with new queue entry
Return Summary:
{
"queue_id": "QUE-20251227-143000",
"total_solutions": N,
"total_tasks": N,
"execution_groups": [{ "id": "P1", "type": "parallel", "count": N }],
"conflicts_resolved": N,
"issues_queued": ["ISS-xxx", "ISS-yyy"]
}
Completion Criteria:
- Queue JSON generated with valid DAG (no cycles between solutions)
- All inter-solution file conflicts resolved with rationale
- Semantic priority calculated for each solution
- Execution groups assigned (parallel P* / sequential S*)
- Issue statuses updated to
queuedviaccw issue update
Core Capabilities
- Agent-driven: issue-queue-agent handles all ordering logic
- Solution-level granularity: Queue items are solutions, not tasks
- Inter-solution dependency DAG (based on file conflicts)
- File conflict detection between solutions
- Semantic priority calculation per solution (0.0-1.0)
- Parallel/Sequential group assignment for solutions
Storage Structure (Queue History)
.workflow/issues/
├── issues.jsonl # All issues (one per line)
├── queues/ # Queue history directory
│ ├── index.json # Queue index (active + history)
│ ├── {queue-id}.json # Individual queue files
│ └── ...
└── solutions/
├── {issue-id}.jsonl # Solutions for issue
└── ...
Queue Index Schema
{
"active_queue_id": "QUE-20251227-143000",
"queues": [
{
"id": "QUE-20251227-143000",
"status": "active",
"issue_ids": ["ISS-xxx", "ISS-yyy"],
"total_solutions": 3,
"completed_solutions": 1,
"created_at": "2025-12-27T14:30:00Z"
}
]
}
Queue File Schema (Solution-Level)
{
"id": "QUE-20251227-143000",
"status": "active",
"solutions": [
{
"item_id": "S-1",
"issue_id": "ISS-20251227-003",
"solution_id": "SOL-20251227-003",
"status": "pending",
"execution_order": 1,
"execution_group": "P1",
"depends_on": [],
"semantic_priority": 0.8,
"assigned_executor": "codex",
"files_touched": ["src/auth.ts", "src/utils.ts"],
"task_count": 3
},
{
"item_id": "S-2",
"issue_id": "ISS-20251227-001",
"solution_id": "SOL-20251227-001",
"status": "pending",
"execution_order": 2,
"execution_group": "P1",
"depends_on": [],
"semantic_priority": 0.7,
"assigned_executor": "codex",
"files_touched": ["src/api.ts"],
"task_count": 2
},
{
"item_id": "S-3",
"issue_id": "ISS-20251227-002",
"solution_id": "SOL-20251227-002",
"status": "pending",
"execution_order": 3,
"execution_group": "S2",
"depends_on": ["S-1"],
"semantic_priority": 0.5,
"assigned_executor": "codex",
"files_touched": ["src/auth.ts"],
"task_count": 4
}
],
"conflicts": [
{
"type": "file_conflict",
"file": "src/auth.ts",
"solutions": ["S-1", "S-3"],
"resolution": "sequential",
"resolution_order": ["S-1", "S-3"],
"rationale": "S-1 creates auth module, S-3 extends it"
}
],
"execution_groups": [
{ "id": "P1", "type": "parallel", "solutions": ["S-1", "S-2"] },
{ "id": "S2", "type": "sequential", "solutions": ["S-3"] }
]
}
Usage
/issue:queue [FLAGS]
# Examples
/issue:queue # Form NEW queue from all bound solutions
/issue:queue --issue GH-123 # Form queue for specific issue only
/issue:queue --append GH-124 # Append to active queue
/issue:queue --list # List all queues (history)
/issue:queue --switch QUE-xxx # Switch active queue
/issue:queue --archive # Archive completed active queue
# Flags
--issue <id> Form queue for specific issue only
--append <id> Append issue to active queue (don't create new)
# CLI subcommands (ccw issue queue ...)
ccw issue queue list List all queues with status
ccw issue queue switch <queue-id> Switch active queue
ccw issue queue archive Archive current queue
ccw issue queue delete <queue-id> Delete queue from history
Execution Process
Phase 1: Solution Loading
├─ Load issues.jsonl
├─ Filter issues with bound_solution_id
├─ Read solutions/{issue-id}.jsonl for each issue
├─ Find bound solution by ID
├─ Collect files_touched from all tasks in solution
└─ Build solution objects (NOT individual tasks)
Phase 2-4: Agent-Driven Queue Formation (issue-queue-agent)
├─ Launch issue-queue-agent with all solutions
├─ Agent performs:
│ ├─ Detect file overlaps between solutions
│ ├─ Build dependency DAG from file conflicts
│ ├─ Detect circular dependencies
│ ├─ Resolve conflicts using priority rules
│ ├─ Calculate semantic priority per solution
│ └─ Assign execution groups (parallel/sequential)
└─ Output: queue JSON with ordered solutions (S-1, S-2, ...)
Phase 5: Queue Output
├─ Write queue.json with solutions array
├─ Update issue statuses in issues.jsonl
└─ Display queue summary
Implementation
Phase 1: Solution Loading
NOTE: Execute code directly. DO NOT pre-read solution files - Bash cat handles all reading.
// Load issues.jsonl
const issuesPath = '.workflow/issues/issues.jsonl';
const allIssues = Bash(`cat "${issuesPath}" 2>/dev/null || echo ''`)
.split('\n')
.filter(line => line.trim())
.map(line => JSON.parse(line));
// Filter issues with bound solutions
const plannedIssues = allIssues.filter(i =>
i.status === 'planned' && i.bound_solution_id
);
if (plannedIssues.length === 0) {
console.log('No issues with bound solutions found.');
console.log('Run /issue:plan first to create and bind solutions.');
return;
}
// Load bound solutions (not individual tasks)
const allSolutions = [];
for (const issue of plannedIssues) {
const solPath = `.workflow/issues/solutions/${issue.id}.jsonl`;
const solutions = Bash(`cat "${solPath}" 2>/dev/null || echo ''`)
.split('\n')
.filter(line => line.trim())
.map(line => JSON.parse(line));
// Find bound solution
const boundSol = solutions.find(s => s.id === issue.bound_solution_id);
if (!boundSol) {
console.log(`⚠ Bound solution ${issue.bound_solution_id} not found for ${issue.id}`);
continue;
}
// Collect all files touched by this solution
const filesTouched = new Set();
for (const task of boundSol.tasks || []) {
for (const mp of task.modification_points || []) {
filesTouched.add(mp.file);
}
}
allSolutions.push({
issue_id: issue.id,
solution_id: issue.bound_solution_id,
task_count: boundSol.tasks?.length || 0,
files_touched: Array.from(filesTouched),
priority: issue.priority || 'medium'
});
}
console.log(`Loaded ${allSolutions.length} solutions from ${plannedIssues.length} issues`);
Phase 2-4: Agent-Driven Queue Formation
// Generate queue-id ONCE here, pass to agent
const now = new Date();
const queueId = `QUE-${now.toISOString().replace(/[-:T]/g, '').slice(0, 14)}`;
// Build minimal prompt - agent orders SOLUTIONS, not tasks
const agentPrompt = `
## Order Solutions
**Queue ID**: ${queueId}
**Solutions**: ${allSolutions.length} from ${plannedIssues.length} issues
**Project Root**: ${process.cwd()}
### Input (Solution-Level)
\`\`\`json
${JSON.stringify(allSolutions, null, 2)}
\`\`\`
### Steps
1. Parse solutions: Extract solution IDs, files_touched, task_count, priority
2. Detect conflicts: Find file overlaps between solutions (files_touched intersection)
3. Build DAG: Create dependency edges where solutions share files
4. Detect cycles: Verify no circular dependencies (abort if found)
5. Resolve conflicts: Apply ordering rules based on action types
6. Calculate priority: Compute semantic priority (0.0-1.0) per solution
7. Assign groups: Parallel (P*) for no-conflict, Sequential (S*) for conflicts
8. Generate queue: Write queue JSON with ordered solutions
9. Update index: Update queues/index.json with new queue entry
### Rules
- **Solution Granularity**: Queue items are solutions, NOT individual tasks
- **DAG Validity**: Output must be valid DAG with no circular dependencies
- **Conflict Detection**: Two solutions conflict if files_touched intersect
- **Ordering Priority**:
1. Higher issue priority first (critical > high > medium > low)
2. Fewer dependencies first (foundation solutions)
3. More tasks = higher priority (larger impact)
- **Parallel Safety**: Solutions in same parallel group must have NO file overlaps
- **Queue Item ID Format**: \`S-N\` (S-1, S-2, S-3, ...)
- **Queue ID**: Use the provided Queue ID (passed above), do NOT generate new one
### Generate Files (STRICT - only these 2)
1. \`.workflow/issues/queues/{Queue ID}.json\` - Use Queue ID from above
2. \`.workflow/issues/queues/index.json\` - Update existing index
Write ONLY these 2 files, using the provided Queue ID.
### Return Summary
\`\`\`json
{
"queue_id": "QUE-YYYYMMDD-HHMMSS",
"total_solutions": N,
"total_tasks": N,
"execution_groups": [{ "id": "P1", "type": "parallel", "count": N }],
"conflicts_resolved": N,
"issues_queued": ["ISS-xxx"]
}
\`\`\`
`;
const result = Task(
subagent_type="issue-queue-agent",
run_in_background=false,
description=`Order ${allSolutions.length} solutions`,
prompt=agentPrompt
);
const summary = JSON.parse(result);
Phase 5: Validation & Status Update
const queuePath = `.workflow/issues/queues/${queueId}.json`;
// 1. Validate queue has solutions
const solCount = Bash(`jq ".solutions | length" "${queuePath}"`).trim();
if (!solCount || solCount === '0') {
console.error(`✗ Queue has no solutions. Aborting.`);
return;
}
// 2. Update issue statuses
for (const id of summary.issues_queued) {
Bash(`ccw issue update ${id} --status queued`);
}
// 3. Summary
console.log(`
## Queue: ${summary.queue_id}
- Solutions: ${summary.total_solutions}
- Tasks: ${summary.total_tasks}
- Issues: ${summary.issues_queued.join(', ')}
Next: /issue:execute
`);
Error Handling
| Error | Resolution |
|---|---|
| No bound solutions | Display message, suggest /issue:plan |
| Circular dependency | List cycles, abort queue formation |
| Unresolved conflicts | Agent resolves using ordering rules |
| Invalid task reference | Skip and warn |
| index.json not updated | Auto-fix: Set active_queue_id to new queue |
| Wrong status value | Auto-fix: Convert non-pending status to "pending" |
| No entry points (all have deps) | Auto-fix: Clear depends_on for first item |
| Queue file missing solutions | Abort with error, agent must regenerate |
Related Commands
/issue:plan- Plan issues and bind solutions/issue:execute- Execute queue with codexccw issue queue list- View current queue