3030#
3131# 5. Multi-Agent Support
3232# - Handles agent-specific file paths and naming conventions
33- # - Supports: Claude, Gemini, Copilot, Cursor, Qwen, opencode, Codex, Windsurf, Junie, Kilo Code, Auggie CLI, Roo Code, CodeBuddy CLI, Qoder CLI, Amp, SHAI, Tabnine CLI, Kiro CLI, Mistral Vibe, Kimi Code, Pi Coding Agent, iFlow CLI, Forge, Antigravity or Generic
33+ # - Supports: Claude, Gemini, Copilot, Cursor, Qwen, opencode, Codex, Windsurf, Junie, Kilo Code, Auggie CLI, Roo Code, CodeBuddy CLI, Qoder CLI, Amp, SHAI, Tabnine CLI, Kiro CLI, Mistral Vibe, Kimi Code, Pi Coding Agent, iFlow CLI, Antigravity or Generic
3434# - Can update single agents or all existing agent files
3535# - Creates default Claude file if no agent files exist
3636#
3737# Usage: ./update-agent-context.sh [agent_type]
38- # Agent types: 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
38+ # Agent types: 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
3939# Leave empty to update all existing agent files
4040
4141set -e
@@ -63,7 +63,7 @@ AGENT_TYPE="${1:-}"
6363# Agent-specific file paths
6464CLAUDE_FILE=" $REPO_ROOT /CLAUDE.md"
6565GEMINI_FILE=" $REPO_ROOT /GEMINI.md"
66- COPILOT_FILE=" $REPO_ROOT /.github/copilot-instructions.md"
66+ COPILOT_FILE=" $REPO_ROOT /.github/agents/ copilot-instructions.md"
6767CURSOR_FILE=" $REPO_ROOT /.cursor/rules/specify-rules.mdc"
6868QWEN_FILE=" $REPO_ROOT /QWEN.md"
6969AGENTS_FILE=" $REPO_ROOT /AGENTS.md"
@@ -74,7 +74,7 @@ AUGGIE_FILE="$REPO_ROOT/.augment/rules/specify-rules.md"
7474ROO_FILE=" $REPO_ROOT /.roo/rules/specify-rules.md"
7575CODEBUDDY_FILE=" $REPO_ROOT /CODEBUDDY.md"
7676QODER_FILE=" $REPO_ROOT /QODER.md"
77- # Amp, Kiro CLI, IBM Bob, Pi, and Forge all share AGENTS.md — use AGENTS_FILE to avoid
77+ # Amp, Kiro CLI, IBM Bob, and Pi all share AGENTS.md — use AGENTS_FILE to avoid
7878# updating the same file multiple times.
7979AMP_FILE=" $AGENTS_FILE "
8080SHAI_FILE=" $REPO_ROOT /SHAI.md"
@@ -86,7 +86,6 @@ VIBE_FILE="$REPO_ROOT/.vibe/agents/specify-agents.md"
8686KIMI_FILE=" $REPO_ROOT /KIMI.md"
8787TRAE_FILE=" $REPO_ROOT /.trae/rules/AGENTS.md"
8888IFLOW_FILE=" $REPO_ROOT /IFLOW.md"
89- FORGE_FILE=" $AGENTS_FILE "
9089
9190# Template file
9291TEMPLATE_FILE=" $REPO_ROOT /.specify/templates/agent-file-template.md"
@@ -122,8 +121,7 @@ cleanup() {
122121 local exit_code=$?
123122 # Disarm traps to prevent re-entrant loop
124123 trap - EXIT INT TERM
125- rm -f /tmp/agent_update_* _$$
126- rm -f /tmp/manual_additions_$$
124+ # mktemp files are cleaned up inline after use — nothing to do here
127125 exit $exit_code
128126}
129127
@@ -284,7 +282,8 @@ get_language_conventions() {
284282create_new_agent_file () {
285283 local target_file=" $1 "
286284 local temp_file=" $2 "
287- local project_name=" $3 "
285+ local project_name
286+ project_name=$( printf ' %s\n' " $3 " | sed ' s/[\\&|]/\\&/g' )
288287 local current_date=" $4 "
289288
290289 if [[ ! -f " $TEMPLATE_FILE " ]]; then
@@ -314,11 +313,11 @@ create_new_agent_file() {
314313 local language_conventions
315314 language_conventions=$( get_language_conventions " $NEW_LANG " )
316315
317- # Perform substitutions with error checking using safer approach
318- # Escape special characters for sed by using a different delimiter or escaping
319- local escaped_lang=$( printf ' %s\n' " $NEW_LANG " | sed ' s/[\[\.*^$()+{} |]/\\&/g' )
320- local escaped_framework=$( printf ' %s\n' " $NEW_FRAMEWORK " | sed ' s/[\[\.*^$()+{} |]/\\&/g' )
321- local escaped_branch=$( printf ' %s\n' " $CURRENT_BRANCH " | sed ' s/[\[\.*^$()+{} |]/\\&/g' )
316+ # Escape special characters for sed replacement strings (right side of s|pattern|replacement|)
317+ # & and \ are replacement-side specials; | must also be escaped because it's our sed delimiter
318+ local escaped_lang=$( printf ' %s\n' " $NEW_LANG " | sed ' s/[\\& |]/\\&/g' )
319+ local escaped_framework=$( printf ' %s\n' " $NEW_FRAMEWORK " | sed ' s/[\\& |]/\\&/g' )
320+ local escaped_branch=$( printf ' %s\n' " $CURRENT_BRANCH " | sed ' s/[\\& |]/\\&/g' )
322321
323322 # Build technology stack and recent change strings conditionally
324323 local tech_stack
@@ -361,12 +360,11 @@ create_new_agent_file() {
361360 fi
362361 done
363362
364- # Convert \n sequences to actual newlines
365- newline=$( printf ' \n' )
366- sed -i.bak2 " s/\\\\ n/${newline} /g" " $temp_file "
363+ # Convert literal \n sequences to actual newlines (portable — works on BSD + GNU)
364+ awk ' {gsub(/\\n/,"\n")}1' " $temp_file " > " $temp_file .tmp" && mv " $temp_file .tmp" " $temp_file "
367365
368- # Clean up backup files
369- rm -f " $temp_file .bak" " $temp_file .bak2 "
366+ # Clean up backup files from sed -i.bak
367+ rm -f " $temp_file .bak"
370368
371369 # Prepend Cursor frontmatter for .mdc files so rules are auto-included
372370 if [[ " $target_file " == * .mdc ]]; then
@@ -691,15 +689,12 @@ update_specific_agent() {
691689 iflow)
692690 update_agent_file " $IFLOW_FILE " " iFlow CLI" || return 1
693691 ;;
694- forge)
695- update_agent_file " $AGENTS_FILE " " Forge" || return 1
696- ;;
697692 generic)
698693 log_info " Generic agent: no predefined context file. Use the agent-specific update script for your agent."
699694 ;;
700695 * )
701696 log_error " Unknown agent type '$agent_type '"
702- 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"
697+ 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"
703698 exit 1
704699 ;;
705700 esac
@@ -743,7 +738,10 @@ update_all_existing_agents() {
743738 _update_if_new " $COPILOT_FILE " " GitHub Copilot" || _all_ok=false
744739 _update_if_new " $CURSOR_FILE " " Cursor IDE" || _all_ok=false
745740 _update_if_new " $QWEN_FILE " " Qwen Code" || _all_ok=false
746- _update_if_new " $AGENTS_FILE " " Codex/opencode/Amp/Kiro/Bob/Pi/Forge" || _all_ok=false
741+ _update_if_new " $AGENTS_FILE " " Codex/opencode" || _all_ok=false
742+ _update_if_new " $AMP_FILE " " Amp" || _all_ok=false
743+ _update_if_new " $KIRO_FILE " " Kiro CLI" || _all_ok=false
744+ _update_if_new " $BOB_FILE " " IBM Bob" || _all_ok=false
747745 _update_if_new " $WINDSURF_FILE " " Windsurf" || _all_ok=false
748746 _update_if_new " $JUNIE_FILE " " Junie" || _all_ok=false
749747 _update_if_new " $KILOCODE_FILE " " Kilo Code" || _all_ok=false
@@ -784,7 +782,7 @@ print_summary() {
784782 fi
785783
786784 echo
787- log_info " Usage: $0 [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]"
785+ log_info " Usage: $0 [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]"
788786}
789787
790788# ==============================================================================
0 commit comments