Skip to content
repoverlay 0.18.1 is available.Release notes

Profiles

A profile is a named configuration for an AI agent. It combines overlays with instruction files and plugins so you can apply them with one command.

An overlay defines files to add to a repository. A profile defines the agent setup for a task, such as Rust development.

You always apply a profile to a specific harness, the application that runs the agent. repoverlay supports GitHub Copilot and Claude Code. The harness determines where repoverlay puts each capability.

An overlay or profile definition is separate from its application to a repository:

  • An overlay is a named set of files that you can reuse in any repository. When you apply it, repoverlay adds the files to that repository's working tree. The applied instance belongs to the repository, but the definition does not.
  • A profile refers to overlays and adds harness capabilities through plugins.
OverlayProfile
RoleDefines a set of filesDefines an agent setup
ContentsA file tree to apply to a repositoryOverlays and harness capabilities
ManagesSymlinks, git excludes, and file conflictsInstructions and plugins with skills, agents, and MCP servers
Works across harnesses?Not applicable: files onlyManaged capabilities that repoverlay can cache work across harnesses. Delegate support depends on the harness.

repoverlay applies profile capabilities to the target repository, not globally for the user or machine. It excludes new files from git when possible. Profiles can also update existing files through managed regions or JSON merges. repoverlay keeps cache and recovery snapshots outside the repository to restore profiles after cleanup.

Profiles do not define MCP servers or skills directly. They use plugins in the Claude Code plugin format. A plugin can contain:

  • Skills for .claude/skills/ (Claude) or .agents/skills/ (Copilot).
  • Agents for .claude/agents/ (Claude) or .github/agents/ (Copilot).
  • MCP server definitions to merge into the repository's .mcp.json.
  • Plugin metadata in .claude-plugin/plugin.json.

The same plugin can supply capabilities to different harnesses. For managed plugins that it can cache, repoverlay extracts the parts and puts them in the paths for the selected harness. This works for persistent applications and temporary (ephemeral) sessions.

Claude can also load plugins through its native settings. Copilot skips delegate plugins and plugins that repoverlay cannot cache, with a warning. repoverlay removes temporary placements when the session ends.

Define profiles under the profiles key in your repoverlay CCL configuration, beside sources and marketplaces:

  • Global configuration: ~/.config/repoverlay/config.ccl
  • Repository configuration: .repoverlay/config.ccl
marketplaces =
=
name = playground
url = obra/claude-plugins
=
name = vendor
url = https://example.com/vendor/market.git
profiles =
rust-dev =
description = Rust development profile
overlays =
= rust-base
= rust-tools
instructions =
=
source = instructions.md
=
content =
Be concise in all responses.
Prefer composition over inheritance.
plugins =
= playground/rust-dev
=
marketplace = vendor
name = cool
install = delegate
scope = local
FieldTypeDescription
descriptionscalarOptional text for profile list and profile show.
overlayslistOverlay references. repoverlay uses the standard source and library resolution rules.
instructionslistInstructions for a managed region in CLAUDE.md (Claude) or AGENTS.md (Copilot). Each entry must set either source or content, but not both. source is a path relative to the configuration file that defines it. content is inline text.
pluginslistPlugin references (see below).

The top-level marketplaces key maps a short name to a marketplace git repository. Plugin references use these names. The url accepts a full git URL or GitHub owner/repo shorthand. The shorthand expands to https://github.com/owner/repo. repoverlay caches marketplace repositories under ~/.cache/repoverlay/, as it does for overlay sources.

Each entry in plugins is one of:

  • Marketplace shorthand: marketplace/plugin, such as playground/rust-dev.

  • Marketplace table: use this to pin a ref or select an install mode:

    KeyDescription
    marketplaceMarketplace name from the registry.
    namePlugin name within the marketplace.
    refOptional git tag, branch, or commit that pins the marketplace repository checkout. The marketplace manifest defines refs for external plugin sources.
    installmanaged (default) or delegate.
    scopeDelegate only: project or local.
  • Local path: a source table or a path that starts with . or /. The path identifies a local plugin directory.

Install modeBehavior
managed (default)repoverlay caches the plugin when it can read its contents. It adds the skills, agents, and MCP servers to the repository. Both Copilot and Claude support plugins that repoverlay can cache.
delegaterepoverlay enables the plugin in the harness configuration. The harness loads the plugin. Only Claude supports this mode. Copilot skips delegate plugins with a warning.

For delegate plugins on Claude, scope selects the settings file that enables the plugin:

ScopeFile
project.claude/settings.json
local.claude/settings.local.json

If you omit scope, persistent applications use project. Ephemeral sessions use local.

A plugin is a directory with a .claude-plugin/plugin.json manifest and the capabilities it supplies. To create one manually:

Terminal window
mkdir -p my-plugin/.claude-plugin my-plugin/skills
my-plugin/.claude-plugin/plugin.json
{
"name": "my-plugin",
"version": "0.1.0",
"description": "What this plugin provides"
}
// my-plugin/.mcp.json (optional — only if the plugin ships MCP servers)
{
"mcpServers": {
"example": { "command": "uvx", "args": ["example-mcp"] }
}
}

