mant 0.11.0

Local-first TUI, structured CLI, and MCP server for manuals and Markdown
# mant

Explanation reports retain separate owners, readable kinds and source coordinates.
Plain output leaves original lines unframed; Markdown quotes them. Complete
displayed definitions suppress duplicate Forms per record, while omitted bodies
keep Forms and truly isolated empty declarations have a distinct notice.
Consecutive native heads can instead carry explicitly recovered group context,
with the original description provider and no inferred alias equivalence. Reports
are for reading; JSON supplies the machine boundary. Environment names use a
separate color family from headings and ordinary variables, without making color
a semantic guarantee. The static pager restores styles on actual soft-wrap rows
and resizes from logical source text rather than inserting hard newlines.

`mant` is `ManT`'s local-first documentation command. It turns native man/mdoc
pages and Markdown libraries into one catalog exposed as an interactive TUI,
a deterministic structured CLI, and a read-only stdio MCP server. Every
interface consumes the same normalized document model.

```sh
mant git                              # interactive reader in a terminal
mant gcc --outline                    # semantic hierarchy for an agent
mant tar --explain=--exclude          # collect documented option evidence
mant --input README.md --node 1       # select one Markdown section
mant git --format json --compact      # deterministic machine output
mant --mcp                            # read-only MCP over stdio
```

## Install

