# agr/agrx: Unified Resource Architecture for Skills, Rules, Commands, Subagents, and Instructions

Date: 2026-01-22

## Executive summary

agr and agrx currently ship a clean, minimal architecture focused on a single resource type (skills). The requested expansion—support rules, subagents, slash commands, and instruction files (e.g., `CLAUDE.md`)—is achievable without compromising simplicity if we standardize on a **resource model** and isolate **tool-specific behavior** behind adapters.

This proposal consolidates what we learned from external tooling docs (Claude Code, Cursor, OpenAI Codex, Copilot, OpenCode, AgentSkills/AGENTS) and maps those constraints onto a world‑class, extensible architecture that keeps agr/agrx unified while keeping future multi-tool support easy.

Key decisions:
- Treat skills, commands, subagents, rules, and instructions as first-class **resources**.
- Adopt a **Tool Adapter** interface to encapsulate paths, validation, and invocation.
- Keep **resource discovery generic** and configurable, with tool overlays.
- Unify agr and agrx via a shared install/run pipeline and install strategies.
- Expand `agr.toml` to support `kind`, `tool`, and `scope` while preserving backward compatibility.

---

## Why this matters (first principles)

1. **Resources are not “skills-only” anymore.** Every modern agent tool exposes multiple types of context and behavior: slash commands, memory/rules, subagents, and instructions. If agr models only skills, it will inevitably bake in tool-specific assumptions and stall future expansion.

2. **Tools diverge in layout and semantics.** Claude, Cursor, Codex, Copilot, and OpenCode all use different directory structures and configuration conventions. The only clean way to support multiple tools is to isolate the differences in adapters and keep core logic tool-agnostic.

3. **User expectation is “install once, work everywhere.”** The architecture should allow a resource to be installable for multiple tools (or a selected tool) without changing its internal format or forcing forks.

---

## External doc constraints (condensed)

These are the relevant constraints surfaced from reading the external docs (linked in `CLAUDE.md`), which directly influence design choices:

- **Claude Code**
  - Skills live in `.claude/skills/` and are folders containing `SKILL.md`.
  - Commands are now folded into skills; legacy `.claude/commands/*.md` still works.
  - Rules/memory live under `.claude/rules/*.md`, and `CLAUDE.md` is used for agent memory/instructions.
  - `context: fork` allows subagent execution.

- **AgentSkills spec (agentskills.io)**
  - Skills are folders with `SKILL.md` frontmatter (name + description required).
  - Supporting files live in `references/`, `scripts/`, `assets/`.

- **OpenAI Codex**
  - Skills are primary extensibility mechanism; custom prompts are deprecated.
  - Tools have multiple scopes (project/user/system), and load precedence matters.

- **GitHub Copilot**
  - Supports the same Agent Skills standard.
  - Allows `.github/skills` or `.claude/skills` for repo scope; `~/.copilot/skills` or `~/.claude/skills` for user scope.

- **Cursor**
  - Rules live in `.cursor/rules` and follow a metadata-driven format.
  - Commands live in `.cursor/commands/*.md`.
  - `AGENTS.md` and `CLAUDE.md` are used as general agent instructions.
  - Subagents exist in Cursor, but are not yet standardized in file format.

- **OpenCode**
  - Skills live in `.opencode/skills` (compatible with `.claude/skills`).
  - Commands live in `.opencode/commands/*.md`.
  - Subagents can be defined in `.opencode/agents/*.md` or `opencode.json`.

- **AGENTS.md standard**
  - `AGENTS.md` is a canonical agent instruction file that tools may read as a generic entry point.

Implication: **we must support multiple resource kinds and different tool layouts**, and avoid coupling resource discovery to a single tool or format.

---

## Proposed architecture

### 1) Resource model

Introduce a generic resource model with explicit kind and tool scoping.

**Kinds**
- `skill`
- `command`
- `rule`
- `subagent`
- `instruction`

**Resource identity**
```
ResourceID = {
  kind,
  name,
  handle (remote or local),
  tool (optional),
  scope (project|user|global, optional)
}
```

The resource itself is a discovered directory or file, plus metadata. Use a lightweight manifest (optional) to avoid forcing change to existing skills.

### 2) Tool adapters

Replace the current `ToolConfig` with an adapter protocol. Core logic becomes tool-agnostic.

```
class ToolAdapter:
    name: str
    config_dir: str
    resource_dirs: dict[ResourceKind, str]
    legacy_dirs: dict[ResourceKind, list[str]]
    def get_repo_install_dir(kind) -> Path
    def get_user_install_dir(kind) -> Path
    def validate(resource) -> None
    def prepare_run_command(resource, prompt, interactive) -> list[str]
    def supports(kind) -> bool
```

Adapters encapsulate:
- install paths
- validation rules (e.g., SKILL.md frontmatter)
- run semantics (agrx)
- legacy compatibility (e.g., `.claude/commands`)

