fix(bash): sed replacement escaping, BSD portability, dead cleanup in update-agent-context.sh#2090
Conversation
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
mnriem
left a comment
There was a problem hiding this comment.
Please address Copilot feedback. You might have to pull in upstream/main
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)
Address PR review feedback: - Restore forge) case in update_specific_agent since src/specify_cli/integrations/forge/__init__.py still exists - Revert COPILOT_FILE path from .github/agents/ back to .github/ to stay consistent with Python integration and tests - Restore FORGE_FILE variable, comments, and usage strings Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
dd96d15 to
1661ddb
Compare
Address Gemini review feedback — the inline sed escaping pattern appeared 7 times in create_new_agent_file(). Extract to a single helper function for maintainability and readability. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Gemini correctly identified that splitting AGENTS_FILE updates into individual calls is redundant — _update_if_new deduplicates by realpath, so only the first call logs. Restore the combined label and add back missing Pi reference. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…s it The old code manually pre-escaped & as \& in get_commands_for_language because the broken escaping function didn't handle &. Now that _esc_sed properly escapes replacement-side specials, the pre-escaping causes double-escaping: && becomes \&\& in generated files. Found by blind audit. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Under set -e, the left side of && does not trigger errexit on failure. Split into two statements so awk failures are fatal instead of silent. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
On Bash 3.2, the ${arr[@]+"${arr[@]}"} pattern expands to a single
empty string when the array is empty, causing rm to target .bak and
.tmp in the current directory. Use explicit length check instead,
which also avoids the word-splitting risk of unquoted expansion.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR fixes portability and correctness issues in scripts/bash/update-agent-context.sh so agent context files can be generated/updated safely on both GNU and BSD (macOS) toolchains, including when project/technology values contain sed-sensitive characters.
Changes:
- Introduces a dedicated sed replacement-side escaping helper and applies it to template substitutions (including
project_name). - Replaces the non-portable BSD
sednewline replacement with a portableawk-based\n→ newline conversion. - Reworks temp-file cleanup to track
mktempoutputs and remove them safely via a trap, avoiding broad/tmpglobs.
Show a summary per file
| File | Description |
|---|---|
| scripts/bash/update-agent-context.sh | Makes sed substitutions safe for replacement strings, improves macOS portability, and strengthens temp-file cleanup behavior. |
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: 0 new
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