> ## Documentation Index
> Fetch the complete documentation index at: https://chatcli.edilsonfreitas.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Customizable Agents (Personas)

> Modular system to create personalities and specialized knowledge for the AI, with automatic dispatch as workers in the multi-agent system, auto-activation of skills via triggers/paths, and per-agent model selection.

ChatCLI lets you create **Customizable Agents** (also called Personas) that define specific behaviors for the AI. This system transforms ChatCLI from a tool with a static "System Prompt" into a **polymorphic platform**.

## Core Concept

The central idea is **prompt composition**:

* **Agents** define *"who"* the AI is (personality, specialization, tone).
* **Skills** define *"what"* it must know/obey (rules, knowledge, compliance).

An Agent can import multiple Skills, creating a **"Super System Prompt"** composed automatically. Both Skills and Agents support per-turn model and effort preferences, honored automatically by the dispatcher when they activate.

## Benefits

<CardGroup cols={2}>
  <Card title="Reuse" icon="recycle">
    Skills can be shared across multiple agents.
  </Card>

  <Card title="Versioning" icon="code-branch">
    `.md` files can be versioned in Git.
  </Card>

  <Card title="Collaboration" icon="people-group">
    Teams can share agents and skills.
  </Card>

  <Card title="Consistency" icon="check-double">
    Coding style rules applied automatically.
  </Card>

  <Card title="Specialization" icon="bullseye">
    Create agents for Go, Python, DevOps, etc.
  </Card>

  <Card title="Dispatch as Worker" icon="users">
    Custom agents are automatically registered in the multi-agent system and can be dispatched via `agent_call` by the LLM orchestrator.
  </Card>

  <Card title="Skill Auto-activation" icon="bolt">
    Skills with `triggers:` or `paths:` in their frontmatter are automatically injected into the system prompt when detected in the user's message.
  </Card>

  <Card title="Per-Agent Model & Effort" icon="gauge-high">
    Each skill and each agent can declare ideal `model:` and `effort:` — the dispatcher routes correctly without changing the user's active choice.
  </Card>
</CardGroup>

## Directory Structure

Files live under `~/.chatcli/`:

```text theme={"system"}
~/.chatcli/
|-- agents/            # Agent files
|   |-- go-expert.md
|   |-- devops-senior.md
|   |-- security-auditor.md
|   +-- python-data-scientist.md
+-- skills/            # Skill files (.md or V2 directories)
    |-- clean-code/    # Skill V2 (package with subskills + scripts)
    |   |-- SKILL.md
    |   |-- naming-rules.md
    |   +-- scripts/
    |       +-- lint_check.py
    |-- error-handling.md  # Skill V1 (single file)
    |-- docker-master.md
    +-- clean-scripts.md
```

## Agent File Format

Agents are Markdown files with YAML frontmatter:

```yaml theme={"system"}
---
name: "devops-senior"
description: "Senior DevOps focused on CI/CD and infrastructure"
tools: Read, Grep, Glob, Bash, Write, Edit   # Tools this agent can use as worker
skills:                    # Skills to import
  - clean-code
  - bash-linux
  - architecture
plugins:                   # Enabled plugins (optional)
  - "@coder"

# LLM preferences (optional) — applied when this agent runs as a worker
model: "claude-opus-4-6"   # Ideal model; transparent swap if user is on another
effort: "high"             # low | medium | high | max

# Optional metadata
category: "devops"
version: "2.1.0"
author: "Edilson Freitas"
tags: devops, cicd, k8s
---
# Base Personality

You are a Senior DevOps Engineer, expert in CI/CD, containers,
infrastructure as code, and observability.
```

### `tools` Field — Multi-Agent Integration

The `tools` field in the YAML frontmatter is the key to integration with the [multi-agent orchestration](/features/multi-agent-orchestration) system. It defines which commands the agent can use when dispatched as a **worker** by the LLM orchestrator.

| Tool in YAML | @coder Command(s)                                                                | Description                                                |
| ------------ | -------------------------------------------------------------------------------- | ---------------------------------------------------------- |
| `Read`       | `read`                                                                           | Read file contents                                         |
| `Grep`       | `search`                                                                         | Search patterns in files                                   |
| `Glob`       | `tree`                                                                           | List directories                                           |
| `Bash`       | `exec`, `test`, `git-status`, `git-diff`, `git-log`, `git-changed`, `git-branch` | Command execution and git operations                       |
| `Write`      | `write`                                                                          | Create/overwrite files                                     |
| `Edit`       | `patch`                                                                          | Precise edits (search/replace)                             |
| `MultiEdit`  | `multipatch`                                                                     | Transactional multi-file edit with all-or-nothing rollback |

