fix(bash): sed replacement escaping, BSD portability, dead cleanup in update-agent-context.sh#2090
Conversation
a6604ae to
44072cb
Compare
Three bugs in update-agent-context.sh:
1. **sed escaping targets wrong side** (line 318-320): The escaping
function escapes regex pattern characters (`[`, `.`, `*`, `^`, `$`,
`+`, `{`, `}`, `|`) but these variables are used as sed
*replacement* strings, not patterns. Only `&` (insert matched text),
`\` (escape char), and `|` (our sed delimiter) are special in the
replacement context. Also adds escaping for `project_name` which
was used unescaped.
2. **BSD sed newline insertion fails on macOS** (line 364-366): Uses
bash variable expansion to insert a literal newline into a sed
replacement string. This works on GNU sed (Linux) but fails silently
on BSD sed (macOS). Replaced with portable awk approach that works
on both platforms.
3. **cleanup() removes non-existent files** (line 125-126): The
cleanup trap attempts `rm -f /tmp/agent_update_*_$$` and
`rm -f /tmp/manual_additions_$$` but the script never creates files
matching these patterns — all temp files use `mktemp`. The wildcard
with `$$` (PID) in /tmp could theoretically match unrelated files.
Fixes github#154 (macOS sed failure)
Fixes github#293 (sed expression errors)
Related: github#338 (shellcheck findings)
44072cb to
dd96d15
Compare
There was a problem hiding this comment.
Pull request overview
This PR updates scripts/bash/update-agent-context.sh to be safer and more portable across GNU/BSD toolchains (notably macOS), focusing on correct escaping for sed replacements, portable newline handling, and safer temp-file cleanup.
Changes:
- Fixes
sedreplacement escaping to prevent corruption when values contain replacement-special characters (notably&and\), and applies escaping to additional substituted values (e.g.,project_name). - Replaces BSD-incompatible
sednewline insertion with a portableawk-based\n→ newline conversion. - Reworks cleanup to track and remove only known temp files; also adjusts agent support/path mappings (notably Copilot path and Forge handling).
Show a summary per file
| File | Description |
|---|---|
| scripts/bash/update-agent-context.sh | Improves sed replacement safety, macOS portability, and temp-file cleanup; updates agent path/support mappings. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 1/1 changed files
- Comments generated: 2
| CLAUDE_FILE="$REPO_ROOT/CLAUDE.md" | ||
| GEMINI_FILE="$REPO_ROOT/GEMINI.md" | ||
| COPILOT_FILE="$REPO_ROOT/.github/copilot-instructions.md" | ||
| COPILOT_FILE="$REPO_ROOT/.github/agents/copilot-instructions.md" |
There was a problem hiding this comment.
COPILOT_FILE was changed to .github/agents/copilot-instructions.md, but the Copilot integration and tests in this repo still define the context file as .github/copilot-instructions.md (see src/specify_cli/integrations/copilot/__init__.py and tests/integrations/test_integration_copilot.py). As-is, running this script will generate/update a different file than the rest of the codebase expects. Consider reverting this path change (keep context in .github/), or update the integration’s context_file + docs/tests in the same PR so the repo stays consistent.
| COPILOT_FILE="$REPO_ROOT/.github/agents/copilot-instructions.md" | |
| COPILOT_FILE="$REPO_ROOT/.github/copilot-instructions.md" |
| iflow) | ||
| update_agent_file "$IFLOW_FILE" "iFlow CLI" || return 1 | ||
| ;; | ||
| forge) | ||
| update_agent_file "$AGENTS_FILE" "Forge" || return 1 | ||
| ;; | ||
| generic) | ||
| log_info "Generic agent: no predefined context file. Use the agent-specific update script for your agent." | ||
| ;; | ||
| *) | ||
| log_error "Unknown agent type '$agent_type'" | ||
| log_error "Expected: claude|gemini|copilot|cursor-agent|qwen|opencode|codex|windsurf|junie|kilocode|auggie|roo|codebuddy|amp|shai|tabnine|kiro-cli|agy|bob|vibe|qodercli|kimi|trae|pi|iflow|forge|generic" | ||
| log_error "Expected: claude|gemini|copilot|cursor-agent|qwen|opencode|codex|windsurf|junie|kilocode|auggie|roo|codebuddy|amp|shai|tabnine|kiro-cli|agy|bob|vibe|qodercli|kimi|trae|pi|iflow|generic" | ||
| exit 1 |
There was a problem hiding this comment.
The forge agent type support was removed (case item deleted and help text updated). However, this repo still has a Forge integration (src/specify_cli/integrations/forge/__init__.py has key = "forge" and context_file = "AGENTS.md"), and AGENTS.md documents Forge-specific behavior. If Forge is still a supported agent, consider keeping a forge) case that maps to AGENTS.md (similar to opencode/codex) or update the related integration/docs in the same PR to avoid breaking ./update-agent-context.sh forge.
mnriem
left a comment
There was a problem hiding this comment.
Please address Copilot feedback. You might have to pull in upstream/main
Summary
Three bugs in
scripts/bash/update-agent-context.shthat cause silent failures on macOS and potential data corruption with special characters in project/technology names.Bug 1: sed escaping targets wrong side (lines 318-320)
The escaping function escapes regex pattern characters (
[,.,*,^,$,+,{,},|) but these variables are used as sed replacement strings, not patterns. In sed replacements, only two characters are special:&— inserts the entire matched pattern\— escape characterImpact: A technology name containing
&(e.g., "AT&T", "R&D") silently corrupts the agent context file. The&gets replaced with the entire matched text from the left side of the substitution.Fix: Escape only
&and\in replacement strings. Also adds escaping forproject_namewhich was used unescaped.Bug 2: BSD sed newline insertion fails on macOS (lines 364-366)
BSD sed does not support literal newlines in replacement strings via variable expansion. GNU sed (Linux) does. This means the
\n→ newline conversion silently fails on macOS, leaving literal\nsequences in the generated agent context files.Fix: Replace with portable
awkapproach:Bug 3: cleanup() removes non-existent files (lines 125-126)
The script never creates files matching these patterns — all temp files use
mktempwith random suffixes. The wildcard with$$(PID) in/tmpis a code smell that could theoretically match unrelated files.Fix: Remove the dead
rmcommands. Temp files frommktempare cleaned up inline after use.Testing
bash -nsyntax check passesRelated Issues
Fixes #154 —
update-agent-context.shseems to be failing on macOSFixes #293 — update-agent-context.sh script fails with sed expression errors
Related: #338 — Problems detected by shellcheck on the provided bash scripts