Gather compiles your AI coding instructions into native formats for Cursor and Claude Code — from a single source of truth.
gather compile cursor
— and your entire team's knowledge flows into every tool.
One command. Resolves and installs the latest release via uv.
Prefer to inspect the script first, pin a specific tag, or install straight from main? Use uv directly:
uv is a fast Python package manager from Astral. It replaces pip, pipx, and virtualenv in a single tool. The install script above installs it automatically if missing; to install it yourself:
Gather requires Python ≥ 3.13. Check with python3 --version.
Pick shared packs from the org catalog.
One command writes everything your tool needs.
That's it. One compile fetched your org's shared instructions, merged your project rules, and wrote everything into Cursor's native format.
One source of truth. One command per tool. Project content always wins.
Shared skills are namespaced as <source>:<skill> on macOS/Linux
(__ on Windows) so the same skill name from different sources does not collide.
Pull skills, agents, and instructions from any branch or GitHub repo.
Edit gather.yaml directly, or use gather.local.yaml to experiment without changing committed config.
Tip: gather.local.yaml sources are appended to gather.yaml — use a unique name so they don't conflict. If the same name appears in both files, gather compile exits with an error.
Run gather status to check. If everything is Clean, you're up to date.
| What changed | What to do |
|---|---|
| Someone updated the org catalog | gather compile cursor |
You edited files in .gather/ |
gather compile cursor |
You changed gather.yaml sources |
gather compile cursor |
| Teammate already compiled & pushed | Nothing — outputs are in the repo |
| You tweaked a generated file | gather status → then decide |
CLAUDE.md gitignored?
CLAUDE.md, .cursor/rules/, and the other tool output files are generated artifacts — Gather writes them fresh on every compile. They belong in .gitignore for the same reason compiled code does: the source of truth lives in .gather/instructions/.
Already have a CLAUDE.md with project knowledge? Move its content into .gather/instructions/your-file.md (any name except CLAUDE.md), then run gather compile claude. Gather regenerates CLAUDE.md from your source files. Your .gather/instructions/ files are committed — that is where your repo knowledge belongs.
Copy your files into the appropriate subdirectory under .gather/ in your repo:
Then run gather compile cursor (or claude). Gather merges your project's .gather/ content with the org catalog and writes fresh output files. Your committed .gather/ files are the source — the output files in .cursor/, CLAUDE.md, etc. are regenerated from them.
You can use gather import to copy existing .cursor/rules/ or CLAUDE.local.md files into .gather/instructions/_imported/ automatically.
No — as long as your content lives in .gather/. Gather reads .gather/instructions/, .gather/agents/, .gather/skills/, and .gather/hooks/ as source, not output. It never modifies anything inside .gather/.
The output files (CLAUDE.md, .cursor/rules/, etc.) are rewritten on each compile — but those are derived from your source. If you have a file like .gather/instructions/developer-guide.md, it will always be included in the output.
If a path conflicts with the org catalog (same relative path under instructions/), your project's copy wins. You always have the final say.
When multiple sources in gather.yaml contribute a skill with the same name, Gather writes each copy under a flat namespace directory so Cursor and Claude never load the wrong file:
On Windows, : is invalid in paths, so Gather uses __ instead (e.g. arbor__pr). Both targets use the same layout.
After upgrading gather-cli, run gather compile <target> . once. Compile removes tracked outputs from older nested or legacy three-segment layouts and updates state.json.
Yes. Add a folder to the arbor-education/knowledge repo under your team's namespace (e.g. teams/frontend/) and populate it with instructions/, agents/, or skills/. Any repo that subscribes to that folder via gather init will pull it in automatically on compile.
For content that is only relevant to a single repo (not worth sharing), keep it in that repo's .gather/ directory instead.
arbor-education/knowledge. Select packs with Space, save with Ctrl+S.
Creates .gather/gather.yaml,
instructions/, agents/, and skills/ directories.
Also writes a .gitignore block that excludes generated output files.
--folders,
or omit it to create the .gather/ structure with no catalog subscriptions.
gather init, but writes the sources entry to
~/.config/gather.yaml (personal overlay) instead of the project's
.gather/gather.yaml. Does not create project .gather/ directories
or touch .gitignore. The entry is saved under a distinct name
(e.g. arbor-personal) so it compiles alongside a project's catalog source —
the same source name in more than one config layer is a compile error.
Combine with --batch --folders for scripting.
~/.config/gather.yaml is global, not per-project; a later
--batch --user overwrites the personal folder selection.
.gather/ content, sends to the compiler, and writes native output files.
Each compile is a full refresh — no incremental state to worry about.
gather.yaml directly, or use gather.local.yaml to experiment without changing committed config.
.cursor/rules/),
promote syncs that change back into .gather/ so it survives the next compile.
.cursor/rules/ or CLAUDE.local.md? Import copies
them into .gather/instructions/_imported/ so they become part of your
canonical source.
.gather/ directory, validates
gather.yaml, tests GitHub auth, verifies the compiler service is reachable.
Locally-modified outputs are preserved by default. If you have edited a compiled file directly, Gather detects that its content no longer matches the recorded checksum and skips deleting it — so your edits are not silently lost. The skipped paths are listed in the output.
To delete locally-modified outputs as well, pass -f/--delete-modified:
The same protection applies during gather compile: locally-modified
outputs cause compile to exit with an error listing the conflicts.
Pass -s/--skip-modified to keep local versions,
-o/--overwrite-modified to replace them,
or -f/--delete-modified to discard local changes before compile: