From bc25777c6a144f6b2f595cf0de12b20d2d97ffc0 Mon Sep 17 00:00:00 2001 From: Drew Ritter Date: Tue, 14 Apr 2026 14:03:56 -0700 Subject: [PATCH] sync-to-codex-plugin: anchor EXCLUDES patterns to source root MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rsync exclude patterns without a leading "/" match any directory of the given name at any depth. The previous "scripts/" pattern was meant to exclude upstream's top-level scripts/ dir (which contains sync-to-codex-plugin.sh itself, bump-version.sh, etc.) but also incorrectly excluded skills/brainstorming/scripts/ — a legitimate skill-adjacent dir with 5 files (frame-template.html, helper.js, server.cjs, start-server.sh, stop-server.sh). Found during a determinism check: comparing the hand-crafted add-superpowers-plugin bootstrap PR against an automated bootstrap PR produced a diff showing those 5 files were missing from the automated version. Fix: anchor every top-level-only exclude with a leading "/". .DS_Store stays unanchored because Finder creates them anywhere. This also prevents future drift if anyone adds a tests/, hooks/, docs/, lib/, etc. subdir inside a skill. Co-Authored-By: Claude Opus 4.6 (1M context) --- scripts/sync-to-codex-plugin.sh | 62 ++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 28 deletions(-) diff --git a/scripts/sync-to-codex-plugin.sh b/scripts/sync-to-codex-plugin.sh index b3dbd1ab..c57eeb82 100755 --- a/scripts/sync-to-codex-plugin.sh +++ b/scripts/sync-to-codex-plugin.sh @@ -40,42 +40,48 @@ DEST_REL="plugins/superpowers" # Paths in upstream that should NOT land in the embedded plugin. # The Codex-only paths are here too — they're managed by generate/bootstrap # steps, not by rsync. +# +# All patterns use a leading "/" to anchor them to the source root. +# Unanchored patterns like "scripts/" would match any directory named +# "scripts" at any depth — including legitimate nested dirs like +# skills/brainstorming/scripts/. Anchoring prevents that. +# (.DS_Store is intentionally unanchored — Finder creates them everywhere.) EXCLUDES=( - # Dotfiles and infra - ".claude/" - ".claude-plugin/" - ".codex/" - ".cursor-plugin/" - ".git/" - ".gitattributes" - ".github/" - ".gitignore" - ".opencode/" - ".version-bump.json" - ".worktrees/" + # Dotfiles and infra — top-level only + "/.claude/" + "/.claude-plugin/" + "/.codex/" + "/.cursor-plugin/" + "/.git/" + "/.gitattributes" + "/.github/" + "/.gitignore" + "/.opencode/" + "/.version-bump.json" + "/.worktrees/" ".DS_Store" # Root ceremony files - "AGENTS.md" - "CHANGELOG.md" - "CLAUDE.md" - "GEMINI.md" - "RELEASE-NOTES.md" - "gemini-extension.json" - "package.json" + "/AGENTS.md" + "/CHANGELOG.md" + "/CLAUDE.md" + "/GEMINI.md" + "/RELEASE-NOTES.md" + "/gemini-extension.json" + "/package.json" # Directories not shipped by canonical Codex plugins - "commands/" - "docs/" - "hooks/" - "lib/" - "scripts/" - "tests/" - "tmp/" + "/commands/" + "/docs/" + "/hooks/" + "/lib/" + "/scripts/" + "/tests/" + "/tmp/" # Codex-only paths — managed outside rsync - ".codex-plugin/" - "assets/" + "/.codex-plugin/" + "/assets/" ) # =============================================================================