Skip to main content
ClaudeWave
Skill63 repo starsupdated 3d ago

exdoc-config

Configures ExDoc for Elixir projects including mix.exs setup, extras, groups, cheatsheets, and livebooks. Use when setting up or modifying ExDoc documentation generation.

Install in Claude Code
Copy
git clone --depth 1 https://github.com/existential-birds/beagle /tmp/exdoc-config && cp -r /tmp/exdoc-config/plugins/beagle-elixir/skills/exdoc-config ~/.claude/skills/exdoc-config
Then start a new Claude Code session; the skill loads automatically.

SKILL.md

# ExDoc Configuration

## Quick Reference

| Topic | Reference |
|-------|-----------|
| Markdown, cheatsheets (.cheatmd), livebooks (.livemd) | [references/extras-formats.md](references/extras-formats.md) |
| Custom head/body tags, syntax highlighting, nesting, annotations | [references/advanced-config.md](references/advanced-config.md) |

## Gates

Use this sequence before claiming ExDoc is wired correctly or that docs build:

1. **Dependencies resolved** — Run `mix deps.get` from the project root. **Pass:** exit code `0`, and `mix.exs` includes `ex_doc` as in [Dependency Setup](#dependency-setup) (or the project’s equivalent dev-only docs dep).
2. **Extra paths real** — For every path string in `extras/0` (and in `groups_for_extras/0` if used), confirm that path exists in the repo **or** you have just created that file. **Pass:** no stale or typo paths remain when you run `mix docs`.
3. **Docs build** — Run `mix docs`. **Pass:** exit code `0`, and the HTML entry exists at `<output>/index.html` (default `<project>/doc/index.html`; use `docs: [output: ...]` if you changed `output`).

For cheatsheets, livebooks, or custom head/body assets, follow the same “path exists before listing” rule; see [When to Load References](#when-to-load-references).

## Dependency Setup

Add ExDoc to `mix.exs` deps:

```elixir
defp deps do
  [
    {:ex_doc, "~> 0.34", only: :dev, runtime: false}
  ]
end
```

## Project Configuration

Configure your `project/0` function in `mix.exs`:

```elixir
def project do
  [
    app: :weather_station,
    version: "0.1.0",
    elixir: "~> 1.17",
    start_permanent: Mix.env() == :prod,
    deps: deps(),

    # ExDoc
    name: "WeatherStation",
    source_url: "https://github.com/acme/weather_station",
    homepage_url: "https://acme.github.io/weather_station",
    docs: docs()
  ]
end
```

## The docs/0 Function

Define a private `docs/0` function to keep project config clean:

```elixir
defp docs do
  [
    main: "readme",
    logo: "priv/static/images/logo.png",
    output: "doc",
    formatters: ["html", "epub"],
    source_ref: "v#{@version}",
    extras: extras(),
    groups_for_modules: groups_for_modules(),
    groups_for_extras: groups_for_extras()
  ]
end
```

### Key Options

| Option | Default | Description |
|--------|---------|-------------|
| `main` | `"api-reference"` | Landing page module name or extra filename (without extension) |
| `logo` | `nil` | Path to logo image displayed in sidebar |
| `output` | `"doc"` | Output directory for generated docs |
| `formatters` | `["html"]` | List of output formats (`"html"`, `"epub"`) |
| `source_ref` | `"main"` | Git ref used for "View Source" links |
| `assets` | `nil` | Map of source directory to target directory for static assets |
| `deps` | `[]` | Links to dependency documentation |

### Setting the Landing Page

The `main` option controls what users see first:

```elixir
# Use the README as the landing page (most common)
docs: [main: "readme"]

# Use a specific module as the landing page
docs: [main: "WeatherStation"]

# Use a custom guide
docs: [main: "getting-started"]
```

The value matches the extra filename without its extension, or a module name.

## Extras

Extras are additional pages beyond the API reference. Add them as a list of file paths:

```elixir
defp extras do
  [
    "README.md",
    "CHANGELOG.md",
    "LICENSE.md",
    "guides/getting-started.md",
    "guides/configuration.md",
    "guides/deployment.md",
    "cheatsheets/query-syntax.cheatmd",
    "notebooks/data-pipeline.livemd"
  ]
end
```

### Controlling Extra Titles

By default, ExDoc uses the first `h1` heading as the title. Override with a keyword tuple:

```elixir
defp extras do
  [
    {"README.md", [title: "Overview"]},
    {"CHANGELOG.md", [title: "Changelog"]},
    "guides/getting-started.md"
  ]
end
```

### Ordering

Extras appear in the sidebar in the order listed. Put the most important pages first:

```elixir
defp extras do
  [
    "README.md",
    "guides/getting-started.md",
    "guides/architecture.md",
    "guides/deployment.md",
    "CHANGELOG.md"
  ]
end
```

## Grouping

### Grouping Modules

Organize modules into logical sections in the sidebar:

```elixir
defp groups_for_modules do
  [
    "Sensors": [
      WeatherStation.Sensor,
      WeatherStation.Sensor.Temperature,
      WeatherStation.Sensor.Humidity,
      WeatherStation.Sensor.Pressure
    ],
    "Data Processing": [
      WeatherStation.Pipeline,
      WeatherStation.Pipeline.Transform,
      WeatherStation.Pipeline.Aggregate
    ],
    "Storage": [
      WeatherStation.Repo,
      WeatherStation.Schema.Reading,
      WeatherStation.Schema.Station
    ]
  ]
end
```

Use regex to group by pattern:

```elixir
defp groups_for_modules do
  [
    "Sensors": [~r/Sensor/],
    "Schemas": [~r/Schema/],
    "Pipeline": [~r/Pipeline/]
  ]
end
```

Modules not matching any group appear under a default "Modules" heading.

### Grouping Functions

Group functions within a module using `groups_for_docs`:

```elixir
defp docs do
  [
    groups_for_docs: [
      "Lifecycle": &(&1[:section] == :lifecycle),
      "Queries": &(&1[:section] == :queries),
      "Mutations": &(&1[:section] == :mutations)
    ]
  ]
end
```

Tag functions in your module with `@doc` metadata:

```elixir
@doc section: :lifecycle
def start_link(opts), do: GenServer.start_link(__MODULE__, opts)

@doc section: :queries
def get_reading(station_id), do: Repo.get(Reading, station_id)
```

### Grouping Extras

Organize guides, cheatsheets, and notebooks in the sidebar:

```elixir
defp groups_for_extras do
  [
    "Guides": [
      "guides/getting-started.md",
      "guides/configuration.md",
      "guides/deployment.md"
    ],
    "Cheatsheets": [
      "cheatsheets/query-syntax.cheatmd",
      "cheatsheets/ecto-types.cheatmd"
    ],
    "Tutorials": [
      "notebooks/data-pipeline.livemd",
      "notebooks/sensor-setup.livemd"
    ]
  ]
end
```

Use glob patterns for convenience:

```elixir
defp grou
release-tagSlash Command

tag and push a release after the release PR is merged

releaseSlash Command

create a release PR (auto-detects previous tag)

deepagents-architectureSkill

Guides architectural decisions for Deep Agents applications. Use when deciding between Deep Agents vs alternatives, choosing backend strategies, designing subagent systems, or selecting middleware approaches.

deepagents-code-reviewSkill

Reviews Deep Agents code for bugs, anti-patterns, and improvements. Use when reviewing code that uses create_deep_agent, backends, subagents, middleware, or human-in-the-loop patterns. Catches common configuration and usage mistakes.

deepagents-implementationSkill

Implements agents using Deep Agents. Use when building agents with create_deep_agent, configuring backends, defining subagents, adding middleware, or setting up human-in-the-loop workflows.

langgraph-architectureSkill

Guides architectural decisions for LangGraph applications. Use when deciding between LangGraph vs alternatives, choosing state management strategies, designing multi-agent systems, or selecting persistence and streaming approaches.

langgraph-code-reviewSkill

Reviews LangGraph code for bugs, anti-patterns, and improvements. Use when reviewing code that uses StateGraph, nodes, edges, checkpointing, or other LangGraph features. Catches common mistakes in state management, graph structure, and async patterns.

langgraph-implementationSkill

Implements stateful agent graphs using LangGraph. Use when building graphs, adding nodes/edges, defining state schemas, implementing checkpointing, handling interrupts, or creating multi-agent systems with LangGraph.