1+ #! /bin/bash
2+ # implement.sh - Execute the implementation plan with dual execution loop support
3+ # Handles SYNC/ASYNC task classification, MCP dispatching, and review enforcement
4+
5+ set -euo pipefail
6+
7+ # Source common utilities
8+ SCRIPT_DIR=" $( cd " $( dirname " ${BASH_SOURCE[0]} " ) " && pwd) "
9+ source " $SCRIPT_DIR /common.sh"
10+ source " $SCRIPT_DIR /tasks-meta-utils.sh"
11+
12+ # Global variables
13+ FEATURE_DIR=" "
14+ AVAILABLE_DOCS=" "
15+ TASKS_FILE=" "
16+ TASKS_META_FILE=" "
17+ CHECKLISTS_DIR=" "
18+ IMPLEMENTATION_LOG=" "
19+
20+ # Logging functions
21+ log_info () {
22+ echo " [INFO] $* " >&2
23+ }
24+
25+ log_success () {
26+ echo " [SUCCESS] $* " >&2
27+ }
28+
29+ log_error () {
30+ echo " [ERROR] $* " >&2
31+ }
32+
33+ log_warning () {
34+ echo " [WARNING] $* " >&2
35+ }
36+
37+ # Initialize implementation environment
38+ init_implementation () {
39+ local json_output=" $1 "
40+
41+ # Parse JSON output from check-prerequisites.sh
42+ FEATURE_DIR=$( echo " $json_output " | jq -r ' .FEATURE_DIR // empty' )
43+ AVAILABLE_DOCS=$( echo " $json_output " | jq -r ' .AVAILABLE_DOCS // empty' )
44+
45+ if [[ -z " $FEATURE_DIR " ]]; then
46+ log_error " FEATURE_DIR not found in prerequisites check"
47+ exit 1
48+ fi
49+
50+ TASKS_FILE=" $FEATURE_DIR /tasks.md"
51+ TASKS_META_FILE=" $FEATURE_DIR /tasks_meta.json"
52+ CHECKLISTS_DIR=" $FEATURE_DIR /checklists"
53+
54+ # Create implementation log
55+ IMPLEMENTATION_LOG=" $FEATURE_DIR /implementation.log"
56+ echo " # Implementation Log - $( date) " > " $IMPLEMENTATION_LOG "
57+ echo " " >> " $IMPLEMENTATION_LOG "
58+
59+ log_info " Initialized implementation for feature: $( basename " $FEATURE_DIR " ) "
60+ }
61+
62+ # Check checklists status
63+ check_checklists_status () {
64+ if [[ ! -d " $CHECKLISTS_DIR " ]]; then
65+ log_info " No checklists directory found - proceeding without checklist validation"
66+ return 0
67+ fi
68+
69+ log_info " Checking checklist status..."
70+
71+ local total_checklists=0
72+ local passed_checklists=0
73+ local failed_checklists=0
74+
75+ echo " ## Checklist Status Report" >> " $IMPLEMENTATION_LOG "
76+ echo " " >> " $IMPLEMENTATION_LOG "
77+ echo " | Checklist | Total | Completed | Incomplete | Status |" >> " $IMPLEMENTATION_LOG "
78+ echo " |-----------|-------|-----------|------------|--------|" >> " $IMPLEMENTATION_LOG "
79+
80+ for checklist_file in " $CHECKLISTS_DIR " /* .md; do
81+ if [[ ! -f " $checklist_file " ]]; then
82+ continue
83+ fi
84+
85+ local filename=$( basename " $checklist_file " .md)
86+ local total_items=$( grep -c " ^- \[" " $checklist_file " || echo " 0" )
87+ local completed_items=$( grep -c " ^- \[X\]\|^- \[x\]" " $checklist_file " || echo " 0" )
88+ local incomplete_items=$(( total_items - completed_items))
89+
90+ local status=" PASS"
91+ if [[ $incomplete_items -gt 0 ]]; then
92+ status=" FAIL"
93+ failed_checklists=$(( failed_checklists + 1 ))
94+ else
95+ passed_checklists=$(( passed_checklists + 1 ))
96+ fi
97+
98+ total_checklists=$(( total_checklists + 1 ))
99+
100+ echo " | $filename | $total_items | $completed_items | $incomplete_items | $status |" >> " $IMPLEMENTATION_LOG "
101+ done
102+
103+ echo " " >> " $IMPLEMENTATION_LOG "
104+
105+ if [[ $failed_checklists -gt 0 ]]; then
106+ log_warning " Found $failed_checklists checklist(s) with incomplete items"
107+ echo " Some checklists are incomplete. Do you want to proceed with implementation anyway? (yes/no): "
108+ read -r response
109+ if [[ ! " $response " =~ ^(yes| y)$ ]]; then
110+ log_info " Implementation cancelled by user"
111+ exit 0
112+ fi
113+ else
114+ log_success " All $total_checklists checklists passed"
115+ fi
116+ }
117+
118+ # Load implementation context
119+ load_implementation_context () {
120+ log_info " Loading implementation context..."
121+
122+ # Required files
123+ local required_files=(" tasks.md" " plan.md" " spec.md" )
124+
125+ for file in " ${required_files[@]} " ; do
126+ if [[ ! -f " $FEATURE_DIR /$file " ]]; then
127+ log_error " Required file missing: $FEATURE_DIR /$file "
128+ exit 1
129+ fi
130+ done
131+
132+ # Optional files
133+ local optional_files=(" data-model.md" " contracts/" " research.md" " quickstart.md" )
134+
135+ for file in " ${optional_files[@]} " ; do
136+ if [[ -f " $FEATURE_DIR /$file " ]] || [[ -d " $FEATURE_DIR /$file " ]]; then
137+ log_info " Found optional context: $file "
138+ fi
139+ done
140+ }
141+
142+ # Parse tasks from tasks.md
143+ parse_tasks () {
144+ log_info " Parsing tasks from $TASKS_FILE ..."
145+
146+ # Extract tasks with their metadata
147+ # This is a simplified parser - in practice, you'd want more robust parsing
148+ local task_lines
149+ task_lines=$( grep -n " ^- \[ \] T[0-9]\+" " $TASKS_FILE " || true)
150+
151+ if [[ -z " $task_lines " ]]; then
152+ log_warning " No uncompleted tasks found in $TASKS_FILE "
153+ return 0
154+ fi
155+
156+ echo " $task_lines " | while IFS=: read -r line_num task_line; do
157+ # Extract task ID, description, and markers
158+ local task_id
159+ task_id=$( echo " $task_line " | sed -n ' s/.*\(T[0-9]\+\).*/\1/p' )
160+
161+ local description
162+ description=$( echo " $task_line " | sed ' s/^- \[ \] T[0-9]\+ //' | sed ' s/\[.*\]//g' | xargs)
163+
164+ local execution_mode=" SYNC" # Default
165+ if echo " $task_line " | grep -q " \[ASYNC\]" ; then
166+ execution_mode=" ASYNC"
167+ fi
168+
169+ local parallel_marker=" "
170+ if echo " $task_line " | grep -q " \[P\]" ; then
171+ parallel_marker=" P"
172+ fi
173+
174+ # Extract file paths (simplified - look for file extensions in the task)
175+ local task_files=" "
176+ task_files=$( echo " $task_line " | grep -oE ' \b\w+\.(js|ts|py|java|cpp|md|json|yml|yaml)\b' | tr ' \n' ' ' | xargs || echo " " )
177+
178+ log_info " Found task $task_id : $description [$execution_mode ] ${parallel_marker: +$parallel_marker } ($task_files )"
179+
180+ # Classify and add to tasks_meta.json
181+ local classified_mode
182+ classified_mode=$( classify_task_execution_mode " $description " " $task_files " )
183+
184+ # Override with explicit marker if present
185+ if [[ " $execution_mode " == " ASYNC" ]]; then
186+ classified_mode=" ASYNC"
187+ fi
188+
189+ add_task " $TASKS_META_FILE " " $task_id " " $description " " $task_files " " $classified_mode "
190+ done
191+ }
192+
193+ # Execute task with dual execution loop
194+ execute_task () {
195+ local task_id=" $1 "
196+ local execution_mode
197+ execution_mode=$( jq -r " .tasks[\" $task_id \" ].execution_mode" " $TASKS_META_FILE " )
198+
199+ log_info " Executing task $task_id in $execution_mode mode"
200+
201+ if [[ " $execution_mode " == " ASYNC" ]]; then
202+ # Dispatch to MCP server
203+ local mcp_config
204+ mcp_config=$( load_mcp_config " .mcp.json" )
205+ dispatch_async_task " $TASKS_META_FILE " " $task_id " " $mcp_config "
206+ else
207+ # Execute SYNC task (would normally involve AI agent execution)
208+ log_info " SYNC task $task_id would be executed here (simulated)"
209+
210+ # Mark as completed (in real implementation, this would happen after successful execution)
211+ safe_json_update " $TASKS_META_FILE " --arg task_id " $task_id " ' .tasks[$task_id].status = "completed"'
212+
213+ # Perform micro-review
214+ perform_micro_review " $TASKS_META_FILE " " $task_id "
215+ fi
216+
217+ # Apply quality gates
218+ apply_quality_gates " $TASKS_META_FILE " " $task_id "
219+ }
220+
221+ # Monitor ASYNC tasks
222+ monitor_async_tasks () {
223+ log_info " Monitoring ASYNC tasks..."
224+
225+ local async_tasks
226+ async_tasks=$( jq -r ' .tasks | to_entries[] | select(.value.execution_mode == "ASYNC" and .value.status != "completed") | .key' " $TASKS_META_FILE " )
227+
228+ if [[ -z " $async_tasks " ]]; then
229+ log_info " No ASYNC tasks to monitor"
230+ return 0
231+ fi
232+
233+ echo " $async_tasks " | while read -r task_id; do
234+ if [[ -z " $task_id " ]]; then
235+ continue
236+ fi
237+
238+ local status
239+ status=$( check_mcp_job_status " $TASKS_META_FILE " " $task_id " )
240+
241+ case " $status " in
242+ " completed" )
243+ log_success " ASYNC task $task_id completed"
244+ # Perform macro-review for completed ASYNC tasks
245+ perform_macro_review " $TASKS_META_FILE "
246+ ;;
247+ " running" )
248+ log_info " ASYNC task $task_id still running"
249+ ;;
250+ " no_job" )
251+ log_warning " ASYNC task $task_id has no job ID"
252+ ;;
253+ esac
254+ done
255+ }
256+
257+ # Main implementation workflow
258+ main () {
259+ local json_output=" $1 "
260+
261+ init_implementation " $json_output "
262+ check_checklists_status
263+ load_implementation_context
264+
265+ # Initialize tasks_meta.json if needed
266+ if [[ ! -f " $TASKS_META_FILE " ]]; then
267+ init_tasks_meta " $FEATURE_DIR "
268+ fi
269+
270+ parse_tasks
271+
272+ # Execute tasks (simplified - in practice would handle phases and dependencies)
273+ local pending_tasks
274+ pending_tasks=$( jq -r ' .tasks | to_entries[] | select(.value.status == "pending") | .key' " $TASKS_META_FILE " )
275+
276+ if [[ -n " $pending_tasks " ]]; then
277+ echo " $pending_tasks " | while read -r task_id; do
278+ if [[ -z " $task_id " ]]; then
279+ continue
280+ fi
281+ execute_task " $task_id "
282+ done
283+ fi
284+
285+ # Monitor ASYNC tasks
286+ monitor_async_tasks
287+
288+ # Check if all tasks are completed for macro-review
289+ local all_completed
290+ all_completed=$( jq ' .tasks | all(.status == "completed")' " $TASKS_META_FILE " )
291+
292+ if [[ " $all_completed " == " true" ]]; then
293+ log_info " All tasks completed - performing macro-review"
294+ perform_macro_review " $TASKS_META_FILE "
295+ else
296+ log_info " Some tasks still pending - macro-review deferred until completion"
297+ fi
298+
299+ # Generate summary
300+ get_execution_summary " $TASKS_META_FILE "
301+
302+ log_success " Implementation phase completed"
303+ }
304+
305+ # Run main if script is executed directly
306+ if [[ " ${BASH_SOURCE[0]} " == " ${0} " ]]; then
307+ if [[ $# -lt 1 ]]; then
308+ echo " Usage: $0 <json_output_from_check_prerequisites>"
309+ exit 1
310+ fi
311+ main " $1 "
312+ fi
0 commit comments