Skip to content

Commit 406521c

Browse files
committed
Simplification
1 parent 1a71b03 commit 406521c

2 files changed

Lines changed: 171 additions & 159 deletions

File tree

scripts/bash/update-agent-context.sh

Lines changed: 123 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -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

436326
update_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

scripts/powershell/update-agent-context.ps1

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,37 @@ $newTesting = Get-PlanValue 'Testing'
4141
$newDb = Get-PlanValue 'Storage'
4242
$newProjectType = Get-PlanValue 'Project Type'
4343

44+
function Format-TechnologyStack($lang, $framework) {
45+
$parts = @()
46+
47+
# Add non-empty parts (excluding "NEEDS CLARIFICATION" and "N/A")
48+
if ($lang -and $lang -ne 'NEEDS CLARIFICATION') { $parts += $lang }
49+
if ($framework -and $framework -ne 'NEEDS CLARIFICATION' -and $framework -ne 'N/A') { $parts += $framework }
50+
51+
# Join with proper formatting
52+
if ($parts.Count -eq 0) {
53+
return ''
54+
} elseif ($parts.Count -eq 1) {
55+
return $parts[0]
56+
} else {
57+
return ($parts -join ' + ')
58+
}
59+
}
60+
4461
function Initialize-AgentFile($targetFile, $agentName) {
4562
if (Test-Path $targetFile) { return }
4663
$template = Join-Path $paths.REPO_ROOT '.specify/templates/agent-file-template.md'
4764
if (-not (Test-Path $template)) { Write-Error "Template not found: $template"; return }
4865
$content = Get-Content $template -Raw
4966
$content = $content.Replace('[PROJECT NAME]', (Split-Path $paths.REPO_ROOT -Leaf))
5067
$content = $content.Replace('[DATE]', (Get-Date -Format 'yyyy-MM-dd'))
51-
$content = $content.Replace('[EXTRACTED FROM ALL PLAN.MD FILES]', "- $newLang + $newFramework ($($paths.CURRENT_BRANCH))")
68+
69+
$techStack = Format-TechnologyStack $newLang $newFramework
70+
if ($techStack) {
71+
$content = $content.Replace('[EXTRACTED FROM ALL PLAN.MD FILES]', "- $techStack ($($paths.CURRENT_BRANCH))")
72+
} else {
73+
$content = $content.Replace('[EXTRACTED FROM ALL PLAN.MD FILES]', '')
74+
}
5275
if ($newProjectType -match 'web') { $structure = "backend/`nfrontend/`ntests/" } else { $structure = "src/`ntests/" }
5376
$content = $content.Replace('[ACTUAL STRUCTURE FROM PLANS]', $structure)
5477
if ($newLang -match 'Python') { $commands = 'cd src && pytest && ruff check .' }
@@ -57,18 +80,38 @@ function Initialize-AgentFile($targetFile, $agentName) {
5780
else { $commands = "# Add commands for $newLang" }
5881
$content = $content.Replace('[ONLY COMMANDS FOR ACTIVE TECHNOLOGIES]', $commands)
5982
$content = $content.Replace('[LANGUAGE-SPECIFIC, ONLY FOR LANGUAGES IN USE]', "${newLang}: Follow standard conventions")
60-
$content = $content.Replace('[LAST 3 FEATURES AND WHAT THEY ADDED]', "- $($paths.CURRENT_BRANCH): Added ${newLang} + ${newFramework}")
83+
84+
$techStack = Format-TechnologyStack $newLang $newFramework
85+
if ($techStack) {
86+
$content = $content.Replace('[LAST 3 FEATURES AND WHAT THEY ADDED]', "- $($paths.CURRENT_BRANCH): Added $techStack")
87+
} else {
88+
$content = $content.Replace('[LAST 3 FEATURES AND WHAT THEY ADDED]', '')
89+
}
6190
$content | Set-Content $targetFile -Encoding UTF8
6291
}
6392

6493
function Update-AgentFile($targetFile, $agentName) {
6594
if (-not (Test-Path $targetFile)) { Initialize-AgentFile $targetFile $agentName; return }
6695
$content = Get-Content $targetFile -Raw
67-
if ($newLang -and ($content -notmatch [regex]::Escape($newLang))) { $content = $content -replace '(## Active Technologies\n)', "`$1- $newLang + $newFramework ($($paths.CURRENT_BRANCH))`n" }
68-
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" }
96+
97+
$techStack = Format-TechnologyStack $newLang $newFramework
98+
if ($techStack -and ($content -notmatch [regex]::Escape($techStack))) {
99+
$content = $content -replace '(## Active Technologies\n)', "`$1- $techStack ($($paths.CURRENT_BRANCH))`n"
100+
}
101+
102+
if ($newDb -and $newDb -ne 'N/A' -and $newDb -ne 'NEEDS CLARIFICATION' -and ($content -notmatch [regex]::Escape($newDb))) {
103+
$content = $content -replace '(## Active Technologies\n)', "`$1- $newDb ($($paths.CURRENT_BRANCH))`n"
104+
}
105+
69106
if ($content -match '## Recent Changes\n([\s\S]*?)(\n\n|$)') {
70107
$changesBlock = $matches[1].Trim().Split("`n")
71-
$changesBlock = ,"- $($paths.CURRENT_BRANCH): Added ${newLang} + ${newFramework}" + $changesBlock
108+
109+
if ($techStack) {
110+
$changesBlock = ,"- $($paths.CURRENT_BRANCH): Added $techStack" + $changesBlock
111+
} elseif ($newDb -and $newDb -ne 'N/A' -and $newDb -ne 'NEEDS CLARIFICATION') {
112+
$changesBlock = ,"- $($paths.CURRENT_BRANCH): Added $newDb" + $changesBlock
113+
}
114+
72115
$changesBlock = $changesBlock | Where-Object { $_ } | Select-Object -First 3
73116
$joined = ($changesBlock -join "`n")
74117
$content = [regex]::Replace($content, '## Recent Changes\n([\s\S]*?)(\n\n|$)', "## Recent Changes`n$joined`n`n")

0 commit comments

Comments
 (0)