fix(install): one payload on dual-target installs, .claude/ symlinked at it - #70
Merged
Merged
Conversation
… at it A repo used by Claude Code *and* Codex/Cursor detects both targets, and each adapter laid down its own full copy: two `SKILL.md` per skill, two `REVIEWER.md`, two `agents/`, two `scripts/`. Two sources of truth one edit away from drifting, and no signal to the reader about which side is canonical. Claude Code can't be pointed at `.agents/skills/` — there's no settings key or env var, and `--add-dir` only picks up `.claude/skills/` inside the added dir — but it does follow symlinks for skill directories and plain files. So on a dual-target install keep one physical payload in `.agents/` + `.rig/` (the locations other agents discover natively) and symlink `.claude/` at it: .claude/skills/<name> -> ../../.agents/skills/<name> .claude/agents/<file> -> ../../.rig/agents/<file> .claude/scripts/<file> -> ../../.rig/scripts/<file> .claude/REVIEWER.md -> ../.rig/REVIEWER.md (same for label-mapping.md) Link text is relative to each link's own directory, so the links survive a clone or a moved checkout — git stores them as mode 120000, not as copies. Single-target installs are untouched: claude-code alone still writes a real `.claude/` tree and never creates `.agents/`; agents-md alone never creates `.claude/`. Dedup engages only when both targets resolve, and only after probing that symlinks actually work — on Windows without developer mode it prints a note and falls back to copying. Since both adapters now run on one install and claude-code links at what agents-md lays down, agents-md is forced to run first regardless of the order targets were given. Side benefit: `review.patternsFile` was a single key with two candidate REVIEWER.md paths, so one was always dead. They now resolve to the same file. Verified end-to-end: dual install yields 2 physical SKILL.md and 17 symlinks, all resolving, none dangling; claude-only and agents-only produce zero symlinks and the same trees as before; `--target claude-code,agents-md` given in that order still links correctly; re-run is idempotent (35 skips, one marker pair); and a git init + clone round-trip resolves every link in the fresh clone. `bun test scripts/` — 39 pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014oVJgHRkCkeCiayKUJ4iSg
pgebheim
added a commit
that referenced
this pull request
Sep 3, 2026
…arget (#71) Two paths were hardcoded to `.claude/` with no indirection, so on an agents-md-only repo — Codex, Cursor, Gemini CLI, the population #69 and #70 exist to serve — they pointed at files that aren't there. rig-worktree named `.claude/scripts/{setup,remove}-worktree.sh` in four places while `agents-md` installs those scripts to `.rig/scripts/`, and the repo has no `.claude/` at all. The skill told the agent to run a path that doesn't exist, right after insisting it must not reimplement the script inline. It now resolves `<SCRIPTS>` first-hit-wins over `.claude/scripts/` then `.rig/scripts/`, in the spirit of the `<TRACKER>` resolver rig-epic/rig-task/rig-issue/rig-doctor/rig-plan already use, and stops with a clear message if neither has the script. The scripts themselves already resolved their own siblings, so only the callers needed fixing. install.sh copied rig.config.example.json verbatim, so every install got `review.patternsFile: .claude/REVIEWER.md` and `tracker.labelMapFile: .claude/label-mapping.md`. Without the claude-code target those docs were installed under `.rig/`, leaving both keys dangling on a fresh install. It now rewrites the two paths when claude-code isn't among the targets. Uses an inline membership test rather than a helper, to stay independent of #70. `.claude/worktrees/` as the default worktree location is deliberate and unchanged — the Claude Code harness only adopts worktrees there (see 41283b3). Documented that it carries no special meaning elsewhere and `--path` overrides. Verified across all three shapes: claude-only keeps `.claude/` paths and resolves to `.claude/scripts`; agents-only gets `.rig/` paths and resolves to `.rig/scripts`; dual keeps `.claude/` paths, both files present. The prescribed resolver snippet was executed as written against each install, and every configured doc path was checked to exist. `bun test scripts/` — 39 pass. Claude-Session: https://claude.ai/code/session_014oVJgHRkCkeCiayKUJ4iSg Co-authored-by: Paul Gebheim <86010+pgebheim@users.noreply.github.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #69.
Problem
A repo used by Claude Code and Codex/Cursor detects both targets, and each adapter laid down its own full copy:
Two sources of truth, one edit away from drifting, with no signal about which side is canonical.
Change
Claude Code can't be pointed at
.agents/skills/— no settings key, no env var, and--add-dironly picks up.claude/skills/inside the added dir. But it does follow symlinks for skill directories and plain files.So on a dual-target install, keep one physical payload in
.agents/+.rig/(the locations other agents discover natively) and symlink.claude/at it:.claude/skills/<name>../../.agents/skills/<name>.claude/agents/<file>../../.rig/agents/<file>.claude/scripts/<file>../../.rig/scripts/<file>.claude/REVIEWER.md../.rig/REVIEWER.md(same forlabel-mapping.md)Link text is relative to each link's own directory, so links survive a clone or a moved checkout — git stores them as mode
120000, not as copies.Guardrails
claude-codealone still writes a real.claude/tree and never creates.agents/;agents-mdalone never creates.claude/. Dedup engages only when both targets resolve.claude-codelinks at whatagents-mdlays down, soagents-mdruns first regardless of the order targets were given.Side benefit
review.patternsFileis a single config key that had two candidateREVIEWER.mdpaths, so one was always the dead copy. They now resolve to the same file.Verification
SKILL.md, 17 symlinks, all resolving, none dangling--target claude-code,agents-mdgiven in that order → still links correctlyrig:startmarker pair, still 2 physicalSKILL.mdgit init+ commit +git cloneround-trip → every link resolves in the fresh clonebun test scripts/— 39 passAdjacent, not fixed here
skills/rig-worktree/SKILL.mdhardcodes.claude/scripts/setup-worktree.shin four places, with no config indirection (unlike the<TRACKER>pattern in rig-epic/rig-task/rig-issue/rig-doctor/rig-plan). The symlinks in this PR make that path work on dual installs, but it's still broken on an agents-md-only repo, where.claude/doesn't exist at all. Worth its own fix.🤖 Generated with Claude Code
https://claude.ai/code/session_014oVJgHRkCkeCiayKUJ4iSg