# `AshLua.Docs`
[🔗](https://github.com/ash-project/ash_lua/blob/v0.1.0/lib/ash_lua/docs.ex#L5)

Generates Lua-side API documentation suitable for an MCP `search_docs` / `get_docs`
surface (notably for `ash_ai`).

The rendered output is intended for external consumers — humans reading hexdocs or
LLM clients picking which callable to invoke — so it deliberately avoids internal
vocabulary. Operations are described as `get` / `list` / `create` / `update` /
`delete` / `call`; stored, computed, and summary fields are all just "fields";
related records are described by cardinality and a link to the related record
type's page.

  * `topics/1` lists general topics of functionality, e.g. `"filters"`,
    `"pagination"`, `"error-handling"`; `topic_doc/2` renders one.
  * `list_callables/1` and `list_types/1` enumerate the documentable surface.
  * `callable_doc/2` renders one operation (e.g. `"posts.post.create"`).
  * `type_doc/2` renders one type (record type identified by its Lua path
    `"posts.post"`, or named type by its readable name).
  * `full_doc/1` concatenates everything into a single page.

# `manifest_or_opts`

```elixir
@type manifest_or_opts() :: Ash.Info.Manifest.t() | keyword()
```

# `callable_doc`

```elixir
@spec callable_doc(manifest_or_opts(), String.t()) ::
  {:ok, String.t()} | {:error, :not_found}
```

Renders the markdown for one operation, addressed by its dotted path.

Returns `{:ok, markdown}` or `{:error, :not_found}`.

# `full_doc`

```elixir
@spec full_doc(manifest_or_opts()) :: String.t()
```

Renders a single page containing every operation and every type.

The "Named types" section is omitted when there are none.

# `list_callables`

```elixir
@spec list_callables(manifest_or_opts()) :: [String.t()]
```

Returns the dotted callable paths (e.g. `"posts.post.create"`) exposed to Lua,
in stable sorted order.

# `list_types`

```elixir
@spec list_types(manifest_or_opts()) :: [String.t()]
```

Returns the documentable type identifiers — record types as their Lua path
(e.g. `"posts.post"`) and named types by their readable name (e.g. `"PostStatus"`).
Sorted.

# `search`

```elixir
@spec search(manifest_or_opts(), String.t()) :: String.t()
```

Searches the documentable surface for entries matching `term`.

Returns markdown — a header plus a bulleted list of matching callables,
record types, named types, and topics, ranked by relevance. The list is
intended as a discovery aid: the LLM (or human) picks one name and follows
up with `callable_doc/2` / `type_doc/2` / `topic_doc/2` for the full page.

An empty / blank term returns an empty result page. The match limit is 20.

# `topic_doc`

```elixir
@spec topic_doc(manifest_or_opts(), String.t()) ::
  {:ok, String.t()} | {:error, :not_found}
```

Renders the markdown for one general topic by name.

Returns `{:ok, markdown}` or `{:error, :not_found}`.

# `topics`

```elixir
@spec topics(manifest_or_opts()) :: [String.t()]
```

Returns the available general-topic identifiers in stable sorted order.

Topics are short reference pages — explanations of how reserved input keys
work, the error-handling convention, etc. — rather than per-callable or
per-type pages.

# `type_doc`

```elixir
@spec type_doc(manifest_or_opts(), String.t() | module()) ::
  {:ok, String.t()} | {:error, :not_found}
```

Renders the markdown for one type. Accepts either:

  * A Lua path string like `"posts.post"` (record type).
  * A named-type readable name (the `:name` field on `Ash.Info.Manifest.Type`).
  * A module — looked up first as a named type, then as a record type.

Returns `{:ok, markdown}` or `{:error, :not_found}`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