Add skills under my-plugin/skills/<skill>/SKILL.md. Then use a local path (= ./my-plugin) to refer to the plugin in a profile.

repoverlay can turn APM output into a repository profile. APM remains responsible for dependency resolution, policy, lockfiles, and target conversion. repoverlay owns the generated files, conflict checks, removal, and recovery.

Install a package without adding it to the repository's APM manifest:

Terminal window
repoverlay apm install tylerbutler/apm-base
repoverlay apm install tylerbutler/apm-base --harness copilot

The generated profile name starts with apm-, for example apm-tylerbutler-apm-base.

Use apm sync when the repository already has an apm.yml and apm.lock.yaml:

Terminal window
repoverlay apm sync
repoverlay apm sync --harness copilot

Sync requires APM 0.31 or later. repoverlay runs the equivalent of a frozen APM install and compile with an isolated output root. APM can read local .apm/ primitives and relative inputs, but it does not write generated output, manifest changes, or lockfile changes into the repository. APM can update harness-specific deployment metadata in the temporary lockfile. Its frozen install enforces the dependency pins.

The result is the apm-project profile. Re-running sync resolves the new output before replacing the active profile. If application fails, repoverlay restores the previous profile.

APM outputClaudeCopilot
Skills.claude/skills/.agents/skills/
Agents.claude/agents/.github/agents/
MCP serversMerged into .mcp.jsonMerged into .mcp.json
LSP servers.claude/skills/apm-lsp/Merged into .github/lsp.json
Commands or prompts.claude/commands/.github/prompts/
Instructions.claude/rules/.github/instructions/
Compiled contextManaged region in CLAUDE.mdManaged regions in AGENTS.md and .github/copilot-instructions.md
HooksMerged into .claude/settings.json.github/hooks/

repoverlay installs LSP configuration, not the language-server executable. Install the executable separately and make it available to the selected harness.

Hooks run commands in the repository and require explicit consent:

Terminal window
repoverlay apm install owner/package --allow-hooks
repoverlay apm sync --allow-hooks

Claude hook scripts stay in the external artifact. repoverlay rewrites hook-script references under ${CLAUDE_PROJECT_DIR}/.claude/hooks/ to that artifact, while leaving references to other repository files unchanged.

Apply and restore reject placements that overlap targets owned by another profile before changing files. This includes shared directories such as .github/hooks/scripts. Remove the conflicting profile before applying its replacement.

Remove APM-generated profiles with the normal profile command:

Terminal window
repoverlay profile remove apm-tylerbutler-apm-base --harness claude
repoverlay profile remove apm-project --harness claude

Use repoverlay remove --all to remove applied overlays and profiles, including APM profiles. Add --dry-run to preview the removal. A live agent session's profile lock blocks bulk removal.

Use repoverlay remove --interactive to select individual overlays or profiles. Select the owning profile to remove a profile-owned overlay. Standalone removal, forced replacement, and switch reject profile-owned overlays before removal. Removing an overlay preserves unrelated profile state, configuration, and library files.

APM profiles use the same external snapshots as configured profiles, so repoverlay restore can rebuild them after git clean. It also repairs missing profile files when applied state remains, including files inside managed plugin directories. Repair preserves existing files and the original removal backups. Use --dry-run to preview recovery. A live profile lock blocks recovery, and a failed profile recovery returns a nonzero exit code.

List configured and applied profiles, including APM-generated profiles:

Terminal window
repoverlay profile list

The list shows each profile once, with its configuration source and applied harnesses. Configured profiles remain visible when they are not applied. APM profiles show their APM origin. profile show includes the recorded package reference or project inputs beside the applied files.

Show a profile's configuration and applied state:

Terminal window
repoverlay profile show rust-dev

Example output:

rust-dev
Source: configured
Description: Rust development profile
Overlays:
- rust-base
- rust-tools
Instructions:
- instructions.md
Plugins:
- playground/rust-dev (managed)
- vendor/cool (delegate, scope: local)

Choose persistent mode to keep the configuration until you remove it. Choose ephemeral mode to use it for one agent session.

profile apply installs the profile and leaves it in place until you remove it:

Terminal window
repoverlay profile apply rust-dev --harness copilot
repoverlay profile apply rust-dev --harness claude

Check what is currently applied:

Terminal window
repoverlay profile status
repoverlay profile status --harness copilot

Use repoverlay status to inspect applied profiles alongside overlays, including APM-generated profiles. It shows each profile's harness and managed files. Use --name <profile> to filter, --json for separate overlays and profiles arrays, or --quiet to check whether a matching overlay or profile is applied.

Remove it when you finish:

Terminal window
repoverlay profile remove rust-dev --harness copilot