<Warning>
  Agents **without** a `tools` field automatically receive `read`, `search`, `tree` and are marked as **read-only**. Agents with `Write`, `Edit`, `MultiEdit`, or `Bash` have **write/execution access**. The 12 built-in agent names (`file`, `coder`, `shell`, `git`, `search`, `planner`, `reviewer`, `tester`, `refactor`, `diagnostics`, `formatter`, `deps`) are **protected** and cannot be overridden.
</Warning>

### Example without `tools`

```yaml theme={"system"}
---
name: "go-expert"
description: "Go/Golang expert focused on clean code"
skills:
  - clean-code
  - error-handling
plugins:
  - "@coder"
---
# Base Personality

You are a Senior Software Engineer, expert in Go/Golang.

## Core Principles

1. **Simplicity**: Prefer simple, readable code.
2. **Composition**: Use small interfaces and composition over inheritance.
3. **Errors**: Handle errors explicitly, never ignore.
4. **Tests**: Write table-driven tests.
```

<Info>This agent will be registered as **read-only** in the multi-agent system (only `read`, `search`, `tree`).</Info>

***

## Advanced Agent Frontmatter

Recent releases bring full parity between agents and skills for LLM preference fields. Both are **optional** and **backwards compatible** — agents without these fields keep working exactly as before.

| Field      | Type         | Default | Description                                                                                                                                                                                                   |
| :--------- | :----------- | :------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `model`    | string       | —       | Preferred model when this agent runs as a worker. If the user is on a different model/provider, the dispatcher attempts a transparent swap (same provider → catalog → family; cross-provider when available). |
| `effort`   | string       | —       | Effort level: `low`, `medium`, `high`, `max`. Maps to *extended thinking* (Anthropic) / *reasoning\_effort* (OpenAI) on supported providers.                                                                  |
| `category` | string       | —       | Category for organization (e.g., `devops`, `security`, `review`).                                                                                                                                             |
| `version`  | string       | —       | Agent version (SemVer recommended).                                                                                                                                                                           |
| `author`   | string       | —       | Agent author.                                                                                                                                                                                                 |
| `tags`     | list\|string | —       | Tags for search and classification. Accepts YAML list or comma-separated string.                                                                                                                              |

### How the Dispatcher Applies Model/Effort

When the orchestrator LLM dispatches an agent via `<agent_call>`, the dispatcher:

<Steps>
  <Step title="Reads `agent.Model()` and `agent.Effort()`">
    For custom agents these come from the frontmatter. For built-ins they come from `BuiltinAgentMeta` (defaults + env var override).
  </Step>

  <Step title="If `Model()` is non-empty, runs the Model Router">
    The resolver tries, in order: API cache of the active provider → static catalog → family heuristic (`claude-*`, `gpt-*`, `gemini-*`, etc.) → optimistic fallback on the user's provider. If the target provider is not configured (no API key), it gracefully falls back to the user's client and logs a clear warning.
  </Step>

  <Step title="If `Effort()` is non-empty, attaches to the worker `ctx`">
    Providers read the hint via `client.EffortFromContext(ctx)` inside `SendPrompt` and inject `thinking.budget_tokens` (Anthropic) or `reasoning.effort` / `reasoning_effort` (OpenAI) into the request body — only on models that support it.
  </Step>

  <Step title="`cli.Client`, `cli.Provider` and `cli.Model` are **not** mutated">
    Swaps are worker-turn scoped. When the worker finishes, the next agent dispatch or chat turn uses the user's original choice.
  </Step>
</Steps>

### Example: Custom Agent with Ideal Model

```yaml theme={"system"}
---
name: "my-strict-reviewer"
description: "Critical reviewer focused on subtle bugs and design issues"
tools: Read, Grep, Glob
skills:
  - go-testing
  - golangci
model: "claude-opus-4-6"   # always runs in Opus, even if user is on Sonnet
effort: "high"             # enables extended thinking
category: "review"
version: "1.0.0"
author: "Edilson Freitas"
---
# Personality

You are an extremely strict reviewer. Focus on subtle bugs, design issues,
SOLID violations, and high-cyclomatic-complexity hotspots. Avoid nit-picky
formatting comments.
```

