Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Shared tooling for coding agents. Declare skills, MCP servers, hooks, subagents,

**Shareable.** Skills are directories with a `SKILL.md`. Host them in any git repo, discover them automatically, install with one command.

**Multi-agent.** Configure Claude, Cursor, Codex, Grok, VS Code, and OpenCode from a single `agents.toml` -- skills, MCP servers, hooks, subagents, and plugins where supported. Pi reads `.agents/skills/` directly.
**Multi-agent.** Configure Claude, Cursor, Codex, GitHub Copilot CLI, Grok, VS Code, and OpenCode from a single `agents.toml` -- skills, MCP servers, hooks, subagents, and plugins where supported. Pi reads `.agents/skills/` directly.

## Quick Start: Global by Default

Expand Down Expand Up @@ -115,14 +115,15 @@ Shorthand (`owner/repo`) resolves to GitHub by default. Set `defaultRepositorySo
The `agents` field tells dotagents which tools to configure:

```toml
agents = ["claude", "cursor", "codex", "grok", "opencode", "pi"]
agents = ["claude", "cursor", "codex", "copilot", "grok", "opencode", "pi"]
```

| Agent | Config Dir | MCP Config | Hooks | Subagents |
|-------|-----------|------------|-------|-----------|
| `claude` | `.claude` | `.mcp.json` | `.claude/settings.json` | `.claude/agents/*.md` |
| `cursor` | `.cursor` | `.cursor/mcp.json` | `.cursor/hooks.json` | `.cursor/agents/*.md` |
| `codex` | `.codex` | `.codex/config.toml` | -- | `.codex/agents/*.toml` |
| `copilot` | `.copilot` | `.mcp.json` or `.github/mcp.json` | -- | -- |
| `grok` | `.grok` | -- | -- | -- |
| `vscode` | `.vscode` | `.vscode/mcp.json` | `.claude/settings.json` | -- |
| `opencode` | `.opencode` | `.opencode/opencode.jsonc` | -- | `.opencode/agents/*.md` |
Expand Down Expand Up @@ -153,19 +154,19 @@ dotagents can also import native runtime subagent files from `.claude/agents/`,

OpenCode reuses an existing project config from `.opencode/opencode.jsonc`, `.opencode/opencode.json`, `opencode.jsonc`, or `opencode.json`, in that order. New projects use `.opencode/opencode.jsonc`.

Plugins are declared with `[[plugins]]` entries. In project scope, dotagents installs canonical bundles into `.agents/plugins/<name>/` and generates runtime plugin outputs such as `.claude-plugin/marketplace.json`, `.agents/plugins/<name>/.claude-plugin/plugin.json`, `.cursor-plugin/marketplace.json`, `.agents/plugins/<name>/.cursor-plugin/plugin.json`, `.agents/plugins/marketplace.json`, `.agents/plugins/<name>/.codex-plugin/plugin.json`, `.grok/plugins/<name>/`, `.opencode/skills/<skill>/`, OpenCode MCP entries, and Pi skill links under `.agents/skills/<skill>/` where supported. During legacy migration, generalized bundles can also project Markdown agents into `.opencode/agents/`; standard extension agents are preserved but are not projected yet:
Plugins are declared with `[[plugins]]` entries. In project scope, dotagents installs canonical bundles into `.agents/plugins/<name>/` and generates runtime plugin outputs such as `.claude-plugin/marketplace.json`, `.github/plugin/marketplace.json`, `.cursor-plugin/marketplace.json`, `.agents/plugins/marketplace.json`, native Claude, Cursor, and Codex manifests, `.grok/plugins/<name>/`, `.opencode/skills/<skill>/`, OpenCode MCP entries, and Pi skill links under `.agents/skills/<skill>/`. During legacy migration, generalized bundles can also project Markdown agents into `.opencode/agents/`; standard extension agents are preserved but are not projected yet:

```toml
[[plugins]]
name = "review-tools"
source = "getsentry/agent-plugins"
path = "plugins/review-tools"
targets = ["claude", "cursor", "codex", "grok", "opencode", "pi"]
targets = ["claude", "cursor", "codex", "copilot", "grok", "opencode", "pi"]
```

The canonical portable format is an [Agent Plugins](https://agent-plugins.org/) v1 bundle: required `plugin.json`, optional `skills/`, optional `mcp.json`, and reverse-domain client extensions. dotagents preserves those portable source files under `.agents/plugins/<name>/` and generates isolated target harnesses. OpenCode receives portable MCP servers under managed keys such as `plugin.<plugin>.<server>`; `${PLUGIN_ROOT}` and `${PLUGIN_DATA}` are expanded into the installed bundle and persistent `.agents/plugin-data/` paths. Generated JSON uses adjacent ownership sidecars, while component symlinks use markers in reserved `.dotagents-managed/` directories, so client-owned JSON remains unchanged. Legacy generalized and native Claude/Cursor/Codex manifests remain discoverable during migration. A valid standard root may also coexist with authored native manifests as a hybrid compatibility bundle: the portable root remains the source of truth, reproducible native manifests are ignored in favor of portable generation, and manifests with behavior an adapter cannot represent are retained byte-for-byte only as matching-client fallbacks. Generated adapters are disposable output and are never imported back into the portable core. Native commands, agents, hooks, MCP, and other resources never leak into unrelated targets. Invalid standard roots still fail instead of falling back to legacy parsing.

Global plugins install canonical bundles under `~/.agents/plugins/`. Claude and Cursor marketplaces are generated under `~/.agents/`, the Codex marketplace is generated at `~/.agents/plugins/marketplace.json`, Grok plugins are copied into `~/.grok/plugins/`, OpenCode skills are linked into `~/.config/opencode/skills/`, portable MCP servers are merged into `~/.config/opencode/opencode.json`, and Pi skills are linked into `~/.agents/skills/`. `--user` remains a compatibility alias for `--global`.
Global plugins install canonical bundles under `~/.agents/plugins/`. Claude and Cursor marketplaces are generated under `~/.agents/`. Copilot uses `~/.agents/.github/plugin/marketplace.json`, and Codex uses `~/.agents/plugins/marketplace.json`. Grok plugins are copied into `~/.grok/plugins/`. OpenCode skills are linked into `~/.config/opencode/skills/`, and portable MCP servers are merged into `~/.config/opencode/opencode.json`. Pi skills are linked into `~/.agents/skills/`. `--user` remains a compatibility alias for `--global`.

Pi plugin targets are global skill projections rather than isolated plugin installs: a Pi-targeted plugin skill is added to `.agents/skills/` and is therefore visible to other clients that consume that shared directory.

Expand Down
22 changes: 14 additions & 8 deletions docs/public/llms.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

> Shared tooling for coding agents

dotagents manages agent skills, MCP servers, hooks, subagents, and plugins declared in `agents.toml`, and handles symlinks and config generation so tools like Claude Code, Cursor, Codex, Grok, VS Code, and OpenCode are configured from a single source of truth.
dotagents manages agent skills, MCP servers, hooks, subagents, and plugins declared in `agents.toml`, and handles symlinks and config generation so tools like Claude Code, Cursor, Codex, GitHub Copilot CLI, Grok, VS Code, and OpenCode are configured from a single source of truth.

Install: `npm install -g @sentry/dotagents`
Run without installing: `npx @sentry/dotagents <command>`
Expand Down Expand Up @@ -66,7 +66,7 @@ Full example with all sections:

```toml
version = 1
agents = ["claude", "cursor", "codex", "grok", "opencode", "pi"]
agents = ["claude", "cursor", "codex", "copilot", "grok", "opencode", "pi"]
minimum_release_age = 60
minimum_release_age_exclude = ["getsentry/*"]

Expand Down Expand Up @@ -149,7 +149,7 @@ targets = ["claude", "codex", "opencode"]
name = "review-tools"
source = "getsentry/agent-plugins"
path = "plugins/review-tools"
targets = ["claude", "cursor", "codex", "grok", "opencode", "pi"]
targets = ["claude", "cursor", "codex", "copilot", "grok", "opencode", "pi"]
```

### Top-level Fields
Expand All @@ -158,9 +158,9 @@ targets = ["claude", "cursor", "codex", "grok", "opencode", "pi"]
|-------|------|----------|---------|-------------|
| `version` | integer | Yes | -- | Schema version. Always `1`. |
| `defaultRepositorySource` | string | No | `github` | Host used for shorthand `owner/repo` skill sources. Valid values: `github`, `gitlab`. |
| `agents` | string[] | No | `[]` | Agent tool IDs: `claude`, `cursor`, `codex`, `grok`, `vscode`, `opencode`, `pi`. Creates symlinks and config files for each where supported. `grok` and `pi` are plugin-only targets. |
| `agents` | string[] | No | `[]` | Agent tool IDs: `claude`, `cursor`, `codex`, `copilot`, `grok`, `vscode`, `opencode`, `pi`. Creates symlinks and config files for each where supported. `grok` and `pi` are plugin-only targets. |
| `subagents` | table[] | No | `[]` | Custom subagent declarations. Generates runtime-specific files for Claude, Cursor, Codex, and OpenCode. |
| `plugins` | table[] | No | `[]` | Plugin declarations. Installs canonical bundles into `.agents/plugins/` and generates runtime plugin outputs for Claude, Cursor, Codex, Grok, OpenCode, and Pi skill projection where supported. |
| `plugins` | table[] | No | `[]` | Plugin declarations. Installs canonical bundles into `.agents/plugins/` and generates runtime plugin outputs for Claude, Cursor, Codex, Copilot, Grok, OpenCode, and Pi skill projection where supported. |
| `minimum_release_age` | integer | No | -- | Minimum commit age, in minutes, before a git skill, subagent, or plugin can install. |
| `minimum_release_age_exclude` | string[] | No | `[]` | Sources that bypass the minimum release age gate. Supports org names, `org/repo`, and `org/*`. |

Expand Down Expand Up @@ -211,14 +211,17 @@ Each `[[mcp]]` entry requires `name` and either `command` (stdio) or `url` (Stre
| `headers` | table | No | HTTP headers (url servers only). Supports `${VAR}` syntax for env var interpolation. |
| `env` | string[] | No | Environment variable names to pass through |

Use `${VAR}` in header values and `url` to reference secrets from the environment. Write `${VAR}` in `agents.toml` — dotagents translates it to each agent's native syntax when generating config files. Claude keeps `${VAR}`, Cursor and VS Code use `${env:VAR}`, OpenCode uses `{env:VAR}`, and Codex splits pure refs into a separate `env_http_headers` field (mixed values like `"Bearer ${TOKEN}"` stay as literals).
Use `${VAR}` in header values and `url` to reference secrets from the environment. Write `${VAR}` in `agents.toml`. Dotagents keeps this syntax for Claude and GitHub Copilot. Cursor and VS Code use `${env:VAR}`, OpenCode uses `{env:VAR}`, and Codex moves pure references to `env_http_headers`. Mixed Codex values such as `"Bearer ${TOKEN}"` stay as literals.

Config files generated per agent:
- Claude: `.mcp.json` (JSON)
- Cursor: `.cursor/mcp.json` (JSON)
- Codex: `.codex/config.toml` (TOML, shared with other Codex config)
- VS Code: `.vscode/mcp.json` (JSON)
- OpenCode: `.opencode/opencode.jsonc` by default (JSONC, shared). Existing `.opencode/opencode.json`, `opencode.jsonc`, or `opencode.json` files are reused in precedence order.
- GitHub Copilot: `.mcp.json` by default (JSON). An existing `.github/mcp.json` is reused when `.mcp.json` is absent.

Copilot accepts both bare server maps and `mcpServers` documents. Global MCP uses `$COPILOT_HOME/mcp-config.json` (default `~/.copilot/mcp-config.json`).

### Hooks

Expand Down Expand Up @@ -303,15 +306,16 @@ dotagents installs canonical plugin bundles under `.agents/plugins/<name>/`. New

Generated project-scope plugin outputs:
- Claude: `.claude-plugin/marketplace.json` and `.agents/plugins/<name>/.claude-plugin/plugin.json`
- GitHub Copilot: `.github/plugin/marketplace.json`; Copilot consumes the canonical `.agents/plugins/<name>/plugin.json`
- Cursor: `.cursor-plugin/marketplace.json` and `.agents/plugins/<name>/.cursor-plugin/plugin.json`
- Codex: `.agents/plugins/marketplace.json` and `.agents/plugins/<name>/.codex-plugin/plugin.json`
- Grok: `.grok/plugins/<name>/` managed copy
- OpenCode: plugin `skills/` symlinked into `.opencode/skills/`; portable `mcp.json` servers merged into `.opencode/opencode.jsonc` under `plugin.<plugin>.<server>` keys; generalized legacy plugin Markdown `agents/` symlinked into `.opencode/agents/`. Standard extension agents are preserved but not projected yet.
- Pi: plugin `skills/` symlinked into `.agents/skills/` when `pi` is a configured plugin target

Generated plugin JSON is deterministic: object keys and plugin entries are sorted, output is two-space indented, and files end with one trailing newline. Generated marketplaces and Claude/Cursor/Codex manifests use adjacent `.dotagents-managed` sidecars so client-owned JSON remains schema-native; legacy `metadata.managedBy` output remains recognizable during migration. Managed Grok copies and OpenCode/Pi component symlinks are pruned when their plugin or target is removed. Plugin sources that resolve to this project's `.agents/plugins/<name>/` install destination are rejected so dotagents never installs a same-repo plugin onto itself. Existing plugin install destinations are overwritten only when their on-disk `.dotagents-managed` marker proves ownership.
Generated plugin JSON is deterministic: object keys and plugin entries are sorted, output is two-space indented, and files end with one trailing newline. Generated marketplaces and Claude, Cursor, and Codex manifests use adjacent `.dotagents-managed` sidecars so client-owned JSON remains schema-native; legacy `metadata.managedBy` output remains recognizable during migration. Managed Grok copies and OpenCode and Pi component symlinks are pruned when their plugin or target is removed. Plugin sources that resolve to this project's `.agents/plugins/<name>/` install destination are rejected so dotagents never installs a same-repo plugin onto itself. Existing plugin install destinations are overwritten only when their on-disk `.dotagents-managed` marker proves ownership.

Global plugins install under `~/.agents/plugins/`. Claude and Cursor marketplaces are generated below `~/.agents/`, Codex uses `~/.agents/plugins/marketplace.json` with paths rooted at the user's home, Grok plugins are copied into `~/.grok/plugins/`, OpenCode skills use `~/.config/opencode/skills/`, portable plugin MCP servers are merged into `~/.config/opencode/opencode.json`, and Pi skill projections use `~/.agents/skills/`.
Global plugins install under `~/.agents/plugins/`. Claude and Cursor marketplaces are generated below `~/.agents/`. Copilot uses `~/.agents/.github/plugin/marketplace.json`. Codex uses `~/.agents/plugins/marketplace.json` with paths rooted at the user's home. Grok plugins are copied into `~/.grok/plugins/`. OpenCode skills use `~/.config/opencode/skills/`, portable plugin MCP servers use `~/.config/opencode/opencode.json`, and Pi skill projections use `~/.agents/skills/`.

### Trust

Expand Down Expand Up @@ -499,6 +503,7 @@ Check selected-scope health: gitignore setup where applicable, installed skills
| `claude` | Claude Code | `.claude` | `.claude/skills/` -> `.agents/skills/` | `.mcp.json` | `.claude/settings.json` | `.claude/agents/*.md` |
| `cursor` | Cursor | `.cursor` | `.claude/skills/` -> `.agents/skills/` | `.cursor/mcp.json` | `.cursor/hooks.json` | `.cursor/agents/*.md` |
| `codex` | Codex | `.codex` | (reads `.agents/skills/` natively) | `.codex/config.toml` | Not supported | `.codex/agents/*.toml` |
| `copilot` | GitHub Copilot CLI | `.copilot` | Project: reads `.agents/skills/`; global: `$COPILOT_HOME/skills/` symlink | `.mcp.json` or `.github/mcp.json` | Not supported | Not supported |
| `vscode` | VS Code Copilot | `.vscode` | (reads `.agents/skills/` natively) | `.vscode/mcp.json` | `.claude/settings.json` | Not supported |
| `opencode` | OpenCode | `.opencode` | (reads `.agents/skills/` natively) | `.opencode/opencode.jsonc` by default | Not supported | `.opencode/agents/*.md` |

Expand Down Expand Up @@ -609,6 +614,7 @@ Location: `~/.local/dotagents/` (override: `DOTAGENTS_STATE_DIR`)
|----------|-------------|
| `DOTAGENTS_STATE_DIR` | Override cache location (default: `~/.local/dotagents`) |
| `DOTAGENTS_HOME` | Override global-scope location (default: `~/.agents`) |
| `COPILOT_HOME` | Override Copilot's global skill and MCP location with a non-empty absolute path (default when unset: `~/.copilot`) |

## Gitignore

Expand Down
Loading
Loading