Skip to content

Extends

extends lets one profile inherit from another. The child profile gets every file the parent contributes, then layers its own files on top — child files of the same name win.

Each profile may extend at most one other profile. If you need multiple sources, use includes instead.

.claude-profiles/dev/profile.json
{
"extends": "base",
"description": "local dev — verbose agents, debug commands"
}

extends

merge

resolved .claude/ after c3p use dev

commands/lint.md ← base

agents/coder.md ← base

agents/debugger.md ← dev (added)

settings.json ← dev (overrides base)

dev (extends: base)

settings.json (override)

agents/debugger.md

base (parent)

settings.json

agents/coder.md

commands/lint.md

The child profile (dev) inherits every file from base, then overrides any file of the same name.

For a file present in both parent and child, the child’s bytes win — parent contributes the file, child overrides it byte-for-byte. Files only present in the parent flow through unchanged.

extends is transitive: devbasecore is allowed. C3P refuses to resolve a cycle (a profile that extends one of its own descendants) and exits with code 3.

  • You have a base set of agents/commands every profile needs (base), and you want a dev and a ci profile that each tweak it differently.
  • You want one place to update a shared rule that propagates to every child.

If you instead want to compose unrelated bundles (Python toolchain + Rust toolchain + shared docs), includes is the right tool.

Run c3p validate <name> to dry-run the resolve+merge without writing anything. Run c3p diff <a> <b> to compare two profiles’ resolved file lists side-by-side.