Public harness for a private Claude Code and Codex configuration.
./setup.sh # install Claude Code and Codex symlinks
./status.sh # check symlink state
./teardown.sh # uninstall, leaving local copiesClaude Code and Codex use different configuration locations, but both support symlinked files and skill folders. This repository contains only the harness; it reads personal content from AGENT_CONTENT_DIR, which defaults to the local, Git-ignored dotclaude/ directory.
| Content source | Claude Code target | Codex target |
|---|---|---|
<content>/CLAUDE.md |
~/.claude/CLAUDE.md |
~/.codex/AGENTS.md |
<content>/skills/<name>/ |
~/.claude/skills/ |
~/.codex/skills/<name>/ |
Other top-level <content>/ entries |
~/.claude/<entry> |
Not managed |
No configuration content is copied during setup. The public repository never tracks your instructions, skills, commands, agents, settings, or credentials. Start a new Codex task after changing the available skill set so it refreshes discovery metadata.
claude-code-dotfiles/
├── setup.sh # Creates Claude Code + Codex symlinks
├── teardown.sh # Removes managed symlinks, leaves standalone local copies
├── status.sh # Read-only report of both platforms' symlink state
├── tests/lifecycle.sh # Isolated lifecycle coverage
├── README.md
├── LICENSE
├── .gitignore
└── dotclaude/
└── .gitignore # Keeps default personal content out of Git
dotclaude/ is a safe default source for one machine. Use a private content repository through AGENT_CONTENT_DIR when you want to synchronize personal configuration between machines. For Claude Code, every non-control top-level entry is linked into ~/.claude/. For Codex, setup links CLAUDE.md and each direct skill bundle (skills/<name>/SKILL.md) into its global discovery locations. Nested skill workspaces and evaluation artifacts are never independently exposed as skills.
- bash — the setup/teardown/status scripts declare
#!/usr/bin/env bash. Run them as./script.shso the shebang is honored; don't invoke them throughzshorsh.
git clone https://github.com/<your-username>/claude-code-dotfiles.git
cd claude-code-dotfiles
mkdir -p dotclaude/skills/my-skill
# Add your own dotclaude/CLAUDE.md and skills/my-skill/SKILL.md.
./setup.shFor a private configuration repository, point all lifecycle commands at it:
AGENT_CONTENT_DIR=~/agent-config ./setup.sh
AGENT_CONTENT_DIR=~/agent-config ./status.sh
AGENT_CONTENT_DIR=~/agent-config ./teardown.shsetup.sh symlinks every non-control content entry into ~/.claude/, maps CLAUDE.md to ~/.codex/AGENTS.md, and links direct skills into ~/.codex/skills/. It backs up conflicts and skips already-correct links. An empty content directory is a valid no-op.
Whenever setup.sh would overwrite something, it moves the pre-existing item into a timestamped backup folder first:
- Claude Code:
~/.claude/backups/YYYYMMDD_HHMMSS/ - Codex guidance:
~/.codex/backups/YYYYMMDD_HHMMSS/ - Codex skills:
~/.codex/backups/YYYYMMDD_HHMMSS/
Backups are a one-way safety net, not a restore mechanism: nothing in this repo reads them back. If you want an old config, pull it out manually. Prune the backups/ directory yourself whenever it gets noisy — the scripts will never touch it.
# On each machine, clone your private content repository.
git clone <private-content-repository> ~/agent-config
# Link the same private content into both tools.
AGENT_CONTENT_DIR=~/agent-config ./setup.shAfter pulling changes to existing private content, the symlinks already point at the updated files. Re-run setup after adding a direct skill bundle, then start a new Codex task.
./teardown.shThis removes every managed symlink in ~/.claude/, ~/.codex/AGENTS.md, and ~/.codex/skills/ that points into the selected content directory, replacing each with a copy of the current content. Unrelated Codex configuration and skills are left alone.
| Content entry | Claude Code target | Codex target |
|---|---|---|
CLAUDE.md |
~/.claude/CLAUDE.md |
~/.codex/AGENTS.md |
skills/<name>/ |
~/.claude/skills/<name>/ |
~/.codex/skills/<name>/ |
settings.json |
~/.claude/settings.json |
Not managed |
statusline.sh |
~/.claude/statusline.sh |
Not managed |
agents/, commands/, kb/ |
~/.claude/<entry> |
Not managed |
The default dotclaude/.gitignore excludes every content entry. Credentials, settings.local.json, sessions, cache, telemetry, Codex config.toml, installed plugin state, and other machine-local state are never touched.
Anything outside the selected content directory is harness plumbing and is never synced into ~/.claude/.
Use the default ignored dotclaude/ directory for machine-local content. Use a private content repository for portable, version-controlled content. A private fork may instead remove dotclaude/.gitignore and track its own content.
Do not commit personal content to the public harness repository. The two repositories can evolve independently: pull harness updates normally, and pull your private content whenever you want its linked configuration to update.