Download a supported prebuilt GitHub Release through
[`cargo-binstall`](https://github.com/cargo-bins/cargo-binstall):

```sh
cargo binstall mant
```

Or compile from crates.io:

```sh
cargo install mant --locked
```

Source builds require Rust 1.88+ and a C compiler. Linux and macOS additionally
require zlib development headers; Windows uses the checked MSVC memory-parser
configuration without a system zlib.

| Target | Prebuilt archive | Source capabilities |
| --- | --- | --- |
| Linux x64, glibc | Yes | Markdown and native man/mdoc |
| Linux arm64, glibc | Yes | Markdown and native man/mdoc |
| Windows x64, MSVC | Yes | Markdown and native man/mdoc |
| macOS | Source build | Markdown and native man/mdoc |

Targets without a matching archive fall back from `cargo binstall` to a Cargo
source build. Public macOS archives remain disabled until they can be signed
and notarized.

## Interactive reader

An ordinary complete query opens the reader when standard input and output are
terminals. Use `--display tui` to require it explicitly:

```sh
mant git
mant --input README.md --display tui
```

The reader provides a resizable outline, collapsible sections, semantic option
nodes, settled-scroll following, typed in-page and cross-document links,
back/forward history, full-document search, keyboard and mouse input, and
optional tldr quick references before the full document. `Ctrl+O` opens the
shared Markdown and native-manual catalog. The upper-right tab stack keeps
successfully opened documents in first-open order and restores each tab's last
selected semantic node. Safe external links are handed asynchronously to the
platform URL handler; WSL uses the Windows handler when it is available, and
the child process cannot read from or write into the TUI terminal streams. A
success notice confirms that handoff started, not that a browser accepted it.
Redirected output stays deterministic instead of emitting terminal control
sequences.

Visual selections copy automatically, while the Edit menu can copy a complete
semantic node as deterministic text or structurally complete `CommonMark`. Local
sessions prefer the native clipboard and fall back to write-only OSC 52. WSL,
SSH, and VS Code remote sessions prefer OSC 52 so compatible outer terminals
and multiplexers can forward the copy to the user's clipboard. Right-clicking
inside the document copies the retained visual selection again when the mouse
event reaches `ManT`. OSC 52 payloads are limited to 400 KiB before Base64
encoding; native clipboard delivery retains the reader-wide 4 MiB limit. This
terminal protocol has no acknowledgement, so a terminal that disables OSC 52
can silently ignore an emitted copy request.

Help, diagnostics, and tldr output share a terminal-aware colour policy.
Use `--color auto|always|never`; automatic mode respects terminal capability,
`NO_COLOR`, and `TERM=dumb`, while structured formats stay undecorated.

Document discovery follows the same rule: long terminal text is pageable,
while short, redirected, JSON, and explicit `--display direct` output stays direct.

```sh
mant --list
mant --find git
mant --find git --display direct
mant --find git --format json
```

## Structured queries for agents and scripts

Discover the document before selecting only the content that matters:

```sh
mant gcc --outline
mant ssh --explain=-L
mant git --tldr
mant gcc --node 4.2 --format markdown
mant tar --explain=--exclude
mant tar --search=--acls --context 1
mant git --search worktree --follow-links
mant --document git --document git-lfs --explain=--work-tree
```

Repeated `--document` values form an ordered query set. `--follow-links` adds typed native-manual and same-source Markdown destinations with bounded breadth-first traversal. Search and explain each use one global offset/`nextOffset` across the set. Explain orders direct entries, explicitly related entries, mentions in other entries and ordinary mentions before paging; within a class it preserves BFS document and original IR order. Explain preserves independent same-name owners, original forms/content, literal support and explicit alias relationships; it never chooses a first result as uniquely correct. Readable no-evidence queries succeed with an explicit outcome; partial source failures retain available evidence and coverage. Interactive search spans the same pre-resolved set while ordinary document discovery remains global.

Compact explanation output shows full direct/related definitions and bounded
match windows for mentions. For example, GCC's `-Q` mentioning `--help` remains
a mention, not an alias. All four category counts distinguish collected totals
from this page; use the read coordinate with `--node` for complete original
content. Group context is returned/displayed once on the same page, even when
the strict original node has only its own head. Preview clipping, body omission
and support omission are reported separately. Consumers of structured explain
must resolve `declaration-member` content through the source-local support pool.

Explanation pages default to 50 owners (`--limit`, maximum 256). `--offset`
continues the result set; `--explain-content-bytes` bounds copied facts/forms, previews
and original bodies (default 1 MiB, maximum 4 MiB). Omitted bodies retain their
strict `--node` location. MCP's character pages remain independent.

All document queries, including `--request-json`, default to text and can
explicitly select Markdown or JSON. Full reading still opens the TUI on an
interactive terminal; redirected output is plain text. `--preserve-anchors`
explicitly selects Markdown unless a format is given. A complete native roff
manual also supports `--format man` for manual-only
plain text without tldr content.

`--display auto|direct|pager|tui` independently controls presentation. Automatic
full reading uses the TUI; other terminal-owned text queries use the built-in
pager only when they exceed the screen. `direct` forbids either interactive
interface. Explicit `pager` and `tui` require usable stdin/stdout terminals;
JSON cannot be paged, and stdin documents/request JSON remain noninteractive.
Explicit formats disable automatic TUI selection; Markdown and man can be
paged only when explicitly requested. Doctor, help, and maintenance reports
stay direct by default. The removed `--ui` and `--no-pager` flags are replaced
by `--display tui` and `--display direct`.
The default outline returns section topology plus compact entry coverage.
`--outline-entries none|summary|all|KINDS` controls expansion, while
`--outline-root` focuses the result on one exact section or semantic entry.
Expanded entries preserve nested command/parameter/value relationships and
keep exact aliases separate from complete authored forms.
A stateless agent can start with the default summary, reuse a path or ID from
that current response as `--outline-root`, expand only that subtree with
`--outline-entries`, and finally pass a returned selector to `--node`. Do not
guess from display titles, and rediscover after the underlying document
changes. Entry paths remain source-order coordinates; generated native IDs
avoid source-order collision suffixes and unrelated-section renumbering.
Text projections use semantic ANSI styles on capable terminals and remain plain
under redirection by default; `--color always` explicitly forces text styling.
Markdown, JSON, man, and MCP never contain ANSI presentation styling.
Terminal-bound Markdown masks control characters in dynamic document identities,
while redirected full/excerpt Markdown preserves those data bytes exactly.
The independent explanation text/CommonMark presentation always masks controls,
including data supplied by unchecked in-process IR producers.
Search results carry reusable outline selectors and exact generated-Markdown
coordinates. Machine consumers can discover the authoritative contracts from
the installed executable:

```sh
mant --doctor
mant --doctor --format json --compact
mant --schema request
mant --schema all --compact
mant --protocol-version
```

`mant --doctor` checks the effective local installation without network access,
external processes, or mutations. Text is intended for people; JSON uses the
independent `mant.doctor/v1` report contract, discoverable with
`mant --schema doctor`. Warnings keep a successful exit status, while a broken
promised capability exits with status `1`.

`mant --mcp` exposes read-only discovery, outline, excerpt, explanation, and
search over stdio JSON-RPC. Its five tools return bounded plain text or
`CommonMark` rather than serializing full AST envelopes. MCP stdout contains
protocol messages only; use CLI JSON output to inspect lowering diagnostics.
Malformed, excessively nested, and oversized input lines receive bounded
errors without ending the session once the offending newline has been drained.
Every successful tool result begins with a `mant-page` header reporting the
Unicode-scalar character interval and full canonical body size. Clients select
a bounded `maxChars` budget and resume statelessly with `startChar`; semantic
`maxResults` and `maxMatches` limits remain separate from presentation paging.
Discovery exposes literal or regex matching and case policy; search exposes
visible or generated-Markdown scope. Both use result `offset`/`nextOffset`
independently from character `startChar`/`nextChar` paging.

## Document sources

On Linux, macOS, and Windows, `ManT` indexes raw, gzip, and zstd manual sources
and parses their roff through bundled libmandoc. It does not require a system
`man` or `mandoc` executable at runtime. A leaf manual-page symlink may point
outside its indexed root, but directory symlinks are not traversed and every
`.so` target must remain inside that root. Windows defaults to
`%APPDATA%\ManT\man`, followed by the compatible
`%USERPROFILE%\.local\share\man` fallback, and also honors configured manual
paths. Its optional `%APPDATA%\ManT\man.conf` accepts direct and mandatory
roots, bounded fragments, PATH mappings, quoted paths, and one-pass `%NAME%`
expansion; `mant --doctor` reports malformed directives without stopping
ordinary document lookup.

Reusable Markdown documents can be registered by relative path below:

- Linux: `${XDG_DATA_HOME:-$HOME/.local/share}/mant/documents`
- macOS: `~/Library/Application Support/ManT/documents`
- Windows: `%APPDATA%\ManT\documents`

Regular Markdown files are discovered recursively with their hierarchy.
Personal `documents/` may use leaf-file symlinks to regular files, including
external targets; directory and broken links are ignored. Managed source
caches never follow links. Git or direct archive sources configured in sibling
`sources.toml` can be installed with `mant --update-docs` and selected with
`--source`. Removed source tables are reported as orphaned installed data;
preview cleanup with `mant --prune-docs --dry-run` and apply it with
`mant --prune-docs`. An unqualified path or unique component suffix resolves
root documents first. Sources then sort around native manuals at priority zero:
positive sources win, manuals win a zero tie, and non-positive sources are
fallbacks. Omitted source priority defaults to one. See the
complete [document-source guide](https://github.com/BryanHeBY/ManT/blob/main/docs/sources.md).

When compatible local tldr data exists, a combined query that selects a native
section `1` or `8` family page prepends it as reserved outline node `0`.
`--tldr` selects only that node, while `--manual` selects only native manual
content and excludes the quick reference. `--man-section` selects an exact
native full document without disabling a compatible command quick reference.
Explicit tldr lookup compares embedded Markdown quick references using their
document priority;
cached tldr and native manuals share the built-in priority-zero baseline.
Markdown without an embedded quick reference is skipped. Reads prefer
installed-client caches and then `ManT`'s private cache; `mant --update-tldr`
updates through an installed client or the private checkout. If no full
document exists, an ordinary query fails with an explicit `mant NAME --tldr`
hint instead of opening a tldr-only reader.

One-off physical input uses `mant --input PATH`; Markdown and plain/gzip/zstd
roff files are supported. Standard input additionally requires
`--input-format markdown|roff`. Manual selectors accept `mant 1 git`,
`mant 'git(1)'`, and `mant manual/1/git`. A dotted selector such as `git.1`
remains an exact logical name and is never guessed to be a manual shorthand.

## Crate architecture

Official/default builds enable all five capabilities. Custom Cargo builds can
disable them with `--no-default-features` and opt in individually:

| Feature | Capability |
| --- | --- |
| `roff` | Native manual parsing through engine → loader → codec |
| `tui` | Interactive reader and its clipboard/external-link host services |
| `pager` | Static terminal pager, without the reader dependency |
| `mcp` | Read-only stdio server and its async runtime |
| `update` | Explicit source and tldr maintenance |

The minimal build retains Markdown, cached quick references, pure queries,
direct text/JSON output, schema output and offline inspection. Native manual
catalogs are read-only metadata and remain discoverable without `roff`; their
presence does not promise that this build can parse those pages. A native read
then returns an explicit capability error. CLI flags and display values for
disabled execution capabilities are omitted, while versioned schemas continue
describing the complete contract. Automatic display only chooses compiled
capabilities; without an applicable reader or pager it writes directly.

`mant::run_process` is now synchronous and owns a runtime only for an explicitly
selected MCP session. Native-process callers no longer await it; callers already
inside an async runtime should use the narrower libraries rather than nesting
the process entry point. `mant::run` remains the injectable stream interface.

- `mant-ir` defines the source-neutral in-memory document and quick-reference model.
- `mant-protocol` defines shared query contracts, logical projections, versioned JSON DTOs, and stable semantic labels.
- `libmandoc-rs` owns the cross-platform libmandoc parser boundary.
- `mant-sources` owns local Markdown discovery and optional source updates.
- `mant-codec` parses Markdown and optional native roff and encodes document Markdown.
- `mant-loader` owns bounded local acquisition, catalogs, caches, and linked-document snapshots.
- `mant-query` projects and searches already loaded IR without loading or rendering.
- `mant-render` formats content and DTO reports without querying or controlling a terminal.
- `mant-engine` composes complete validated requests over loading and pure queries.
- `mant-ui` provides the source-neutral Ratatui frontend.
- `mant` owns command-line, terminal-selection, and MCP process boundaries.

Within the command host, CLI input adaptation and output dispatch are separate
from typed application navigation, system services, and process delivery.
The crate root exposes stream and native-process entry points; the private
process adapter alone chooses terminal delivery and owns native stdio policy.
The native reader records each attempted terminal acquisition before executing
it, including partial writes. Its backend and outer session share one cleanup
ledger: restoration runs in reverse acquisition order, attempts every pending
operation, retains the first error, and retries only failed releases on drop.
The embeddable UI never acquires these process resources. Signal handlers only
record termination; ordinary host code restores modes before applying the
signal's exit behavior. Uncatchable signals cannot be recovered.
`CliHost`/`SystemHost` retain the injectable service boundary; maintenance lives
under the host rather than in the read-only engine. Schema output is an offline
adapter, and CLI and MCP share DTO renderers without sharing CLI format types.

Creating a command host does not discover local sources. Complete requests and
catalog filters are validated before its first document snapshot is captured;
subsequent reads and discovery within that operation or reader session reuse
the same snapshot. Help, schema output, malformed requests and direct stdin
parsing do not initialize the resolver. There is no process-global document
cache. Normal CLI requests use the engine's complete request pipeline, as MCP
does, instead of independently combining loading and projection.

The package also exposes `mant::run` for deterministic single-invocation tests
or embedding with explicit input/output streams, and `mant::run_process` for
the real terminal-sensitive process including MCP. Most library users should
prefer the narrower component crate matching their boundary instead of
embedding the complete command host.

The complete [user manual](https://github.com/BryanHeBY/ManT/blob/main/docs/manuals/mant.md),
[protocol reference](https://github.com/BryanHeBY/ManT/blob/main/docs/manuals/mant-protocol.md),
and [release archives](https://github.com/BryanHeBY/ManT/releases) live in the
`ManT` repository.
Compatibility and migration notes are recorded in the
[crate changelog](https://github.com/BryanHeBY/ManT/blob/main/CHANGELOG.md).

## License

Apache-2.0. Native builds also contain the separately attributed upstream
mandoc sources distributed by `libmandoc-rs`; downloaded tldr-pages content
is CC BY 4.0 and is attributed when rendered.