botfile
dotfiles for your agents' skills and instructions
botfile is a CLI for managing AI-agent components (skills and instructions).
It reads a config.toml that declares local source directories and which agents should receive their components. It then creates symlinks from those sources into each agent's native config paths.
It is inspired by Stow: under the hood it is a symlink farm that follows the Unix philosophy of doing one thing well, and is strictly guided by its tenets.
Use botfile if you have user-scoped agent components (like skills or instructions) you use across projects, teams, agents, or devices. botfile-managed components can be:
- kept in version control like git
- synced across machines
- publicly shared with a team, kept private in a personal dir, or a mix
- installed into multiple agents from one config
botfile manages two kinds:
- skill (
skill/<name>): invokable on demand, a directory likeskills/meow/SKILL.md, described in detail at agentskills.io - instruction (
instruction/<name>): ambient context injected at harness runtime, a file likeinstructions/favorite-food.md, following agents.md
Other agentic components exist, like hooks, memory, and MCP config. botfile will support them if there's demand. For now skills and instructions are the most standardized components and the best fit for the project tenets.
A source is a local directory that holds botfile components, usually a git repo. Its layout is:
<source>/
<plugin>/
skills/
<skill-name>/
SKILL.md
instructions/
<instruction-name>.md
For example:
~/botfiles/personal/
cats/
skills/
meow/
SKILL.md
instructions/
favorite-food.md
In ~/.config/botfile/config.toml you give the source a name and location:
[[sources]]
name = "personal"
location = "~/botfiles/personal"
A declared source needs a selection that declares the symlink destination. Add one and the file reads:
[[sources]]
name = "personal"
location = "~/botfiles/personal"
[[selections]]
source = "personal"
plugin = "cats"
agents = ["claude-code", "codex-cli"]
That installs the selected components on the next botfile sync. Meaning:
source: personalplugin: catsagents: claude-code, codex-cli- every component in the
catsplugin (themeowskill andfavorite-foodinstruction) installs for both agents
plugin and component are optional: omit plugin to select every plugin in the source, or add component to pin the selection to one component.
Seven, each for both skills and instructions:
claude-codecodex-clicopilot-clicopilot-vscodecrushopencodepi.dev
Skill paths vary by agent: most share ~/.agents/skills, while Claude Code uses ~/.claude/skills. Instructions install to each agent's native instruction path.
See the support matrix for the exact paths.
No. botfile is scoped to user-level agent skills and instructions:
~/.claude/skills~/.claude/rules~/.agents/skills~/.codex/AGENTS.md
It does not manage project-local files such as:
./AGENTS.md./CLAUDE.md./.github/copilot-instructions.md./.vscode/settings.json
Keep project instructions in the project repo directly. botfile is for shared personal and team agent context across projects and machines.
Yes, mostly at the file-format level.
skills.sh distributes agent skills as SKILL.md packages, and botfile's skill component is also a directory containing SKILL.md. So a skill from skills.sh can be managed by botfile if it is placed in a botfile source tree.
Typical flow:
- Install/download a skill into a botfile source, then
botfile sync.
Sources: skills.sh
Yes. Each piece has a clear owner, so nothing is managed twice:
- git owns the source repos: you clone, pull, and push each one (such as
~/botfiles/personal) - your dotfile manager (Stow, chezmoi) owns
~/.config/botfile/config.toml - botfile owns the agent-native symlinks it creates
Yes. botfile's CLI can respond with structured JSON that makes it easy for an agent to use:
- Run
botfile status --format json. - Inspect managed, out-of-sync, and adoptable components.
- Run
botfile plan --format json. - Explain the planned changes.
- Only run
botfile syncafter your approval. - Use
botfile adopt <path> --into <source>/<plugin>to bring an existing agent-created skill or instruction into a source.
The agent can help edit source files and config.toml, then use botfile to preview and apply the symlinks.
Still require your approval before:
- running
botfile sync - running
botfile adopt - editing shared or team source repos
- changing selections that affect multiple agents
botfile is built so agents do not scrape text: use --format json.
Use it if you have a real need for versioned, reusable agent context.
Good fit:
- you use multiple agents
- you use multiple machines
- you want skills/instructions in git
- you want team-shared agent components
- agents create useful skills locally and you want to adopt them into a repo
Probably not worth it:
- you use one agent on one machine
- you rarely customize skills or instructions
- you are happy letting each agent/tool manage its own files
- you scope agent components at the project level and rarely across projects
- you mainly want MCP/settings/plugin management
So: yes for managing portable skills and instructions; no if you only need a one-off local setup.
Install botfile
curl -fsSL https://botfile.org/install.sh | sh
irm https://botfile.org/install.ps1 | iex
Either script drops a single botfile binary on your
PATH. Run botfile --help and you should see the
plan, sync, status, and
adopt commands. On Windows, symlink creation needs Developer
Mode enabled.
Create a skill, share it with your agents
Start simple. Keep a skill in a dotfiles repo and let botfile symlink it
into the agents you use. Here a meow skill in
~/botfiles/personal goes to both Claude Code and Codex.
mkdir -p ~/botfiles/personal/cats/skills/meow
cat > ~/botfiles/personal/cats/skills/meow/SKILL.md <<'MD'
---
name: meow
description: Always reply with "meow", and nothing else.
---
# Meow
When this skill is used, respond with exactly:
meow
MD
Tell botfile where the source is and which agents get it. botfile reads
config.toml from ~/.config/botfile/:
[[sources]]
name = "personal"
location = "~/botfiles/personal"
[[selections]]
source = "personal"
agents = ["claude-code", "codex-cli"]
Apply it. One source file becomes a symlink in each agent's native path:
$ botfile sync
create ~/.agents/skills/meow -> ~/botfiles/personal/cats/skills/meow
create ~/.claude/skills/meow -> ~/botfiles/personal/cats/skills/meow
note skills for [codex-cli] also reach [copilot-cli copilot-vscode crush opencode pi.dev] via ~/.agents/skills
synced: 2 operation(s) applied
Claude Code reads ~/.claude/skills/; Codex reads the
cross-agent ~/.agents/skills/ pool, which the note flags is
shared with the other terminal agents. botfile installs symlinks, not
copies, so editing the source file is live through every agent at once.
Import skills from a team repo
Your team keeps shared skills and instructions in a git repo. Clone it, declare it as a second source, and select it for your agents. botfile does the symlinks; git does the fetching.
git clone https://github.com/acme/team-dotfiles ~/botfiles/team
The repo is a source tree with the
<plugin>/<kind>/<component> grammar; here the
plugin is standards:
standards/
skills/echo/SKILL.md
instructions/go-style.md
Declare the cloned repo as a second source next to the personal one, and
select it for three agents. Your config.toml now has both:
[[sources]]
name = "personal"
location = "~/botfiles/personal"
[[selections]]
source = "personal"
agents = ["claude-code", "codex-cli"]
[[sources]]
name = "team"
location = "~/botfiles/team"
[[selections]]
source = "team"
agents = ["claude-code", "codex-cli", "copilot-vscode"]
Then apply it. The team's echo skill and
go-style instruction land at each agent's native path:
$ botfile sync
create ~/.agents/skills/echo -> ~/botfiles/team/standards/skills/echo
create ~/.claude/rules/go-style.md -> ~/botfiles/team/standards/instructions/go-style.md
create ~/.claude/skills/echo -> ~/botfiles/team/standards/skills/echo
create ~/.codex/AGENTS.md -> ~/botfiles/team/standards/instructions/go-style.md
create ~/.copilot/instructions/go-style.instructions.md -> ~/botfiles/team/standards/instructions/go-style.md
note skills for [codex-cli] also reach [copilot-cli copilot-vscode crush opencode pi.dev] via ~/.agents/skills
note skills for [codex-cli copilot-vscode] also reach [copilot-cli crush opencode pi.dev] via ~/.agents/skills
synced: 5 operation(s) applied
That is a Claude rule, the Codex AGENTS.md singleton, and a
Copilot VS Code drop-in file, all from the one team source.
Adopt a skill your agent made
Skills also turn up in your agent dirs on their own: a tool like skills.sh
installs one, or an agent writes one, into the shared
~/.agents/skills/ pool. That review skill is not
in any source, so it is not version-controlled or shared. botfile reports it
as adoptable:
$ botfile status
managed (7)
~/.agents/skills/echo
~/.agents/skills/meow
~/.claude/rules/go-style.md
~/.claude/skills/echo
~/.claude/skills/meow
~/.codex/AGENTS.md
~/.copilot/instructions/go-style.instructions.md
notes (2)
note skills for [codex-cli] also reach [copilot-cli copilot-vscode crush opencode pi.dev] via ~/.agents/skills
note skills for [codex-cli copilot-vscode] also reach [copilot-cli crush opencode pi.dev] via ~/.agents/skills
adoptable (1)
codex-cli,copilot-vscode skill/review ~/.agents/skills/review
7 managed, 0 out of sync, 0 skipped, 1 adoptable
Adopt it into the team repo so everyone gets it. botfile moves the skill into the source and links it back where Codex still finds it:
$ botfile adopt ~/.agents/skills/review --into team/standards
move ~/.agents/skills/review -> ~/botfiles/team/standards/skills/review
link ~/.agents/skills/review -> ~/botfiles/team/standards/skills/review
select skill/review for copilot-cli,crush,opencode,pi.dev
adopted skill/review into source "team" (plugin "standards")
review lived in the shared ~/.agents/skills/ pool
that six agents read. The team selection already covered
codex-cli and copilot-vscode, so adopt added the
smallest selection to keep it for the other four. Your
config.toml now ends with that precise block:
[[sources]]
name = "personal"
location = "~/botfiles/personal"
[[selections]]
source = "personal"
agents = ["claude-code", "codex-cli"]
[[sources]]
name = "team"
location = "~/botfiles/team"
[[selections]]
source = "team"
agents = ["claude-code", "codex-cli", "copilot-vscode"]
[[selections]]
source = "team"
plugin = "standards"
component = "skill/review"
agents = ["copilot-cli", "crush", "opencode", "pi.dev"]
Commit the team repo and review syncs to every teammate. Every
command also accepts --format json for agents and scripts.
Support matrix
| Agent | Skills | Instructions |
|---|---|---|
claude-code |
~/.claude/skills/<name>/ |
~/.claude/rules/<name>.md drop-in |
codex-cli |
~/.agents/skills/<name>/ shared |
~/.codex/AGENTS.md singleton |
copilot-cli |
~/.agents/skills/<name>/ shared |
~/.copilot/copilot-instructions.md singleton |
copilot-vscode |
~/.agents/skills/<name>/ shared |
~/.copilot/instructions/<name>.instructions.md drop-in |
crush |
~/.agents/skills/<name>/ shared |
~/.config/crush/CRUSH.md singleton |
opencode |
~/.agents/skills/<name>/ shared |
~/.config/opencode/AGENTS.md singleton |
pi.dev |
~/.agents/skills/<name>/ shared |
~/.pi/agent/AGENTS.md singleton |
shared: the six terminal agents read the cross-agent
~/.agents/skills pool, so one symlink there serves all of them;
Claude Code is isolated in ~/.claude/skills.
drop-in: a directory of one file per instruction, isolated
per agent. singleton: a single fixed instruction file;
precedence picks the occupant and a pre-existing file is a conflict you take
over by adopting it, never a clobber.