Skip to content

Instantly share code, notes, and snippets.

@Nottlespike
Created February 6, 2026 23:39
Show Gist options
  • Select an option

  • Save Nottlespike/b2c34baff1d7ba7fa34a8b6df6d326cc to your computer and use it in GitHub Desktop.

Select an option

Save Nottlespike/b2c34baff1d7ba7fa34a8b6df6d326cc to your computer and use it in GitHub Desktop.
Set up agent guides. AGENTS.md CLAUDE.md GEMINI.md in one script
#!/usr/bin/env bash
# setup-agent-guides.sh
# ---------------------
# Bootstraps agent guide files for a repository.
#
# This script is intended for "new repo setup" and repeat-safe updates:
# 1) Reads a source guide file (`.md` by default, or a provided path)
# 2) Copies it to `AGENTS.md` (canonical guide file)
# 3) Creates `CLAUDE.md` and `GEMINI.md` aliases to `AGENTS.md`
# 4) Falls back to plain file copies if symlinks are unavailable
# 5) Adds `AGENTS.md`, `CLAUDE.md`, and `GEMINI.md` to `.gitignore`
#
# Compatibility target: Bash on macOS and Linux.
set -euo pipefail
print_usage() {
cat <<'USAGE'
Usage:
scripts/setup-agent-guides.sh [source_file]
Examples:
scripts/setup-agent-guides.sh
scripts/setup-agent-guides.sh agent.md
scripts/setup-agent-guides.sh docs/agent.md
Notes:
- Creates AGENTS.md as the canonical guide.
- Creates CLAUDE.md and GEMINI.md as symlinks when possible.
- Falls back to copying files if symlinks are not supported.
USAGE
}
copy_fallback_aliases=()
ensure_alias_file() {
local canonical="$1"
local alias_name="$2"
if [[ -d "$alias_name" && ! -L "$alias_name" ]]; then
echo "Error: '$alias_name' is a directory; expected a file path." >&2
exit 1
fi
if ln -sfn "$canonical" "$alias_name" 2>/dev/null; then
return 0
fi
rm -f "$alias_name"
if ln -s "$canonical" "$alias_name" 2>/dev/null; then
return 0
fi
cp "$canonical" "$alias_name"
copy_fallback_aliases+=("$alias_name")
}
if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
print_usage
exit 0
fi
if repo_root="$(git rev-parse --show-toplevel 2>/dev/null)"; then
cd "$repo_root"
fi
source_file="${1:-}"
if [[ -z "$source_file" ]]; then
if [[ -f "agent.md" ]]; then
source_file="agent.md"
elif [[ -f "AGENTS.md" ]]; then
source_file="AGENTS.md"
else
echo "Error: no source file found. Provide one (for example: agent.md)." >&2
exit 1
fi
fi
if [[ ! -f "$source_file" ]]; then
echo "Error: source file '$source_file' does not exist." >&2
exit 1
fi
source_dir="$(cd "$(dirname "$source_file")" && pwd)"
source_abs="${source_dir}/$(basename "$source_file")"
target_abs="$(pwd)/AGENTS.md"
if [[ "$source_abs" != "$target_abs" ]]; then
cp "$source_file" AGENTS.md
fi
ensure_alias_file AGENTS.md CLAUDE.md
ensure_alias_file AGENTS.md GEMINI.md
touch .gitignore
entries=("AGENTS.md" "CLAUDE.md" "GEMINI.md")
missing=()
for entry in "${entries[@]}"; do
if ! grep -Fxq "$entry" .gitignore; then
missing+=("$entry")
fi
done
if (( ${#missing[@]} > 0 )); then
if [[ -s .gitignore ]]; then
printf '\n' >> .gitignore
fi
printf '%s\n' "${missing[@]}" >> .gitignore
fi
echo "Done."
echo "- Canonical file: AGENTS.md"
if (( ${#copy_fallback_aliases[@]} == 0 )); then
echo "- Aliases: CLAUDE.md, GEMINI.md (symlinks)"
else
echo "- Aliases: CLAUDE.md, GEMINI.md (copy fallback used)"
fi
echo "- Updated .gitignore entries (if missing): AGENTS.md, CLAUDE.md, GEMINI.md"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment