diff --git a/barretenberg/.codex b/barretenberg/.codex deleted file mode 120000 index c8161850a43d..000000000000 --- a/barretenberg/.codex +++ /dev/null @@ -1 +0,0 @@ -.claude \ No newline at end of file diff --git a/barretenberg/.codex/agents b/barretenberg/.codex/agents new file mode 120000 index 000000000000..0efb85ec44f4 --- /dev/null +++ b/barretenberg/.codex/agents @@ -0,0 +1 @@ +../.claude/agents \ No newline at end of file diff --git a/barretenberg/.codex/skills b/barretenberg/.codex/skills new file mode 120000 index 000000000000..454b8427cd75 --- /dev/null +++ b/barretenberg/.codex/skills @@ -0,0 +1 @@ +../.claude/skills \ No newline at end of file diff --git a/barretenberg/cpp/.codex b/barretenberg/cpp/.codex deleted file mode 120000 index c8161850a43d..000000000000 --- a/barretenberg/cpp/.codex +++ /dev/null @@ -1 +0,0 @@ -.claude \ No newline at end of file diff --git a/barretenberg/cpp/.codex/agents b/barretenberg/cpp/.codex/agents new file mode 120000 index 000000000000..0efb85ec44f4 --- /dev/null +++ b/barretenberg/cpp/.codex/agents @@ -0,0 +1 @@ +../.claude/agents \ No newline at end of file diff --git a/docs/.codex b/docs/.codex deleted file mode 120000 index c8161850a43d..000000000000 --- a/docs/.codex +++ /dev/null @@ -1 +0,0 @@ -.claude \ No newline at end of file diff --git a/docs/.codex/agents b/docs/.codex/agents new file mode 120000 index 000000000000..0efb85ec44f4 --- /dev/null +++ b/docs/.codex/agents @@ -0,0 +1 @@ +../.claude/agents \ No newline at end of file diff --git a/docs/.codex/commands b/docs/.codex/commands new file mode 120000 index 000000000000..0b631dd5b721 --- /dev/null +++ b/docs/.codex/commands @@ -0,0 +1 @@ +../.claude/commands \ No newline at end of file diff --git a/yarn-project/.codex b/yarn-project/.codex deleted file mode 120000 index c8161850a43d..000000000000 --- a/yarn-project/.codex +++ /dev/null @@ -1 +0,0 @@ -.claude \ No newline at end of file diff --git a/yarn-project/.codex/agents b/yarn-project/.codex/agents new file mode 120000 index 000000000000..0efb85ec44f4 --- /dev/null +++ b/yarn-project/.codex/agents @@ -0,0 +1 @@ +../.claude/agents \ No newline at end of file diff --git a/yarn-project/.codex/scripts b/yarn-project/.codex/scripts new file mode 120000 index 000000000000..26e538548009 --- /dev/null +++ b/yarn-project/.codex/scripts @@ -0,0 +1 @@ +../.claude/scripts \ No newline at end of file diff --git a/yarn-project/.codex/settings.json b/yarn-project/.codex/settings.json new file mode 120000 index 000000000000..11a726369cef --- /dev/null +++ b/yarn-project/.codex/settings.json @@ -0,0 +1 @@ +../.claude/settings.json \ No newline at end of file diff --git a/yarn-project/.codex/skills b/yarn-project/.codex/skills new file mode 120000 index 000000000000..454b8427cd75 --- /dev/null +++ b/yarn-project/.codex/skills @@ -0,0 +1 @@ +../.claude/skills \ No newline at end of file diff --git a/yarn-project/precommit.sh b/yarn-project/precommit.sh index a4863d268296..1f5bd7c8420a 100755 --- a/yarn-project/precommit.sh +++ b/yarn-project/precommit.sh @@ -10,6 +10,50 @@ cd $(dirname $0) export FORCE_COLOR=true +# Verify every .codex directory mirrors its sibling .claude via child symlinks, so that adding a +# file or folder to a .claude config does not silently leave the sandboxed .codex path behind. +# Only immediate children are checked: a symlinked folder (e.g. .codex/skills) already covers its +# contents, and a .codex that is itself a symlink (the repo root) mirrors .claude inherently. +check_codex_symlinks() { + local repo_root claude_dirs claude_dir codex_dir path name + local -a errors=() + repo_root=$(git rev-parse --show-toplevel) + claude_dirs=$(cd "$repo_root" && git ls-files -- '.claude/*' '*/.claude/*' | sed -E 's#(.*/)?\.claude/.*#\1.claude#' | sort -u) + + for claude_dir in $claude_dirs; do + codex_dir="${claude_dir%.claude}.codex" + if [ -L "$repo_root/$codex_dir" ]; then + continue + fi + if [ ! -d "$repo_root/$codex_dir" ]; then + errors+=("missing directory $codex_dir (should mirror $claude_dir)") + continue + fi + while IFS= read -r path; do + name=$(basename "$path") + if [ ! -L "$repo_root/$codex_dir/$name" ] || [ ! "$repo_root/$codex_dir/$name" -ef "$path" ]; then + errors+=("$codex_dir/$name should be a symlink to ../.claude/$name") + fi + done < <(find "$repo_root/$claude_dir" -mindepth 1 -maxdepth 1) + while IFS= read -r path; do + name=$(basename "$path") + if [ ! -e "$repo_root/$claude_dir/$name" ] && [ ! -L "$repo_root/$claude_dir/$name" ]; then + errors+=("$codex_dir/$name is stale; no matching $claude_dir/$name") + fi + done < <(find "$repo_root/$codex_dir" -mindepth 1 -maxdepth 1) + done + + if (( ${#errors[@]} > 0 )); then + echo -e "\033[31mError:\033[0m .codex directories are out of sync with their .claude siblings:" + for e in "${errors[@]}"; do echo " - $e"; done + echo "Each entry under a .claude folder needs a sibling symlink in .codex, e.g.:" + echo " (cd /.codex && ln -s ../.claude/ && git add )" + return 1 + fi +} + +check_codex_symlinks + # Get all staged files (excluding deleted), relative to yarn-project staged_files=$(git diff-index --diff-filter=d --relative --cached --name-only HEAD) @@ -18,6 +62,11 @@ staged_files=$(git diff-index --diff-filter=d --relative --cached --name-only HE # Filter for formattable files staged_format_files=$(echo "$staged_files" | grep -E '\.(json|js|mjs|cjs|ts)$' || true) +# Drop symlinks; prettier errors when handed a symbolic link (e.g. .codex/settings.json). +if [[ -n "$staged_format_files" ]]; then + staged_format_files=$(echo "$staged_format_files" | while IFS= read -r f; do [ -L "$f" ] || printf '%s\n' "$f"; done) +fi + # Get unstaged changes for formattable files unstaged_format_files=$(git diff --relative --name-only --diff-filter=d | grep -E '\.(json|js|mjs|cjs|ts)$' || true)