Skip to content

agents-init

Usage
agents-init [-a | --agents] [-p | --plugins] [-e | --enable]
[--public | --private] [--pull]
[-v | --verbose] [-q | --quiet] [-s | --silent] [-h | --help]

Scaffolds an AGENTS/ sub-repository inside a project directory. Creates a self-contained git repo for agent specifications, moves any existing agent-related files into it, and replaces them with symlinks so the outer project never tracks agent files directly. This applies at the project root and, automatically, to any subdirectory that carries its own scoped AGENTS.md or CLAUDE.md – discovered by scanning the tree, not a hardcoded list. The scan prunes dot-directories (.git/, .claude/, …), nested repos, AGENTS/ itself, node_modules/, and generated-output directories (build/, dist/, out/, target/).

A real instruction file that the project deliberately tracks – in git’s index, in a project whose .gitignore is non-empty – is left exactly where it is, with a warning, rather than moved into AGENTS/ and replaced by a symlink. See _agents_init_path_is_protected.

Scaffolding runs only inside a git repository, or in a directory that already has an AGENTS.md, CLAUDE.md, or AGENTS/. Elsewhere it is a no-op, so running an agent CLI in an arbitrary directory does not create a repository there.

A project marked disabled is skipped entirely. agents-cleanup sets the per-clone git config key agents-init.disabled; a .agents-disabled file in the project root, which a team may commit, has the same effect. Either one turns every wrapper launch into a silent no-op there. --enable clears the git key and scaffolds; the file has to be deleted by hand, because it is a decision shared with every clone. --enable only clears the repository-local key: if the key is still in effect from another scope (global, system, include), it names that origin on stderr, exits 1 and does not scaffold.

Two modes, recorded in AGENTS/.mode. In both, each real file lives in the repository whose visibility matches it, and the other side holds a symlink:

public (default for a new project inside git)
<root>/AGENTS.md real, tracked by the project
<root>/AGENTS.local.md → AGENTS/AGENTS.local.md (gitignored)
AGENTS/AGENTS.local.md private instructions (real file)
AGENTS/AGENTS.md → ../AGENTS.md
private (every project scaffolded before modes existed)
the layout below, unchanged.

The public starter AGENTS.md points agents at AGENTS.local.md, both as an @ import (Claude Code expands it) and as a plain sentence (agents that do not expand imports still follow it). A real public AGENTS.md is never moved or rewritten. A project with no AGENTS/.mode is private. --public on a private project migrates it: each private AGENTS.md is renamed to AGENTS.local.md inside AGENTS/ (history kept) and replaced in the project by a public starter, so nothing private is published. Nothing is committed in the project; review and commit it yourself. --private on a public project is refused: what was published is already in history. Wrapper launches pass no mode flag and never change modes.

File layout after setup (private mode):

AGENTS/AGENTS.md canonical root agent spec (real file)
AGENTS/<subdir>/AGENTS.md canonical spec for any subdir with its own scoped instructions (real file, discovered automatically – see above)
<root>/AGENTS.md → AGENTS/AGENTS.md
<root>/<subdir>/AGENTS.md → AGENTS/<subdir>/AGENTS.md
AGENTS/plans superpowers plans (real dir, .gitkeep)
AGENTS/specs superpowers specs (real dir, .gitkeep)
AGENTS/devlogs agent development logs (real dir, .gitkeep)
AGENTS/.version MAJOR.MINOR.PATCH structure version (seed 1.0.0)
AGENTS/.agents-tools/ committed version-bump script + git hook shims
docs/superpowers/plans → ../../AGENTS/plans (always)
docs/superpowers/specs → ../../AGENTS/specs (always)
docs/plans → ../AGENTS/plans (only if docs/plans existed)
docs/specs → ../AGENTS/specs (only if docs/specs existed)
docs/devlogs → ../AGENTS/devlogs (only if docs/devlogs existed)

No CLAUDE.md survives anywhere in a managed tree: claude-code reads AGENTS.md natively when CLAUDE.md is absent, so CLAUDE.md exists here purely as a retirement target – any found (root or subdirectory, real file or leftover symlink) is folded into the AGENTS.md-only shape above by _agents_init_sync_instructions.

