From 406521c66402a29b012cd124e925a57498358b08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Den=20Delimarsky=20=F0=9F=8C=BA?= <53200638+localden@users.noreply.github.com> Date: Sat, 20 Sep 2025 15:29:37 -0700 Subject: [PATCH] Simplification --- scripts/bash/update-agent-context.sh | 269 +++++++++----------- scripts/powershell/update-agent-context.ps1 | 53 +++- 2 files changed, 167 insertions(+), 155 deletions(-) diff --git a/scripts/bash/update-agent-context.sh b/scripts/bash/update-agent-context.sh index d68250d9e..bba241576 100644 --- a/scripts/bash/update-agent-context.sh +++ b/scripts/bash/update-agent-context.sh @@ -151,6 +151,7 @@ extract_plan_field() { grep "^\*\*${field_pattern}\*\*: " "$plan_file" 2>/dev/null | \ head -1 | \ sed "s|^\*\*${field_pattern}\*\*: ||" | \ + sed 's/^[ \t]*//;s/[ \t]*$//' | \ grep -v "NEEDS CLARIFICATION" | \ grep -v "^N/A$" || echo "" } @@ -194,6 +195,31 @@ parse_plan_data() { log_info "Found project type: $NEW_PROJECT_TYPE" fi } + +format_technology_stack() { + local lang="$1" + local framework="$2" + local parts=() + + # Add non-empty parts + [[ -n "$lang" && "$lang" != "NEEDS CLARIFICATION" ]] && parts+=("$lang") + [[ -n "$framework" && "$framework" != "NEEDS CLARIFICATION" && "$framework" != "N/A" ]] && parts+=("$framework") + + # Join with proper formatting + if [[ ${#parts[@]} -eq 0 ]]; then + echo "" + elif [[ ${#parts[@]} -eq 1 ]]; then + echo "${parts[0]}" + else + # Join multiple parts with " + " + local result="${parts[0]}" + for ((i=1; i<${#parts[@]}; i++)); do + result="$result + ${parts[i]}" + done + echo "$result" + fi +} + #============================================================================== # Template and Content Generation Functions #============================================================================== @@ -293,145 +319,9 @@ create_new_agent_file() { return 0 } -update_active_technologies() { - local target_file="$1" - local temp_file="$2" - - # Find the Active Technologies section and add new entries - local tech_section_start - tech_section_start=$(grep -n "## Active Technologies" "$target_file" | cut -d: -f1) - - if [[ -z "$tech_section_start" ]]; then - return 0 # No Active Technologies section found - fi - - # Find the end of the Active Technologies section (next ## heading or empty line) - local tech_section_end - tech_section_end=$(tail -n +$((tech_section_start + 1)) "$target_file" | grep -n "^## \|^$" | head -1 | cut -d: -f1) - - if [[ -n "$tech_section_end" ]]; then - tech_section_end=$((tech_section_start + tech_section_end)) - else - tech_section_end=$(wc -l < "$target_file") - fi - - # Extract existing technologies section - local existing_tech - existing_tech=$(sed -n "${tech_section_start},${tech_section_end}p" "$target_file") - - # Build list of new additions - local additions=() - if [[ -n "$NEW_LANG" ]] && ! echo "$existing_tech" | grep -q "$NEW_LANG"; then - additions+=("- $NEW_LANG + $NEW_FRAMEWORK ($CURRENT_BRANCH)") - fi - - if [[ -n "$NEW_DB" ]] && [[ "$NEW_DB" != "N/A" ]] && ! echo "$existing_tech" | grep -q "$NEW_DB"; then - additions+=("- $NEW_DB ($CURRENT_BRANCH)") - fi - - # If we have additions, update the section - if [[ ${#additions[@]} -gt 0 ]]; then - { - # Copy everything before the Active Technologies section - head -n $((tech_section_start)) "$target_file" - - # Copy existing tech section content - sed -n "$((tech_section_start + 1)),$((tech_section_end - 1))p" "$target_file" - - # Add new technologies - printf '%s\n' "${additions[@]}" - echo - - # Copy everything after the Active Technologies section - tail -n +$((tech_section_end + 1)) "$target_file" - } > "$temp_file" - else - cp "$target_file" "$temp_file" - fi -} -update_recent_changes() { - local temp_file="$1" - local temp_file2="$2" - - # Find Recent Changes section - local changes_section_start - changes_section_start=$(grep -n "## Recent Changes" "$temp_file" | cut -d: -f1) - - if [[ -z "$changes_section_start" ]]; then - return 0 # No Recent Changes section found - fi - - # Find the end of the Recent Changes section - local changes_section_end - changes_section_end=$(tail -n +$((changes_section_start + 1)) "$temp_file" | grep -n "^## \|^$" | head -1 | cut -d: -f1) - - if [[ -n "$changes_section_end" ]]; then - changes_section_end=$((changes_section_start + changes_section_end)) - else - changes_section_end=$(wc -l < "$temp_file") - fi - - # Extract existing changes, keep only non-empty lines, and limit to 2 (so we can add 1 new one) - local existing_changes=() - while IFS= read -r line; do - if [[ -n "$line" ]] && [[ "$line" == "- "* ]]; then - existing_changes+=("$line") - fi - done < <(sed -n "$((changes_section_start + 1)),$((changes_section_end - 1))p" "$temp_file") - - # Keep only the first 2 existing changes - existing_changes=("${existing_changes[@]:0:2}") - - # Create updated Recent Changes section - { - # Copy everything before Recent Changes - head -n "$changes_section_start" "$temp_file" - - # Add new change at the top - echo "- $CURRENT_BRANCH: Added $NEW_LANG + $NEW_FRAMEWORK" - - # Add existing changes (up to 2) - printf '%s\n' "${existing_changes[@]}" - echo - - # Copy everything after Recent Changes section - tail -n +$((changes_section_end + 1)) "$temp_file" - } > "$temp_file2" -} -update_last_updated() { - local temp_file="$1" - local current_date="$2" - - # Update the "Last updated" timestamp - 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" - rm -f "$temp_file.bak" -} -preserve_manual_additions() { - local target_file="$1" - local temp_file="$2" - - # Check if there are manual additions to preserve - local manual_start manual_end - manual_start=$(grep -n "" "$target_file" 2>/dev/null | cut -d: -f1 || echo "") - manual_end=$(grep -n "" "$target_file" 2>/dev/null | cut -d: -f1 || echo "") - - if [[ -n "$manual_start" ]] && [[ -n "$manual_end" ]]; then - # Extract manual additions - local manual_file="/tmp/manual_additions_$$" - sed -n "${manual_start},${manual_end}p" "$target_file" > "$manual_file" - - # Remove any existing manual additions from temp file - sed -i.bak '//,//d' "$temp_file" - rm -f "$temp_file.bak" - - # Append preserved manual additions - cat "$manual_file" >> "$temp_file" - rm -f "$manual_file" - fi -} update_existing_agent_file() { local target_file="$1" @@ -439,26 +329,105 @@ update_existing_agent_file() { log_info "Updating existing agent context file..." - local temp_file1="/tmp/agent_update_1_$$" - local temp_file2="/tmp/agent_update_2_$$" + # Use a single temporary file for atomic update + local temp_file + temp_file=$(mktemp) || { + log_error "Failed to create temporary file" + return 1 + } - # Step 1: Update Active Technologies section - update_active_technologies "$target_file" "$temp_file1" + # Process the file in one pass + local tech_stack=$(format_technology_stack "$NEW_LANG" "$NEW_FRAMEWORK") + local new_tech_entries=() + local new_change_entry="" - # Step 2: Update Recent Changes section - update_recent_changes "$temp_file1" "$temp_file2" + # Prepare new technology entries + if [[ -n "$tech_stack" ]] && ! grep -q "$tech_stack" "$target_file"; then + new_tech_entries+=("- $tech_stack ($CURRENT_BRANCH)") + fi - # Step 3: Update timestamp - update_last_updated "$temp_file2" "$current_date" + if [[ -n "$NEW_DB" ]] && [[ "$NEW_DB" != "N/A" ]] && [[ "$NEW_DB" != "NEEDS CLARIFICATION" ]] && ! grep -q "$NEW_DB" "$target_file"; then + new_tech_entries+=("- $NEW_DB ($CURRENT_BRANCH)") + fi - # Step 4: Preserve manual additions - preserve_manual_additions "$target_file" "$temp_file2" + # Prepare new change entry + if [[ -n "$tech_stack" ]]; then + new_change_entry="- $CURRENT_BRANCH: Added $tech_stack" + elif [[ -n "$NEW_DB" ]] && [[ "$NEW_DB" != "N/A" ]] && [[ "$NEW_DB" != "NEEDS CLARIFICATION" ]]; then + new_change_entry="- $CURRENT_BRANCH: Added $NEW_DB" + fi - # Move the final result to target - mv "$temp_file2" "$target_file" + # Process file line by line + local in_tech_section=false + local in_changes_section=false + local tech_entries_added=false + local changes_entries_added=false + local existing_changes_count=0 - # Cleanup - rm -f "$temp_file1" + while IFS= read -r line || [[ -n "$line" ]]; do + # Handle Active Technologies section + if [[ "$line" == "## Active Technologies" ]]; then + echo "$line" >> "$temp_file" + in_tech_section=true + continue + elif [[ $in_tech_section == true ]] && [[ "$line" =~ ^##[[:space:]] ]]; then + # Add new tech entries before closing the section + if [[ $tech_entries_added == false ]] && [[ ${#new_tech_entries[@]} -gt 0 ]]; then + printf '%s\n' "${new_tech_entries[@]}" >> "$temp_file" + tech_entries_added=true + fi + echo "$line" >> "$temp_file" + in_tech_section=false + continue + elif [[ $in_tech_section == true ]] && [[ -z "$line" ]]; then + # Add new tech entries before empty line in tech section + if [[ $tech_entries_added == false ]] && [[ ${#new_tech_entries[@]} -gt 0 ]]; then + printf '%s\n' "${new_tech_entries[@]}" >> "$temp_file" + tech_entries_added=true + fi + echo "$line" >> "$temp_file" + continue + fi + + # Handle Recent Changes section + if [[ "$line" == "## Recent Changes" ]]; then + echo "$line" >> "$temp_file" + # Add new change entry right after the heading + if [[ -n "$new_change_entry" ]]; then + echo "$new_change_entry" >> "$temp_file" + fi + in_changes_section=true + changes_entries_added=true + continue + elif [[ $in_changes_section == true ]] && [[ "$line" =~ ^##[[:space:]] ]]; then + echo "$line" >> "$temp_file" + in_changes_section=false + continue + elif [[ $in_changes_section == true ]] && [[ "$line" == "- "* ]]; then + # Keep only first 2 existing changes + if [[ $existing_changes_count -lt 2 ]]; then + echo "$line" >> "$temp_file" + ((existing_changes_count++)) + fi + continue + fi + + # Update timestamp + if [[ "$line" =~ \*\*Last\ updated\*\*:.*[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] ]]; then + echo "$line" | sed "s/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]/$current_date/" >> "$temp_file" + else + echo "$line" >> "$temp_file" + fi + done < "$target_file" + + # Move temp file to target atomically + if ! mv "$temp_file" "$target_file"; then + log_error "Failed to update target file" + rm -f "$temp_file" + return 1 + fi + + return 0 } #============================================================================== # Main Agent File Update Function diff --git a/scripts/powershell/update-agent-context.ps1 b/scripts/powershell/update-agent-context.ps1 index 923a43781..9ea3220bb 100644 --- a/scripts/powershell/update-agent-context.ps1 +++ b/scripts/powershell/update-agent-context.ps1 @@ -41,6 +41,23 @@ $newTesting = Get-PlanValue 'Testing' $newDb = Get-PlanValue 'Storage' $newProjectType = Get-PlanValue 'Project Type' +function Format-TechnologyStack($lang, $framework) { + $parts = @() + + # Add non-empty parts (excluding "NEEDS CLARIFICATION" and "N/A") + if ($lang -and $lang -ne 'NEEDS CLARIFICATION') { $parts += $lang } + if ($framework -and $framework -ne 'NEEDS CLARIFICATION' -and $framework -ne 'N/A') { $parts += $framework } + + # Join with proper formatting + if ($parts.Count -eq 0) { + return '' + } elseif ($parts.Count -eq 1) { + return $parts[0] + } else { + return ($parts -join ' + ') + } +} + function Initialize-AgentFile($targetFile, $agentName) { if (Test-Path $targetFile) { return } $template = Join-Path $paths.REPO_ROOT '.specify/templates/agent-file-template.md' @@ -48,7 +65,13 @@ function Initialize-AgentFile($targetFile, $agentName) { $content = Get-Content $template -Raw $content = $content.Replace('[PROJECT NAME]', (Split-Path $paths.REPO_ROOT -Leaf)) $content = $content.Replace('[DATE]', (Get-Date -Format 'yyyy-MM-dd')) - $content = $content.Replace('[EXTRACTED FROM ALL PLAN.MD FILES]', "- $newLang + $newFramework ($($paths.CURRENT_BRANCH))") + + $techStack = Format-TechnologyStack $newLang $newFramework + if ($techStack) { + $content = $content.Replace('[EXTRACTED FROM ALL PLAN.MD FILES]', "- $techStack ($($paths.CURRENT_BRANCH))") + } else { + $content = $content.Replace('[EXTRACTED FROM ALL PLAN.MD FILES]', '') + } if ($newProjectType -match 'web') { $structure = "backend/`nfrontend/`ntests/" } else { $structure = "src/`ntests/" } $content = $content.Replace('[ACTUAL STRUCTURE FROM PLANS]', $structure) if ($newLang -match 'Python') { $commands = 'cd src && pytest && ruff check .' } @@ -57,18 +80,38 @@ function Initialize-AgentFile($targetFile, $agentName) { else { $commands = "# Add commands for $newLang" } $content = $content.Replace('[ONLY COMMANDS FOR ACTIVE TECHNOLOGIES]', $commands) $content = $content.Replace('[LANGUAGE-SPECIFIC, ONLY FOR LANGUAGES IN USE]', "${newLang}: Follow standard conventions") - $content = $content.Replace('[LAST 3 FEATURES AND WHAT THEY ADDED]', "- $($paths.CURRENT_BRANCH): Added ${newLang} + ${newFramework}") + + $techStack = Format-TechnologyStack $newLang $newFramework + if ($techStack) { + $content = $content.Replace('[LAST 3 FEATURES AND WHAT THEY ADDED]', "- $($paths.CURRENT_BRANCH): Added $techStack") + } else { + $content = $content.Replace('[LAST 3 FEATURES AND WHAT THEY ADDED]', '') + } $content | Set-Content $targetFile -Encoding UTF8 } function Update-AgentFile($targetFile, $agentName) { if (-not (Test-Path $targetFile)) { Initialize-AgentFile $targetFile $agentName; return } $content = Get-Content $targetFile -Raw - if ($newLang -and ($content -notmatch [regex]::Escape($newLang))) { $content = $content -replace '(## Active Technologies\n)', "`$1- $newLang + $newFramework ($($paths.CURRENT_BRANCH))`n" } - if ($newDb -and $newDb -ne 'N/A' -and ($content -notmatch [regex]::Escape($newDb))) { $content = $content -replace '(## Active Technologies\n)', "`$1- $newDb ($($paths.CURRENT_BRANCH))`n" } + + $techStack = Format-TechnologyStack $newLang $newFramework + if ($techStack -and ($content -notmatch [regex]::Escape($techStack))) { + $content = $content -replace '(## Active Technologies\n)', "`$1- $techStack ($($paths.CURRENT_BRANCH))`n" + } + + if ($newDb -and $newDb -ne 'N/A' -and $newDb -ne 'NEEDS CLARIFICATION' -and ($content -notmatch [regex]::Escape($newDb))) { + $content = $content -replace '(## Active Technologies\n)', "`$1- $newDb ($($paths.CURRENT_BRANCH))`n" + } + if ($content -match '## Recent Changes\n([\s\S]*?)(\n\n|$)') { $changesBlock = $matches[1].Trim().Split("`n") - $changesBlock = ,"- $($paths.CURRENT_BRANCH): Added ${newLang} + ${newFramework}" + $changesBlock + + if ($techStack) { + $changesBlock = ,"- $($paths.CURRENT_BRANCH): Added $techStack" + $changesBlock + } elseif ($newDb -and $newDb -ne 'N/A' -and $newDb -ne 'NEEDS CLARIFICATION') { + $changesBlock = ,"- $($paths.CURRENT_BRANCH): Added $newDb" + $changesBlock + } + $changesBlock = $changesBlock | Where-Object { $_ } | Select-Object -First 3 $joined = ($changesBlock -join "`n") $content = [regex]::Replace($content, '## Recent Changes\n([\s\S]*?)(\n\n|$)', "## Recent Changes`n$joined`n`n")