Initially implement **ClaudeAdapter** only, but design for:
- CursorAdapter
- CodexAdapter
- CopilotAdapter
- OpenCodeAdapter

### 3) Resource discovery

Unify discovery for all kinds with a canonical layout and legacy fallbacks.

**Canonical layout**
```
resources/
  skills/<name>/...
  commands/<name>/...
  rules/<name>/...
  subagents/<name>/...
  instructions/<name>/...
```

**Legacy fallbacks**
- `skills/<name>/SKILL.md`
- `<name>/SKILL.md` (root-level skill)
- `.claude/commands/*.md` (Claude legacy commands)
- `.cursor/rules/*.md` (Cursor rules)
- `.opencode/commands/*.md` (OpenCode commands)

Discovery should select tool-specific variants when a tool is requested (e.g., `resources/skills/foo/tool/claude/`).

### 4) Install strategies (shared by agr and agrx)

Replace ad hoc install logic with a shared pipeline:

```
fetch_repo(handle) -> ResourceSet
select_resource(ResourceID) -> Resource
install_resource(Resource, tool, scope, strategy)
```

**Strategies**
- `permanent`: install into tool’s repo scope or user scope
- `temporary`: install into temp location, or prefix for cleanup

This merges agr and agrx on the same implementation path.

### 5) Run semantics (agrx)

agrx should call the tool adapter’s `prepare_run_command(...)` so each tool can define how to invoke the resource (skills, commands, subagents).

For Claude:
- Skill invocation remains `claude -p "/<skill> ..."` for now.
- Subagent invocation can be represented as skill with `context: fork`.

---

## Repository and config updates

### agr.toml schema (backward compatible)

Current config only supports `type=skill` with `handle` or `path`.

Proposed expanded schema:
```
dependencies = [
  { kind = "skill", handle = "anthropics/skills/frontend-design", tool = "claude" },
  { kind = "rule",  path = "./rules/python-style", tool = "cursor" },
  { kind = "instruction", path = "./CLAUDE.md", tool = "claude", scope = "project" }
]
```

Rules:
- `kind` defaults to `skill` when missing.
- `tool` defaults to default adapter.
- `scope` defaults to `project`.

### Instruction files

Treat `CLAUDE.md`, `AGENTS.md`, etc. as `instruction` resources.

Install logic should map:
- `CLAUDE.md` → `.claude/CLAUDE.md` (or repo root if tool expects)
- `AGENTS.md` → repo root
- Cursor’s `.cursor/rules` if using rule format

The adapter is responsible for the right target for each tool.

---

## Subagents

Subagents are still tool-dependent. We should model them as a `subagent` resource kind with a minimal standard representation (e.g., a folder containing `SUBAGENT.md` or a `SKILL.md` with `context: fork` for Claude). Tool adapters can map them to the tool’s preferred representation. This prevents coupling to Cursor’s or OpenCode’s evolving formats.

---

## Migration and compatibility

- **No breaking change**: existing `SKILL.md` skills are still discoverable with the same search paths.
- Existing `agr.toml` dependencies continue to function unchanged.
- New `kind/tool/scope` fields are optional.

---

## Implementation sketch (modules)

- `agr/resources.py`
  - `ResourceKind` enum
  - discovery functions
  - validation helpers (generic + per-kind)

- `agr/adapters/claude.py`
  - ClaudeAdapter: paths, validation, run command generation

- `agr/install.py`
  - `install_resource(Resource, tool, scope, strategy)`

- `agr/registry.py`
  - tool registry, default tool selection

- `agrx/main.py`
  - use shared install/run pipeline

- `agr/fetcher.py`
  - refactor to `fetch_repo()` + `select_resource()`

---

## Testing strategy

To keep confidence high while expanding scope:

1. **Discovery tests**
   - skills in all supported locations
   - commands/rules/instructions in canonical + legacy locations
   - tool overlay selection

2. **Adapter tests**
   - tool path resolution (repo/user/global)
   - validation errors (missing SKILL.md frontmatter)

3. **Config tests**
   - backward compatibility for old `agr.toml`
   - new schema fields and defaulting

4. **agrx integration tests**
   - temporary install + command generation
   - cleanup behavior

---

## Decisions that future‑proof multi‑tool support now

- **Resource-first core** instead of skill-first core
- **Tool adapters** for all install/run behavior
- **Canonical resource layout** plus legacy fallbacks
- **Config schema with kind/tool/scope**
- **Shared install pipeline for agr and agrx**

These choices keep the current UX intact while enabling rapid expansion to new tools with minimal code churn.

---

## Next steps (if approved)

1. Introduce `ResourceKind` and `Resource` model + discovery layer.
2. Refactor fetch/install pipeline into `fetch_repo` + `install_resource`.
3. Implement ClaudeAdapter (no behavior change, just port existing logic).
4. Update `agrx` to use shared install/run path.
5. Extend `agr.toml` parsing with defaulted fields.

This path keeps current users stable and sets the foundation for rules, commands, subagents, and instruction files without ad hoc branching.