<Tip>
  If the user has `CLAUDEAI` configured but is on `claude-sonnet-4-6`, this agent runs in `claude-opus-4-6` automatically. If the user is on `OPENAI` with `gpt-5` and does **not** have `ANTHROPIC_API_KEY`, the dispatcher falls back gracefully to the user's model and prints a clear notice explaining why.
</Tip>

***

## Skill File Format

Skills contain pure knowledge or compliance rules:

```yaml theme={"system"}
---
name: "clean-code"
description: "Clean Code principles and best practices"
---
# Clean Code Rules

## Naming

1. **Meaningful names**: Variables and functions must reveal their purpose.
2. **Avoid misinformation**: Do not use names that may confuse.
3. **Pronounceable names**: Use names that can be discussed verbally.

## Functions

1. **Small**: Functions should do one thing only.
2. **Few arguments**: Ideally 0–2 arguments, max 3.
3. **No side effects**: Functions should do only what they promise.
```

## Skills V2 — Packages with Subskills and Scripts

Beyond V1 skills (single `.md` file), ChatCLI supports **V2 Skills**: directories with multiple documents and executable scripts.

### V2 Skill Structure

```text theme={"system"}
skills/
+-- clean-code/
    |-- SKILL.md            # Main content (frontmatter + body)
    |-- naming-rules.md     # Subskill: naming rules
    |-- formatting.md       # Subskill: formatting rules
    +-- scripts/
        +-- lint_check.py   # Executable script
```

### Subskills

`.md` files inside the skill directory (except `SKILL.md`) are registered as **subskills**. When the agent is dispatched as a worker, subskill paths appear in the worker's system prompt, which can `read` them as needed.

### Scripts

Files in `scripts/` are registered as **executable skills** on the worker. The system automatically infers the run command from the extension:

| Extension | Inferred Command              |
| --------- | ----------------------------- |
| `.sh`     | `bash script.sh`              |
| `.py`     | `python3 script.py`           |
| `.js`     | `node script.js`              |
| `.ts`     | `npx ts-node script.ts`       |
| `.rb`     | `ruby script.rb`              |
| Others    | `./script` (direct execution) |

Scripts run via the `@coder` `exec` command and their results return to the worker.

***

## Advanced Skill Frontmatter

Beyond the basic fields (`name`, `description`, `allowed-tools`), skills support advanced frontmatter for fine-grained behavior control. **All advanced fields are optional and backwards compatible** — existing skills keep working unchanged.

```yaml theme={"system"}
---
name: "go-testing"
description: "Go testing patterns and best practices"
allowed-tools: Read, Grep, Glob, Bash

# LLM preferences (propagated to the turn that activates the skill)
model: "sonnet"                        # Preferred model
effort: "high"                         # Effort level: low, medium, high, max

# Metadata
category: "testing"
version: "1.2.0"
author: "Edilson Freitas"
tags: testing, go, unit-tests, tdd

# Automatic activation
triggers: test, testing, tdd, unittest # Keywords that auto-activate
paths: ["*_test.go", "test/**"]        # Globs that auto-activate per-file

# Invocation control
user-invocable: true                   # Can be invoked via /skill-name
disable-model-invocation: false        # If true, manual-only
argument-hint: "<package>"             # Hint shown in autocomplete
---

## Go Testing Patterns
...
```

### Automatic Activation: `triggers`

Keywords that activate the skill automatically when detected in the user message. Case-insensitive, with two tiers:

1. **Contiguous substring** (fast path) — the whole trigger appears as-is: `servicenow login` fires on *"do the ServiceNow login"*.
2. **All words, any order** — multi-word triggers also fire when **every word appears as a whole token** in the text, regardless of order: `servicenow login` also fires on *"preciso fazer o login no servicenow"*. Whole tokens only — short words never match inside other words (`message me` does **not** fire on *"user message"*), and punctuation tokenizes on both sides (`unit-tests` ≈ `unit tests`).

```yaml theme={"system"}
triggers: test, testing, tdd
```

If the user types *"how do I write **tests** for this handler?"*, the skill is automatically injected into the turn's system prompt — together with the descriptive and full content of the skill. The LLM then follows the instructions automatically.

