claude-commands-export-superset
Audit, rebase, supersede, and ship the jleechanorg/claude-commands export pipeline. Five-session playbook covering consolidation, supersession, fresh export, AND the cleanup-PR + script-patch archetype (Pitfall 10) for excluding content categories like `_archive/` that should never have shipped. v1.2.0 adds Pitfalls 11 + 12 covering cross-vendor re-sync staleness (vendored copy drifts from upstream between exports) and content-filter rewrites BODY-but-not-FILENAMES (install scripts that reference filter-rewritten filenames break at install time). Triggers on "consolidate the open claude-commands PRs", "fresh /exportcommands", "remove the archive from the PR and modify /exportcommands to stop exporting it", "supersede #N", "edit the export to exclude _archive/", "the cmux-goal pair isn't on main", "re-sync the vendored watchdog", "stale cmux_resume_watchdog in the export", "install script fails with no such file", "com.$USER.cmux-resume-watchdog.plist not found", etc. Encodes twelve pitfalls.
- License 许可
- MIT
- 最近更新
- 2026-11-12
- Stars
- ★ 6
- Forks
- 0
01 前言 Front Matter
- name
- claude-commands-export-superset
- version
- 1.2.0
- metadata
- { "hermes": { "tags": [ "github", "claude-commands", "export", "supersession", "rebase", "audit", "drive-pr-to-green", "exclude-paths", "script-patch", "vendoring", "cross-vendor-sync" ], "related_skills": [ "drive-pr-to-green", "github-pr-automation-debug", "github-pr-workflow", "patch-tool-safe-editing" ] } }
- platforms
- [ "macos", "linux" ]
- description
- Audit, rebase, supersede, and ship the jleechanorg/claude-commands export pipeline. Five-session playbook covering consolidation, supersession, fresh export, AND the cleanup-PR + script-patch archetype (Pitfall 10) for excluding content categories like `_archive/` that should never have shipped. v1.2.0 adds Pitfalls 11 + 12 covering cross-vendor re-sync staleness (vendored copy drifts from upstream between exports) and content-filter rewrites BODY-but-not-FILENAMES (install scripts that reference filter-rewritten filenames break at install time). Triggers on "consolidate the open claude-commands PRs", "fresh /exportcommands", "remove the archive from the PR and modify /exportcommands to stop exporting it", "supersede #N", "edit the export to exclude _archive/", "the cmux-goal pair isn't on main", "re-sync the vendored watchdog", "stale cmux_resume_watchdog in the export", "install script fails with no such file", "com.$USER.cmux-resume-watchdog.plist not found", etc. Encodes twelve pitfalls.
02 资源文件 4
- 参考文档references/cleanup-archetype-recipe.md8.3 KB
- 参考文档references/cross-vendor-resync-recipe.md10.9 KB
- 参考文档references/exportcommands-sh-contract.md6.2 KB
- 参考文档references/sessions-recap.md9.6 KB
03 SKILL.md 正文
claude-commands-export-superset
Audit, rebase, supersede, and ship the jleechanorg/claude-commands export pipeline. This is the
canonical workflow when the user wants "the latest ~/.claude/ shipped" — multiple sessions have
hit this same task with subtle differences (open PRs vary, some already merged, some still stale,
sometimes the auto-opened PR contains content the user wants excluded), and the playbook below
locks in the four most common pitfalls PLUS the 5th-archetype cleanup workflow discovered 2026-07-13.
Trigger
Any of these messages should fire this skill:
- "consolidate the open claude-commands PRs" / "consolidate #N/#M/#O into one PR"
- "fresh /exportcommands and check the PRs"
- "the export is stale / has new content since last run"
- "see what else is needed / what's incremental" (mid-task state re-check)
- "supersede #N" / "close #N as superseded"
- "remove the archive from the PR and modify /exportcommands to stop exporting it"
- "/exportcommands [from ~/your-project.com]"
- "the cmux-goal / ironclad pair isn't on main yet"
- "the latest commands/skills aren't in jleechanorg/claude-commands"
- "edit the export to exclude _archive/" / "stop exporting archive paths"
Pitfall 1 — Always re-check current state BEFORE planning (added 2026-07-13)
The user may have merged some PRs mid-task, or some may have closed, between your first gh pr list
and your final action. Re-run the state-recency check after every user message and after every
OOB directive, not just at session start. Specifically:
# Step 0 of every task in this class — re-run on any pivot
HOME=$HOME GH_TOKEN="" gh api 'repos/jleechanorg/claude-commands/pulls?state=open&per_page=20&sort=created&direction=desc' \
--jq '[.[] | {n: .number, title: .title, state: .state, headRefName: .head.ref, headSha: .head.sha, baseSha: .base.sha, mergeable: .mergeable, mergeable_state: .mergeable_state, additions: .additions, deletions: .deletions, commits: .commits}]'
# Also verify main SHA right now (not from earlier in the session)
HOME=$HOME GH_TOKEN="" gh api 'repos/jleechanorg/claude-commands/branches/main' \
--jq '{sha: .commit.sha, lastCommit: .commit.commit.message, lastCommitDate: .commit.commit.author.date}'
Verified 2026-07-13: an earlier session plan started "consolidate #324/#325/#326 into one PR." A
mid-task user OOB ("i just merged some of those PRs") revealed that #325 and #326 had already
landed on main at 337dc6d7 8 minutes before the task. The original plan was obsolete; the
correct response was to (a) supersede #324 as no-longer-net-new, (b) run a fresh
/exportcommands for the incremental, (c) close the original 3-PR plan entirely.
Anti-pattern: building a consolidation strategy on stale state. Even if your first gh pr list
returned 3 open PRs, a user pivot 60s later may have already merged 2 of them. Always re-verify.
Pitfall 2 — mergeable_state: dirty on a stale-base PR means BASE != main (added 2026-07-13)
When you see mergeable_state: dirty or mergeable: false on a PR, the FIRST diagnostic is
base vs main comparison, not the file list. The PR may simply be 200+ commits behind main
because it was cut before several merges.
# Verify the staleness
HOME=$HOME GH_TOKEN="" gh api 'repos/<owner>/<repo>/pulls/<N>' \
--jq '{baseSha: .base.sha, headSha: .head.sha, baseRef: .base.ref, mergeable: .mergeable, mergeable_state: .mergeable_state}'
HOME=$HOME GH_TOKEN="" gh api 'repos/<owner>/<repo>/branches/main' \
--jq '{main: .commit.sha}'
# If baseSha != main, the PR is stale. Three options:
# 1. git merge origin/main into the PR branch (merge-commit pattern, preserves N-commit history)
# 2. git rebase origin/main onto the PR branch (cleaner history, but replays N commits)
# 3. Compare file content vs current main — if no truly-new content, supersede without merging
For the claude-commands export PRs specifically, the third option is often correct: the
PR's "content" is cp from ~/.claude/, and if ~/.claude/ hasn't changed since the branch was
cut, the rebase just produces duplicate work.
Verified 2026-07-13: PR #324 (add-cmux-goal-ironclad-thin-commands) had mergeable_state: dirty,
base a30c037 (3 days stale), 300 files vs current main, 200 commits. On rebase audit:
- 0 truly net-new files (excluding
backup/,.beads/,.agentloop/) - 183 files where #324 had older content (main was ~4× larger in those paths)
- 42 files in main but not in #324 (came from #325/#326 merges)
Conclusion: #324 was obsolete and would re-introduce the backup/ security leak it pre-dated.
Right action: supersede, do not rebase.
Pitfall 3 — ~/.claude/commands/exportcommands.sh is NOT the canonical version (added 2026-07-13)
Two scripts coexist:
| Path | Version | Hermes superset? |
|---|---|---|
~/.claude/commands/exportcommands.sh (466 lines) |
Original 2024-06 version | ❌ NO — CLAUDE_DIRS=(commands skills hooks agents scripts) only |
your-project.com/.claude/commands/exportcommands.sh |
Live (per export-commands-orchestration-contract) |
✅ YES — adds HERMES_DIRS=(skills commands) (PR #8135) |
The "live" version lives in the your-project.com repo and is the one you want for /exportcommands
runs targeting jleechanorg/claude-commands. The global one still ships, but its hermes surface
is missing.
Run recipe (verified 2026-07-13):
# Run from your-project.com so the hermes-aware union-merge fires
cd ~/your-project.com
HOME=$HOME PROJECT_ROOT=$HOME/your-project.com \
bash $HOME/.claude/commands/exportcommands.sh
# Output structure (script writes to stdout in this exact shape):
# ▶ Cloning jleechanorg/claude-commands...
# ✅ commands (global-only:N project-only:N identical:N auto-resolved:N)
# ✅ skills (...) ✅ hooks (...) ✅ agents (...) ✅ scripts (...)
# ✅ orchestration ✅ automation ✅ ralph ✅ workflows
# ✅ Filters applied
# ▶ Scanning for leaked paths...
# ▶ Updating README.md via Claude...
# ⚠️ Claude CLI failed — keeping existing README unchanged ← safe to ignore if non-blocking
# git secret guard: scanning outgoing range <BASE>..<HEAD> for refs/heads/export-YYYYMMDD-HHMMSS
# ✅ Export complete!
# PR: https://github.com/jleechanorg/claude-commands/pull/<N>
# Branch: export-YYYYMMDD-HHMMSS
Branch naming is deterministic: export-YYYYMMDD-HHMMSS (local PT timezone). The PR
auto-opens via the script's gh pr create --head <branch> --base main step.
Per-file byte-identity audit (not file-list audit) is the correct delta test:
# For each file in the diff, fetch main's content and branch's content and compare bytes
git show origin/main:<path> # main's version
git show origin/<branch>:<path> # branch's version
# If identical → no net change
# If branch has older/smaller content → obsolete
# If branch has net-new content → genuinely incremental
Pitfall 4 — Bot rate-limit faux-green on the auto-opened export PR (added 2026-07-13)
The export script's auto-opened PR almost always posts CodeRabbit status = success BUT with body = "Review limit reached". Same for Cursor Bugbot with "Bugbot couldn't run - usage limit reached". These are NOT real reviews — they're webhook-level "success" statuses the bot posted to clear the queue without doing work.
Verification recipe (every time the export script's auto-PR is involved):
# 1. Get the bot comments
HOME=$HOME GH_TOKEN="" gh api 'repos/jleechanorg/claude-commands/issues/<N>/comments?per_page=10' \
--jq '[.[] | select(.user.login | test("coderabbitai|cursor|chatgpt-codex-connector"; "i")) | {login: .user.login, body: .body[:200]}]'
# 2. Match for the rate-limit telltales
# coderabbitai[bot]: contains "Review limit reached" or "rate limited"
# cursor[bot]: contains "Bugbot couldn't run" or "usage limit reached"
# chatgpt-codex-connector[bot]: contains "Codex usage limits"
# If any of these phrases appears → status=success is FAUX. Document in the PR with a comment
# citing coderabbit-slow-bot-policy from SOUL.md and proceed with the merge anyway.
# 3. Also check the actual review state (not the status webhook)
HOME=$HOME GH_TOKEN="" gh api 'repos/jleechanorg/claude-commands/pulls/<N>/reviews' \
--jq '[.[] | {state: .state, login: .user.login, submitted_at: .submitted_at}]'
# Empty array = no real review was submitted = faux-green.
Pattern (verified 2026-07-13, PR #327): all three bots posted rate-limit comments within 60s
of each other at PR creation; the status webhooks all showed success; the actual review array
was empty. Per coderabbit-slow-bot-policy in SOUL.md, this is non-blocking after ONE once-per-head
review attempt. Document the timeout in a PR comment with the same phrases the bots used, then
proceed with the green-check + human-merge handoff.
Pitfall 5 — git secret guard output IS the security pre-check (added 2026-07-13)
The export script runs git secret guard on the outgoing range and prints to stdout. Look for:
git secret guard: scanning outgoing range <BASE>..<HEAD> for refs/heads/<BRANCH>
A line WITHOUT a FAIL after it = clean. A line WITH FAIL or WARNING = block the PR until
resolved. This is the ONLY security check the script does — there's no pre-commit hook or
workflow gate. If the script's stdout doesn't show this line at all, run git secret scan <BASE>..<HEAD> yourself before pushing.
Pitfall 6 — localexportcommands.md and exportcommands.md are DOCS, not scripts (added 2026-07-13)
Three documents live in ~/.claude/commands/:
| File | Role |
|---|---|
exportcommands.sh (466 lines, 19.1K) |
The script. Invoked by /exportcommands. |
exportcommands.md (45.1K) |
Operator doc — explains what /exportcommands does, full superset spec, hermes-deploy-pipeline relationship. |
localexportcommands.md (23.2K) |
Local-only doc — variant for projects that want to skip the global union and ship only their own .claude/ dir. |
exportcommands.py (96.4K) |
Companion Python (alternative entry point; not invoked by /exportcommands). |
tests/test_exportcommands.py |
Contract tests for the Python entry. |
When users say "/exportcommands", they mean the bash script, not the docs or the Python.
Pitfall 7 — The auto-opened PR has no .github/workflows/ (verified 2026-07-13)
jleechanorg/claude-commands has CI at ./workflows/*.yml, NOT at .github/workflows/. Earlier
gh api .github/workflows returns 404 — that's expected. The CI is:
workflows/coderabbit-ping-on-push.yml(CodeRabbit webhook ping)workflows/claude-code.yml(some Claude Code integration)workflows/claude-processor.yml- Plus 30+ others
When driving an export PR to green, don't look for .github/workflows/. The "green" check
on this repo is:
mergeable_state: clean(REST pulls endpoint)statusCheckRollupempty (no GH Actions runs on the export PR's head)- Real bot reviews OR documented rate-limit timeout per Pitfall 4
Pitfall 8 — Supersession comment template (verified 2026-07-13)
When posting a supersession comment on a STALE PR (before closing), include:
- Base staleness evidence — the SHA the PR branched from and main's current SHA.
- Per-file diff math — total files, net-new, modified, main-only counts.
- Why it's superseded — concrete examples (empty files, security-leak files, files where main has 4× the content).
- Forward path — where the incremental went instead (the new fresh-export PR).
- Co-Authored-By — Claude Code attribution.
## Closing as superseded — consolidation audit findings
After the merges of [PR #325](...) and [PR #326](...) landed on `main` @ `<MAIN_SHA>`,
this PR's value collapsed. Detailed audit:
### Diff math
- Total files in #N: **<N>** (vs current main)
- Files in #N *only* (not in main): **<X>** truly net-new (excluding `backup/`, `.beads/`, ...)
- Files *modified* in #N vs main: **<Y>**
- Files in main but not in #N: **<Z>** (came from #N+1/#N+2 merges)
For the <Y> files where #N differs from current main, main has ~<M> MB of content vs #N's ~<m> MB.
- `<file_a>`, `<file_b>` in this PR are **empty files**; main has the real implementations.
- 29 `workflows/*.yml` files predate the `security(backup)` gitignore; rebase reintroduces leaks.
### Security incident this PR still contains
`backup/<HOSTNAME>/...` — <N> files. The original 2026-07-12 home-config snapshot leak that
prompted the `security: gitignore backup/` commit. **Merging would re-introduce that leak.**
### Recommendation
- **`<key feature>` is on main** (via [<PR>](...) merge <DATE>).
- All remaining valuable content is **already represented** in main via #N+1+#N+2.
Closing as superseded.
? Generated with [Claude Code](https://claude.com/claude-code). Co-Authored-By: Claude <noreply@anthropic.com>
Pitfall 9 — /exportcommands from a non-main branch (verified 2026-07-13)
The export script uses git rev-parse --show-toplevel to detect PROJECT_ROOT, NOT
--abbrev-ref HEAD. So it works from any branch. BUT — if you're on feat/issue-8084 with N
uncommitted files, those files don't affect the export (uncommitted = not in worktree), but the
export still uses the WORKTREE'S HEAD for diff calculations.
Recipe: if you want a "true diff vs prior export", check out the branch that matches the
prior export's source state, run /exportcommands from there, then post the diff against the
prior PR's branch. Verified 2026-07-13: running from feat/issue-8084 produced PR #327 (66 files,
+7,436/−19) — clean against current main 337dc6d7. Branch mismatch didn't corrupt anything
because the union-merge ignores branch identity.
Pitfall 11 — Vendored-source re-sync staleness (verified 2026-08-01, PR #38 → #40)
When the export bundles source files (Python scripts + tests) that originated in
a DIFFERENT upstream repo (e.g. user_scope/scripts/cmux_resume_watchdog.py
re-shipped as your-project.com/.claude/skills/cmux-resume-watchdog/cmux_resume_watchdog.py),
the export's snapshot has a second decay axis the existing 10 pitfalls don't
cover: the vendored copy can drift from upstream between export runs. The
signal is the bug-by-bug re-discovery cycle:
- Run
/exportcommandsfrom your-project.com → snapshot ofcmux_resume_watchdog.pyfrom this exact moment lands in the export branch. - Meanwhile,
user_scopemain advances (a real bug fix lands: 3 new quota regex anchors, 10 new network patterns). - Live daemon on this machine is now running the upstream HEAD (auto-pulled by launchd), but the vendored copy in
your-project.com(and downstream inclaude-commands) is still pre-fix. - The first /advice review returns "vendored copy is stale, missing 13 patterns". Round-trip fix: re-copy from upstream, re-sync both PRs.
- Second /advice review returns "vendored test file uses
REPO_ROOT = Path(__file__).resolve().parents[1]" — but in the vendored location the script lives inparents[0]. Every test fails onimportlib.SpecNotFound. Round-trip fix: patch REPO_ROOT in the vendored copy only. - Web-advice review independently catches a fixture leak (
"$USER@jeffreys-macbook-pro: ~/projects/cold-reviewer"in aSurface()test fixture) that survived the SUBS filter because the regexs|\bjleechan\b|$USER|grewrote$USERbut the hostname + project path survived verbatim.
The cure (recipe, 2026-08-01):
# Phase A — re-sync the script AND its sibling test file
cp $HOME/projects/<upstream>/scripts/<script>.py \
$HOME/.worktrees/<export-wt>/.claude/skills/<skill>/<script>.py
cp $HOME/projects/<upstream>/tests/test_<script>.py \
$HOME/.worktrees/<export-wt>/.claude/skills/<skill>/test_<script>.py
# Phase B — fix REPO_ROOT in the test file if it was authored for upstream's
# tree layout (parents[N]) but the vendored location has a different depth.
# Common case: upstream test does Path(__file__).resolve().parents[1] / "scripts" / X
# → vendored test needs Path(__file__).resolve().parent / X
# Phase C — grep both files for fixture-style literals that the SUBS regex
# won't catch (usernames, hostnames, project paths). Replace with placeholders.
# Per SUBS spec (lines 220-260 of exportcommands.sh), `\bjleechan\b` is rewritten
# to `$USER`, but `$USER@<hostname>` is rewritten only on the prefix half.
# Always run:
rg -n '\bjleechan\b|@.*-macbook-pro|~/projects/[^/]+/' \
$HOME/.worktrees/<export-wt>/.claude/skills/<skill>/
# Phase D — run the test suite IN THE VENDORED LOCATION, not upstream
cd $HOME/.worktrees/<export-wt>/.claude/skills/<skill>/
~/.local/orch-venv/bin/python3 -m pytest test_<script>.py -q
# Expect: same pass count as upstream, but RUN from this dir so the REPO_ROOT
# lookup targets the vendored layout.
# Phase E — only after test D passes, amend + force-push the export branches
git add .claude/skills/<skill>/<script>.py .claude/skills/<skill>/test_<script>.py
git commit --amend --no-edit
git push --force-with-lease=<expected_old_sha> origin HEAD
# Mirror to downstream (claude-commands export branch):
cd $HOME/.worktrees/<downstream-wt>
cp ... same files ...
git add ... same files ...
git commit -m "feat(skills/<skill>): re-sync from <upstream> PR #N"
git push origin HEAD
Three anti-patterns the recipe explicitly avoids:
- ❌ Re-running
/exportcommandsto "refresh" the vendored copy — the export script does a UNION-MERGE of all skill files; if upstream's file is functionally newer than the export's, the union-merge may not even detect the change because the export's content filters rewrite upstream's bytes too. Re-run is the wrong tool. - ❌ Patching only the script (not the test file). The test file's
REPO_ROOTresolution depends on the file's position in the vendored tree, which differs from upstream's tree. Always ship both files together. - ❌ Trusting the SUBS regex to filter fixture leaks. The regex is fine-grained for
$USERstandalone but mechanically blind to the surrounding context ($USER@<host>,~/projects/<path>/). Always run the Phase C leak grep after every re-sync.
The cross-vendor re-sync is a three-PR pipeline (verified 2026-08-01):
- Upstream:
jleechanorg/user_scopePR #40 — canonical fix lands here. - Source-side:
$GITHUB_REPOSITORYPR #8681 — re-sync the vendored copy + force-push. - Downstream:
jleechanorg/claude-commandsPR #346 — mirror the re-sync + push.
All three PRs must move together or the merge decouples. Force-push only to branches you own; use gh pr view --json headRefName,author to verify branch ownership before each --force-with-lease=<expected_old_sha>.
Pitfall 12 — Content-filter regex rewrites BODY but not FILENAMES (verified 2026-08-01, install_cmux_resume_watchdog.sh)
The export's perl -pi -e 's|...|...|g' SUBS regexes rewrite CONTENT of filtered files in place. Filenames are NOT filtered. This is a sharp edge when an install script or shell wrapper does both:
- Defines a
LABEL=com.<githubuser>.<skill>constant in CONTENT (gets filter-rewritten toLABEL=com.$USER.<skill>). - References
$SKILL_DIR/$LABEL.<ext>to find a sibling file on disk (FILENAME on disk is NOT rewritten — stillcom.<githubuser>.<skill>.<ext>).
Symptom (verified 2026-08-01, install_cmux_resume_watchdog.sh:18): script does sed -e "s|@HOME@|$HOME|g" ... "$SKILL_DIR/$LABEL.plist.template" where $LABEL is post-filter com.$USER.cmux-resume-watchdog but the shipped template file is com.$USER.cmux-resume-watchdog.plist.template. The set -euo pipefail script aborts on ls returning empty — and the install is broken for every downstream user, not just the bad commit author.
Three cure recipes, pick the one that matches the install script's structure:
# Recipe A — rename the file to be filter-stable (drop the user-name prefix).
# Before: com.$USER.cmux-resume-watchdog.plist.template
# After: cmux-resume-watchdog.plist.template
# Pros: zero install-script changes needed (the file path becomes predictable).
# Cons: doesn't help if the script reaches for files by user-derived names.
# Recipe B — use @PLACEHOLDER@ in the file's CONTENT and `sed "s|@PLACEHOLDER@|$LABEL|g"`
# in the installer. The export's SUBS regex is non-greedy on `@` so `@LABEL@`,
# `@DEST@`, `@HOME@` survive the filter intact.
# Pros: any user-derived token can be parameterized without filter breakage.
# Cons: the install script must explicitly run the sed pass; a literal-substitute
# installer will break.
# Recipe C — pick a vendor-neutral name that doesn't contain the github username.
# com.localhost.<skill> — stable across users; macOS launchd accepts
# labels with localhost domain; no filter
# rewrite is needed even if the content
# mentions the literal string.
# com.example.<skill> — same idea
# Pros: zero filter interaction at all.
# Cons: many users' machines already have a com.<their-actual-github-user>.<skill>
# entry in /Library/LaunchAgents, so first install requires explicit bootout
# of the old label.
Detection recipe (run BEFORE every export of a skill that has shell installers):
# For every shell/script file in the staged export, list every reference to a
# github-username-prefixed file path:
HOME=$HOME git -C $HOME/.worktrees/<export-wt> diff --name-only \
--diff-filter=AM HEAD~1..HEAD | grep -E '\.(sh|bash|zsh|fish)$' | while read f; do
echo "=== $f ==="
grep -nE "com\\.\\w+|com\\.\\\$USER|/\\\$LABEL/\\\$|\\\$SKILL_DIR/\\\$LABEL" "$f"
done
# Each "Yes I do" hit → apply Recipe A, B, or C above.
The mental model: filter rewrites apply to content. Any cross-reference between
a content-managed variable (like LABEL=...) and a filesystem name is a latent
breakage waiting for a fresh export on a different host. Audit every ls $X,
@file_template, $CONFIG_DIR/... reference for this property before pushing.
Pitfall 10 — The 5th archetype: cleanup-PR + script-patch workflow (added 2026-07-13)
The export script has no exclude logic for content categories. It's a copy-everything
union-merge. A fresh export will ship every file under ~/.claude/skills/_archive/,
~/.claude/skills/_archived_loose_md/, .beads/, etc. — local history-keeping surfaces that
should never reach the public jleechanorg/claude-commands repo.
When the user says "remove the archive from the PR and modify /exportcommands to stop exporting it", the correct response is a two-track atomic edit:
Track A — patch exportcommands.sh so future runs skip the category
The script has TWO union-merge surfaces plus an rsync for root-level dirs. Each needs its own exclude:
# Surface 1: union_dir() global find — add to the `\( -not -path ... \)` block
\( -not -path '*/_archive/*' \) \
# Surface 2: union_dir() project find — same exclude, different anchor context
\( -not -path '*/_archive/*' \) \
# Surface 3: rsync block for orchestration/automation/ralph — add to --exclude list
--exclude='_archive/' \
--exclude='*/_archive' \
The script's find calls have ~25 lines of --not -path clauses between them — use unique
surrounding context (e.g. the union_dir() body or while IFS= read -r -d '' f; do lines) to
disambiguate. After patching, run bash -n ~/.claude/commands/exportcommands.sh to confirm syntax.
Smoke-test the patch before pushing: extract the union_dir function and run it against a
fixture with files in both _archive/ and non-_archive/ paths. Confirm the count of returned
files matches the expected (non-archive) total.
Track B — amend the auto-opened PR to drop the unwanted content
In a fresh worktree of the PR branch:
# 1. Get the diff-list and identify files in the unwanted category
HOME=$HOME git -C ~/worktrees/<branch> diff --name-only --diff-filter=AM HEAD~1..HEAD \
| grep '<unwanted-category-pattern>' > /tmp/rm_files.txt
# 2. git rm the matching files
HOME=$HOME git -C ~/worktrees/<branch> rm -rf $(cat /tmp/rm_files.txt)
# 3. Commit and force-push
HOME=$HOME git -C ~/worktrees/<branch> commit -F <commit-message-file>
HOME=$HOME git -C ~/worktrees/<branch> push --force-with-lease origin \
HEAD:refs/heads/<branch>
CRITICAL — distinguish "files I ADDED" vs "files main already had"
The auto-opened PR may include files that already existed on main (in modified form, because the export's content filters changed them by ~30 bytes). Removing those files wholesale will make them disappear from main on merge, which is wrong.
Recipe to keep main's version intact while still removing only the unwanted category:
# For each "already-on-main" file the script modified, restore it to main's exact bytes
git restore --source=<MAIN_SHA> --staged --worktree -- <file-path>
# Verify byte identity before committing
git show <MAIN_SHA>:<file> | git hash-object --stdin
cat <file> | git hash-object --stdin
# Both SHAs must match — if they differ by even 1 byte, the content-filter stripped a trailing newline
Don't use git checkout HEAD~1 -- <file> — that restores to the export-PR's modified version
(before the cleanup), not to main's original. git restore --source=<MAIN_SHA> is the only path
that ensures zero net diff vs main.
Final shape
After Track A + Track B, the PR diff shrinks from "all categories" to "the actual incremental
the user wanted". Verified 2026-07-13 with PR #327: original 66 files → 5 files after the
cleanup. The 5-file PR contained exactly /harness --optimize flag, new /slackbots command,
/social draft-only semantics, plus the two backing skill files.
Always close by posting a follow-up PR comment that summarizes the cleanup (what was removed, why, what the script patch prevents) — this is the durable record for future sessions and audit trails. CodeRabbit may now actually review the PR (since the bot rate limit resets on push), so the post-cleanup push is also your chance to retrigger a real review.
The full sequence (execute in order, no pauses)
Phase 0 — Re-check state (Pitfall 1)
HOME=$HOME GH_TOKEN="" gh api 'repos/jleechanorg/claude-commands/pulls?state=open&per_page=20' \
--jq '[.[] | {n: .number, title: .title, baseSha: .base.sha, mergeable: .mergeable, mergeable_state: .mergeable_state, headRefName: .head.ref, headSha: .head.sha, files: .changed_files, additions: .additions, deletions: .deletions, commits: .commits}]'
HOME=$HOME GH_TOKEN="" gh api 'repos/jleechanorg/claude-commands/branches/main' \
--jq '{main: .commit.sha, lastCommit: .commit.commit.message, lastCommitDate: .commit.commit.author.date}'
If main advanced past the open PRs' bases, reclassify each open PR as:
- FRESH — baseSha == main → drive to green directly
- STALE — baseSha < main → run Pitfall 2 audit (base audit + content audit)
- CLEANUP_NEEDED — auto-opened export PR with files in unwanted categories → Pitfall 10
- AUTO-MERGED —
state: closed, mergedAt: <recent>→ already in main, no action - CLOSED-UNMERGED —
state: closed, mergedAt: null→ archive, don't reopen
Phase 1 — Content audit on each STALE PR (Pitfall 2 + 3)
For each STALE PR, in a fresh clone:
git clone https://github.com/jleechanorg/claude-commands.git /tmp/<purpose>-audit
cd /tmp/<purpose>-audit
git fetch origin <branch>
git checkout -B audit/<pr-n> origin/<branch>
# Per-file byte identity check (not just name overlap)
python3 <<'PY'
import subprocess, os, time
# ... fetch main's content + branch's content for each file in diff, compare bytes
PY
The output is one of:
- 0 truly new files + N outdated files + security-leak files → supersede
- <10 truly new files + 0 outdated → rebase + merge (preserves the unique work)
- Many new files, all in
.claude/not inbackup/etc → rebase + merge - Many new files in unwanted categories (
_archive/, etc.) → Pitfall 10 cleanup-PR + script-patch
If supersede, post a detailed audit comment per the Pitfall 8 template.
Phase 2 — Run fresh /exportcommands (Pitfall 3 + 5)
cd ~/your-project.com
HOME=$HOME PROJECT_ROOT=$HOME/your-project.com \
bash $HOME/.claude/commands/exportcommands.sh
Capture:
- Branch name (
export-YYYYMMDD-HHMMSS) - Commit SHA
- PR number (auto-opened)
git secret guardline (must be clean)- File count / additions / deletions
Phase 2.5 — (Optional) Cleanup-PR + script-patch (Pitfall 10)
If the auto-opened PR contains content the user wants excluded:
- Patch
~/.claude/commands/exportcommands.sh(Track A) with the 3 exclude additions. - Run
bash -nto confirm syntax + a smoke-test fixture to confirmfindno longer picks up files in the unwanted category. - In a fresh worktree,
git rmthe unwanted files,git restore --source=<MAIN_SHA>the already-on-main files that the script's content filters modified (Track B). git commit --amendto fold the restorations into the cleanup commit (or new commit).git push --force-with-lease origin HEAD:refs/heads/<branch>.- Verify the PR's file list via REST: must show exactly the categories you want.
Phase 3 — Drive the new PR to green (Pitfall 4 + 7)
# REST (GraphQL is rate-limited; use REST for state)
HOME=$HOME GH_TOKEN="" gh api "repos/jleechanorg/claude-commands/pulls/<N>" \
--jq '{mergeable: .mergeable, mergeable_state: .mergeable_state, headSha: .head.sha, baseSha: .base.sha, changed_files: .changed_files, additions: .additions, deletions: .deletions}'
# Bot faux-green check
HOME=$HOME GH_TOKEN="" gh api "repos/jleechanorg/claude-commands/issues/<N>/comments?per_page=10" \
--jq '[.[] | {login: .user.login, body: .body[:150]}] | map(select(.login | test("coderabbit|cursor|chatgpt-codex"; "i")))'
# Status webhook (often shows success despite no real review)
HOME=$HOME GH_TOKEN="" gh api "repos/jleechanorg/claude-commands/commits/<HEAD_SHA>/status" \
--jq '{state: .state, contexts: [.statuses[] | {context: .context, state: .state}]}'
If bots rate-limited → post a documentation comment per the template in Pitfall 4 (cite
coderabbit-slow-bot-policy from SOUL.md, ping @coderabbitai to retrigger, set a 2h SLA).
If bots substantive and CHANGES_REQUESTED → fix inline (the export script's content is generated, not authored, so fixes are usually trivial content adjustments — re-run the script).
If bots substantive and APPROVED → ready to merge.
Phase 4 — Supersede any STALE PR (Pitfall 8)
Do NOT close the STALE PR before the new fresh-export PR is verified clean. Close order matters: if you close #324 first and the new export PR turns out to be wrong, you've burned your reference state. Post the supersession comment, leave the PR open until the new one is green, then close.
Phase 5 — Final reply (Slack thread + PR description)
Same shape as drive-pr-to-green Step 10 — single reply with PR URL, gate-by-gate verdicts, and
the per-PR supersession receipts. Cite each bot's rate-limit timeout in the reply so the user
knows why a "green" PR has no real review. If Phase 2.5 ran, include the script-patch path
(~/.claude/commands/exportcommands.sh line ranges + before/after file count) so the user can
see the durable prevention fix.
References
references/sessions-recap.md— session-by-session audit of what was learned across 2026-07-01, 2026-07-02, 2026-07-06, 2026-07-13 (1st cleanup session)references/cleanup-archetype-recipe.md— detailed Track A (script-patch) + Track B (PR cleanup) workflow with the 5-file vs 66-file PR case studyreferences/exportcommands-sh-contract.md— full content-filter + union-merge spec extracted from the live scriptreferences/cross-vendor-resync-recipe.md— Pitfall 11 deep-dive: the three-bug cycle (stale source → REPO_ROOT break → fixture leak) when an exported skill bundles code from a different upstream repo, with verified recipe (Phases A-F)references/routing-eval.jsonl—{intent, expected_skill, ambiguous_with?}fixture for skill resolver routing evals
Resolver Trigger Entry
For the resolver, the heading line MUST contain the user-typed trigger phrases on the same line as the ## heading. Add this entry to ~/.hermes/skills/RESOLVER.md (the canonical resolver graph):
## claude-commands-export-superset — consolidate claude-commands PRs, run fresh /exportcommands, cleanup-PR + script-patch to exclude categories, supersede stale PRs, drive to green
triggers: consolidate the open claude-commands PRs, fresh /exportcommands and check the PRs, the export is stale, see what else is needed / what's incremental, supersede #N, /exportcommands from ~/your-project.com, the cmux-goal / ironclad pair isn't on main, the latest commands/skills aren't in jleechanorg/claude-commands, run a fresh export of my claude config, audit the open export PRs, close #N as superseded, remove the archive from the PR and modify /exportcommands to stop exporting it, edit the export to exclude _archive/, stop exporting archive paths, drop the archive from this PR
Skills Index / Discovery
This skill is referenced by / related to:
drive-pr-to-green— general PR-to-green workflow; we use it for the new export PR's Phase 3 (faux-green detection)github-pr-automation-debug— explains the bot-authoring pattern; useful for the Phase 3 bot rate-limit faux-green checkgithub-pr-workflow— low-levelgh prhelpers used throughout Phases 0–4patch-tool-safe-editing— relevant for the script-patch phase (Pitfall 10 Track A); the union-merge script has 3 surfaces with shared\( -not -path ... \)patterns that require unique surrounding context to disambiguate
The class is distinct from those because:
- The export script's auto-opened PR has specific union-merge semantics that other PRs don't (Pitfall 3, 5)
- The
mergeable_state: dirtyaudit is content-driven not just branch-driven (Pitfall 2) - The bot faux-green pattern shows up reliably on every auto-opened export PR (Pitfall 4)
- Supersession is a first-class action in this workflow, unlike other PR workflows
- Cleanup-PR + script-patch is the 5th archetype for content categories that should never have shipped (Pitfall 10)
04 同仓库更多 Skills
instinct
Use when the user invokes /instinct or /in, or asks to "message Instinct", "ask Instinct", "tell Instinct", "check Instinct", or read replies from the configured peer assistant. iMessage first, WhatsApp Web as fallback.
hr
Compatibility alias for history-resume; produce the same fresh-state, provenance-aware resume briefing.
history-resume
Resume briefing for the current repository branch or worktree using fresh state and admitted history sources.
grok
Alias for the canonical grokbot browser conversation workflow; /grok talks to the Grok bot the same way /dot talks to Dot.
codexa-bench
Compare `codexa` and normal `codex` on a fair split of comparable work by default; use `--strict` for duplicate runs of the exact same task.
frontend-design
Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, artifacts, posters, or applications (examples include websites, landing pages, dashboards, React components, HTML/CSS layouts, or when styling/beautifying any web UI). Generates creative, polished code and UI design that avoids generic AI aesthetics.