@@ -151,6 +151,7 @@ extract_plan_field() {
151151 grep " ^\*\*${field_pattern} \*\*: " " $plan_file " 2> /dev/null | \
152152 head -1 | \
153153 sed " s|^\*\*${field_pattern} \*\*: ||" | \
154+ sed ' s/^[ \t]*//;s/[ \t]*$//' | \
154155 grep -v " NEEDS CLARIFICATION" | \
155156 grep -v " ^N/A$" || echo " "
156157}
@@ -194,6 +195,31 @@ parse_plan_data() {
194195 log_info " Found project type: $NEW_PROJECT_TYPE "
195196 fi
196197}
198+
199+ format_technology_stack () {
200+ local lang=" $1 "
201+ local framework=" $2 "
202+ local parts=()
203+
204+ # Add non-empty parts
205+ [[ -n " $lang " && " $lang " != " NEEDS CLARIFICATION" ]] && parts+=(" $lang " )
206+ [[ -n " $framework " && " $framework " != " NEEDS CLARIFICATION" && " $framework " != " N/A" ]] && parts+=(" $framework " )
207+
208+ # Join with proper formatting
209+ if [[ ${# parts[@]} -eq 0 ]]; then
210+ echo " "
211+ elif [[ ${# parts[@]} -eq 1 ]]; then
212+ echo " ${parts[0]} "
213+ else
214+ # Join multiple parts with " + "
215+ local result=" ${parts[0]} "
216+ for (( i= 1 ; i< ${# parts[@]} ; i++ )) ; do
217+ result=" $result + ${parts[i]} "
218+ done
219+ echo " $result "
220+ fi
221+ }
222+
197223# ==============================================================================
198224# Template and Content Generation Functions
199225# ==============================================================================
@@ -293,172 +319,115 @@ create_new_agent_file() {
293319
294320 return 0
295321}
296- update_active_technologies () {
297- local target_file=" $1 "
298- local temp_file=" $2 "
299-
300- # Find the Active Technologies section and add new entries
301- local tech_section_start
302- tech_section_start=$( grep -n " ## Active Technologies" " $target_file " | cut -d: -f1)
303-
304- if [[ -z " $tech_section_start " ]]; then
305- return 0 # No Active Technologies section found
306- fi
307-
308- # Find the end of the Active Technologies section (next ## heading or empty line)
309- local tech_section_end
310- tech_section_end=$( tail -n +$(( tech_section_start + 1 )) " $target_file " | grep -n " ^## \|^$" | head -1 | cut -d: -f1)
311-
312- if [[ -n " $tech_section_end " ]]; then
313- tech_section_end=$(( tech_section_start + tech_section_end))
314- else
315- tech_section_end=$( wc -l < " $target_file " )
316- fi
317-
318- # Extract existing technologies section
319- local existing_tech
320- existing_tech=$( sed -n " ${tech_section_start} ,${tech_section_end} p" " $target_file " )
321-
322- # Build list of new additions
323- local additions=()
324- if [[ -n " $NEW_LANG " ]] && ! echo " $existing_tech " | grep -q " $NEW_LANG " ; then
325- additions+=(" - $NEW_LANG + $NEW_FRAMEWORK ($CURRENT_BRANCH )" )
326- fi
327-
328- if [[ -n " $NEW_DB " ]] && [[ " $NEW_DB " != " N/A" ]] && ! echo " $existing_tech " | grep -q " $NEW_DB " ; then
329- additions+=(" - $NEW_DB ($CURRENT_BRANCH )" )
330- fi
331-
332- # If we have additions, update the section
333- if [[ ${# additions[@]} -gt 0 ]]; then
334- {
335- # Copy everything before the Active Technologies section
336- head -n $(( tech_section_start)) " $target_file "
337-
338- # Copy existing tech section content
339- sed -n " $(( tech_section_start + 1 )) ,$(( tech_section_end - 1 )) p" " $target_file "
340-
341- # Add new technologies
342- printf ' %s\n' " ${additions[@]} "
343- echo
344-
345- # Copy everything after the Active Technologies section
346- tail -n +$(( tech_section_end + 1 )) " $target_file "
347- } > " $temp_file "
348- else
349- cp " $target_file " " $temp_file "
350- fi
351- }
352322
353- update_recent_changes () {
354- local temp_file=" $1 "
355- local temp_file2=" $2 "
356-
357- # Find Recent Changes section
358- local changes_section_start
359- changes_section_start=$( grep -n " ## Recent Changes" " $temp_file " | cut -d: -f1)
360-
361- if [[ -z " $changes_section_start " ]]; then
362- return 0 # No Recent Changes section found
363- fi
364-
365- # Find the end of the Recent Changes section
366- local changes_section_end
367- changes_section_end=$( tail -n +$(( changes_section_start + 1 )) " $temp_file " | grep -n " ^## \|^$" | head -1 | cut -d: -f1)
368-
369- if [[ -n " $changes_section_end " ]]; then
370- changes_section_end=$(( changes_section_start + changes_section_end))
371- else
372- changes_section_end=$( wc -l < " $temp_file " )
373- fi
374-
375- # Extract existing changes, keep only non-empty lines, and limit to 2 (so we can add 1 new one)
376- local existing_changes=()
377- while IFS= read -r line; do
378- if [[ -n " $line " ]] && [[ " $line " == " - " * ]]; then
379- existing_changes+=(" $line " )
380- fi
381- done < <( sed -n " $(( changes_section_start + 1 )) ,$(( changes_section_end - 1 )) p" " $temp_file " )
382-
383- # Keep only the first 2 existing changes
384- existing_changes=(" ${existing_changes[@]: 0: 2} " )
385-
386- # Create updated Recent Changes section
387- {
388- # Copy everything before Recent Changes
389- head -n " $changes_section_start " " $temp_file "
390-
391- # Add new change at the top
392- echo " - $CURRENT_BRANCH : Added $NEW_LANG + $NEW_FRAMEWORK "
393-
394- # Add existing changes (up to 2)
395- printf ' %s\n' " ${existing_changes[@]} "
396- echo
397-
398- # Copy everything after Recent Changes section
399- tail -n +$(( changes_section_end + 1 )) " $temp_file "
400- } > " $temp_file2 "
401- }
402323
403- update_last_updated () {
404- local temp_file=" $1 "
405- local current_date=" $2 "
406-
407- # Update the "Last updated" timestamp
408- sed -i.bak " s/Last updated: [0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]/Last updated: $current_date /" " $temp_file "
409- rm -f " $temp_file .bak"
410- }
411324
412- preserve_manual_additions () {
413- local target_file=" $1 "
414- local temp_file=" $2 "
415-
416- # Check if there are manual additions to preserve
417- local manual_start manual_end
418- manual_start=$( grep -n " <!-- MANUAL ADDITIONS START -->" " $target_file " 2> /dev/null | cut -d: -f1 || echo " " )
419- manual_end=$( grep -n " <!-- MANUAL ADDITIONS END -->" " $target_file " 2> /dev/null | cut -d: -f1 || echo " " )
420-
421- if [[ -n " $manual_start " ]] && [[ -n " $manual_end " ]]; then
422- # Extract manual additions
423- local manual_file=" /tmp/manual_additions_$$ "
424- sed -n " ${manual_start} ,${manual_end} p" " $target_file " > " $manual_file "
425-
426- # Remove any existing manual additions from temp file
427- sed -i.bak ' /<!-- MANUAL ADDITIONS START -->/,/<!-- MANUAL ADDITIONS END -->/d' " $temp_file "
428- rm -f " $temp_file .bak"
429-
430- # Append preserved manual additions
431- cat " $manual_file " >> " $temp_file "
432- rm -f " $manual_file "
433- fi
434- }
435325
436326update_existing_agent_file () {
437327 local target_file=" $1 "
438328 local current_date=" $2 "
439329
440330 log_info " Updating existing agent context file..."
441331
442- local temp_file1=" /tmp/agent_update_1_$$ "
443- local temp_file2=" /tmp/agent_update_2_$$ "
444-
445- # Step 1: Update Active Technologies section
446- update_active_technologies " $target_file " " $temp_file1 "
447-
448- # Step 2: Update Recent Changes section
449- update_recent_changes " $temp_file1 " " $temp_file2 "
450-
451- # Step 3: Update timestamp
452- update_last_updated " $temp_file2 " " $current_date "
453-
454- # Step 4: Preserve manual additions
455- preserve_manual_additions " $target_file " " $temp_file2 "
332+ # Use a single temporary file for atomic update
333+ local temp_file
334+ temp_file=$( mktemp) || {
335+ log_error " Failed to create temporary file"
336+ return 1
337+ }
338+
339+ # Process the file in one pass
340+ local tech_stack=$( format_technology_stack " $NEW_LANG " " $NEW_FRAMEWORK " )
341+ local new_tech_entries=()
342+ local new_change_entry=" "
343+
344+ # Prepare new technology entries
345+ if [[ -n " $tech_stack " ]] && ! grep -q " $tech_stack " " $target_file " ; then
346+ new_tech_entries+=(" - $tech_stack ($CURRENT_BRANCH )" )
347+ fi
348+
349+ if [[ -n " $NEW_DB " ]] && [[ " $NEW_DB " != " N/A" ]] && [[ " $NEW_DB " != " NEEDS CLARIFICATION" ]] && ! grep -q " $NEW_DB " " $target_file " ; then
350+ new_tech_entries+=(" - $NEW_DB ($CURRENT_BRANCH )" )
351+ fi
352+
353+ # Prepare new change entry
354+ if [[ -n " $tech_stack " ]]; then
355+ new_change_entry=" - $CURRENT_BRANCH : Added $tech_stack "
356+ elif [[ -n " $NEW_DB " ]] && [[ " $NEW_DB " != " N/A" ]] && [[ " $NEW_DB " != " NEEDS CLARIFICATION" ]]; then
357+ new_change_entry=" - $CURRENT_BRANCH : Added $NEW_DB "
358+ fi
359+
360+ # Process file line by line
361+ local in_tech_section=false
362+ local in_changes_section=false
363+ local tech_entries_added=false
364+ local changes_entries_added=false
365+ local existing_changes_count=0
366+
367+ while IFS= read -r line || [[ -n " $line " ]]; do
368+ # Handle Active Technologies section
369+ if [[ " $line " == " ## Active Technologies" ]]; then
370+ echo " $line " >> " $temp_file "
371+ in_tech_section=true
372+ continue
373+ elif [[ $in_tech_section == true ]] && [[ " $line " =~ ^# #[[:space:]] ]]; then
374+ # Add new tech entries before closing the section
375+ if [[ $tech_entries_added == false ]] && [[ ${# new_tech_entries[@]} -gt 0 ]]; then
376+ printf ' %s\n' " ${new_tech_entries[@]} " >> " $temp_file "
377+ tech_entries_added=true
378+ fi
379+ echo " $line " >> " $temp_file "
380+ in_tech_section= false
381+ continue
382+ elif [[ $in_tech_section == true ]] && [[ -z " $line " ]]; then
383+ # Add new tech entries before empty line in tech section
384+ if [[ $tech_entries_added == false ]] && [[ ${# new_tech_entries[@]} -gt 0 ]]; then
385+ printf ' %s\n' " ${new_tech_entries[@]} " >> " $temp_file "
386+ tech_entries_added=true
387+ fi
388+ echo " $line " >> " $temp_file "
389+ continue
390+ fi
391+
392+ # Handle Recent Changes section
393+ if [[ " $line " == " ## Recent Changes" ]]; then
394+ echo " $line " >> " $temp_file "
395+ # Add new change entry right after the heading
396+ if [[ -n " $new_change_entry " ]]; then
397+ echo " $new_change_entry " >> " $temp_file "
398+ fi
399+ in_changes_section=true
400+ changes_entries_added=true
401+ continue
402+ elif [[ $in_changes_section == true ]] && [[ " $line " =~ ^# #[[:space:]] ]]; then
403+ echo " $line " >> " $temp_file "
404+ in_changes_section= false
405+ continue
406+ elif [[ $in_changes_section == true ]] && [[ " $line " == " - " * ]]; then
407+ # Keep only first 2 existing changes
408+ if [[ $existing_changes_count -lt 2 ]]; then
409+ echo " $line " >> " $temp_file "
410+ (( existing_changes_count++ ))
411+ fi
412+ continue
413+ fi
414+
415+ # Update timestamp
416+ if [[ " $line " =~ \*\* Last\ updated\*\* :.* [0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] ]]; then
417+ echo " $line " | sed " s/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]/$current_date /" >> " $temp_file "
418+ else
419+ echo " $line " >> " $temp_file "
420+ fi
421+ done < " $target_file "
456422
457- # Move the final result to target
458- mv " $temp_file2 " " $target_file "
423+ # Move temp file to target atomically
424+ if ! mv " $temp_file " " $target_file " ; then
425+ log_error " Failed to update target file"
426+ rm -f " $temp_file "
427+ return 1
428+ fi
459429
460- # Cleanup
461- rm -f " $temp_file1 "
430+ return 0
462431}
463432# ==============================================================================
464433# Main Agent File Update Function
0 commit comments