# Agloom — full documentation
> Transpile canonical agent configurations across AI coding assistants
This file concatenates the full text of all documentation pages,
intended for ingestion by LLMs. See /llms.txt for an indexed version.
---
# Formatting
Source: https://docs.agloom.sh/guide/formatting
> How to format and lint Markdown, JSON, YAML, and TOML files with agloom format
# Formatting
This guide teaches you how to format and lint your project's Markdown, JSON, YAML, and TOML files using the built-in `agloom format` command.
## What `agloom format` Does
`agloom format` is a wrapper around [prettier](https://prettier.io/) and [markdownlint-cli2](https://github.com/DavidAnson/markdownlint-cli2) that ships with Agloom. It exists so you do not have to install and wire up those tools yourself just to keep your canonical files tidy.
The command has two modes:
- **Write mode** (default) — formats files in place and applies autofixable lint rules.
- **Check mode** (`--check`) — reports unformatted files and lint violations without modifying anything. Exits with code 1 if any file needs attention. Useful for CI.
## Supported File Types
| Extension | prettier | markdownlint |
| --------------- | -------- | ------------ |
| `.md`, `.mdx` | yes | yes |
| `.json` | yes | no |
| `.yaml`, `.yml` | yes | no |
| `.toml` | yes | no |
Files with any other extension are silently skipped, even if they match the glob.
## Default File Set
When you run `agloom format` with no arguments, it processes:
- `.agloom/**/*.{md,mdx,json,yaml,yml,toml}` — everything inside the canonical directory.
- `**/AGLOOM.md` — canonical instruction files anywhere in the project.
The following directories are always excluded: `node_modules`, `.git`, `dist`, `build`, `coverage`, `.next`, `.turbo`, `.cache`. Files and directories listed in `.gitignore` are also excluded.
## Formatting Extra Directories
Positional arguments **replace** the default file set — they do not extend it. To format your `docs/` directory along with the defaults, pass both explicitly:
```bash
agloom format ".agloom/**/*.{md,mdx,json,yaml,yml,toml}" "**/AGLOOM.md" "docs/**/*.{md,mdx,json,yaml,yml,toml}"
```
A common pattern is to wrap this in an npm script:
```json title="package.json"
{
"scripts": {
"fmt:md": "agloom format \".agloom/**/*.{md,mdx,json,yaml,yml,toml}\" \"**/AGLOOM.md\" \"docs/**/*.{md,mdx,json,yaml,yml,toml}\"",
"fmt:md:check": "agloom format --check \".agloom/**/*.{md,mdx,json,yaml,yml,toml}\" \"**/AGLOOM.md\" \"docs/**/*.{md,mdx,json,yaml,yml,toml}\""
}
}
```
If you want to format **every** supported file under the project root, use `--all`:
```bash
agloom format --all
```
`--all` cannot be combined with positional arguments.
## Configuration
`agloom format` resolves prettier and markdownlint configuration from three layers, in order of increasing priority:
1. **Built-in defaults** — bundled with Agloom, see below.
2. **Native config files** — `.prettierrc.*` and `.markdownlint.*` in the project root. Prettier and markdownlint discover these themselves.
3. **Sections in `.agloom/config.yml`** — `prettier` and `markdownlint` top-level fields. Values are passed to the tools as-is (shallow merge over layers 1 and 2).
### Built-in Defaults
Prettier defaults:
```yaml
proseWrap: preserve
tabWidth: 2
```
Markdownlint defaults:
```yaml
MD007:
indent: 2
MD013: false
MD024:
siblings_only: true
MD025: false
MD049:
style: "underscore"
MD050:
style: "asterisk"
```
### Overriding via `.agloom/config.yml`
Add `prettier` and `markdownlint` top-level sections to `.agloom/config.yml`:
```yaml title=".agloom/config.yml"
prettier:
proseWrap: always
tabWidth: 4
markdownlint:
MD013:
line_length: 80
```
Agloom does not validate the contents of these sections — prettier and markdownlint own their own schemas and will report errors directly if a value is invalid.
---
# Getting Started
Source: https://docs.agloom.sh/guide/getting-started
> From zero to your first transpile in 5 minutes
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
# Getting Started
This guide walks you through installing Agloom and running your first transpilation. By the end, you will have a working `.agloom/` directory and generated config files for your AI coding tool.
## Prerequisites
- **Node.js 20+** (check with `node -v`)
- **npm** or **pnpm** package manager
## Installation
Install Agloom globally:
```bash
npm install -g agloom
```
Verify the installation:
```bash
agloom --version
```
## Step 1: Initialize
Create a `.agloom/config.yml` file in your project root. You can do this manually or use the `init` command.
Using `init`:
```bash
agloom init --adapter claude
```
This creates a `config.yml` and copies any existing Claude Code files (`CLAUDE.md`, `.claude/`, `.mcp.json`) into `.agloom/overlays/claude/` so they are preserved as overlays.
```bash
agloom init --adapter codex
```
This creates a `config.yml` and copies any existing Codex files (`AGENTS.md`, `.codex/`, `.agents/`) into `.agloom/overlays/codex` so they are preserved as overlays.
```bash
agloom init --adapter gemini
```
This creates a `config.yml` and copies any existing Gemini files (`GEMINI.md`, `.gemini/`) into `.agloom/overlays/gemini/` so they are preserved as overlays.
```bash
agloom init --adapter opencode
```
This creates a `config.yml` and copies any existing OpenCode files (`AGENTS.md`, `.opencode/`, `opencode.json`) into `.agloom/overlays/opencode` so they are preserved as overlays.
```bash
agloom init --adapter kilocode
```
This creates a `config.yml` and copies any existing KiloCode files (`AGENTS.md`, `.kilo/`) into `.agloom/overlays/kilocode` so they are preserved as overlays.
Or create it manually:
```yaml
# .agloom/config.yml
adapters:
- claude
```
```yaml
# .agloom/config.yml
adapters:
- codex
```
```yaml
# .agloom/config.yml
adapters:
- gemini
```
```yaml
# .agloom/config.yml
adapters:
- opencode
```
```yaml
# .agloom/config.yml
adapters:
- kilocode
```
The `adapters` field tells Agloom which target tools to generate files for. You can list multiple adapters to generate files for several tools at once.
## Step 2: Write Instructions
Create an `AGLOOM.md` file in your project root with your project instructions:
```markdown
# My Project
## Stack
TypeScript, Node.js, React.
## Conventions
- Use functional components.
- Write tests for all new features.
- Keep functions pure when possible.
```
Agloom discovers `AGLOOM.md` files in the project root and any subdirectories (excluding `node_modules`, hidden directories, and `.gitignore` entries). Each file is transpiled into the corresponding instruction file for every adapter listed in your config.
## Step 3: Transpile
Run the transpile command:
```bash
agloom transpile
```
Agloom reads your `.agloom/` directory and generates config files for each adapter:
Produces a `CLAUDE.md` in your project root.
Add `--verbose` to see all steps:
```bash
agloom transpile --verbose
```
```text
✓ Transpiling for claude...
✓ Instructions 1 files
✓ Commands 0 files
✓ Skills 0 files
✓ Agents 0 files
✓ MCP 0 files
✓ Permissions 0 files
✓ Docs 0 files
✓ Schemas 0 files
✓ Overlay 0 files
Done. 1 files written.
```
Produces an `AGENTS.md` in your project root (the shared instruction format used by Codex).
Add `--verbose` to see all steps:
```bash
agloom transpile --verbose
```
```text
✓ Transpiling for agentsmd...
✓ Instructions 1 files
✓ Overlay 0 files
✓ Transpiling for codex...
✓ Instructions 0 files
✓ Commands 0 files
✓ Skills 0 files
✓ Agents 0 files
✓ Overlay 0 files
Done. 1 files written.
```
Produces a `GEMINI.md` in your project root.
Add `--verbose` to see all steps:
```bash
agloom transpile --verbose
```
```text
✓ Transpiling for gemini...
✓ Instructions 1 files
✓ Commands 0 files
✓ Skills 0 files
✓ Agents 0 files
✓ Docs 0 files
✓ Schemas 0 files
✓ Overlay 0 files
Done. 1 files written.
```
Produces an `AGENTS.md` in your project root (the shared instruction format used by OpenCode).
Add `--verbose` to see all steps:
```bash
agloom transpile --verbose
```
```text
✓ Transpiling for agentsmd...
✓ Instructions 1 files
✓ Overlay 0 files
✓ Transpiling for opencode...
✓ Instructions 0 files
✓ Commands 0 files
✓ Skills 0 files
✓ Agents 0 files
✓ MCP 0 files
✓ Permissions 0 files
✓ Docs 0 files
✓ Schemas 0 files
✓ Overlay 0 files
Done. 1 files written.
```
Produces an `AGENTS.md` in your project root (the shared instruction format used by KiloCode).
Add `--verbose` to see all steps:
```bash
agloom transpile --verbose
```
```text
✓ Transpiling for agentsmd...
✓ Instructions 1 files
✓ Overlay 0 files
✓ Transpiling for kilocode...
✓ Instructions 0 files
✓ Commands 0 files
✓ Skills 0 files
✓ Agents 0 files
✓ Docs 0 files
✓ Schemas 0 files
✓ Overlay 0 files
Done. 1 files written
```
## Step 4: Verify
Open the generated `CLAUDE.md` and confirm it contains your instructions.
Open the generated `AGENTS.md` and confirm it contains your instructions.
Open the generated `GEMINI.md` and confirm it contains your instructions.
Open the generated `AGENTS.md` and confirm it contains your instructions.
Open the generated `AGENTS.md` and confirm it contains your instructions.
## Formatting
Agloom includes a `format` command to format canonical files (Markdown, JSON, YAML, TOML). By default, it targets `.agloom/**/*` and `**/AGLOOM.md`:
```bash
agloom format
```
You can pass specific paths or globs, or use `--all` to format all supported files in the project:
```bash
agloom format "docs/**/*.md"
agloom format --all
```
Use `--check` to verify formatting without modifying files. See [reference/cli](../reference/cli.md) for full details.
## What's Next
- Learn about the [project structure](project-structure.md) to understand what goes where in `.agloom/`.
- Add [agent-specific instructions](instructions.md) for different tools.
- Create reusable [skills and agents](skills-and-agents.md).
- Share configurations with [plugins](plugins.md).
---
# Instructions
Source: https://docs.agloom.sh/guide/instructions
> How to write instructions for AI agents with agent-specific blocks
# Instructions
This guide teaches you how to write instructions for AI coding assistants using the canonical `AGLOOM.md` format.
## What Are Instructions
Instructions are `AGLOOM.md` files placed in your project root or any subdirectory. They contain project-level guidance for AI coding assistants — your stack, conventions, boundaries, and workflow preferences.
When you run `agloom transpile`, Agloom discovers all `AGLOOM.md` files and transforms each one into agent-specific instruction files (`CLAUDE.md`, `AGENTS.md`, `GEMINI.md`, etc.) at the same relative path, based on your configured adapters.
## Basic Instructions
Start by creating a simple `AGLOOM.md` with content that applies to all agents:
```markdown
# My Project
## Stack
TypeScript, React, PostgreSQL.
## Conventions
- Use functional components with hooks.
- All API calls go through the `api/` directory.
- Write unit tests for business logic.
## Boundaries
- Never modify database migrations directly — use the migration generator.
- Never commit `.env` files.
```
Everything in this file (outside of agent-specific blocks) is included in the output for **every** adapter.
## Agent-Specific Blocks
Sometimes you need instructions that apply only to a particular tool. Use HTML comment tags to define agent-specific sections:
```markdown
# My Project
All agents see this content.
Use the `Grep` and `Glob` tools for code search instead of shelling out to `grep`/`find`. Run shell commands only when no dedicated tool exists.
Use the file search and read tools provided by your environment. Always read a file before editing it.
This content is also visible to all agents.
```
When transpiling for Claude, the `agentsmd` block is removed and the `claude` block content is included (without the comment tags). When transpiling for AGENTS.md, the reverse happens.
## Valid Agent IDs
Only agents that have their own instruction file format can be used in agent-specific blocks:
| Agent ID | Instruction file | Can use in blocks |
| ---------- | ---------------- | ----------------- |
| `claude` | `CLAUDE.md` | Yes |
| `agentsmd` | `AGENTS.md` | Yes |
| `gemini` | `GEMINI.md` | Yes |
| `opencode` | _(none)_ | No |
| `kilocode` | _(none)_ | No |
| `codex` | _(none)_ | No |
`opencode`, `kilocode`, and `codex` do not have their own instruction file format — they use `AGENTS.md` (generated by the `agentsmd` adapter). To write content specific to these tools, use `` blocks.
Using an invalid agent ID in a block (e.g., ``) will cause a transpilation error.
## Multiple Instruction Files
Agloom supports instruction files in subdirectories. If you place an `AGLOOM.md` in a subdirectory (e.g., `src/AGLOOM.md`), it will be transpiled to the corresponding location (e.g., `src/CLAUDE.md` for the Claude adapter).
This lets you provide directory-level instructions that agents pick up when working in specific parts of your codebase.
## Example
Here is a complete `AGLOOM.md` with shared and agent-specific sections.
```markdown
---
description: Main project instructions
---
# My Web App
## Stack
TypeScript, Next.js 14, Prisma, PostgreSQL.
## Commands
- Build: `pnpm run build`
- Test: `pnpm run test`
- Lint: `pnpm run lint`
## Conventions
- Use server components by default.
- Client components must have the `"use client"` directive.
- All database queries go through Prisma — never write raw SQL.
- Tests live next to source as `*.spec.ts`, not in a separate `__tests__` tree.
## Claude Code workflow
- For non-trivial features, draft a plan with the `ExitPlanMode` tool before writing code. The plan must list the files you intend to touch.
- Track multi-step work with `TaskCreate` / `TaskUpdate`. Mark each task completed as you finish it, not in batches at the end.
- For independent investigations (e.g. "is X used anywhere?"), spawn the`Explore` subagent in parallel rather than running searches sequentially in the main thread.
- Prefer dedicated tools over Bash: `Read` over `cat`, `Grep` over `grep`, `Glob` over `find`, `Edit` over `sed`.
## AGENTS.md workflow
- Read the relevant file fully before editing it; do not patch based on a partial view.
- After every meaningful change, run `pnpm run test` and address failures before moving on.
- For multi-file changes, write a short outline of the planned edits at the top of your response so the user can interrupt early if the direction is wrong.
## Boundaries
- Never modify files in `generated/` — they are produced by `prisma generate`.
- Never skip TypeScript strict mode or use `// @ts-ignore`.
- Never commit `.env*` files; use `.env.example` for documenting variables.
```
The YAML frontmatter is optional. If present, it can contain an `override` block for adapter-specific frontmatter fields. See [reference/transpilers](../reference/transpilers.md) for details on frontmatter overrides.
---
# Introduction
Source: https://docs.agloom.sh/
> What Agloom does, why it exists, and when to use it
# Introduction
## The Problem
AI coding assistants are becoming an essential part of the development workflow. Claude Code, OpenCode, Codex, KiloCode, Gemini, and others each bring unique capabilities to the table. But they also bring unique configuration formats:
- Claude Code reads `CLAUDE.md` and `.claude/`
- OpenCode reads `AGENTS.md` and `.opencode/`
- Codex reads `AGENTS.md` and `.codex/`
- KiloCode reads `AGENTS.md` and `.kilo/`
- Gemini reads `GEMINI.md` and `.gemini/`
Maintaining separate config files for each assistant is tedious and error-prone. Instructions drift apart, skills get duplicated, and there is no single source of truth for how your project should be understood by AI agents.
## The Solution
Agloom introduces a **canonical format** — a single `.agloom/` directory that holds all your instructions, skills, agent definitions, docs, and schemas. When you run `agloom transpile`, it generates the correct config files for each target assistant.
Think of it like Sass compiling to CSS, or TypeScript compiling to JavaScript. You write once, and Agloom produces the right output for each tool.
```text
AGLOOM.md --> CLAUDE.md, AGENTS.md, GEMINI.md
.agloom/
config.yml (project configuration)
skills/ --> .claude/skills/, .opencode/skills/, ...
agents/ --> .claude/agents/, .opencode/agents/, ...
docs/ --> .claude/docs/, .opencode/docs/, ...
mcp.yml --> .mcp.json, opencode.json (mcp section)
permissions.yml --> .claude/settings.json, opencode.json (permissions)
```
## Core Principles
**Single source of truth.** One `.agloom/` directory, multiple outputs. Edit your instructions in one place and let Agloom keep everything in sync.
**Adapter-driven.** Each target tool is supported by an adapter. Adapters know how to transform canonical files into the format their tool expects. Agloom ships with adapters for Claude Code, OpenCode, Codex, KiloCode, and Gemini.
**Plugin-extensible.** Package your skills, agents, docs, and schemas into plugins and reuse them across projects. Plugins can be loaded from local directories or git repositories.
**Non-intrusive.** Agloom generates files but does not interfere with how target tools work. The generated files are standard config files that each tool reads natively.
**Project-scoped.** Agloom only reads from and writes to your project directory. It never touches global or home-directory configuration like `~/.claude/`, `~/.codex/`, or `~/.config/gemini/`. Your personal preferences and machine-wide tool settings stay completely out of scope — switching to Agloom in one project does not affect any other project or your global setup.
## Key Features
**Agent-specific blocks.** Use `` and `` HTML comments to include content that only applies to a specific agent. Shared content lives outside these blocks and reaches all agents.
**Frontmatter overrides.** YAML frontmatter in markdown files supports an `override` block where you can set agent-specific metadata, such as a model selection.
**Variable interpolation.** Reference environment variables (`${env:API_KEY}`), dir paths (`${agloom:SKILLS_DIR}`), and plugin values (`${values:name}`) anywhere in your canonical files. Values are resolved at transpile time.
**Overlays.** Place raw files in `.agloom/overlays//` for content that does not fit the canonical format — agent-specific JSON settings, TOML configs, or any file the target tool expects. Overlays support deep merge, full replacement, and patch operations.
## When to Use Agloom
Agloom is a good fit when:
- Your project uses **two or more** AI coding assistants.
- Your team wants to **standardize** instructions and conventions across agents.
- You have **reusable skills or agents** that should be shared between projects.
- You want a **plugin system** to distribute team-wide configurations.
## When NOT to Use Agloom
Agloom may not be worth the overhead when:
- Your project uses **only one** AI coding assistant, and you have no plans to add others.
- You have no need for plugins or shared configurations.
In that case, editing the tool's native config files directly is simpler.
## What's Next
- **[Getting Started](./getting-started.md)** — Install Agloom and run your first transpile in five minutes.
- **[Project Structure](./project-structure.md)** — Tour the anatomy of the `.agloom/` directory and the files it produces.
- **[Instructions](./instructions.md)** — Write canonical `AGLOOM.md` files with agent-specific blocks.
- **[Skills and Agents](./skills-and-agents.md)** — Define reusable skills and sub-agent definitions once, ship them everywhere.
- **[Variables and Interpolation](./variables.md)** — Reference environment variables, project paths, and plugin values from canonical files.
- **[Plugins](./plugins.md)** — Package and share configurations across projects.
- **[Formatting](./formatting.md)** — Format and lint Markdown, JSON, YAML, and TOML files via `agloom format`.
---
# Overlays
Source: https://docs.agloom.sh/guide/overlays
> How to use overlays for adapter-specific file customization
# Overlays
This guide teaches you how to use overlays to add adapter-specific files that do not fit the canonical format.
## What Are Overlays
Overlays are raw files placed in `.agloom/overlays//`. After transpilation, these files are copied to the project root, preserving their relative path within the overlay directory.
Overlays run **after** all transpiler steps (instructions, skills, agents, docs, schemas). If an overlay file has the same path as a transpiled file, the overlay takes precedence.
## When to Use Overlays
Use overlays for adapter-specific configuration files that Agloom does not generate through its canonical format:
- Claude Code settings (`settings.json`)
- Claude Code only slash commands
- MCP configuration overlays
- OpenCode configuration files
- Any tool-specific config that needs to be in a specific format
## Example
To add a Claude Code `settings.json`, create the overlay file:
```text
.agloom/overlays/claude/.claude/settings.json
```
```json
{
"permissions": {
"allow": ["Bash(npm run *)"],
"deny": ["Bash(rm -rf *)"]
}
}
```
When you run `agloom transpile`, this file is copied to `.claude/settings.json` in your project root.
Another example — a Claude Code slash command:
```text
.agloom/overlays/claude/.claude/commands/deploy.md
```
This copies to `.claude/commands/deploy.md` after transpilation.
## File Merge Strategies
When an overlay file targets a path that already has content from a previous layer (e.g., a plugin), the merge strategy depends on the file format:
**Deep merge** applies to structured file formats:
- `.json`, `.jsonc`
- `.yaml`, `.yml`
- `.toml`
For these formats, Agloom performs a deep merge — objects are merged recursively, and arrays are replaced.
**Full replacement** applies to everything else (`.md`, `.txt`, images, etc.). The overlay file completely replaces the existing file.
## Suffix Modifiers
Two special suffixes let you control the merge behavior:
### `.override` — Force Replacement
Add `.override` before the file extension to force full replacement, even for merge-eligible formats:
```text
.agloom/overlays/claude/.claude/settings.override.json
```
This replaces the entire `settings.json` instead of deep-merging it.
### `.patch` — Patch Operations
Add `.patch` before the file extension to apply fine-grained modifications:
```text
.agloom/overlays/claude/.claude/settings.patch.json
```
Patch files contain declarative operations that modify specific parts of the target file:
```json
{
"permissions": {
"allow": {
"$append": ["Bash(docker *)"]
}
}
}
```
This appends `"Bash(docker *)"` to the `permissions.allow` array without replacing the entire file or array.
Available patch operations: `$set`, `$merge`, `$append`, `$prepend`, `$remove`, `$unset`, `$mergeBy`, `$insertAt`.
See [reference/patch-operations](../reference/patch-operations.md) for the full list of operations with examples.
## Interpolation in Overlays
Overlay files with certain extensions (`.md`, `.txt`, `.json`, `.jsonc`, `.jsonl`, `.xml`, `.html`, `.svg`, `.toml`, `.yml`, `.yaml`) go through variable interpolation before being written. You can use `${agloom:VAR}`, `${env:VAR}`, and `${values:VAR}` in these files.
Binary files and files with other extensions are copied as-is.
See [Variables](variables.md) for more on interpolation.
---
# Plugins
Source: https://docs.agloom.sh/guide/plugins
> How to use and create plugins for sharing configurations
# Plugins
This guide teaches you how to use existing plugins and create your own.
## What Are Plugins
Plugins are reusable packages of skills, agents, docs, schemas, instructions, and overlays. They let you share AI agent configurations across projects.
A plugin is a directory containing a `plugin.yml` manifest and an `.agloom/`-like structure. Plugins can be loaded from local paths or git repositories.
## Using a Plugin
Add plugins to the `plugins` section of your `.agloom/config.yml`.
### From a Git Repository
Use a git URL (SSH or HTTPS):
```yaml title=".agloom/config.yml"
adapters:
- claude
plugins:
- git@github.com:user/my-plugin
- https://github.com/user/another-plugin
```
You can pin a specific ref (branch, tag, or commit) and point to a subdirectory within the repo:
```yaml title=".agloom/config.yml"
plugins:
- git@github.com:user/my-plugin#v1.0.0
- git@github.com:user/monorepo#main//packages/agloom-plugin
```
The `#ref` suffix specifies the git ref. The `//path` suffix specifies a subdirectory within the repository.
### From a Local Path
Use a relative path:
```yaml title=".agloom/config.yml"
plugins:
- ../shared-plugin
```
### Object Form
For more control, use the object form:
```yaml title=".agloom/config.yml"
plugins:
- git: git@github.com:user/my-plugin
ref: v1.0.0
path: subdir
values:
team_name: "platform"
api_token: "${env:API_TOKEN}"
- path: ../local-plugin
values:
feature_flag: "true"
```
The object form lets you specify `ref`, `path`, and `values` (see below).
## Plugin Values
Plugins can declare variables that consumers must (or may) provide. Values are passed through the `values` field in the plugin entry.
For example, if a plugin declares a `team_name` variable:
```yaml title="plugin.yml"
variables:
team_name:
description: "Team name for commit messages"
required: true
```
You provide the value in your config:
```yaml title=".agloom/config.yml"
plugins:
- git: git@github.com:user/team-plugin
values:
team_name: "platform"
```
Values can reference environment variables using `${env:VAR}`:
```yaml title=".agloom/config.yml"
plugins:
- git: git@github.com:user/team-plugin
values:
team_name: "platform"
api_token: "${env:TEAM_API_TOKEN}"
```
Sensitive variables (declared with `sensitive: true` in the plugin manifest) **must** use `${env:VAR}` — inline values are rejected to prevent accidental commits of secrets.
See [Variables](variables.md) for more on how interpolation works.
## Creating a Plugin
Step 1: Create a directory with a `plugin.yml` manifest:
```yaml title="my-plugin/plugin.yml"
name: my-plugin
version: 1.0.0
description: "Shared coding conventions for our team"
author:
name: "Jane Doe"
email: "jane@example.com"
```
Step 2: Add content using the same structure as `.agloom/`:
```title="my-plugin structure"
my-plugin/
├── plugin.yml
├── skills/
│ └── code-review/
│ └── SKILL.md
├── agents/
│ └── reviewer.md
└── overlays/
└── claude/
└── .claude/
└── settings.json
```
Step 3: Optionally declare variables:
```yaml title="my-plugin/plugin.yml"
name: my-plugin
version: 1.0.0
description: "Shared coding conventions"
author:
name: "Jane Doe"
variables:
team_name:
description: "Team name"
required: true
slack_channel:
description: "Slack channel for notifications"
default: "#engineering"
```
See [reference/plugin-manifest](../reference/plugin-manifest.md) for the full manifest format.
## Plugin Caching
Git plugins are cached locally in `~/.agloom/cache/plugins/`. On subsequent transpile runs, Agloom uses the cached version instead of cloning again.
To force a fresh clone:
```bash
agloom transpile --refresh
```
To clear the entire cache:
```bash
agloom cache clean
```
## How Plugins Merge
Plugins go through the same transpilation pipeline as your local `.agloom/` content. Their instructions, skills, agents, docs, schemas, and overlays are merged into the final output.
The merge order follows the plugin declaration order in `config.yml`. Plugins listed first have lower priority — later plugins and the local project can override earlier ones. The local project always has the highest priority.
---
# Project Structure
Source: https://docs.agloom.sh/guide/project-structure
> Anatomy of the .agloom/ directory and generated output files
# Project Structure
This guide explains the layout of the `.agloom/` directory and how it maps to generated output files.
## Canonical Directory
The `.agloom/` directory is the single source of truth for your project's AI agent configuration. Here is the full structure:
```text
.agloom/
├── agents/ # Sub-agent definitions
│ └── reviewer.md
├── commands/ # Slash-command definitions
│ ├── deploy.md
│ └── git/
│ └── commit.md
├── docs/ # Documentation files for agents
├── schemas/ # JSON/OpenAPI schemas for other files
├── skills/ # Reusable skill definitions
│ └── my-skill/
│ ├── SKILL.md
│ └── helpers.ts
├── config.yml # Project configuration (adapters, plugins, variables)
├── mcp.yml # MCP server configuration
├── permissions.yml # Agent permissions
├── overlays/ # Per-adapter overrides
│ ├── claude/
│ └── opencode/
└── AGLOOM.md # Instructions for AI agents
```
### What Each Part Does
**`config.yml`** — project configuration. Lists which adapters to use, which plugins to load, and project-level variables.
**`AGLOOM.md`** — top-level `AGLOOM.md` file, the canonical instructions file. This is where you write project conventions, stack descriptions, and coding guidelines that AI agents should follow.
**`skills/`** — reusable action definitions. Each skill is a directory containing a `SKILL.md` file and any supporting files. Skills are copied to each agent's skill directory during transpilation.
**`agents/`** — sub-agent definitions. Each agent is a single `.md` file with YAML frontmatter describing the agent's role, model, and tools.
**`commands/`** — slash-command definitions. Each command is a single `.md` file with YAML frontmatter and a Markdown body. Commands may be organized into subdirectories (e.g., `commands/git/commit.md`). During transpilation, commands are transformed and written to each agent's commands directory. See [Skills and Agents](skills-and-agents.md) for details on creating commands.
**`docs/`** — documentation files that agents can reference. Copied to each agent's docs directory.
**`schemas/`** — JSON or OpenAPI schema files. Copied to each agent's schemas directory.
**`mcp.yml`** — MCP (Model Context Protocol) server configuration. Transpiled into agent-specific formats (`.mcp.json` for Claude, `opencode.json` for OpenCode). See [reference/transpilers](../reference/transpilers.md) for details.
**`permissions.yml`** — agent permissions configuration. Transpiled into agent-specific formats. See [reference/transpilers](../reference/transpilers.md) for details.
**`overlays/`** — per-agent override files. Files placed here are copied directly to the project root after transpilation. Use overlays for agent-specific config that does not fit the canonical format. See [Overlays](overlays.md) for details.
## Generated Files
Each adapter generates different output files. Here is what you get:
| Adapter | Generated files |
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `claude` | `CLAUDE.md`, `.claude/agents/`, `.claude/commands/`, `.claude/docs/`, `.claude/schemas/`, `.claude/skills/`, `.claude/settings.json`, `.mcp.json` |
| `codex` | `AGENTS.md`, `.agents/skills/`, `.codex/agents/`, `.codex/docs/`, `.codex/schemas/`, |
| `gemini` | `GEMINI.md`, `.gemini/agents/`, `.gemini/commands/`, `.gemini/docs/`, `.gemini/schemas/`, `.gemini/skills/` |
| `opencode` | `AGENTS.md`, `.opencode/agents/`, `.opencode/commands/`, `.opencode/docs/`, `.opencode/schemas/`, `.opencode/skills/`, `opencode.json` |
| `kilocode` | `AGENTS.md`, `.kilo/agents/`, `.kilo/commands/`, `.kilo/docs/`, `.kilo/schemas/`, `.kilo/skills/`, `kilo.json` |
| `agentsmd` | `AGENTS.md` (generated automatically as a dependency) |
Note that `agentsmd` is a hidden adapter — you do not configure it directly. It is included automatically when you use `opencode`, `kilocode`, or `codex` (which depend on it for `AGENTS.md` generation).
## Important Rule
**Never edit generated files directly.** Always edit the canonical files in `.agloom/` and run `agloom transpile`. Generated files are overwritten on every transpile run.
## .gitignore
It is recommended to **commit** the `.agloom/` directory to version control and **add generated files** to `.gitignore`:
```gitignore
# Agloom (local instructions)
AGLOOM.override.md
# AGENTS.md generated
AGENTS.md
AGENTS.override.md
!.agloom/**/AGENTS
# Claude Code generated
.claude/
.mcp.json
CLAUDE.md
!.agloom/**/.claude
!.agloom/**/.mcp.json
!.agloom/**/CALUDE.md
# Codex generated
.agents/
.codex/
!.agloom/**/.agents
!.agloom/**/.codex
# Gemini generated
.gemini/
GEMINI.md
!.agloom/**/.gemini
!.agloom/**/GEMINI.md
# OpenCode generated
.opencode/
opencode.json
opencode.jsonс
!.agloom/**/.opencode
!.agloom/**/opencode.json
!.agloom/**/opencode.jsonс
# KiloCode generated
.kilo/
kilo.json
kilo.jsonc
!.agloom/**/.kilo
!.agloom/**/kilo.json
!.agloom/**/kilo.jsonc
```
This way, your team shares the canonical source and each developer generates output locally.
---
# Skills and Agents
Source: https://docs.agloom.sh/guide/skills-and-agents
> How to create reusable skills and sub-agent definitions
# Skills and Agents
This guide teaches you how to create skills (reusable actions) and agents (sub-agent definitions) in Agloom.
## What Are Skills
Skills are reusable action definitions stored in `.agloom/skills/`. Each skill is a directory containing a `SKILL.md` file and any number of supporting files (helpers, templates, data).
During transpilation, skill directories are copied to each adapter's skill directory (e.g., `.claude/skills/`, `.opencode/skills/`).
## Creating a Skill
Step 1: Create a skill directory:
```bash
mkdir -p .agloom/skills/code-review
```
Step 2: Create the `SKILL.md` file with YAML frontmatter and a Markdown body:
```markdown
---
name: code-review
description: Reviews code changes for quality and conventions
---
# Code Review
Review the provided code changes for:
1. Correctness — does the code do what it claims?
2. Style — does it follow project conventions?
3. Tests — are new features covered by tests?
4. Security — are there any obvious vulnerabilities?
Provide feedback as a numbered list of findings.
```
Markdown files inside a skill package (`SKILL.md` and any supporting
`.md` files) support variable interpolation, agent-specific blocks, and a
frontmatter `override` block for per-adapter customization.
Step 3: Optionally add supporting files:
```text
.agloom/skills/code-review/
├── SKILL.md
├── checklist.md
└── examples/
└── good-review.md
```
All files in the skill directory are copied to the output.
Step 4: Run `agloom transpile`. The skill appears in each adapter's directory:
```text
.claude/skills/code-review/SKILL.md
.claude/skills/code-review/checklist.md
.claude/skills/code-review/examples/good-review.md
.opencode/skills/code-review/SKILL.md
...
```
## What Are Agents
Agents are sub-agent definitions stored in `.agloom/agents/`. Each agent is a single `.md` file with YAML frontmatter describing the agent's role, model, and available tools.
During transpilation, agent files are transformed (frontmatter overrides are applied, agent-specific blocks are filtered) and written to each adapter's agents directory.
## Creating an Agent
Step 1: Create an agent file at `.agloom/agents/reviewer.md`:
```markdown
---
name: code-reviewer
description: Reviews code for best practices
model: sonnet
tools:
- Read
- Grep
- Glob
override:
opencode:
model: anthropic/claude-sonnet-4-5
temperature: 0.1
---
You are a code reviewer. Analyze the provided code and report issues related
to correctness, performance, and maintainability.
Focus on actionable feedback. Do not nitpick style issues that a linter
would catch.
```
The `override` block lets you customize frontmatter fields per adapter. In this example, when transpiling for OpenCode, the `model` field is replaced with `anthropic/claude-sonnet-4-5` and `temperature: 0.1` is added. The `override` key itself is removed from the output.
Step 2: Run `agloom transpile`. The agent file appears in each adapter's directory:
```text
.claude/agents/reviewer.md
.opencode/agents/reviewer.md
```
Each output file has adapter-specific frontmatter applied.
## What Are Commands
Commands are slash-command definitions stored in `.agloom/commands/`. Each command is a single `.md` file with YAML frontmatter and a Markdown body. Unlike skills (which are directories), a command is a single file.
Commands may be organized into subdirectories. For example, you can group git-related commands under `commands/git/`.
## Creating a Command
Step 1: Create a command file at `.agloom/commands/deploy.md`:
```markdown
---
description: Deploy to production
---
Deploy the current branch to production environment.
Verify all tests pass before deploying.
```
The frontmatter fields are passed through to each adapter. Agloom does not validate or interpret command-specific fields like `description` — the target agent defines what fields are meaningful.
Step 2: Run `agloom transpile`. The command appears in each adapter's commands directory:
```text
.claude/commands/deploy.md
.gemini/commands/deploy.toml
.kilo/commands/deploy.md
.opencode/commands/deploy.md
```
Note that Gemini receives a `.toml` file (converted automatically) and Codex receives a skill package in `.agents/skills/deploy/SKILL.md` (since Codex does not support commands natively).
### Commands in Subdirectories
You can organize commands into subdirectories:
```text
.agloom/commands/
├── deploy.md
└── git/
├── commit.md
└── push.md
```
Some adapters **preserve** the subdirectory structure (Claude, Gemini), while others **flatten** it (OpenCode, KiloCode, Codex):
- Preserve: `.agloom/commands/git/commit.md` becomes `.claude/commands/git/commit.md`
- Flatten: `.agloom/commands/git/commit.md` becomes `.opencode/commands/commit.md`
When flattening, if two commands from different subdirectories have the same filename, transpilation fails with a name conflict error.
### Frontmatter Override
Like agents, commands support per-adapter frontmatter overrides:
```markdown
---
description: Deploy to production
override:
gemini:
description: Deploy the app to production
claude:
argument-hint: "[environment]"
---
Deploy the current branch.
```
The `override` block merges adapter-specific fields into the frontmatter for each target. The `override` key itself is removed from the output. See [reference/transpilers](../reference/transpilers.md) for details on the commands transpiler.
### Agent-Specific Sections
The body may contain agent-specific sections, just like agent definitions:
```markdown
---
description: Deploy to production
---
Deploy the current branch to production.
Use the Bash tool to run deployment scripts.
Use !{deploy.sh} to deploy.
```
Content outside sections appears in all outputs. Matching sections are unwrapped; non-matching sections are removed.
## Adapter Support
Not all adapters support skills, agents, and commands:
| Adapter | Skills | Agents | Commands |
| ---------- | ------ | ------ | --------------- |
| `claude` | Yes | Yes | Yes |
| `codex` | Yes | Yes | Yes (as skills) |
| `gemini` | Yes | Yes | Yes (TOML) |
| `opencode` | Yes | Yes | Yes |
| `kilocode` | Yes | Yes | Yes |
| `agentsmd` | No | No | No |
The `agentsmd` adapter only handles instruction files (`AGENTS.md`). It does not have its own skills, agents, or commands directories. The `codex` adapter converts commands into skill packages (`.agents/skills//SKILL.md`) since Codex does not support commands natively. The `gemini` adapter converts commands from Markdown to TOML format.
## Example
Here is a realistic skill and agent working together.
**Skill** — `.agloom/skills/spec-review/SKILL.md`:
```markdown
---
name: spec-review
description: Review a specification document for completeness
---
# Spec Review
Given a specification document, check for:
1. All operations have defined inputs and outputs.
2. Error cases are documented with specific error messages.
3. No ambiguous language (look for "TBD", "TODO", "FIXME").
4. Cross-references to other specs are valid.
Output a checklist with pass/fail for each criterion.
```
**Agent** — `.agloom/agents/spec-reviewer.md`:
```markdown
---
name: spec-reviewer
description: Reviews specification documents
model: sonnet
tools:
- Read
- Glob
- Grep
---
You are a specification reviewer. Use the spec-review skill to analyze
documents in the `docs/specs/` directory.
Read each spec file, apply the review checklist, and produce a summary report.
```
---
# Variables and Interpolation
Source: https://docs.agloom.sh/guide/variables
> How to use variables and interpolation in canonical files
# Variables and Interpolation
This guide teaches you how to use variables for dynamic content in your canonical files.
## What Is Interpolation
Interpolation is the substitution of variable references with their values during transpilation. When Agloom encounters a pattern like `${agloom:VAR}` in your files, it replaces it with the actual value before writing the output.
## Variable Namespaces
Agloom supports three variable namespaces:
### `${agloom:VAR}` — Agloom Variables
These are adapter-dependent path variables. They resolve to different values depending on which adapter is being transpiled.
**Dynamic variables** resolve to directories of the adapter currently
being transpiled:
| Variable | Example (Claude) |
| -------------- | ------------------ |
| `SKILLS_DIR` | `.claude/skills` |
| `AGENTS_DIR` | `.claude/agents` |
| `COMMANDS_DIR` | `.claude/commands` |
| `DOCS_DIR` | `.claude/docs` |
| `SCHEMAS_DIR` | `.claude/schemas` |
Each adapter owns a different set of directories, so a dynamic variable
is only available when the current adapter defines it. For instance,
`${agloom:COMMANDS_DIR}` is undefined when transpiling for Codex,
because Codex has no project-level commands directory. Referencing an
undefined variable fails transpilation.
**Canonical variables** (fixed, do not change per adapter):
| Variable | Value |
| -------------------- | ----------------------------- |
| `PROJECT_DIR` | Absolute path to project root |
| `AGLOOM_DIR` | `.agloom` |
| `AGLOOM_SKILLS_DIR` | `.agloom/skills` |
| `AGLOOM_AGENTS_DIR` | `.agloom/agents` |
| `AGLOOM_DOCS_DIR` | `.agloom/docs` |
| `AGLOOM_SCHEMAS_DIR` | `.agloom/schemas` |
`PROJECT_DIR` is the only canonical variable that contains an absolute
path. All other canonical variables contain paths relative to the
project root. You can compose absolute paths by concatenating
`${agloom:PROJECT_DIR}` with any relative variable, for example
`${agloom:PROJECT_DIR}/${agloom:AGLOOM_DIR}` expands to
`/.agloom`.
**Per-adapter variables** address another adapter's directories
regardless of which adapter is currently being transpiled. Their names
follow the pattern `{ADAPTER}__DIR`, where `{ADAPTER}` is the
uppercased adapter id:
```markdown
${agloom:CLAUDE_SKILLS_DIR} → .claude/skills
${agloom:OPENCODE_AGENTS_DIR} → .opencode/agents
${agloom:GEMINI_COMMANDS_DIR} → .gemini/commands
```
Each adapter generates the prefixed variables only for the directories
it owns. Two exceptions are worth remembering: `CODEX_COMMANDS_DIR` does
not exist (Codex has no commands directory), and the `agentsmd` adapter
generates no per-adapter variables at all because it owns no directory
of its own — it only emits an `AGENTS.md` file. For the complete list
of paths per adapter, see [reference/adapters](../reference/adapters.md).
Example usage in an agent file:
```markdown
Read the protocol at `${agloom:DOCS_DIR}/protocol.md`.
Skills are located at `${agloom:SKILLS_DIR}/`.
```
When transpiling for Claude, this becomes:
```markdown
Read the protocol at `.claude/docs/protocol.md`.
Skills are located at `.claude/skills/`.
```
### `${env:VAR}` — Environment Variables
Reference environment variables from `process.env`:
```markdown
Project: ${env:PROJECT_NAME}
API endpoint: ${env:API_URL}
```
Agloom automatically loads a `.env` file from your project root (if it exists) before transpilation. Variables defined in `process.env` take precedence over `.env` values.
If the referenced variable is not defined, transpilation fails with an error.
### `${values:VAR}` — Plugin and Project Values
Reference resolved values from plugins or project variables:
```markdown
Team: ${values:team_name}
Base URL: ${values:base_url}
```
These values come from two sources:
1. **Plugin values** — resolved from plugin variable declarations and the
`values` field in your config (see [Plugins](plugins.md)).
2. **Project variables** — resolved from the `variables` section of
`config.yml` (see below).
Each plugin receives only its own resolved values — plugins cannot access each other's values.
## Project Variables
Declare project-level variables in the `variables` section of `config.yml`:
```yaml title=".agloom/config.yml"
adapters:
- claude
variables:
project_name: "${env:PROJECT_NAME}"
team:
description: "Team name"
default: "platform"
api_key:
description: "API key for external service"
default: "${env:API_KEY}"
sensitive: true
required: true
```
### Shorthand Form
A string value is shorthand for `{ default: "" }`:
```yaml
variables:
project_name: "${env:PROJECT_NAME}"
```
This is equivalent to:
```yaml
variables:
project_name:
default: "${env:PROJECT_NAME}"
```
### Full Form
The full form supports these fields:
- `description` — human-readable description (optional in config, required in
plugin manifests).
- `default` — default value. Can contain `${env:VAR}` references.
- `required` — if `true`, the variable must have a value (from default or
environment). Defaults to `false`.
- `sensitive` — if `true`, the value must reference an environment variable
(`${env:VAR}`). Inline values are rejected. Defaults to `false`.
## .env File
Agloom loads a `.env` file from the project root before transpilation. This file follows the standard `dotenv` format:
```bash title=".env"
PROJECT_NAME=my-app
API_KEY=secret-key-123
```
Variables from `.env` are available through `${env:VAR}` in instructions, skills, agents, overlays, and variable defaults.
If `.env` does not exist, Agloom silently continues without it.
## Where Interpolation Applies
Interpolation runs in the following contexts:
- **Instructions** — `AGLOOM.md` files (`.md`)
- **Skills** — `.md` files within skill directories
- **Agents** — `.md` agent definition files
- **Docs** — `.md` files in the docs directory
- **Schemas** — `.md` files in the schemas directory
- **Overlays** — files with interpolatable extensions: `.md`, `.txt`, `.json`,
`.jsonc`, `.jsonl`, `.xml`, `.html`, `.svg`, `.toml`, `.yml`, `.yaml`
Binary files and non-interpolatable extensions are always copied as-is.
## Escaping
To include a literal `${agloom:VAR}` in your output (without interpolation), prefix with a backslash:
```markdown
Use \${agloom:SKILLS_DIR} to reference the skills directory.
```
This outputs the literal text `${agloom:SKILLS_DIR}`.
## Example
Here is an end-to-end example: declaring a variable in config, using it in a skill, and seeing the result after transpile.
**Step 1:** Declare the variable in `config.yml`:
```yaml title=".agloom/config.yml"
adapters:
- claude
variables:
team_name: "platform"
```
**Step 2:** Use it in a skill:
```markdown title=".agloom/skills/deploy/SKILL.md"
---
name: deploy
description: Deploy the application
---
# Deploy
Deploy the application for the ${values:team_name} team.
Artifacts are stored in `${agloom:DOCS_DIR}/deployments/`.
```
**Step 3:** Run `agloom transpile`. The output in `.claude/skills/deploy/SKILL.md`:
```markdown title=".claude/skills/deploy/SKILL.md"
---
name: deploy
description: Deploy the application
---
# Deploy
Deploy the application for the platform team.
Artifacts are stored in `.claude/docs/deployments/`.
```
The `${values:team_name}` was replaced with `"platform"` and `${agloom:DOCS_DIR}` was replaced with `.claude/docs`.
---
# Adapters
Source: https://docs.agloom.sh/reference/adapters
> Reference for all available adapters, capabilities, and dependencies
# Adapters
Adapters define how Agloom transpiles canonical configurations into agent-specific files. Each adapter targets a specific AI coding assistant.
## Adapter Table
| ID | Description | Output Files | Hidden |
| ---------- | ------------------------------------------ | --------------------------------- | ------ |
| `claude` | Claude Code | `CLAUDE.md`, `.mcp.json` | No |
| `opencode` | OpenCode | `opencode.json` | No |
| `agentsmd` | AGENTS.md (Codex, OpenCode, KiloCode, ...) | `AGENTS.md`, `AGENTS.override.md` | Yes |
| `kilocode` | KiloCode | _(none)_ | No |
| `codex` | Codex (OpenAI) | _(none)_ | No |
| `gemini` | Gemini (Google) | `GEMINI.md` | No |
## Per-Adapter Details
### claude
- **Instructions file:** `CLAUDE.md`
- **Dependencies:** None
- **Output paths:**
| Type | Path |
| -------- | ------------------ |
| Skills | `.claude/skills` |
| Agents | `.claude/agents` |
| Commands | `.claude/commands` |
| Docs | `.claude/docs` |
| Schemas | `.claude/schemas` |
- **Target files:** `CLAUDE.md`, `.mcp.json`
- **Overlay import paths:** `.claude`, `**/CLAUDE.md`, `.mcp.json`
### opencode
- **Instructions file:** None (uses `AGENTS.md` via `agentsmd` dependency)
- **Dependencies:** `agentsmd`
- **Output paths:**
| Type | Path |
| -------- | -------------------- |
| Skills | `.opencode/skills` |
| Agents | `.opencode/agents` |
| Commands | `.opencode/commands` |
| Docs | `.opencode/docs` |
| Schemas | `.opencode/schemas` |
- **Target files:** `opencode.json`
- **Overlay import paths:** `.opencode`, `opencode.json`
OpenCode does not have its own instruction file format. The `AGENTS.md` file is generated by the `agentsmd` adapter, which is automatically included as a dependency.
### agentsmd
- **Instructions file:** `AGENTS.md`
- **Dependencies:** None
- **Output paths:** _(none — empty paths object)_
- **Target files:** `AGENTS.md`, `AGENTS.override.md`
- **Overlay import paths:** `.agents`, `**/AGENTS.md`, `**/AGENTS.override.md`
- **Hidden:** Yes — cannot be specified in config or via `--adapter`. Included only as a dependency of other adapters or when using `--all`.
The `agentsmd` adapter produces the `AGENTS.md` format used by multiple AI coding assistants (OpenCode, KiloCode, Codex, and others).
### kilocode
- **Instructions file:** None (uses `AGENTS.md` via `agentsmd` dependency)
- **Dependencies:** `agentsmd`
- **Output paths:**
| Type | Path |
| -------- | ---------------- |
| Skills | `.kilo/skills` |
| Agents | `.kilo/agents` |
| Commands | `.kilo/commands` |
| Docs | `.kilo/docs` |
| Schemas | `.kilo/schemas` |
- **Target files:** _(none)_
- **Overlay import paths:** `.kilo`
### codex
- **Instructions file:** None (uses `AGENTS.md` via `agentsmd` dependency)
- **Dependencies:** `agentsmd`
- **Output paths:**
| Type | Path |
| ------ | ---------------- |
| Skills | `.agents/skills` |
| Agents | `.codex/agents` |
Note: Codex places skills in `.agents/skills/` (not `.codex/skills/`).
- **Target files:** _(none)_
- **Overlay import paths:** `.codex`, `.agents`
### gemini
- **Instructions file:** `GEMINI.md`
- **Dependencies:** None
- **Output paths:**
| Type | Path |
| -------- | ------------------ |
| Skills | `.gemini/skills` |
| Agents | `.gemini/agents` |
| Commands | `.gemini/commands` |
| Docs | `.gemini/docs` |
| Schemas | `.gemini/schemas` |
- **Target files:** `GEMINI.md`
- **Overlay import paths:** `.gemini`, `**/GEMINI.md`
## Capability Matrix
| Feature | claude | opencode | agentsmd | kilocode | codex | gemini |
| ------------ | ------ | -------- | -------- | -------- | --------------- | ---------- |
| Instructions | Yes | No-op | Yes | No-op | No-op | Yes |
| Commands | Yes | Yes | No | Yes | Yes (as skills) | Yes (TOML) |
| Skills | Yes | Yes | No | Yes | Yes | Yes |
| Agents | Yes | Yes | No | Yes | Yes | Yes |
| Docs | Yes | Yes | No | Yes | Yes | Yes |
| Schemas | Yes | Yes | No | Yes | Yes | Yes |
| MCP | Yes | Yes | No | No | No | No |
| Permissions | Yes | Yes | No | No | No | No |
| Overlays | Yes | Yes | Yes | Yes | Yes | Yes |
Adapters marked "No-op" for Instructions return an empty array — their instruction files are generated by a dependency adapter (typically `agentsmd`).
Adapters marked "No" for Skills/Agents have an empty `paths` object and do not produce skill or agent directories.
For Commands: Codex converts commands into skill packages at `.agents/skills/`. Gemini converts commands from Markdown to TOML format. See [Transpilers](transpilers.md) for full details on the commands transpiler.
## Dependencies
Dependencies are resolved automatically. When you specify an adapter (via config or `--adapter`), its dependencies are included before it in topological order.
| Adapter | Depends On |
| ---------- | ---------- |
| `claude` | _(none)_ |
| `opencode` | `agentsmd` |
| `agentsmd` | _(none)_ |
| `kilocode` | `agentsmd` |
| `codex` | `agentsmd` |
| `gemini` | _(none)_ |
**Example:** Specifying `opencode` in config results in the transpilation order: `agentsmd` then `opencode`.
## Hidden Adapters
Hidden adapters have `hidden: true` and:
- Cannot be specified in `.agloom/config.yml`.
- Cannot be used with `--adapter`.
- Do not appear in `agloom adapters` output.
- Are included only via `dependsOn` of another adapter, or when using `--all`.
Currently, `agentsmd` is the only hidden adapter.
---
# CLI Commands
Source: https://docs.agloom.sh/reference/cli
> Complete reference for all Agloom CLI commands, options, and exit codes
# CLI Commands
Agloom provides a command-line interface built on React + Ink for transpiling canonical configurations into agent-specific files.
## Global Options
### --help
```text
agloom --help
```
Displays the general help message with a list of available commands and global options. Calling `agloom` without any command also displays this help.
Exit code: `0`.
### --version
```text
agloom --version
```
Displays the version of the installed Agloom package (read from `package.json`).
Also available as `agloom version`.
Exit code: `0`.
### Unknown Command
If an unknown command is provided, Agloom displays:
```text
Unknown command: . Run 'agloom --help' to see available commands.
```
Exit code: `1`.
The `--help` flag does **not** suppress this error. Unknown command detection takes priority over global `--help`.
## Commands
### transpile
Runs the transpilation pipeline for all registered transpiler modules.
```text
agloom transpile [--adapter | --all] [--clean] [--verbose] [--refresh]
```
#### Options
| Option | Type | Default | Description |
| ----------------------- | ------- | ------- | -------------------------------------------------------------------------------- |
| `--adapter ` | string | - | Adapter ID from the registry. Mutually exclusive with `--all`. |
| `--all` | boolean | `false` | Transpile for all adapters in the registry. Mutually exclusive with `--adapter`. |
| `--clean` | boolean | `false` | Run clean before transpiling (see [clean](#clean)). |
| `--verbose` | boolean | `false` | Show all steps including those with 0 files. |
| `--refresh` | boolean | `false` | Force re-fetch of cached git plugins. |
When neither `--adapter` nor `--all` is specified, adapters are read from `.agloom/config.yml`.
#### Adapter Resolution
- `--adapter `: resolves the specified adapter and its dependencies (topological order).
- `--all`: uses all adapters from the registry in definition order.
- Neither: loads adapters from `config.yml`, resolves dependencies, deduplicates.
Dependencies are resolved automatically. For example, `--adapter opencode` also transpiles the `agentsmd` adapter first (since `opencode.dependsOn = ["agentsmd"]`).
#### Pipeline
For each resolved adapter entry, the command executes transpiler steps in order:
1. Instructions
2. Skills
3. Agents
4. Docs
5. Schemas
6. Overlay step (MCP + Permissions)
#### Verbose Filtering
Without `--verbose`, steps with 0 written files and no errors are hidden. If all steps for all adapters are hidden and there are no errors, the output is:
```text
Nothing to transpile.
```
#### --clean Behavior
When `--clean` is provided, the clean procedure runs before transpilation for each adapter entry. With `--adapter`, the clean result is displayed before transpilation output. With `--all` or config mode, clean results are not displayed.
#### Examples
```sh
# Transpile using config
agloom transpile
# Transpile for a specific adapter
agloom transpile --adapter claude
# Transpile for all adapters with verbose output
agloom transpile --all --verbose
# Clean then transpile
agloom transpile --clean
```
#### Exit Codes
| Code | Condition |
| ---- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `0` | All steps completed without errors. |
| `1` | Any step had errors, both `--adapter` and `--all` specified, config not found (without `--adapter`/`--all`), config error, unknown/hidden adapter. |
---
### clean
Removes generated agent-specific files.
```text
agloom clean [--adapter | --all] [--verbose]
```
#### Options
| Option | Type | Default | Description |
| ----------------------- | ------- | ------- | -------------------------------------------------------------- |
| `--adapter ` | string | - | Adapter ID from the registry. Mutually exclusive with `--all`. |
| `--all` | boolean | `false` | Clean for all adapters. Mutually exclusive with `--adapter`. |
| `--verbose` | boolean | `false` | Show details even when 0 files removed. |
#### Behavior
For each resolved adapter, the clean procedure:
1. Recursively removes directories listed in `entry.paths` (skills, agents, docs, schemas).
2. Deletes files listed in `entry.targetFiles`.
Missing files and directories are silently skipped.
#### Output
Without `--verbose`, adapters with 0 removed files and no errors are hidden. If all adapters have 0 removed files:
```text
Nothing to clean.
```
#### Examples
```sh
agloom clean --adapter claude
agloom clean --all
agloom clean --verbose
```
#### Exit Codes
| Code | Condition |
| ---- | ------------------------------------------------------------------------------------------------------------------ |
| `0` | All clean operations completed without errors. |
| `1` | Both `--adapter` and `--all` specified, config not found, config error, unknown/hidden adapter, or deletion error. |
---
### init
Imports existing agent-specific files into `.agloom/overlays/` and creates the configuration file.
```text
agloom init [--adapter | --all] [--force] [--verbose]
```
#### Options
| Option | Type | Default | Description |
| ----------------------- | ------- | ------- | ----------------------------------------------------------------------- |
| `--adapter ` | string | - | Adapter identifier. Mutually exclusive with `--all`. |
| `--all` | boolean | `false` | Initialize all supported adapters. Mutually exclusive with `--adapter`. |
| `--force` | boolean | `false` | Overwrite existing files. |
| `--verbose` | boolean | `false` | Show all steps including 0-file ones. |
#### Behavior
1. Resolves adapters (same rules as `transpile`).
2. Checks if `.agloom/` directory exists (error without `--force`).
3. Creates `.agloom/config.yml` when `--adapter` or `--all` is specified.
4. For each adapter, copies files from `entry.overlayImportPaths` into `.agloom/overlays//`.
The generated `config.yml` includes onboarding comments:
```yaml
# Agloom configuration
# List of adapters to use by default when no --adapter or --all flag is provided.
# Run 'agloom adapters --all' to see all available adapters.
adapters:
- claude
```
#### Examples
```sh
agloom init --adapter claude
agloom init --all
agloom init --adapter opencode --force
```
#### Exit Codes
| Code | Condition |
| ---- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `0` | All steps completed without errors (including 0 files). |
| `1` | Both `--adapter` and `--all` specified, config not found (without flags), `.agloom/` already exists without `--force`, overlay directory exists without `--force`, copy or directory creation error. |
---
### adapters
Lists available or active adapters.
```text
agloom adapters [--all]
```
#### Options
| Option | Type | Default | Description |
| ------- | ------- | ------- | ---------------------------------------------------------------------------- |
| `--all` | boolean | `false` | Show all available (non-hidden) adapters instead of active ones from config. |
#### Behavior
- Without `--all`: loads config and shows active adapters. If no config exists, falls back to showing all non-hidden adapters.
- With `--all`: shows all non-hidden adapters from the registry.
Hidden adapters (e.g., `agentsmd`) are never displayed.
#### Output
```text
Active adapters:
claude Claude Code
opencode OpenCode
```
Exit code: `0`.
---
### format
Formats and lints project files (Markdown, JSON, YAML, TOML).
```text
agloom format [--check] [--all] [...]
```
#### Options
| Option | Type | Default | Description |
| ----------------- | -------- | ------- | -------------------------------------------------------------------------------------------------------------------------- |
| `--check` | boolean | `false` | Check files without modifying. Exit code 1 if unformatted. |
| `--all` | boolean | `false` | Format all supported files in the project (`**/*.{md,mdx,json,yaml,yml,toml}`). Mutually exclusive with `...`. |
| `...` | string[] | - | Custom glob patterns or file paths. Mutually exclusive with `--all`. |
#### Default Target Files
When neither `--all` nor file arguments are provided:
- `.agloom/**/*.{md,mdx,json,yaml,yml,toml}`
- `**/AGLOOM.md`
#### Supported Formats
| Extension | prettier | markdownlint |
| --------------- | -------- | ------------ |
| `.md`, `.mdx` | Yes | Yes |
| `.json` | Yes | No |
| `.yaml`, `.yml` | Yes | No |
| `.toml` | Yes | No |
Unsupported extensions are silently skipped.
#### Configuration Priority
1. Built-in defaults (bundled in `@agloom/markdown-tools`).
2. Native config files (`.prettierrc.*`, `.markdownlint.*` in project root).
3. `prettier` and `markdownlint` sections in `.agloom/config.yml` (shallow merge on top).
#### Excluded Directories
Glob expansion always excludes: `node_modules`, `.git`, `dist`, `build`, `coverage`, `.next`, `.turbo`, `.cache`, and paths matching `.gitignore`.
#### Examples
```sh
# Format default files
agloom format
# Check without modifying
agloom format --check
# Format all supported files
agloom format --all
# Format specific files
agloom format "src/**/*.md" ".agloom/**/*.yaml"
```
#### Exit Codes
| Code | Condition |
| ---- | ----------------------------------------------------------------------------------------------------------- |
| `0` | Format completed without errors, or all files pass check. |
| `1` | Format errors, files need formatting (check mode), config parse error, or `--all` used with file arguments. |
---
### help
Shows help topics or displays a specific help topic rendered from Markdown.
```text
agloom help []
```
#### Arguments
| Argument | Type | Description |
| --------- | ------ | -------------------------------------------------------------------------------------------------------------- |
| `` | string | Topic name. Full format: `guide/getting-started`, `reference/cli`. Short format (slug only): `cli`, `plugins`. |
#### Behavior
Without ``: displays a categorized list of all available help topics (Guide and Reference).
With ``: resolves the topic name, reads the corresponding Markdown file from `docs/guide/` or `docs/reference/`, strips frontmatter, and renders to the terminal using `marked` + `marked-terminal`.
Short topic names (without category prefix) are searched across all categories. If the slug is ambiguous (exists in multiple categories), an error lists matching topics.
#### Exit Codes
| Code | Condition |
| ---- | ------------------------------------------------------------------ |
| `0` | Topic list displayed or topic rendered successfully. |
| `1` | Topic not found, ambiguous topic, read error, no topics available. |
---
### cache clean
Clears the plugin cache directory.
```text
agloom cache clean
```
Git plugins are cached in `~/.agloom/cache/plugins/`. This command removes all cached plugins, forcing re-fetch on the next `transpile`.
Exit code: `0`.
---
# Configuration File
Source: https://docs.agloom.sh/reference/config
> Complete reference for .agloom/config.yml format, fields, and validation
# Configuration File
The file `.agloom/config.yml` is the project-level configuration for Agloom. It defines which adapters to use by default and optionally configures plugins, variables, and formatting tools.
## File Location
```text
/.agloom/config.yml
```
The file is loaded by the commands `transpile`, `clean`, `init`, and `adapters` when neither `--adapter` nor `--all` is specified.
## Schema
### adapters
- **Type:** `array`
- **Required:** Yes
- **Constraints:** Must not be empty. Each element must be a known, non-hidden adapter ID from the registry.
List of adapter identifiers to use by default.
```yaml
adapters:
- claude
- opencode
```
Hidden adapters (e.g., `agentsmd`) cannot be specified in `adapters`. They are included automatically when a dependent adapter (e.g., `opencode`) is resolved.
### plugins
- **Type:** `array`
- **Required:** No
List of plugins to load. Each entry can be:
**String form (git shorthand):**
```yaml
plugins:
- git@github.com:user/plugin
- https://github.com/user/plugin
```
**Object form (local plugin):**
```yaml
plugins:
- path: ../my-local-plugin
```
**Object form (git plugin with options):**
```yaml
plugins:
- git: git@github.com:user/plugin
ref: v1.0.0
path: packages/my-plugin
values:
team_name: platform
api_token: "${env:API_TOKEN}"
```
| Field | Type | Description |
| -------- | ------ | ---------------------------------------------------------------------------- |
| `git` | string | Git URL (SSH or HTTPS). |
| `path` | string | Local path (for local plugins) or subpath within git repo (for git plugins). |
| `ref` | string | Git ref (tag, branch, commit SHA). Optional for git plugins. |
| `values` | object | Key-value pairs passed to the plugin. All values must be strings. |
### variables
- **Type:** `object`
- **Required:** No
Declares project-level variables accessible via `${values:NAME}` interpolation.
**Shorthand form** (string value treated as default):
```yaml
variables:
project_name: "${env:PROJECT_NAME}"
```
**Full form:**
```yaml
variables:
team:
description: "Team name"
default: "platform"
api_key:
description: "API key"
default: "${env:API_KEY}"
sensitive: true
required: true
```
Each variable declaration supports:
| Field | Type | Default | Description |
| ------------- | ------- | ------- | ----------------------------------------------------------------------------------- |
| `description` | string | `""` | Description of the variable. Optional in config (required in plugin manifests). |
| `required` | boolean | `false` | If `true`, variable must have a resolved value. |
| `default` | string | - | Default value. May contain `${env:VAR}` for environment variable substitution. |
| `sensitive` | boolean | `false` | If `true`, the value must reference an environment variable (cannot be set inline). |
### prettier
- **Type:** `object`
- **Required:** No
Prettier configuration overrides. Values are passed to prettier as-is and shallow-merged on top of native config files and built-in defaults.
```yaml
prettier:
proseWrap: always
tabWidth: 4
```
### markdownlint
- **Type:** `object`
- **Required:** No
Markdownlint configuration overrides. Values are passed to markdownlint as-is.
```yaml
markdownlint:
MD013:
line_length: 80
```
## Validation Rules
The following conditions produce errors during config loading:
| Condition | Error Message |
| ------------------------------------------- | ----------------------------------------------------------------- |
| `adapters` field missing | `Invalid config: 'adapters' field is required.` |
| `adapters` is not an array of strings | `Invalid config: 'adapters' must be an array of strings.` |
| `adapters` is empty | `Invalid config: 'adapters' must not be empty.` |
| Unknown adapter ID | `Invalid config: unknown adapter ''.` |
| Hidden adapter specified | `Invalid config: adapter '' cannot be specified in config.` |
| `variables` is not an object | `Invalid config: 'variables' must be an object.` |
| Variable value is neither string nor object | `Invalid config: variable '' must be a string or an object.` |
| Plugin `values` is not an object | `Invalid config: plugin 'values' must be an object.` |
| Plugin `values` entry is not a string | `Invalid config: plugin 'values' entry '' must be a string.` |
## Complete Example
```yaml
# Agloom configuration
adapters:
- claude
- opencode
plugins:
- git@github.com:cusxy/skill-cycling
- git: git@github.com:cusxy/shared-agents
ref: v2.0.0
values:
team_name: "platform"
api_token: "${env:CYCLING_API_TOKEN}"
- path: ../local-plugin
variables:
project_name: "${env:PROJECT_NAME}"
team:
description: "Team name"
default: "platform"
api_key:
description: "API key"
default: "${env:API_KEY}"
sensitive: true
prettier:
proseWrap: always
markdownlint:
MD013:
line_length: 80
```
---
# Interpolation
Source: https://docs.agloom.sh/reference/interpolation
> Complete reference for variable interpolation syntax, namespaces, and resolution
# Interpolation
Agloom supports variable interpolation in canonical files during transpilation. Variables are substituted with adapter-specific paths, environment values, or plugin/project values.
## Syntax
```text
${type:key}
```
- `type` — the variable namespace (`agloom`, `env`, or `values`).
- `key` — the variable name. One or more characters not containing `}`.
### Escaping
Prefix with a backslash to produce the literal text:
```text
\${agloom:VAR} --> ${agloom:VAR}
\${env:VAR} --> ${env:VAR}
\${values:VAR} --> ${values:VAR}
```
The backslash is consumed during interpolation.
### Unrecognized Namespaces
Patterns with namespaces other than `agloom`, `env`, or `values` (e.g., `${foo:bar}`) are preserved as literal text without processing.
## Variable Namespaces
### agloom
Adapter-dependent variables built by `buildVariables()`. Divided into three groups:
#### Canonical (fixed) Variables
Values are fixed regardless of the current adapter.
| Variable | Value |
| -------------------- | --------------------------------- |
| `PROJECT_DIR` | Absolute path to the project root |
| `AGLOOM_DIR` | `.agloom` |
| `AGLOOM_SKILLS_DIR` | `.agloom/skills` |
| `AGLOOM_AGENTS_DIR` | `.agloom/agents` |
| `AGLOOM_DOCS_DIR` | `.agloom/docs` |
| `AGLOOM_SCHEMAS_DIR` | `.agloom/schemas` |
`PROJECT_DIR` is the only canonical variable containing an absolute path. All others are relative. Compose them for absolute paths: `${agloom:PROJECT_DIR}/${agloom:AGLOOM_DIR}`.
#### Dynamic (per-current-adapter) Variables
Values depend on the adapter currently being transpiled. Sourced from the adapter's `paths` field.
| Variable | Source |
| ------------- | ------------------------------ |
| `SKILLS_DIR` | `currentAdapter.paths.skills` |
| `AGENTS_DIR` | `currentAdapter.paths.agents` |
| `DOCS_DIR` | `currentAdapter.paths.docs` |
| `SCHEMAS_DIR` | `currentAdapter.paths.schemas` |
A dynamic variable is only present if the corresponding `paths` field is defined for the current adapter. For example, the `agentsmd` adapter has empty `paths`, so none of these variables exist when transpiling for `agentsmd`.
#### Static (per-all-adapters) Variables
Generated for every adapter in the registry that has at least one defined `paths` field. The prefix is the adapter ID in uppercase.
| Pattern | Source |
| ---------------------- | ----------------------- |
| `{PREFIX}_SKILLS_DIR` | `adapter.paths.skills` |
| `{PREFIX}_AGENTS_DIR` | `adapter.paths.agents` |
| `{PREFIX}_DOCS_DIR` | `adapter.paths.docs` |
| `{PREFIX}_SCHEMAS_DIR` | `adapter.paths.schemas` |
Where `{PREFIX}` = `adapter.id.toUpperCase()`.
**Example values:**
| Variable | Value |
| ---------------------- | ------------------- |
| `CLAUDE_SKILLS_DIR` | `.claude/skills` |
| `CLAUDE_AGENTS_DIR` | `.claude/agents` |
| `CLAUDE_DOCS_DIR` | `.claude/docs` |
| `CLAUDE_SCHEMAS_DIR` | `.claude/schemas` |
| `OPENCODE_SKILLS_DIR` | `.opencode/skills` |
| `OPENCODE_AGENTS_DIR` | `.opencode/agents` |
| `OPENCODE_DOCS_DIR` | `.opencode/docs` |
| `OPENCODE_SCHEMAS_DIR` | `.opencode/schemas` |
Adapters with empty `paths` (e.g., `agentsmd`) do not generate static variables.
### env
Environment variables from `process.env`.
```text
${env:HOME}
${env:PROJECT_NAME}
```
The `.env` file in the project root is automatically loaded before transpilation using `dotenv`. Variables already set in `process.env` take priority over `.env` values.
#### Error on Missing Variable
If the referenced environment variable is not defined, interpolation fails with:
```text
InterpolationError("Undefined environment variable: ")
```
### values
Plugin or project values resolved from `variables` declarations. See [config.md](config.md) for project variables and [plugin-manifest.md](plugin-manifest.md) for plugin variables.
```text
${values:team_name}
${values:api_token}
```
#### Resolution Order
**For plugin values** (priority high to low):
1. `values` from plugin entry in `config.yml` (user-provided).
2. `default` from `variables` in `plugin.yml`.
**For project variables:**
1. `default` from `variables` in `config.yml`.
Values containing `${env:VAR}` are resolved using `process.env` during the resolution step.
#### Isolation
Each plugin receives only its own resolved values. Plugin A cannot access values from Plugin B. The local project receives its own resolved local values.
#### Error on Missing Variable
```text
InterpolationError("Unknown values variable: ")
```
## Sensitive Variables
Variables declared with `sensitive: true` must not be set inline in `values`. The value must contain at least one `${env:VAR}` reference.
- `api_token: "my-secret"` — **rejected** (inline value for sensitive variable).
- `api_token: "${env:API_TOKEN}"` — **accepted**.
- `api_token: "prefix-${env:API_TOKEN}"` — **accepted** (contains `${env:`).
## Supported File Extensions
Interpolation is performed on files with the following extensions (case-insensitive comparison):
```text
.md .txt .json .jsonc .jsonl .xml .html .svg .toml .yml .yaml
```
Files with other extensions are copied byte-for-byte without interpolation.
## Where Interpolation Applies
- **Instructions transpiler:** `transformContent` applies interpolation to the full transformed content.
- **Agents transpiler:** `transformContent` applies interpolation to the full transformed content.
- **Skills transpiler:** `writeResults` applies interpolation to `.md` files only.
- **Docs transpiler:** `writeResults` applies interpolation to supported extensions.
- **Schemas transpiler:** `writeResults` applies interpolation to supported extensions.
- **Overlay step:** applies interpolation to files with supported extensions before merge/override/patch.
## Error Handling
| Condition | Error |
| ------------------------ | -------------------------------------------------------------- |
| Unknown `${agloom:NAME}` | `InterpolationError("Unknown agloom variable: ")` |
| Undefined `${env:NAME}` | `InterpolationError("Undefined environment variable: ")` |
| Unknown `${values:NAME}` | `InterpolationError("Unknown values variable: ")` |
In the instructions and agents transpilers, interpolation errors are wrapped as `TransformError` or `AgentTransformError`. In the skills transpiler, they are wrapped as `SkillWriteError`.
## Example
Canonical content:
```markdown
Skills are at `${agloom:SKILLS_DIR}`.
Claude skills: `${agloom:CLAUDE_SKILLS_DIR}`.
Project: ${env:PROJECT_NAME}
Team: ${values:team_name}
Escaped: \${env:HOME}
```
After interpolation for the `claude` adapter (with `PROJECT_NAME=myapp`, `team_name=platform`):
```markdown
Skills are at `.claude/skills`.
Claude skills: `.claude/skills`.
Project: myapp
Team: platform
Escaped: ${env:HOME}
```
After interpolation for the `opencode` adapter:
```markdown
Skills are at `.opencode/skills`.
Claude skills: `.claude/skills`.
Project: myapp
Team: platform
Escaped: ${env:HOME}
```
---
# Patch Operations
Source: https://docs.agloom.sh/reference/patch-operations
> Reference for all patch operations used in .patch overlay files
# Patch Operations
Patch operations provide fine-grained control over structured files (JSON, JSONC, YAML, TOML) in overlays. Instead of replacing a file entirely (override) or deep-merging it (overlay), a `.patch` file applies targeted modifications using declarative markers.
## File Naming Convention
Patch files use the naming pattern:
```text
.patch.
```
The `.patch` suffix is removed when determining the target file. For example, `settings.patch.yaml` applies to `settings.yaml`.
The format of the patch file may differ from the target. For example, `tsconfig.patch.yaml` can patch `tsconfig.json` — the patch is parsed as YAML, and the result is serialized as JSON.
Suffixes `.patch` and `.override` are mutually exclusive. A file with both suffixes (e.g., `settings.patch.override.json`) is an error.
## Operations
### $set
Replaces the value of a key entirely. Creates the key if it does not exist.
**Value type:** any
**Input:**
```json
{ "editor": { "fontSize": 14, "tabSize": 2 } }
```
**Patch:**
```yaml
editor:
fontSize:
$set: 16
```
**Result:**
```json
{ "editor": { "fontSize": 16, "tabSize": 2 } }
```
---
### $merge
Deep merges an object into the target. If the target does not exist, it is created as an empty object first.
**Value type:** object
**Input:**
```json
{ "editor": { "fontSize": 14, "tabSize": 2, "rulers": [80] } }
```
**Patch:**
```yaml
editor:
$merge:
fontSize: 16
tabSize: 4
```
**Result:**
```json
{ "editor": { "fontSize": 16, "tabSize": 4, "rulers": [80] } }
```
---
### $mergeBy
Merges an array of objects by a key field (similar to Kustomize strategic merge patch).
**Value type:** object with fields:
| Field | Type | Description |
| ------- | -------------- | ---------------------------------------------------- |
| `key` | string | Field name used for matching. |
| `items` | array\