mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-05 01:50:27 +08:00
feat(discovery): enhance discovery progress reading with new schema support
This commit is contained in:
@@ -172,19 +172,17 @@ TodoWrite({
|
||||
});
|
||||
```
|
||||
|
||||
### Phase 2: Unified Explore + Plan (issue-plan-agent)
|
||||
### Phase 2: Unified Explore + Plan (issue-plan-agent) - PARALLEL
|
||||
|
||||
```javascript
|
||||
Bash(`mkdir -p .workflow/issues/solutions`);
|
||||
const pendingSelections = []; // Collect multi-solution issues for user selection
|
||||
|
||||
for (const [batchIndex, batch] of batches.entries()) {
|
||||
updateTodo(`Plan batch ${batchIndex + 1}`, 'in_progress');
|
||||
|
||||
// Build issue list with metadata for agent context
|
||||
// Build prompts for all batches
|
||||
const agentTasks = batches.map((batch, batchIndex) => {
|
||||
const issueList = batch.map(i => `- ${i.id}: ${i.title}${i.tags.length ? ` [${i.tags.join(', ')}]` : ''}`).join('\n');
|
||||
const batchIds = batch.map(i => i.id);
|
||||
|
||||
// Build minimal prompt - agent handles exploration, planning, and binding
|
||||
const issuePrompt = `
|
||||
## Plan Issues
|
||||
|
||||
@@ -223,32 +221,43 @@ ${issueList}
|
||||
\`\`\`
|
||||
`;
|
||||
|
||||
// Launch issue-plan-agent - agent writes solutions directly
|
||||
const batchIds = batch.map(i => i.id);
|
||||
const result = Task(
|
||||
subagent_type="issue-plan-agent",
|
||||
run_in_background=false,
|
||||
description=`Explore & plan ${batch.length} issues: ${batchIds.join(', ')}`,
|
||||
prompt=issuePrompt
|
||||
);
|
||||
return { batchIndex, batchIds, issuePrompt, batch };
|
||||
});
|
||||
|
||||
// Parse summary from agent
|
||||
const summary = JSON.parse(result);
|
||||
// Launch agents in parallel (max 10 concurrent)
|
||||
const MAX_PARALLEL = 10;
|
||||
for (let i = 0; i < agentTasks.length; i += MAX_PARALLEL) {
|
||||
const chunk = agentTasks.slice(i, i + MAX_PARALLEL);
|
||||
const taskIds = [];
|
||||
|
||||
// Display auto-bound solutions
|
||||
for (const item of summary.bound || []) {
|
||||
console.log(`✓ ${item.issue_id}: ${item.solution_id} (${item.task_count} tasks)`);
|
||||
// Launch chunk in parallel
|
||||
for (const { batchIndex, batchIds, issuePrompt, batch } of chunk) {
|
||||
updateTodo(`Plan batch ${batchIndex + 1}`, 'in_progress');
|
||||
const taskId = Task(
|
||||
subagent_type="issue-plan-agent",
|
||||
run_in_background=true,
|
||||
description=`Explore & plan ${batch.length} issues: ${batchIds.join(', ')}`,
|
||||
prompt=issuePrompt
|
||||
);
|
||||
taskIds.push({ taskId, batchIndex });
|
||||
}
|
||||
|
||||
// Collect pending selections for Phase 3
|
||||
pendingSelections.push(...(summary.pending_selection || []));
|
||||
console.log(`Launched ${taskIds.length} agents (batch ${i/MAX_PARALLEL + 1}/${Math.ceil(agentTasks.length/MAX_PARALLEL)})...`);
|
||||
|
||||
// Show conflicts
|
||||
if (summary.conflicts?.length > 0) {
|
||||
console.log(`⚠ Conflicts: ${summary.conflicts.map(c => c.file).join(', ')}`);
|
||||
// Collect results from this chunk
|
||||
for (const { taskId, batchIndex } of taskIds) {
|
||||
const result = TaskOutput(task_id=taskId, block=true);
|
||||
const summary = JSON.parse(result);
|
||||
|
||||
for (const item of summary.bound || []) {
|
||||
console.log(`✓ ${item.issue_id}: ${item.solution_id} (${item.task_count} tasks)`);
|
||||
}
|
||||
pendingSelections.push(...(summary.pending_selection || []));
|
||||
if (summary.conflicts?.length > 0) {
|
||||
console.log(`⚠ Conflicts: ${summary.conflicts.map(c => c.file).join(', ')}`);
|
||||
}
|
||||
updateTodo(`Plan batch ${batchIndex + 1}`, 'completed');
|
||||
}
|
||||
|
||||
updateTodo(`Plan batch ${batchIndex + 1}`, 'completed');
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -116,13 +116,51 @@ function readDiscoveryState(discoveriesDir: string, discoveryId: string): any |
|
||||
}
|
||||
|
||||
function readDiscoveryProgress(discoveriesDir: string, discoveryId: string): any | null {
|
||||
const progressPath = join(discoveriesDir, discoveryId, 'discovery-progress.json');
|
||||
if (!existsSync(progressPath)) return null;
|
||||
try {
|
||||
return JSON.parse(readFileSync(progressPath, 'utf8'));
|
||||
} catch {
|
||||
return null;
|
||||
// Try merged state first (new schema)
|
||||
const statePath = join(discoveriesDir, discoveryId, 'discovery-state.json');
|
||||
if (existsSync(statePath)) {
|
||||
try {
|
||||
const state = JSON.parse(readFileSync(statePath, 'utf8'));
|
||||
// New merged schema: perspectives array + results object
|
||||
if (state.perspectives && Array.isArray(state.perspectives)) {
|
||||
const completed = state.perspectives.filter((p: any) => p.status === 'completed').length;
|
||||
const total = state.perspectives.length;
|
||||
return {
|
||||
discovery_id: discoveryId,
|
||||
phase: state.phase,
|
||||
last_update: state.updated_at || state.created_at,
|
||||
progress: {
|
||||
perspective_analysis: {
|
||||
total,
|
||||
completed,
|
||||
in_progress: state.perspectives.filter((p: any) => p.status === 'in_progress').length,
|
||||
percent_complete: total > 0 ? Math.round((completed / total) * 100) : 0
|
||||
},
|
||||
external_research: state.external_research || { enabled: false, completed: false },
|
||||
aggregation: { completed: state.phase === 'aggregation' || state.phase === 'complete' },
|
||||
issue_generation: { completed: state.phase === 'complete', issues_count: state.results?.issues_generated || 0 }
|
||||
},
|
||||
agent_status: state.perspectives
|
||||
};
|
||||
}
|
||||
// Old schema: metadata.perspectives (backward compat)
|
||||
if (state.metadata?.perspectives) {
|
||||
return {
|
||||
discovery_id: discoveryId,
|
||||
phase: state.phase,
|
||||
progress: { perspective_analysis: { total: state.metadata.perspectives.length, completed: state.perspectives_completed?.length || 0 } }
|
||||
};
|
||||
}
|
||||
} catch {
|
||||
// Fall through
|
||||
}
|
||||
}
|
||||
// Fallback: try legacy progress file
|
||||
const progressPath = join(discoveriesDir, discoveryId, 'discovery-progress.json');
|
||||
if (existsSync(progressPath)) {
|
||||
try { return JSON.parse(readFileSync(progressPath, 'utf8')); } catch { return null; }
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function readPerspectiveFindings(discoveriesDir: string, discoveryId: string): any[] {
|
||||
|
||||
Reference in New Issue
Block a user