Skip to main content

workflow-lite-execute

Lightweight execution engine - multi-mode input, task grouping, batch execution, chain to workflow-lite-test-review

Informations de source

Dépôt
catlog22/Claude-Code-Workflow
Dernière activité de la source
14 mai 2026 à 15:44
Langue détectée de SKILL.md
anglais
Étoiles
2 128
Forks
166

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
workflow-lite-execute
description
Lightweight execution engine - multi-mode input, task grouping, batch execution, chain to workflow-lite-test-review
allowed-tools
Skill, Agent, AskUserQuestion, TodoWrite, Read, Write, Edit, Bash, Glob, Grep
# Workflow-Lite-Execute Execution engine for workflow-lite-plan handoff and standalone task execution. --- ## Usage ``` <input> Task description string, or path to file (required) ``` | Flag | Description | |------|-------------| | `--in-memory` | Mode 1: Use executionContext from workflow-lite-plan handoff (via Skill({ skill: "workflow-lite-execute", args: "--in-memory" }) | ## Input Modes ### Mode 1: In-Memory Plan **Trigger**: `--in-memory` flag or `executionContext` global variable available **Input Source**: `executionContext` global variable set by workflow-lite-plan **Behavior**: Skip execution method/code review selection (already chosen in LP-Phase 4), directly proceed with full context (exploration, clarifications, plan artifacts all available) > **Note**: LP-Phase 4 is the single confirmation gate. Mode 1 invocation means user already approved — no further prompts. ### Mode 2: Prompt Description **Trigger**: User calls with task description string (e.g., "Add unit tests for auth module") **Behavior**: Store prompt as `originalUserInput` → create simple execution plan → run `selectExecutionOptions()` → proceed ### Mode 3: File Content **Trigger**: User calls with file path (ends with .md/.json/.txt) ```javascript fileContent = Read(filePath) try { jsonData = JSON.parse(fileContent) // plan.json detection: two-layer format with task_ids[] if (jsonData.summary && jsonData.approach && jsonData.task_ids) { planObject = jsonData originalUserInput = jsonData.summary isPlanJson = true const planDir = filePath.replace(/[/\\][^/\\]+$/, '') planObject._loadedTasks = loadTaskFiles(planDir, jsonData.task_ids) } else { originalUserInput = fileContent isPlanJson = false } } catch { originalUserInput = fileContent isPlanJson = false } ``` - `isPlanJson === true`: Use `planObject` directly → run `selectExecutionOptions()` - `isPlanJson === false`: Treat as prompt (same as Mode 2) ### User Selection (Mode 2/3 shared) ```javascript function selectExecutionOptions() { // autoYes: set by -y flag (standalone only; Mode 1 never reaches here) const autoYes = workflowPreferences?.autoYes ?? false if (autoYes) { return { execution_method: "Auto", code_review_tool: "Skip", convergence_review_tool: "Skip" } } return AskUserQuestion({ questions: [ { question: "Select execution method:", header: "Execution", multiSelect: false, options: [ { label: "Agent", description: "@code-developer agent" }, { label: "Codex", description: "codex CLI tool" }, { label: "Auto", description: "Auto-select based on complexity" } ] }, { question: "Code review after execution? (runs here in lite-execute)", header: "Code Review", multiSelect: false, options: [ { label: "Gemini Review", description: "Gemini CLI: git diff quality review" }, { label: "Codex Review", description: "Codex CLI: prompt-based code quality review (--mode analysis)" }, { label: "Agent Review", description: "@code-reviewer agent" }, { label: "Skip", description: "No code review" } ] }, { question: "Convergence review in workflow-lite-test-review phase?", header: "Convergence Review", multiSelect: false, options: [ { label: "Agent", description: "Agent: verify convergence criteria" }, { label: "Gemini", description: "Gemini CLI: convergence verification" }, { label: "Codex", description: "Codex CLI: convergence verification" }, { label: "Skip", description: "Skip convergence review, run tests only" } ] } ] }) } ``` ## Execution Steps ### Step 1: Initialize & Echo Strategy ```javascript previousExecutionResults = [] // Mode 1: echo strategy for transparency if (executionContext) { console.log(` Execution Strategy (from lite-plan): Method: ${executionContext.executionMethod} Code Review: ${executionContext.codeReviewTool} Convergence Review: ${executionContext.convergenceReviewTool} Tasks: ${getTasks(executionContext.planObject).length} Complexity: ${executionContext.planObject.complexity} ${executionContext.executorAssignments ? ` Assignments: ${JSON.stringify(executionContext.executorAssignments)}` : ''} `) } // Helper: load .task/*.json files (two-layer format) function loadTaskFiles(planDir, taskIds) { return taskIds.map(id => JSON.parse(Read(`${planDir}/.task/${id}.json`))) } function getTasks(planObject) { return planObject._loadedTasks || [] } ``` ### Step 2: Task Grouping & Batch Creation ```javascript // Dependency extraction: explicit depends_on only (no file/keyword inference) function extractDependencies(tasks) { const taskIdToIndex = {} tasks.forEach((t, i) => { taskIdToIndex[t.id] = i }) return tasks.map((task, i) => { const deps = (task.depends_on || []) .map(depId => taskIdToIndex[depId]) .filter(idx => idx !== undefined && idx < i) return { ...task, taskIndex: i, dependencies: deps } }) } // Executor resolution: executorAssignments[taskId] > executionMethod > Auto fallback function getTaskExecutor(task) { const assignments = executionContext?.executorAssignments || {} if (assignments[task.id]) return assignments[task.id].executor // 'gemini' | 'codex' | 'agent' const method = executionContext?.executionMethod || 'Auto' if (method === 'Agent') return 'agent' if (method === 'Codex') return 'codex' return planObject.complexity === 'Low' ? 'agent' : 'codex' // Auto fallback } function groupTasksByExecutor(tasks) { const groups = { gemini: [], codex: [], agent: [] } tasks.forEach(task => { groups[getTaskExecutor(task)].push(task) }) return groups } // Batch creation: independent → per-executor parallel, dependent → sequential phases function createExecutionCalls(tasks, executionMethod) { const tasksWithDeps = extractDependencies(tasks) const processed = new Set() const calls = [] // Phase 1: Independent tasks → per-executor parallel batches const independentTasks = tasksWithDeps.filter(t => t.dependencies.length === 0) if (independentTasks.length > 0) { const executorGroups = groupTasksByExecutor(independentTasks) let parallelIndex = 1 for (const [executor, tasks] of Object.entries(executorGroups)) { if (tasks.length === 0) continue tasks.forEach(t => processed.add(t.taskIndex)) calls.push({ method: executionMethod, executor, executionType: "parallel", groupId: `P${parallelIndex++}`, taskSummary: tasks.map(t => t.title).join(' | '), tasks }) } } // Phase 2+: Dependent tasks → respect dependency order let sequentialIndex = 1 let remaining = tasksWithDeps.filter(t => !processed.has(t.taskIndex)) while (remaining.length > 0) { let ready = remaining.filter(t => t.dependencies.every(d => processed.has(d))) if (ready.length === 0) { console.warn('Circular dependency detected, forcing remaining'); ready = [...remaining] } if (ready.length > 1) { const executorGroups = groupTasksByExecutor(ready) for (const [executor, tasks] of Object.entries(executorGroups)) { if (tasks.length === 0) continue tasks.forEach(t => processed.add(t.taskIndex)) calls.push({ method: executionMethod, executor, executionType: "parallel", groupId: `P${calls.length + 1}`, taskSummary: tasks.map(t => t.title).join(' | '), tasks }) } } else { ready.forEach(t => processed.add(t.taskIndex)) calls.push({ method: executionMethod, executor: getTaskExecutor(ready[0]), executionType: "sequential", groupId: `S${sequentialIndex++}`, taskSummary: ready[0].title, tasks: ready }) } remaining = remaining.filter(t => !processed.has(t.taskIndex)) } return calls } executionCalls = createExecutionCalls(getTasks(planObject), executionMethod).map(c => ({ ...c, id: `[${c.groupId}]` })) TodoWrite({ todos: executionCalls.map((c, i) => ({ content: `${c.executionType === "parallel" ? "⚡" : `→ [${i+1}/${executionCalls.filter(x=>x.executionType==="sequential").length}]`} ${c.id} [${c.executor}] ${c.tasks.map(t=>t.id).join(', ')}`, status: "pending", activeForm: `Waiting: ${c.tasks.length} task(s) via ${c.executor}` })) }) ``` ### Step 3: Launch Execution & Track Progress > **CHECKPOINT**: Verify Phase 2 execution protocol (Step 3-5) is in active memory. If only a summary remains, re-read `phases/02-lite-execute.md` now. **Batch Routing** (by `batch.executor` field): ```javascript function executeBatch(batch) { const executor = batch.executor || getTaskExecutor(batch.tasks[0]) const sessionId = executionContext?.session?.id || 'standalone' const fixedId = `${sessionId}-${batch.groupId}` if (executor === 'agent') { return Agent({ subagent_type: "code-developer", run_in_background: false, description: batch.taskSummary, prompt: buildExecutionPrompt(batch) }) } else { // CLI execution (codex/gemini): background with fixed ID const tool = executor // 'codex' | 'gemini' const mode = executor === 'gemini' ? 'analysis' : 'write' const previousCliId = batch.resumeFromCliId || null const cmd = previousCliId ? `ccw cli -p "${buildExecutionPrompt(batch)}" --tool ${tool} --mode ${mode} --id ${fixedId} --resume ${previousCliId}` : `ccw cli -p "${buildExecutionPrompt(batch)}" --tool ${tool} --mode ${mode} --id ${fixedId}` return Bash(cmd, { run_in_background: true }) // STOP - wait for task hook callback } } ``` **Parallel execution rules**: - Each batch = one independent CLI instance or Agent call - Parallel = multiple Bash(run_in_background=true) or multiple Agent() in single message - Never merge independent tasks into one CLI prompt - Agent: run_in_background=false, but multiple Agent() calls can be concurrent in single message **Execution Flow**: Parallel batches concurrently → Sequential batches in order ```javascript const parallel = executionCalls.filter(c => c.executionType === "parallel") const sequential = executionCalls.filter(c => c.executionType === "sequential") // Phase 1: All parallel batches (single message, multiple tool calls) if (parallel.length > 0) { TodoWrite({ todos: executionCalls.map(c => ({ status: c.executionType === "parallel" ? "in_progress" : "pending", activeForm: c.executionType === "parallel" ? `Running [${c.executor}]: ${c.tasks.map(t=>t.id).join(', ')}` : `Blocked by parallel phase` })) }) parallelResults = await Promise.all(parallel.map(c => executeBatch(c))) previousExecutionResults.push(...parallelResults) TodoWrite({ todos: executionCalls.map(c => ({ status: parallel.includes(c) ? "completed" : "pending", activeForm: parallel.includes(c) ? `Done [${c.executor}]` : `Ready` })) }) } // Phase 2: Sequential batches one by one for (const call of sequential) { TodoWrite({ todos: executionCalls.map(c => ({ status: c === call ? "in_progress" : (c.status === "completed" ? "completed" : "pending"), activeForm: c === call ? `Running [${c.executor}]: ${c.tasks.map(t=>t.id).join(', ')}` : undefined
Voir sur GitHub
Ce SKILL.md est tres volumineux, SkillsMP affiche donc ici seulement la premiere section. Voir sur GitHub