Removal deletes the harness files and merged configuration entries that the profile created. repoverlay removes an overlay only if both conditions apply:

  • This profile applied the overlay.
  • No other applied profile refers to the overlay.

repoverlay pins managed plugins to their resolved commit when you apply a profile. It records that commit in profile state.

Run repoverlay update to resolve managed plugins again for persistent profiles. If a plugin source has changed, repoverlay applies the profile again. Use repoverlay update <profile> to update one profile across its applied harnesses. It does not change delegate plugins or plugins pinned to a fixed ref. A failed application restores the previous profile.

Use repoverlay update --dry-run to preview which profiles need a new application.

For APM profiles, update refreshes installed packages through APM using their recorded references, including version pins. It refreshes apm-project through the frozen sync workflow without changing apm.yml or apm.lock.yaml. APM dry runs show the planned refresh without running APM. Add --allow-hooks if the refreshed output contains hooks. Live profile locks block updates, and failed profile updates return a nonzero exit code.

APM profiles created before repoverlay recorded their origin need one explicit refresh. Run repoverlay apm sync for a project. For a package, remove the profile and reinstall the original package reference, including its pin. update reports the required action instead of guessing a missing reference.

Use repoverlay copilot --profile or repoverlay claude --profile to apply profiles for one agent session. repoverlay removes the session changes automatically when the agent exits:

Terminal window
repoverlay copilot --profile rust-dev
repoverlay claude --profile rust-dev

The flow is:

  1. Resolve and plan the profile for the harness.
  2. Apply it using session-scoped state.
  3. Launch the agent harness.
  4. Wait for the agent to exit.
  5. Remove the session's profile effects.
  6. Exit with the agent's exit code (unless cleanup fails).

Put extra arguments for the agent after --:

Terminal window
repoverlay copilot --profile rust-dev -- --help

Applying several profiles at once v0.17.0

Section titled “Applying several profiles at once ”v0.17.0

Repeat --profile to use multiple profiles in one ephemeral session. repoverlay applies and locks each profile separately. It removes all of them when the agent exits:

Terminal window
repoverlay copilot --profile rust-dev --profile docs-dev
repoverlay claude --profile rust-dev --profile docs-dev -- --help

Profiles can share instruction files: CLAUDE.md for Claude and AGENTS.md for Copilot. Each profile has its own managed region. repoverlay merges servers in .mcp.json and records which profile owns each server.

If one profile fails to apply, repoverlay rolls back the profiles already applied by the same command. This prevents a partially configured repository. Do not repeat a profile name in one command.

For Claude and Copilot, repoverlay extracts managed plugins that it can cache into repository files. These include skills, agents, and merged .mcp.json servers. Persistent applications and ephemeral sessions use the same process.

Claude loads delegate plugins and plugins that repoverlay cannot cache through its own settings. Copilot skips them with a warning. repoverlay removes ephemeral placements when the session exits.

repoverlay applies each capability to the target repository according to the selected harness:

CapabilityClaudeCopilot
overlaysUses the standard overlay process: symlinks, git excludes, and state.Same.
plugin skills<repo>/.claude/skills/<skill><repo>/.agents/skills/<skill>
plugin agents<repo>/.claude/agents/<agent><repo>/.github/agents/<agent>
plugin MCP serversMerged into <repo>/.mcp.json (mcpServers key).Merged into <repo>/.mcp.json (mcpServers key).
delegate pluginsRecorded in .claude/settings.json / .claude/settings.local.json.Skipped with a warning.
instructionsrepoverlay combines each entry's source file or inline content in the profile's managed region of <repo>/CLAUDE.md.Same, in <repo>/AGENTS.md.

repoverlay applies capabilities to the target repository, not globally for the user or machine. It excludes new files from git when possible. It can update existing files through managed regions or JSON merges. Cache and recovery snapshots stay outside the repository.

Instruction source paths must be relative to the configuration file that defines them. They must stay within that file's directory. repoverlay rejects absolute paths and paths outside the directory, such as ../secret.md.

Store repository profile sources within the directory that contains <repo>/.repoverlay/config.ccl. Store global profile sources within the global configuration directory. To avoid separate files, use inline content.

If a repository profile and a global profile have the same name, repoverlay starts with the global profile. It applies repository values according to the field type:

Field typeMerge behavior
Scalars (description)Uses the repository value if set. Otherwise, keeps the global value.
Lists (overlays, instructions, plugins)Uses the repository list if it is not empty. Otherwise, keeps the global list.

The top-level marketplaces registry merges by name. Repository entries replace global entries with the same name. repoverlay keeps other global marketplaces.

repoverlay records profile state separately from overlay state:

.repoverlay/profiles/<profile-name>.<harness>.ccl

State records the applied profile, harness, fingerprint, applied overlays, managed files, and merged configuration entries. profile remove and ephemeral cleanup use these records to remove only what the profile created.

If an ephemeral session stops unexpectedly and cleanup fails, repoverlay reports the error. It keeps enough session state for later cleanup. Use profile remove to finish the cleanup.