plans/ and specs/ are merged from every legacy location (docs/<tgt>, docs/superpowers/<tgt>, and the old AGENTS/plugins/ layout) into the canonical AGENTS/<tgt>; the AGENTS/plugins/ layer is removed.

Each AGENTS repo carries a self-contained version bumper wired via core.hooksPath: a pre-commit hook bumps AGENTS/.version on every commit (MINOR when the tracked directory set changes, PATCH otherwise; MAJOR is manual-only), and a prepare-commit-msg hook appends “(vX.Y.Z)” to the commit subject. Each shim then chains (execs) to the global/system core.hooksPath hook of the same name, so this local override does not shadow global hooks (e.g. ggshield, Git LFS). The script/hooks are version-managed from scripts/agents-tools/ and refreshed when their marker is stale.

Downstream tooling can read AGENTS/.version directly — a changed MINOR field signals a structure change.

With no flags, runs both --agents and --plugins setup; --agents re-runs only the AGENTS.md / symlink step and --plugins only the plans/specs/ devlogs wiring step. Managed paths are added to .gitignore. At the end of every invocation any uncommitted changes inside the sub-repo are auto-committed so agent-made edits are captured automatically. Fully idempotent: a second run produces no output and no new commits.

The commit is local only. Nothing here fetches or pushes: the wrappers call this synchronously before starting an agent, and a network round trip there blocks the launch until an unreachable remote times out and can prompt for credentials with nobody watching. A sub-repo that has an upstream is pulled by hand, on the user’s own schedule: --pull does it on request. It pulls with a rebase after the local commit, cannot prompt, and is capped at 20 seconds (see _agents_repo_net_git); a conflicting rebase is aborted and the sub-repo is left at its local HEAD. A sub-repo with no upstream is not an error. The wrappers never pass it.

Called automatically by the claude and agy wrappers on every invocation.

-a, --agents Set up AGENTS/ repo + AGENTS.md symlinks (root and every discovered subdirectory) only
-p, --plugins Set up AGENTS/ repo + plans/specs/devlogs dirs + docs/ symlinks only
-e, --enable Clear the git key agents-cleanup set, then scaffold as normal (refused while .agents-disabled exists)
--public New project: scaffold public mode (the default inside git). Private project: migrate it to public mode.
--private New project: scaffold private mode. Refused on a public project.
--pull After the local commit, pull the AGENTS/ sub-repo from its upstream (rebase, no prompts, 20 second cap)
-v, --verbose Print all per-step output (default)
-q, --quiet Print one summary line only if changes were made
-s, --silent Suppress all output; errors only (standard UNIX convention)
-h, --help Show this help message and exit
0 Setup completed successfully
1 Fatal error (git init failed, move failed, the AGENTS/ commit was rejected, or an unresolved rebase blocked it), --enable refused because .agents-disabled exists, a migration precondition failed, or --private given for a public project; also --enable when unsetting the git key failed or the key is still in effect from another scope (global/system), which is reported on stderr with its origin or --pull could not reach the remote, hit a rebase conflict (aborted), or has no timeout(1) to bound it
2 Unknown option, or both --public and --private given

This header covers usage only. The full concept/behavior/purpose write-up – the AGENTS.md convention, the AGENTS/ sub-repository, the discovery and safety model, and a complete scenario-by-scenario reference table – lives in its own manual section: docs/manual/17-agent-tooling.md. Update that section in the same change whenever this function’s behavior changes; see “Dedicated manual sections for complex subsystems” in CONTRIBUTING.md.

Terminal window
agents-init
agents-init --agents
agents-init --plugins
agents-init --quiet
agents-init --public
agents-init --pull

Dependencies: _agents_init_find, _agents_init_sync_instructions, _agents_init_sync_public, _agents_init_migrate_public, _agents_repo_install_tools, _agents_repo_sync, _agents_init_ensure_gitignore, _agents_init_pull

Classification: self-limiting(rm,mkdir,grep), bypasses-shadow(mv), manual-section(17-agent-tooling)

Used by: agy, claude

See also: 17. AI AGENT TOOLING