Implemented in `pkg/persona/manager.go#FindTriggeredSkills`. Detection runs on every chat turn and, in agent/coder mode, at the start of the run **and again on every turn of the ReAct loop** (see [Mid-task re-activation](#mid-task-re-activation-agentcoder)).

### Automatic Activation: `paths`

File globs that activate the skill when matching files are being discussed. Supports `*`, `**` (recursive doublestar), and `?`.

```yaml theme={"system"}
paths: ["*_test.go", "test/**", "src/**/*.ts"]
```

ChatCLI extracts file-path-looking tokens from the user input (`@file path/...`, `@path/to/file.go`, or bare tokens like `pkg/foo/bar_test.go` and `main.go`) and matches each against the `paths:` patterns of every installed skill.

Examples that trigger `*_test.go`:

* `"run the tests in pkg/foo/bar_test.go"`
* `"@file pkg/foo/bar_test.go"`
* `"@pkg/foo/bar_test.go"`

Implemented in `pkg/persona/types.go#MatchesPath` (with a custom doublestar matcher, zero external deps) and `pkg/persona/manager.go#FindPathMatchedSkills`. Path extraction from input is in `cli/skill_activation.go#extractFilePaths`.

<Tip>
  When the same skill matches via both `triggers` and `paths`, it is injected only once (deduplicated by name).
</Tip>

### Mid-task re-activation (agent/coder)

In agent/coder mode, activation is not limited to the initial query. On **every turn of the ReAct loop**, ChatCLI re-scans for skills that haven't fired yet, matching against:

* the model's **own reasoning** and the file paths inside its `tool_call` args — if the agent decides mid-task to *"write a Helm chart for this"*, or starts touching files matching a skill's `paths:` globs, the skill activates in time to shape the very next action;
* **follow-up instructions** you type mid-session (the type-ahead queue or the coder continuation prompt).

Newly matched skills are injected as an append-only `[SKILL AUTO-ACTIVATION — MID-TASK]` message at the next turn boundary, so the cached system-prompt prefix is never invalidated mid-run. Each skill fires at most **once per run** (deduplicated against startup injection), and the dedup set survives `@park`/resume. Mid-task `model:`/`effort:` hints are honored only when no startup skill already claimed them.

Disable with `CHATCLI_AGENT_SKILL_RESCAN=false` (on by default; listed in `/config` under skills).

### `model` and `effort` Propagation

When a skill auto-activates (via `triggers` or `paths`), is pinned (`/skill pin`), or is manually invoked, its `model:` and `effort:` are propagated to the current turn:

* **`model:`** — the dispatcher/resolver swaps the LLM client for this turn. Works within the same provider (e.g., `sonnet` → `opus` on Claude) or cross-provider (e.g., user on Claude, skill wants `gpt-5` on OpenAI). If the target provider is not configured, it falls back to the user's client with a visible notice.
* **`effort:`** — mapped to `thinking.budget_tokens` (Anthropic, Opus 4.x / Sonnet 4.x / 3.7 models) or `reasoning_effort` / `reasoning.effort` (OpenAI, o1/o3/o4/gpt-5 models). Unsupported models silently ignore.

**Precedence when multiple modes fire in the same turn:**

```
manual /<skill-name>  >  /skill pin  >  auto-activation (triggers/paths)
```

The first non-empty `model:` in this order wins; subsequent conflicts are logged as warnings but don't force additional swaps.

### Manual Invocation via `/<skill-name>`

Skills with `user-invocable: true` are available as direct slash commands:

```bash theme={"system"}
/go-testing generate tests for Handler{}
```

ChatCLI intercepts `/<skill-name>` ahead of the default router, validates that the skill exists with `user-invocable: true`, loads its content, displays the `argument-hint` (when args are empty), and fires the turn with the skill injected as a "# Manually Invoked Skill" block in the system prompt — taking precedence over auto-activated skills.

The protected command list (`/agent`, `/coder`, `/run`, `/switch`, `/help`, `/skill`, etc.) can **never** be shadowed by a skill — even a skill named `agent` won't shadow the built-in command.

Slash command autocomplete also includes all `user-invocable: true` skills, showing `description` and `argument-hint` side by side.

### Invocation Control

| Field                      | Type   | Default | Description                                                                                               |
| :------------------------- | :----- | :------ | :-------------------------------------------------------------------------------------------------------- |
| `user-invocable`           | bool   | `false` | Enables invocation via `/skill-name`                                                                      |
| `disable-model-invocation` | bool   | `false` | Blocks automatic activation via triggers/paths (user can still invoke manually if `user-invocable: true`) |
| `argument-hint`            | string | —       | Text shown in autocomplete and as a hint when invoked without args                                        |

<Info>
  `disable-model-invocation: true` together with `user-invocable: true` = the skill **only** runs when the user types `/skill-name`, never through automatic detection. Useful for destructive or highly specific skills.
</Info>

### Pin a Skill for the Session (`/skill pin`)

When you need a skill to apply to **every** turn of the session — not only those that match `triggers:`/`paths:` — pin it:

```bash theme={"system"}
/skill pin go-testing      # Pin
/skill pinned              # List pinned
/skill unpin go-testing    # Unpin
```

Pin is a session-scoped intent (doesn't persist across runs) and lives in its own `# Pinned Skills` block in the system prompt, cacheable via `cache_control: ephemeral`. On hint conflicts, pinned beats auto-activation but loses to a manual `/<skill-name>` invocation.

Skills with `disable-model-invocation: true` **cannot** be pinned — the flag exists precisely to forbid automatic injection. Use manual `/<skill-name>` for those.

Full details, examples, and the precedence table: [Pin Skills in Skill Registry](/features/skill-registry#pin-skills-for-the-session).

***

## `/agent` Without Context

Before: typing `/agent` alone entered agent mode immediately and sent an empty message to the LLM.

Now: typing `/agent` (or `/run`) without an inline task prints the persona handler help plus a usage hint and does **not** start the ReAct loop. Same applies to `/coder`. This avoids token burn on empty messages and makes the UX more predictable.

```bash theme={"system"}
/agent
# 📋 persona handler help + examples
# 💡 Usage: /agent <task>  (e.g., /agent investigate 500 error)
```

To enter agent mode with context, pass the task inline:

```bash theme={"system"}
/agent refactor the auth module
```

***

## Skills from Remote Registries

Besides creating skills manually, you can **search and install** skills from remote registries via the `/skill` command:

```bash theme={"system"}
# Search kubernetes skills
/skill search kubernetes

# Install a skill
/skill install k8s-ops

# Verify it shows up in the available skills
/agent skills
```

<Info>
  Skills installed via registry are saved in `~/.chatcli/skills/<name>/SKILL.md` as V2 packages and are immediately available for agents. ChatCLI supports multiple registries simultaneously (ChatCLI.dev, ClawHub, corporate registries) with fan-out parallel search. See [Skill Registry](/features/skill-registry) for full details.
</Info>

***

## Dispatch as Worker (Multi-Agent)

When starting `/coder` or `/agent`, **all custom agents** are automatically registered in the [multi-agent orchestration](/features/multi-agent-orchestration) system. The LLM orchestrator can then dispatch them via `<agent_call>`:

```xml theme={"system"}
<agent_call agent="devops-senior" task="Configure CI/CD pipeline with GitHub Actions" />
<agent_call agent="my-strict-reviewer" task="Audit the authentication module for OWASP" />
```

### What the worker gets

When dispatched, CustomAgent runs with:

<Steps>
  <Step title="Personalized system prompt">
    Includes agent content (markdown body), loaded skills, subskill paths, script commands, and tool\_call instructions.
  </Step>

  <Step title="Mini ReAct loop">
    The same ReAct loop as built-in agents, with reasoning, action, and observation.
  </Step>

  <Step title="Permitted commands">
    Based on the `tools` field of the frontmatter.
  </Step>

  <Step title="Per-turn resolved client">
    If the agent declares `model:`, the dispatcher calls `ResolveModelRouting` to obtain the correct client before each mini-ReAct turn.
  </Step>

  <Step title="Effort applied to ctx">
    If the agent declares `effort:`, the worker's ctx receives `WithEffortHint`, read by the provider inside `SendPrompt`.
  </Step>

  <Step title="Parallel reads">
    Read-only tool calls run in parallel goroutines.
  </Step>

  <Step title="File locks">
    Writes use per-filepath mutex for anti-race safety.
  </Step>

  <Step title="Error recovery">
    The orchestrator can use direct `tool_call` to diagnose and fix failures.
  </Step>
</Steps>

### End-to-End Example

```bash theme={"system"}
# 1. Create the agent in ~/.chatcli/agents/devops-senior.md (with model/effort)
# 2. Start coder mode
/coder configure the deployment pipeline and monitoring

# The LLM orchestrator can dispatch:
# <agent_call agent="devops-senior" task="Set up CI/CD with GitHub Actions" />
# <agent_call agent="file" task="Read current Dockerfile and docker-compose.yml" />
#
# Both run in parallel with their own ReAct loops.
# devops-senior can run on opus-4-6 with effort=high while file runs on
# sonnet with effort=low — respecting each agent's preferences.
```

***

## Management Commands

All management commands are integrated under `/agent`:

| Command                | Description                                                                   |
| ---------------------- | ----------------------------------------------------------------------------- |
| `/agent`               | Shows active agent status and help (does not enter agent mode without a task) |
| `/agent list`          | Lists all available agents                                                    |
| `/agent status`        | Lists only attached agents (short) — alias: `attached`, `list-attached`       |
| `/agent load <name>`   | Loads a specific agent                                                        |
| `/agent attach <name>` | Attaches an additional agent to the session                                   |
| `/agent detach <name>` | Removes an attached agent                                                     |
| `/agent skills`        | Lists all available skills                                                    |
| `/agent show [--full]` | Shows the active agent with example prompts (use `--full` for everything)     |
| `/agent off`           | Deactivates all currently active agents                                       |
| `/agent <task>`        | Executes a task in agent mode                                                 |

## Prompt Assembly Order

When an agent is loaded, the system prompt is assembled in this order:

<Steps>
  <Step title="[ROLE]">
    Agent identity (name, description)
  </Step>

  <Step title="[PERSONALITY]">
    Agent base content (markdown body)
  </Step>

  <Step title="[SKILLS]">
    Imported skill knowledge (numbered)
  </Step>

  <Step title="[AUTO-LOADED SKILLS]">
    Skills auto-activated via `triggers:` or `paths:` on the current message
  </Step>

  <Step title="[MANUAL SKILL]">
    Extra block when the message was invoked via `/<skill-name>`
  </Step>

  <Step title="[PLUGINS]">
    Enabled plugin hints
  </Step>

  <Step title="[REMINDER]">
    Anchor with application instructions
  </Step>
</Steps>

This ordering ensures the AI receives context in a structured way, with explicit user intent (manual) taking precedence over auto-activation.

## Full Practical Example

### 1. Create an agent

Create the file `~/.chatcli/agents/python-data.md`:

```yaml theme={"system"}
---
name: "python-data"
description: "Python Data Scientist specialist"
skills:
  - clean-code
plugins:
  - "@coder"
model: "claude-opus-4-6"     # always runs in Opus
effort: "medium"
category: "data-science"
tags: python, ml, data
---
# Base Personality

You are a Senior Data Scientist, expert in Python.

## Preferred Tools

- Pandas for data manipulation
- NumPy for numeric computation
- Matplotlib/Seaborn for visualization
- Scikit-learn for classic ML
- PyTorch for deep learning
```

### 2. Use the agent

```bash theme={"system"}
# List agents
/agent list

# Available Agents:
#   go-expert - Go/Golang specialist [2 skills]
#   python-data - Data Scientist [1 skills]

# Load the agent
/agent load python-data

# Agent 'python-data' loaded successfully!
#    Python Data Scientist specialist
#    Attached skills:
#     - clean-code

# Use in agent mode
/agent analyze this dataset and create visualizations

# Or in coder mode
/coder build a classification ML pipeline
```

## Agent and Skill Precedence (Project > Global)

Both agents and skills support **per-project directories** with precedence over the globals. ChatCLI auto-detects the project root by looking for a `.agent/` or `.git/` directory upward from the current directory.

### Search Order

| Resource   | 1. Project (priority)  | 2. Global (fallback)     |
| ---------- | ---------------------- | ------------------------ |
| **Agents** | `./.agent/agents/*.md` | `~/.chatcli/agents/*.md` |
| **Skills** | `./.agent/skills/`     | `~/.chatcli/skills/`     |

If an agent or skill with the same name exists in both directories, the project version wins.

### Project Structure

```text theme={"system"}
my-project/
|-- .agent/                  # Marks the project root for ChatCLI
|   |-- agents/              # Project-specific agents
|   |   +-- backend.md       # Overrides ~/.chatcli/agents/backend.md
|   +-- skills/              # Project-specific skills
|       +-- team-rules.md    # Team-specific rules
|-- src/
+-- ...
```

<Tip>
  If your project already has `.git/`, ChatCLI uses that directory as the project root automatically. `.agent/` is optional — use it when you want project-local agents/skills without depending on Git.
</Tip>

## Integration with `/coder`

When an agent is loaded:

* `/agent <task>` — Uses the agent's persona.
* `/coder <task>` — Combines the agent's persona with the coder prompt.

This lets you have a Go-expert agent using `@coder` tools to edit files, run tests, etc. The agent's `model:` and `effort:` preferences are honored in both modes.

## Tips

<CardGroup cols={2}>
  <Card title="Start Simple" icon="seedling">
    Create agents with a few skills and add more as needed.
  </Card>

  <Card title="Version on Git" icon="code-branch">
    Keep your agents and skills in a repo.
  </Card>

  <Card title="Share with the Team" icon="share-nodes">
    Coding-style skills enforce consistency.
  </Card>

  <Card title="Use Clear Descriptions" icon="tag">
    Helps understand each agent/skill's purpose.
  </Card>

  <Card title="Test the Prompt" icon="flask-vial">
    Use `/agent show` to inspect the assembled prompt.
  </Card>

  <Card title="Assign `effort` Carefully" icon="gauge">
    `effort: high` costs more tokens. Reserve it for agents that truly need deep reasoning (reviewers, planners, diagnostics).
  </Card>
</CardGroup>

## Useful Skill Examples

* **clean-code** — Clean code principles
* **error-handling** — Error handling patterns
* **testing-patterns** — Automated testing patterns
* **docker-master** — Dockerfile best practices
* **clean-scripts** — Safe Bash scripting patterns
* **aws-security** — AWS security rules
* **team-conventions** — Team-specific conventions

## Remote Agents and Skills

When connected to a ChatCLI server via `chatcli connect`, the client automatically discovers agents and skills available on the server. They are transferred to the client and composed locally, allowing merge with local resources.

Since the recent update, the gRPC wire (`pb.AgentInfo`) carries **all** the advanced fields — `model`, `effort`, `category`, `version`, `author`, `tags` — so remote agents behave exactly like local ones for routing purposes.

```bash theme={"system"}
# On connect, the client shows available resources
Connected to ChatCLI server (version: 1.3.0, provider: CLAUDEAI, model: claude-sonnet-4-6)
 Server has 3 plugins, 2 agents, 4 skills available

# Remote agents appear in the listing
/agent list

# Available Agents:
#   go-expert       - Go/Golang specialist              [local]
#   devops-senior   - Senior DevOps focused on K8s      [remote]

# Loading a remote agent works the same way
/agent load devops-senior
```

### Provisioning via Kubernetes

<Tabs>
  <Tab title="Helm">
    ```bash theme={"system"}
    # Helm: inline agents and skills
    helm install chatcli oci://ghcr.io/diillson/charts/chatcli \
      --set agents.enabled=true \
      --set-file agents.definitions.devops-senior\\.md=agents/devops-senior.md \
      --set skills.enabled=true \
      --set-file skills.definitions.k8s-best-practices\\.md=skills/k8s-best-practices.md
    ```
  </Tab>

  <Tab title="Operator">
    ```yaml theme={"system"}
    # Operator: reference existing ConfigMaps
    apiVersion: platform.chatcli.io/v1alpha1
    kind: Instance
    metadata:
      name: chatcli-prod
    spec:
      provider: CLAUDEAI
      agents:
        configMapRef: chatcli-agents
        skillsConfigMapRef: chatcli-skills
    ```
  </Tab>
</Tabs>

<Info>
  ConfigMaps are mounted at `/home/chatcli/.chatcli/agents/` and `/home/chatcli/.chatcli/skills/`, and are available for remote discovery automatically. Advanced frontmatter fields (`model`, `effort`, `category`, etc.) are read by the chatcli binary inside the pod — the CRD and operator do not need changes to support them.
</Info>

***

## Next steps

<CardGroup cols={2}>
  <Card title="Multi-Agent Orchestration" icon="network-wired" href="/features/multi-agent-orchestration">
    How multiple custom agents run in parallel via `<agent_call>`.
  </Card>

  <Card title="Skill Registry" icon="store" href="/features/skill-registry">
    Publish and discover skills shared across teams.
  </Card>

  <Card title="Subagent Delegation" icon="share" href="/features/subagent-delegation">
    Focused delegation for concentrated analysis over a large payload.
  </Card>

  <Card title="Server Mode" icon="server" href="/features/server-mode">
    Distribute agents via ConfigMap to the entire team.
  </Card>
</CardGroup>
