@@ -186,34 +186,143 @@ output → Variable name to store this step's result
186186
187187** Execution Flow** :
188188```
189- FOR each step in implementation_approach[] (ordered by step number):
190- 1. Check depends_on: Wait for all listed step numbers to complete
191- 2. Variable Substitution: Replace [variable_name] in description/modification_points
192- with values stored from previous steps' output
193- 3. Execute step (choose one):
194-
195- IF step.command exists:
196- → Execute the CLI command via Bash tool
197- → Capture output
198-
199- ELSE (no command - Agent direct implementation):
200- → Read modification_points[] as list of files to create/modify
201- → Read logic_flow[] as implementation sequence
202- → For each file in modification_points:
203- • If "Create new file: path" → Use Write tool to create
204- • If "Modify file: path" → Use Edit tool to modify
205- • If "Add to file: path" → Use Edit tool to append
206- → Follow logic_flow sequence for implementation logic
207- → Use [focus_paths] from context as working directory scope
208-
209- 4. Store result in [step.output] variable for later steps
210- 5. Mark step complete, proceed to next
189+ // Read task-level execution config (Single Source of Truth)
190+ const executionMethod = task.meta?.execution_config?.method || 'agent';
191+ const cliTool = task.meta?.execution_config?.cli_tool || 'codex';
192+
193+ // Phase 1: Execute pre_analysis (always by Agent)
194+ const preAnalysisResults = {};
195+ for (const step of task.flow_control.pre_analysis || []) {
196+ const result = executePreAnalysisStep(step);
197+ preAnalysisResults[step.output_to] = result;
198+ }
199+
200+ // Phase 2: Determine execution mode
201+ const hasLegacyCommands = task.flow_control.implementation_approach
202+ .some(step => step.command);
203+
204+ IF hasLegacyCommands:
205+ // Backward compatibility: Old mode with step.command fields
206+ FOR each step in implementation_approach[]:
207+ IF step.command exists:
208+ → Execute via Bash: Bash({ command: step.command, timeout: 3600000 })
209+ ELSE:
210+ → Agent direct implementation
211+
212+ ELSE IF executionMethod === 'cli':
213+ // New mode: CLI Handoff
214+ → const cliPrompt = buildCliHandoffPrompt(preAnalysisResults, task)
215+ → const cliCommand = buildCliCommand(task, cliTool, cliPrompt)
216+ → Bash({ command: cliCommand, run_in_background: false, timeout: 3600000 })
217+
218+ ELSE IF executionMethod === 'hybrid':
219+ // Hybrid mode: Agent decides based on task complexity
220+ → IF task is complex (multiple files, complex logic):
221+ Use CLI Handoff (same as cli mode)
222+ ELSE:
223+ Use Agent direct implementation
224+
225+ ELSE (executionMethod === 'agent'):
226+ // Default: Agent direct implementation
227+ FOR each step in implementation_approach[]:
228+ 1. Variable Substitution: Replace [variable_name] with preAnalysisResults
229+ 2. Read modification_points[] as files to create/modify
230+ 3. Read logic_flow[] as implementation sequence
231+ 4. For each file in modification_points:
232+ • If "Create new file: path" → Use Write tool
233+ • If "Modify file: path" → Use Edit tool
234+ • If "Add to file: path" → Use Edit tool (append)
235+ 5. Follow logic_flow sequence
236+ 6. Use [focus_paths] from context as working directory scope
237+ 7. Store result in [step.output] variable
238+ ```
239+
240+ ** CLI Handoff Functions** :
241+
242+ ``` javascript
243+ // Build CLI prompt from pre-analysis results and task
244+ function buildCliHandoffPrompt (preAnalysisResults , task ) {
245+ const contextSection = Object .entries (preAnalysisResults)
246+ .map (([key , value ]) => ` ### ${ key} \n ${ value} ` )
247+ .join (' \n\n ' );
248+
249+ const approachSection = task .flow_control .implementation_approach
250+ .map ((step , i ) => `
251+ ### Step ${ step .step } : ${ step .title }
252+ ${ step .description }
253+
254+ **Modification Points**:
255+ ${ step .modification_points ? .map (m => ` - ${ m} ` ).join (' \n ' ) || ' N/A' }
256+
257+ ** Logic Flow** :
258+ ${step .logic_flow ? .map ((l , j ) => ` ${ j + 1 } . ${ l} ` ).join (' \n ' ) || ' Follow modification points' }
259+ ` ).join('\n ');
260+
261+ return `
262+ PURPOSE : ${task .title }
263+ Complete implementation based on pre- analyzed context.
264+
265+ ## PRE - ANALYSIS CONTEXT
266+ ${contextSection}
267+
268+ ## REQUIREMENTS
269+ ${task .context .requirements ? .map (r => ` - ${ r} ` ).join (' \n ' ) || task .context .requirements }
270+
271+ ## IMPLEMENTATION APPROACH
272+ ${approachSection}
273+
274+ ## ACCEPTANCE CRITERIA
275+ ${task .context .acceptance ? .map (a => ` - ${ a} ` ).join (' \n ' ) || task .context .acceptance }
276+
277+ ## TARGET FILES
278+ ${task .flow_control .target_files ? .map (f => ` - ${ f} ` ).join (' \n ' ) || ' See modification points above' }
279+
280+ MODE : write
281+ CONSTRAINTS : Follow existing patterns | No breaking changes
282+ ` .trim();
283+ }
284+
285+ // Build CLI command with resume strategy
286+ function buildCliCommand(task, cliTool, cliPrompt) {
287+ const cli = task.cli_execution || {};
288+ const escapedPrompt = cliPrompt.replace(/"/g, '\\ "');
289+ const baseCmd = ` ccw cli - p " ${escapedPrompt}" ` ;
290+
291+ switch (cli.strategy) {
292+ case 'new':
293+ return ` ${baseCmd} -- tool ${cliTool} -- mode write -- id ${task .cli_execution_id }` ;
294+ case 'resume':
295+ return ` ${baseCmd} -- resume ${cli .resume_from } -- tool ${cliTool} -- mode write` ;
296+ case 'fork':
297+ return ` ${baseCmd} -- resume ${cli .resume_from } -- id ${task .cli_execution_id } -- tool ${cliTool} -- mode write` ;
298+ case 'merge_fork':
299+ return ` ${baseCmd} -- resume ${cli .merge_from .join (' ,' )} -- id ${task .cli_execution_id } -- tool ${cliTool} -- mode write` ;
300+ default:
301+ // Fallback: no resume, no id
302+ return ` ${baseCmd} -- tool ${cliTool} -- mode write` ;
303+ }
304+ }
211305` ` `
212306
213- ** CLI Command Execution (CLI Execute Mode)** :
214- When step contains ` command ` field with Codex CLI, execute via CCW CLI. For Codex resume:
215- - First task (` depends_on: [] ` ): ` ccw cli -p "..." --tool codex --mode write --cd [path] `
216- - Subsequent tasks (has ` depends_on ` ): Use CCW CLI with resume context to maintain session
307+ ** Execution Config Reference** (from task .meta .execution_config ):
308+ | Field | Values | Description |
309+ | ------ - | -------- | ------------ - |
310+ | ` method` | ` agent` / ` cli` / ` hybrid` | Execution mode (default: agent) |
311+ | ` cli_tool` | ` codex` / ` gemini` / ` qwen` | CLI tool preference (default: codex) |
312+ | ` enable_resume` | ` true` / ` false` | Enable CLI session resume |
313+
314+ ** CLI Execution Reference** (from task .cli_execution ):
315+ | Field | Values | Description |
316+ | ------ - | -------- | ------------ - |
317+ | ` strategy` | ` new` / ` resume` / ` fork` / ` merge_fork` | Resume strategy |
318+ | ` resume_from` | ` {session}-{task_id}` | Parent task CLI ID (resume/ fork) |
319+ | ` merge_from` | ` [{id1}, {id2}]` | Parent task CLI IDs (merge_fork) |
320+
321+ ** Resume Strategy Examples** :
322+ - ** New task** (no dependencies): ` --id WFS-001-IMPL-001`
323+ - ** Resume** (single dependency, single child): ` --resume WFS-001-IMPL-001`
324+ - ** Fork** (single dependency, multiple children): ` --resume WFS-001-IMPL-001 --id WFS-001-IMPL-002`
325+ - ** Merge** (multiple dependencies): ` --resume WFS-001-IMPL-001,WFS-001-IMPL-002 --id WFS-001-IMPL-003`
217326
218327** Test- Driven Development** :
219328- Write tests first (red → green → refactor)
0 commit comments