From c24ad501b55660f91f22e0695827195f814626c6 Mon Sep 17 00:00:00 2001 From: catlog22 Date: Sun, 28 Dec 2025 20:35:29 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0=E9=97=AE=E9=A2=98?= =?UTF-8?q?=E6=89=A7=E8=A1=8C=E5=92=8C=E9=98=9F=E5=88=97=E7=94=9F=E6=88=90?= =?UTF-8?q?=E9=80=BB=E8=BE=91=EF=BC=8C=E6=94=AF=E6=8C=81=E8=A7=A3=E5=86=B3?= =?UTF-8?q?=E6=96=B9=E6=A1=88=E6=A0=BC=E5=BC=8F=E5=B9=B6=E5=A2=9E=E5=BC=BA?= =?UTF-8?q?=E5=85=83=E6=95=B0=E6=8D=AE=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .codex/prompts/issue-execute.md | 223 ++++++++++++++++--------------- .codex/prompts/issue-queue.md | 225 ++++++++++++++++++++++++++++++++ CHANGELOG.md | 23 ++++ ccw/src/commands/issue.ts | 48 +++++-- package.json | 2 +- 5 files changed, 404 insertions(+), 117 deletions(-) create mode 100644 .codex/prompts/issue-queue.md diff --git a/.codex/prompts/issue-execute.md b/.codex/prompts/issue-execute.md index d9f3b2ab..46b683be 100644 --- a/.codex/prompts/issue-execute.md +++ b/.codex/prompts/issue-execute.md @@ -1,104 +1,114 @@ --- -description: Execute issue queue tasks sequentially with git commit after each task -argument-hint: "[--dry-run]" +description: Execute solution from issue queue with git commit after each task +argument-hint: " [--dry-run]" --- # Issue Execute (Codex Version) ## Core Principle -**Serial Execution**: Execute tasks ONE BY ONE from the issue queue. Complete each task fully (implement → test → commit) before moving to next. Continue autonomously until ALL tasks complete or queue is empty. +**Solution-Aware Execution**: Receive a complete solution with all its tasks, execute tasks sequentially within the solution (implement → test → commit per task), then report solution completion. This aligns with the Queue's Solution-Level design. ## Execution Flow ``` -INIT: Fetch first task via ccw issue next +INIT: Receive solution ID (S-N) from orchestrator -WHILE task exists: - 1. Receive task JSON from ccw issue next - 2. Execute full lifecycle: - - IMPLEMENT: Follow task.implementation steps - - TEST: Run task.test commands - - VERIFY: Check task.acceptance criteria - - COMMIT: Stage files, commit with task.commit.message_template - 3. Report completion via ccw issue complete - 4. Fetch next task via ccw issue next +FOR solution: + 1. Fetch full solution via: ccw issue detail + 2. Iterate through solution.tasks sequentially: + FOR each task in solution.tasks: + - IMPLEMENT: Follow task.implementation steps + - TEST: Run task.test commands + - VERIFY: Check task.acceptance criteria + - COMMIT: Stage files, commit with task.commit.message_template + 3. Report solution completion: ccw issue done -WHEN queue empty: - Output final summary +OUTPUT: Final summary with all commits ``` -## Step 1: Fetch First Task +## Step 1: Fetch Solution -Run this command to get your first task: +Run this command to get the full solution: ```bash -ccw issue next +ccw issue detail ``` -This returns JSON with the full task definition: -- `item_id`: Unique task identifier in queue (e.g., "T-1") -- `issue_id`: Parent issue ID (e.g., "ISSUE-20251227-001") -- `task`: Full task definition with implementation steps -- `context`: Relevant files and patterns +This returns JSON with the complete solution definition: +- `item_id`: Solution identifier in queue (e.g., "S-1") +- `issue_id`: Parent issue ID (e.g., "ISS-20251227-001") +- `solution_id`: Solution ID (e.g., "SOL-20251227-001") +- `solution`: Full solution with all tasks - `execution_hints`: Timing and executor hints -If response contains `{ "status": "empty" }`, all tasks are complete - skip to final summary. +## Step 2: Parse Solution Response -## Step 2: Parse Task Response - -Expected task structure: +Expected solution structure: ```json { - "item_id": "T-1", - "issue_id": "ISSUE-20251227-001", - "solution_id": "SOL-001", - "task": { - "id": "T1", - "title": "Task title", - "scope": "src/module/", - "action": "Create|Modify|Fix|Refactor", - "description": "What to do", - "modification_points": [ - { "file": "path/to/file.ts", "target": "function name", "change": "description" } + "item_id": "S-1", + "issue_id": "ISS-20251227-001", + "solution_id": "SOL-20251227-001", + "status": "pending", + "solution": { + "id": "SOL-20251227-001", + "approach": "Description of solution approach", + "tasks": [ + { + "id": "T1", + "title": "Task title", + "scope": "src/module/", + "action": "Create|Modify|Fix|Refactor", + "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 requirements", + "integration": "Integration test requirements (optional)" + }, + "acceptance": [ + "Criterion 1: Must pass", + "Criterion 2: Must verify" + ], + "commit": { + "message_template": "feat(scope): description" + } + } ], - "implementation": [ - "Step 1: Do this", - "Step 2: Do that" - ], - "test": { - "commands": ["npm test -- --filter=xxx"], - "unit": "Unit test requirements", - "integration": "Integration test requirements (optional)" - }, - "acceptance": [ - "Criterion 1: Must pass", - "Criterion 2: Must verify" - ], - "commit": { - "message_template": "feat(scope): description" + "exploration_context": { + "relevant_files": ["path/to/reference.ts"], + "patterns": "Follow existing pattern in xxx" } }, - "context": { - "relevant_files": ["path/to/reference.ts"], - "patterns": "Follow existing pattern in xxx" + "execution_hints": { + "executor": "codex", + "estimated_minutes": 180 } } ``` -## Step 3: Execute Task Lifecycle +## Step 3: Execute Tasks Sequentially + +Iterate through `solution.tasks` array and execute each task: ### Phase A: IMPLEMENT -1. Read all `context.relevant_files` to understand existing patterns +1. Read all `exploration_context.relevant_files` to understand existing patterns 2. Follow `task.implementation` steps in order 3. Apply changes to `task.modification_points` files -4. Follow `context.patterns` for code style consistency +4. Follow `exploration_context.patterns` for code style consistency **Output format:** ``` -## Implementing: [task.title] +## Implementing: [task.title] (Task [N]/[Total]) **Scope**: [task.scope] **Action**: [task.action] @@ -149,7 +159,7 @@ All criteria met: YES ### Phase D: COMMIT -After all phases pass, commit the changes: +After all phases pass, commit the changes for this task: ```bash # Stage all modified files @@ -159,7 +169,7 @@ git add path/to/file1.ts path/to/file2.ts ... git commit -m "$(cat <<'EOF' [task.commit.message_template] -Item-ID: [item_id] +Solution-ID: [solution_id] Issue-ID: [issue_id] Task-ID: [task.id] EOF @@ -175,92 +185,91 @@ EOF **Files**: N files changed ``` -## Step 4: Report Completion +### Repeat for Next Task -After commit succeeds, report to queue system: +Continue to next task in `solution.tasks` array until all tasks are complete. + +## Step 4: Report Solution Completion + +After ALL tasks in the solution are complete, report to queue system: ```bash -ccw issue complete [item_id] --result '{ - "files_modified": ["path1", "path2"], - "tests_passed": true, - "acceptance_passed": true, - "committed": true, - "commit_hash": "[actual hash]", - "summary": "[What was accomplished]" +ccw issue done --result '{ + "summary": "[What was accomplished]", + "files_modified": ["path1", "path2", ...], + "tasks_completed": N, + "commits": [ + { "task_id": "T1", "hash": "abc123" }, + { "task_id": "T2", "hash": "def456" } + ] }' ``` -**If task failed and cannot be fixed:** +**If any task failed and cannot be fixed:** ```bash -ccw issue fail [item_id] --reason "Phase [X] failed: [details]" +ccw issue done --fail --reason "Task [task.id] failed: [details]" ``` -## Step 5: Continue to Next Task - -Immediately fetch the next task: - -```bash -ccw issue next -``` - -**Output progress:** -``` -✓ [N/M] Completed: [item_id] - [task.title] -→ Fetching next task... -``` - -**DO NOT STOP.** Return to Step 2 and continue until queue is empty. - ## Final Summary -When `ccw issue next` returns `{ "status": "empty" }`: +When all tasks in solution are complete: ```markdown -## Issue Queue Execution Complete +## Solution Execution Complete + +**Solution**: [solution_id] +**Issue**: [issue_id] +**Tasks Executed**: N/N -**Total Tasks Executed**: N **All Commits**: -| # | Item ID | Task | Commit | -|---|---------|------|--------| -| 1 | T-1 | Task title | abc123 | -| 2 | T-2 | Task title | def456 | +| # | Task ID | Task Title | Commit | +|---|---------|------------|--------| +| 1 | T1 | Task title | abc123 | +| 2 | T2 | Task title | def456 | **Files Modified**: - path/to/file1.ts - path/to/file2.ts **Summary**: -[Overall what was accomplished] +[Overall what was accomplished for this solution] ``` ## Execution Rules -1. **Never stop mid-queue** - Continue until queue is empty -2. **One task at a time** - Fully complete (including commit) before moving on +1. **Solution-aware** - Receive complete solution, iterate tasks internally +2. **Sequential within solution** - Complete each task (including commit) before moving to next 3. **Tests MUST pass** - Do not proceed to commit if tests fail 4. **Commit after each task** - Each task gets its own commit 5. **Self-verify** - All acceptance criteria must pass before commit -6. **Report accurately** - Use ccw issue complete/fail after each task -7. **Handle failures gracefully** - If a task fails, report via ccw issue fail and continue to next +6. **Report accurately** - Use `ccw issue done` after all tasks complete +7. **Handle failures gracefully** - If a task fails, report via `ccw issue done --fail` ## Error Handling | Situation | Action | |-----------|--------| -| ccw issue next returns empty | All done - output final summary | +| Solution not found | Report error, abort | | Tests fail | Fix code, re-run tests | | Verification fails | Go back to implement phase | | Git commit fails | Check staging, retry commit | -| ccw issue complete fails | Log error, continue to next task | -| Unrecoverable error | Call ccw issue fail, continue to next | +| Unrecoverable error | Call `ccw issue done --fail`, report details | + +## CLI Command Reference + +| Command | Purpose | +|---------|---------| +| `ccw issue detail ` | Fetch full solution (READ-ONLY) | +| `ccw issue done ` | Mark solution complete | +| `ccw issue done --fail` | Mark solution failed | ## Start Execution -Begin by running: +When invoked by orchestrator with solution ID: ```bash -ccw issue next +ccw issue detail ``` -Then follow the lifecycle for each task until queue is empty. +Then follow the task lifecycle for each task in `solution.tasks` until all complete. diff --git a/.codex/prompts/issue-queue.md b/.codex/prompts/issue-queue.md new file mode 100644 index 00000000..1fd350ce --- /dev/null +++ b/.codex/prompts/issue-queue.md @@ -0,0 +1,225 @@ +--- +description: Form execution queue from bound solutions (orders solutions, detects conflicts, assigns groups) +argument-hint: "[--issue ]" +--- + +# Issue Queue (Codex Version) + +## Goal + +Create an ordered execution queue from all bound solutions. Analyze inter-solution file conflicts, calculate semantic priorities, and assign parallel/sequential execution groups. + +This workflow is **ordering only** (no execution): it reads bound solutions, detects conflicts, and produces a queue file that `issue-execute.md` can consume. + +## Inputs + +- **All planned**: Default behavior → queue all issues with `planned` status and bound solutions +- **Specific issue**: `--issue ` → queue only that issue's solution + +## Output Requirements + +**Generate Files (EXACTLY 2):** +1. `.workflow/issues/queues/{queue-id}.json` - Full queue with solutions, conflicts, groups +2. `.workflow/issues/queues/index.json` - Update with new queue entry + +**Return Summary:** +```json +{ + "queue_id": "QUE-YYYYMMDD-HHMMSS", + "total_solutions": 3, + "total_tasks": 12, + "execution_groups": [{ "id": "P1", "type": "parallel", "count": 2 }], + "conflicts_resolved": 1, + "issues_queued": ["ISS-xxx", "ISS-yyy"] +} +``` + +## Workflow + +### Step 1: Generate Queue ID + +Generate queue ID ONCE at start, reuse throughout: + +```bash +# Format: QUE-YYYYMMDD-HHMMSS (UTC) +QUEUE_ID="QUE-$(date -u +%Y%m%d-%H%M%S)" +``` + +### Step 2: Load Planned Issues + +Get all issues with bound solutions: + +```bash +ccw issue list --status planned --json +``` + +For each issue in the result: +- Extract `id`, `bound_solution_id`, `priority` +- Read solution from `.workflow/issues/solutions/{issue-id}.jsonl` +- Find the bound solution by matching `solution.id === bound_solution_id` +- Collect `files_touched` from all tasks' `modification_points.file` + +Build solution list: +```json +[ + { + "issue_id": "ISS-xxx", + "solution_id": "SOL-xxx", + "task_count": 3, + "files_touched": ["src/auth.ts", "src/utils.ts"], + "priority": "medium" + } +] +``` + +### Step 3: Detect File Conflicts + +Build a file → solutions mapping: + +```javascript +fileModifications = { + "src/auth.ts": ["SOL-001", "SOL-003"], + "src/api.ts": ["SOL-002"] +} +``` + +Conflicts exist when a file has multiple solutions. For each conflict: +- Record the file and involved solutions +- Will be resolved in Step 4 + +### Step 4: Resolve Conflicts & Build DAG + +**Resolution Rules (in priority order):** +1. Higher issue priority first: `critical > high > medium > low` +2. Foundation solutions first: fewer dependencies +3. More tasks = higher priority: larger impact + +For each file conflict: +- Apply resolution rules to determine order +- Add dependency edge: later solution `depends_on` earlier solution +- Record rationale + +**Semantic Priority Formula:** +``` +Base: critical=0.9, high=0.7, medium=0.5, low=0.3 +Boost: task_count>=5 → +0.1, task_count>=3 → +0.05 +Final: clamp(base + boost, 0.0, 1.0) +``` + +### Step 5: Assign Execution Groups + +- **Parallel (P1, P2, ...)**: Solutions with NO file overlaps between them +- **Sequential (S1, S2, ...)**: Solutions that share files must run in order + +Group assignment: +1. Start with all solutions in potential parallel group +2. For each file conflict, move later solution to sequential group +3. Assign group IDs: P1 for first parallel batch, S2 for first sequential, etc. + +### Step 6: Generate Queue Files + +**Queue file structure** (`.workflow/issues/queues/{QUEUE_ID}.json`): + +```json +{ + "id": "QUE-20251228-120000", + "status": "active", + "issue_ids": ["ISS-001", "ISS-002"], + "solutions": [ + { + "item_id": "S-1", + "issue_id": "ISS-001", + "solution_id": "SOL-001", + "status": "pending", + "execution_order": 1, + "execution_group": "P1", + "depends_on": [], + "semantic_priority": 0.8, + "assigned_executor": "codex", + "files_touched": ["src/auth.ts"], + "task_count": 3 + } + ], + "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"], "solution_count": 2 }, + { "id": "S2", "type": "sequential", "solutions": ["S-3"], "solution_count": 1 } + ] +} +``` + +**Update index** (`.workflow/issues/queues/index.json`): + +```json +{ + "active_queue_id": "QUE-20251228-120000", + "queues": [ + { + "id": "QUE-20251228-120000", + "status": "active", + "issue_ids": ["ISS-001", "ISS-002"], + "total_solutions": 3, + "completed_solutions": 0, + "created_at": "2025-12-28T12:00:00Z" + } + ] +} +``` + +### Step 7: Update Issue Statuses + +For each queued issue, update status to `queued`: + +```bash +ccw issue update --status queued +``` + +## Queue Item ID Format + +- Solution items: `S-1`, `S-2`, `S-3`, ... +- Sequential numbering starting from 1 + +## Done Criteria + +- [ ] Exactly 2 files generated: queue JSON + index update +- [ ] Queue has valid DAG (no circular dependencies) +- [ ] All file conflicts resolved with rationale +- [ ] Semantic priority calculated for each solution (0.0-1.0) +- [ ] Execution groups assigned (P* for parallel, S* for sequential) +- [ ] Issue statuses updated to `queued` +- [ ] Summary JSON returned with correct shape + +## Validation Rules + +1. **No cycles**: If resolution creates a cycle, abort and report +2. **Parallel safety**: Solutions in same P* group must have NO file overlaps +3. **Sequential order**: Solutions in S* group must be in correct dependency order +4. **Single queue ID**: Use the same queue ID throughout (generated in Step 1) + +## Error Handling + +| Situation | Action | +|-----------|--------| +| No planned issues | Return empty queue summary | +| Circular dependency detected | Abort, report cycle details | +| Missing solution file | Skip issue, log warning | +| Index file missing | Create new index | + +## Start Execution + +Begin by listing planned issues: + +```bash +ccw issue list --status planned --json +``` + +Then follow the workflow to generate the queue. diff --git a/CHANGELOG.md b/CHANGELOG.md index e5ef1f7c..13b478f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,29 @@ All notable changes to Claude Code Workflow (CCW) will be documented in this fil The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [6.3.11] - 2025-12-28 + +### 🔧 Issue System Enhancements | Issue系统增强 + +#### CLI Improvements | CLI改进 +- **Added**: `ccw issue update --status ` command for pure field updates +- **Added**: Support for `--priority`, `--title`, `--description` in update command +- **Added**: Auto-timestamp setting based on status (planned_at, queued_at, completed_at) + +#### Issue Plan Command | Issue Plan命令 +- **Changed**: Agent execution from sequential to parallel (max 10 concurrent) +- **Added**: Multi-solution user selection prompt with clear notification +- **Added**: Explicit binding check (`solutions.length === 1`) before auto-bind + +#### Issue Queue Command | Issue Queue命令 +- **Fixed**: Queue ID generation moved from agent to command (avoid duplicate IDs) +- **Fixed**: Strict output file control (exactly 2 files per execution) +- **Added**: Clear documentation for `update` vs `done`/`queue add` usage + +#### Discovery System | Discovery系统 +- **Enhanced**: Discovery progress reading with new schema support +- **Enhanced**: Discovery index reading and issue exporting + ## [6.3.9] - 2025-12-27 ### 🔧 Issue System Consistency | Issue系统一致性修复 diff --git a/ccw/src/commands/issue.ts b/ccw/src/commands/issue.ts index c5fd6cc5..53f26bb3 100644 --- a/ccw/src/commands/issue.ts +++ b/ccw/src/commands/issue.ts @@ -350,12 +350,30 @@ function createEmptyQueue(): Queue { function writeQueue(queue: Queue): void { ensureQueuesDir(); + // Support both old (tasks) and new (solutions) queue format + const items = queue.solutions || queue.tasks || []; + const isSolutionQueue = !!queue.solutions; + + // Ensure _metadata exists (support queues with 'metadata' field from external sources) + if (!queue._metadata) { + const extMeta = (queue as any).metadata; + queue._metadata = { + version: '2.0', + total_tasks: extMeta?.total_tasks || items.length, + pending_count: items.filter(q => q.status === 'pending').length, + executing_count: items.filter(q => q.status === 'executing').length, + completed_count: items.filter(q => q.status === 'completed').length, + failed_count: items.filter(q => q.status === 'failed').length, + updated_at: new Date().toISOString() + }; + } + // Update metadata counts - queue._metadata.total_tasks = queue.tasks.length; - queue._metadata.pending_count = queue.tasks.filter(q => q.status === 'pending').length; - queue._metadata.executing_count = queue.tasks.filter(q => q.status === 'executing').length; - queue._metadata.completed_count = queue.tasks.filter(q => q.status === 'completed').length; - queue._metadata.failed_count = queue.tasks.filter(q => q.status === 'failed').length; + queue._metadata.total_tasks = items.length; + queue._metadata.pending_count = items.filter(q => q.status === 'pending').length; + queue._metadata.executing_count = items.filter(q => q.status === 'executing').length; + queue._metadata.completed_count = items.filter(q => q.status === 'completed').length; + queue._metadata.failed_count = items.filter(q => q.status === 'failed').length; queue._metadata.updated_at = new Date().toISOString(); // Write queue file @@ -366,16 +384,28 @@ function writeQueue(queue: Queue): void { const index = readQueueIndex(); const existingIdx = index.queues.findIndex(q => q.id === queue.id); - const indexEntry = { + // Derive issue_ids from solutions if not present + const issueIds = queue.issue_ids || (isSolutionQueue + ? [...new Set(items.map(item => item.issue_id))] + : []); + + const indexEntry: QueueIndex['queues'][0] = { id: queue.id, status: queue.status, - issue_ids: queue.issue_ids, - total_tasks: queue._metadata.total_tasks, - completed_tasks: queue._metadata.completed_count, + issue_ids: issueIds, created_at: queue.id.replace('QUE-', '').replace(/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/, '$1-$2-$3T$4:$5:$6Z'), // Derive from ID completed_at: queue.status === 'completed' ? new Date().toISOString() : undefined }; + // Add format-specific counts + if (isSolutionQueue) { + indexEntry.total_solutions = items.length; + indexEntry.completed_solutions = queue._metadata.completed_count; + } else { + indexEntry.total_tasks = items.length; + indexEntry.completed_tasks = queue._metadata.completed_count; + } + if (existingIdx >= 0) { index.queues[existingIdx] = indexEntry; } else { diff --git a/package.json b/package.json index 882865c8..247bdcc4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "claude-code-workflow", - "version": "6.3.10", + "version": "6.3.11", "description": "JSON-driven multi-agent development framework with intelligent CLI orchestration (Gemini/Qwen/Codex), context-first architecture, and automated workflow execution", "type": "module", "main": "ccw/src/index.js",