From 8985894c22c0174f897054c29f784d7eed0b7d95 Mon Sep 17 00:00:00 2001 From: catlog22 Date: Sun, 15 Feb 2026 13:57:00 +0800 Subject: [PATCH] feat: Enhance role functionality and task management across coordinator, explorer, implementer, planner, reviewer, and workflow phases --- .../skills/team-issue/roles/coordinator.md | 13 +++++++++--- .claude/skills/team-issue/roles/explorer.md | 3 +++ .../skills/team-issue/roles/implementer.md | 14 ++++++++++++- .claude/skills/team-issue/roles/planner.md | 3 +++ .claude/skills/team-issue/roles/reviewer.md | 20 ++++++++++++++++++- .../phases/04-task-generation.md | 11 +++++++--- .../phases/05-tdd-task-generation.md | 2 +- .../phases/06-tdd-structure-validation.md | 9 +++++++-- .claude/skills/workflow-test-fix/SKILL.md | 14 ++++--------- 9 files changed, 68 insertions(+), 21 deletions(-) diff --git a/.claude/skills/team-issue/roles/coordinator.md b/.claude/skills/team-issue/roles/coordinator.md index c8d591f7..e70cb1cd 100644 --- a/.claude/skills/team-issue/roles/coordinator.md +++ b/.claude/skills/team-issue/roles/coordinator.md @@ -101,7 +101,8 @@ function detectMode(issueIds, userMode) { const hasHighPriority = issues.some(i => i.priority >= 4) return hasHighPriority ? 'full' : 'quick' } - return count <= 5 ? 'full' : 'batch' + // 3-4 issues with review, 5+ triggers batch parallel processing + return count >= 5 ? 'batch' : 'full' } ``` @@ -228,19 +229,25 @@ for (const issueId of issueIds) { const exploreBatches = chunkArray(issueIds, 5) // max 5 parallel const solveBatches = chunkArray(issueIds, 3) // max 3 parallel -// Create EXPLORE tasks (parallel within batch) +// Create EXPLORE tasks — all parallel within each batch, batches run in rolling window +// Each batch of ≤5 runs concurrently; next batch starts when current batch completes const exploreTaskIds = [] +let prevBatchLastId = null for (const [batchIdx, batch] of exploreBatches.entries()) { + const batchTaskIds = [] for (const issueId of batch) { const id = TaskCreate({ subject: `EXPLORE-${String(exploreTaskIds.length + 1).padStart(3, '0')}: Context for ${issueId}`, description: `Batch ${batchIdx + 1}: Explore codebase context for issue ${issueId}.`, activeForm: `Exploring ${issueId}`, owner: "explorer", - addBlockedBy: batchIdx > 0 ? [exploreTaskIds[exploreTaskIds.length - 1]] : [] + // Only block on previous batch's LAST task (not within same batch) + addBlockedBy: prevBatchLastId ? [prevBatchLastId] : [] }) + batchTaskIds.push(id) exploreTaskIds.push(id) } + prevBatchLastId = batchTaskIds[batchTaskIds.length - 1] } // Create SOLVE tasks (blocked by corresponding EXPLORE) diff --git a/.claude/skills/team-issue/roles/explorer.md b/.claude/skills/team-issue/roles/explorer.md index c6025876..67647d8b 100644 --- a/.claude/skills/team-issue/roles/explorer.md +++ b/.claude/skills/team-issue/roles/explorer.md @@ -72,6 +72,9 @@ TaskUpdate({ taskId: task.id, status: 'in_progress' }) ### Phase 2: Issue Loading & Context Setup ```javascript +// Resolve project root from working directory +const projectRoot = Bash('pwd').trim() + // Extract issue ID from task description const issueIdMatch = task.description.match(/(?:GH-\d+|ISS-\d{8}-\d{6})/) const issueId = issueIdMatch ? issueIdMatch[0] : null diff --git a/.claude/skills/team-issue/roles/implementer.md b/.claude/skills/team-issue/roles/implementer.md index b6cd2469..a0bb7e54 100644 --- a/.claude/skills/team-issue/roles/implementer.md +++ b/.claude/skills/team-issue/roles/implementer.md @@ -185,8 +185,20 @@ Dependencies: ${explorerContext.dependencies?.join(', ') || 'N/A'} ### Phase 4: Verify & Commit ```javascript +// Detect test command from package.json or project config +let testCmd = 'npm test' +try { + const pkgJson = JSON.parse(Read('package.json')) + if (pkgJson.scripts?.test) testCmd = 'npm test' + else if (pkgJson.scripts?.['test:unit']) testCmd = 'npm run test:unit' +} catch { + // Fallback: try common test runners + const hasYarn = Bash('test -f yarn.lock && echo yes || echo no').trim() === 'yes' + if (hasYarn) testCmd = 'yarn test' +} + // Verify implementation -const testResult = Bash(`npm test 2>&1 || echo "TEST_FAILED"`) +const testResult = Bash(`${testCmd} 2>&1 || echo "TEST_FAILED"`) const testPassed = !testResult.includes('TEST_FAILED') && !testResult.includes('FAIL') if (!testPassed) { diff --git a/.claude/skills/team-issue/roles/planner.md b/.claude/skills/team-issue/roles/planner.md index 53b7d3eb..0e740d04 100644 --- a/.claude/skills/team-issue/roles/planner.md +++ b/.claude/skills/team-issue/roles/planner.md @@ -71,6 +71,9 @@ TaskUpdate({ taskId: task.id, status: 'in_progress' }) ### Phase 2: Context Loading ```javascript +// Resolve project root from working directory +const projectRoot = Bash('pwd').trim() + // Extract issue ID const issueIdMatch = task.description.match(/(?:GH-\d+|ISS-\d{8}-\d{6})/) const issueId = issueIdMatch ? issueIdMatch[0] : null diff --git a/.claude/skills/team-issue/roles/reviewer.md b/.claude/skills/team-issue/roles/reviewer.md index 94800d74..69517170 100644 --- a/.claude/skills/team-issue/roles/reviewer.md +++ b/.claude/skills/team-issue/roles/reviewer.md @@ -163,7 +163,7 @@ for (const issueId of issueIds) { completeness: { score: 0, findings: [] } } - // 1. Technical Feasibility — verify solution references real files + // 1. Technical Feasibility — verify solution references real files + semantic validation if (context && context.relevant_files) { const solutionFiles = solution.bound.tasks?.flatMap(t => t.files || []) || [] const contextFiles = context.relevant_files.map(f => f.path || f) @@ -177,6 +177,24 @@ for (const issueId of issueIds) { `Uncovered files: ${uncovered.join(', ')}` ) } + + // Semantic validation via ACE — verify solution references exist in codebase + const projectRoot = Bash('pwd').trim() + const aceResults = mcp__ace-tool__search_context({ + project_root_path: projectRoot, + query: `${solution.bound.title || issue.title}. Verify patterns: ${solutionFiles.slice(0, 5).join(', ')}` + }) + if (aceResults && aceResults.length > 0) { + // Cross-check ACE results against solution's assumed patterns + const aceFiles = aceResults.map(r => r.file || r.path).filter(Boolean) + const missedByAce = solutionFiles.filter(sf => !aceFiles.some(af => af.includes(sf))) + if (missedByAce.length > solutionFiles.length * 0.5) { + review.technical_feasibility.score = Math.max(50, review.technical_feasibility.score - 10) + review.technical_feasibility.findings.push( + `ACE semantic search found divergent patterns — solution may reference outdated code` + ) + } + } } else { review.technical_feasibility.score = 70 // No context to validate against review.technical_feasibility.findings.push('Explorer context not available for cross-validation') diff --git a/.claude/skills/workflow-plan/phases/04-task-generation.md b/.claude/skills/workflow-plan/phases/04-task-generation.md index 99d03d3a..a2c9d83c 100644 --- a/.claude/skills/workflow-plan/phases/04-task-generation.md +++ b/.claude/skills/workflow-plan/phases/04-task-generation.md @@ -468,7 +468,12 @@ if (userChoice.answers["Next Action"] === "Verify Plan Quality (Recommended)") { Skill(skill="workflow-execute", args="--session " + sessionId); } else if (userChoice.answers["Next Action"] === "Review Status Only") { console.log("\nDisplaying session status...\n"); - Skill(skill="workflow:status", args="--session " + sessionId); + // Display session status inline + const sessionMeta = JSON.parse(Read(`.workflow/active/${sessionId}/workflow-session.json`)); + const todoList = Read(`.workflow/active/${sessionId}/TODO_LIST.md`); + console.log(`Session: ${sessionId}`); + console.log(`Status: ${sessionMeta.status}`); + console.log(`\n--- TODO List ---\n${todoList}`); } ``` @@ -477,7 +482,7 @@ if (userChoice.answers["Next Action"] === "Verify Plan Quality (Recommended)") { **Return to Orchestrator**: Based on user's choice: - **Verify** -> Orchestrator reads phases/05-plan-verify.md and executes Phase 5 in-process - **Execute** -> Skill(skill="workflow-execute") -- **Review** -> Route to /workflow:status +- **Review** -> Display session status inline ## Output @@ -492,4 +497,4 @@ if (userChoice.answers["Next Action"] === "Verify Plan Quality (Recommended)") { Based on user's plan confirmation choice: - If "Verify" -> [Phase 5: Plan Verification](05-plan-verify.md) - If "Execute" -> Skill(skill="workflow-execute") -- If "Review" -> External: /workflow:status +- If "Review" -> Display session status inline diff --git a/.claude/skills/workflow-tdd/phases/05-tdd-task-generation.md b/.claude/skills/workflow-tdd/phases/05-tdd-task-generation.md index 9431d2ba..dd9183bb 100644 --- a/.claude/skills/workflow-tdd/phases/05-tdd-task-generation.md +++ b/.claude/skills/workflow-tdd/phases/05-tdd-task-generation.md @@ -113,7 +113,7 @@ const userConfig = { } ``` -**Auto Mode**: When `--yes` or `-y`: Skip user questions, use defaults (no materials, Agent executor). +**Auto Mode**: When `workflowPreferences.autoYes` is true, skip user questions, use defaults (no materials, Agent executor). --- diff --git a/.claude/skills/workflow-tdd/phases/06-tdd-structure-validation.md b/.claude/skills/workflow-tdd/phases/06-tdd-structure-validation.md index 70cdd141..e5198d7f 100644 --- a/.claude/skills/workflow-tdd/phases/06-tdd-structure-validation.md +++ b/.claude/skills/workflow-tdd/phases/06-tdd-structure-validation.md @@ -159,7 +159,12 @@ if (userChoice === "Verify TDD Compliance (Recommended)") { } else if (userChoice === "Start Execution") { Skill(skill="workflow-execute", args="--session " + sessionId); } else if (userChoice === "Review Status Only") { - Skill(skill="workflow:status", args="--session " + sessionId); + // Display session status inline + const sessionMeta = JSON.parse(Read(`.workflow/active/${sessionId}/workflow-session.json`)); + const todoList = Read(`.workflow/active/${sessionId}/TODO_LIST.md`); + console.log(`\nSession: ${sessionId}`); + console.log(`Status: ${sessionMeta.status}`); + console.log(`\n--- TODO List ---\n${todoList}`); } ``` @@ -176,4 +181,4 @@ if (userChoice === "Verify TDD Compliance (Recommended)") { Based on user's plan confirmation choice: - If "Verify" → [Phase 7: TDD Verification](07-tdd-verify.md) - If "Execute" → Skill(skill="workflow-execute") -- If "Review" → External: /workflow:status +- If "Review" -> Display session status inline diff --git a/.claude/skills/workflow-test-fix/SKILL.md b/.claude/skills/workflow-test-fix/SKILL.md index f61bed5f..8ecf6677 100644 --- a/.claude/skills/workflow-test-fix/SKILL.md +++ b/.claude/skills/workflow-test-fix/SKILL.md @@ -54,20 +54,14 @@ Task Pipeline (generated in Phase 4, executed in Phase 5): 5. **Progressive Phase Loading**: Phase docs read **only** when that phase executes, not upfront 6. **Adaptive Strategy**: Fix loop auto-selects strategy (conservative/aggressive/surgical) based on iteration context 7. **Quality Gate**: Pass rate >= 95% (criticality-aware) terminates the fix loop -8. **Original Commands Preserved**: Phase files preserve full original command content and Skill() calls +8. **Phase File Hygiene**: Phase files reference `workflowPreferences.*` for preferences, no CLI flag parsing ## Usage -```bash -# Full pipeline: generate + execute -/workflow:test-fix-gen "Test the user authentication API" -/workflow:test-fix-gen WFS-user-auth-v2 +Full pipeline and execute-only modes are triggered by skill name routing (see Mode Detection). Workflow preferences (auto mode) are collected interactively via AskUserQuestion before dispatching to phases. -# Execute only (resume from existing test session with generated tasks) -/workflow:test-cycle-execute -/workflow:test-cycle-execute --resume-session="WFS-test-user-auth" -/workflow:test-cycle-execute --max-iterations=15 -``` +**Full pipeline** (workflow:test-fix-gen): Task description or session ID as arguments → interactive preference collection → generate + execute pipeline +**Execute only** (workflow:test-cycle-execute): Auto-discovers active session → interactive preference collection → execution loop ## Interactive Preference Collection