Manual/documentation for all programming languages and libraries, for agents and human
- Rust 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| docs | ||
| src | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| CONTEXT.md | ||
| PLAN.md | ||
| README.md | ||
| TODO.md | ||
manman
man pages from many sources — a local documentation search tool for developers and AI agents.
manman clones git repositories containing documentation (language references, library docs, etc.), extracts searchable sections, indexes them with full-text search, and provides a CLI for querying — all offline, all local.
How it works
┌──────────┐ ┌─────────┐ ┌──────────┐ ┌───────────┐
│ Config │──►│ Clone │──►│ Extract │──►│ Index │
│ .toml │ │ /pull │ │ sections │ │ (tantivy) │
└──────────┘ └─────────┘ └──────────┘ └─────┬─────┘
│
┌────────▼──────┐
│ search / │
│ read_full │
└───────────────┘
- Configure a doc set via a TOML file (git remote, branch, extraction strategy)
- Fetch → clones/pulls the repo, extracts sections from markdown files, indexes them
- Search → full-text search across headings and bodies
- Read → retrieve the full content of any section by its content-hash ID
Installation
cargo install --path .
Requires Rust 2021 edition.
Usage
1. Add a doc set
Create a TOML file in the config sources directory:
mkdir -p ~/.config/manman/sources
# ~/.config/manman/sources/rust-stdlib.toml
id = "rust/stdlib"
remote = "https://github.com/rust-lang/rust"
branch = "master"
extract_strategy = "plain-markdown"
extract_path = "library/std/src" # optional scope
2. Fetch and index
manman fetch rust/stdlib
# → Fetching rust/stdlib...
# Files changed: (all — initial fetch or no prior state)
# Extracted sections: 847
# Indexed 847 sections
# Indexed at commit: abc1234
3. Search
manman search -l rust/stdlib "vec push"
Returns JSON:
[
{
"doc_id": "2299900dc08e401296f19cb59c514d2f49df916ab00405d06bc81fc93d9a067e",
"heading": "fn Vec::push(&mut self, value: T)",
"preview": "Appends an element to the back of a collection."
}
]
4. Read full section
manman read-full <doc_id>
# → raw markdown output
manman read-full <doc_id> --format json
# → JSON with heading, body, source_path, doc_set
5. Manage doc sets
manman list # all configured
manman list --fetched # only fetched/cloned
manman list --available # configured but not yet fetched
manman status # show sync status vs remote
manman remove <doc_set> # delete everything for a doc set
manman update # fetch all configured doc sets
manman fetch --all # same as update
Commands
| Command | Description |
|---|---|
fetch <doc_set> |
Clone or pull, then extract and index |
fetch --all |
Fetch all configured doc sets |
search -l <doc_set> <query> |
Full-text search, JSON output |
read-full <doc_id> [--format json|raw] |
Retrieve section body |
list [--fetched] [--available] |
List doc sets with optional filters |
status |
Show last-indexed vs remote HEAD per doc set |
remove <doc_set> |
Delete repo, index, and config |
update |
Fetch all configured doc sets |
Configuration
Environment variables
| Variable | Default | Description |
|---|---|---|
$MANMAN_DATA_DIR |
Platform data dir (~/.local/share/manman/) |
Where repos, indexes, and state live |
$MANMAN_CONFIG_DIR |
Platform config dir (~/.config/manman/) |
Where source TOML files live |
Doc set config reference
id = "rust/stdlib" # Unique identifier (e.g. "lang/project")
remote = "https://..." # Git remote URL
branch = "master" # Git branch to track
extract_strategy = "plain-markdown" # "plain-markdown" (more coming)
extract_path = "docs" # Optional: scope extraction to a subdirectory
Disk layout
~/.local/share/manman/
├── repos/
│ ├── rust-stdlib/ # git clone
│ └── python-stdlib/
├── indexes/
│ ├── rust-stdlib/ # Tantivy index
│ └── python-stdlib/
└── state.json # last-indexed commit per doc set
~/.config/manman/
└── sources/
├── rust-stdlib.toml
└── python-stdlib.toml
Extraction strategies
| Strategy | Description | Status |
|---|---|---|
plain-markdown |
Split .md files on ##/### headings |
✅ Implemented |
rustdoc-md |
Parse Rust doc comments in .rs files |
🔜 Future |
Architecture
- Synchronous — no async runtime
- Extraction trait — each strategy implements
Extract, making it easy to add new formats - Content-hash IDs —
doc_id = sha256(heading + body + doc_set), so IDs change when content changes (natural change detection) - Upsert indexing — on re-fetch, sections are deleted and re-added by doc_id (idempotent)
- Incremental sync — only changed files are re-extracted (diff against last-indexed commit)
Development
git clone https://github.com/your-username/manman
cd manman
cargo build
cargo test
Project structure
src/
├── main.rs # CLI entry point, command dispatch
├── cli.rs # Clap derive structs
├── domain.rs # Core types (Section, DocSetConfig, State, ...)
├── error.rs # Error enum with thiserror
├── paths.rs # Directory resolution with env overrides
├── config.rs # Load/save doc set TOML configs
├── state.rs # Load/save state.json
├── git.rs # Clone, pull, diff via git2
├── extract/
│ ├── mod.rs # Extract trait
│ └── markdown.rs # Plain-markdown extraction strategy
└── index/
└── mod.rs # Tantivy index operations
Similar tools
| Tool | Language | Approach |
|---|---|---|
| Zeal | C++/Qt | GUI offline doc browser with curated docsets |
| Dash (macOS) | Swift | Paid GUI doc browser with 200+ docsets |
| DevDocs | Ruby/JS | Web-based doc browser with offline support |
| qmd | TypeScript | CLI markdown search engine, supports Frontmatter, tags |
| rustdoc | Rust | Generates HTML docs from Rust source; --open for local viewing |
| mdBook | Rust | Create online books from markdown files |
| how2 | Rust | Stack Overflow CLI with AI summarization |
manman differentiates itself by being git-native: you point it at any git repo with markdown docs and it handles cloning, syncing, and incremental updates automatically, with no curated docset format or manual download step.
License
MIT