| Crates.io | hero_atlas |
| lib.rs | hero_atlas |
| version | 0.1.0 |
| created_at | 2026-01-16 15:01:06.620587+00 |
| updated_at | 2026-01-16 15:01:06.620587+00 |
| description | Hero Atlas - Document collection management system with web server |
| homepage | |
| repository | https://github.com/geomind/hero_atlas |
| max_upload_size | |
| id | 2048743 |
| size | 368,982 |
A Rust-based document collection management system with CLI, library, and web interfaces for processing markdown-based documentation with support for cross-collection references, link validation, and export to self-contained directories.
This is a single Rust package (hero_atlas) with multiple entry points:
src/lib.rs) - Core functionality for document collection managementsrc/bin/cli.rs) - Command-line interface (atlas binary)src/bin/web.rs) - HTTP API and web interface (atlas-web binary)DocTree Module - Complete document collection management system
Website Module - Metadata-driven website definitions
# Build the project
./build.sh
# Run the CLI
./target/release/atlas --help
# Start the web server
./target/release/atlas-web
# Or use the build script which handles everything
./run.sh
.collection filescollection:page syntax!!include collection:page.group files./build.sh
Binaries will be at:
target/release/atlas - CLI applicationtarget/release/atlas-web - Web server./install.sh
Installs both binaries to ~/.local/bin/:
~/.local/bin/atlas - CLI application~/.local/bin/atlas-web - Web serverHero Atlas separates content from presentation:
DocTree (Content):
Website (Presentation):
This separation allows flexible website layouts without changing content.
Collections: Directories of markdown pages marked with .collection file
Pages: Individual markdown files with:
Links: References to pages, images, or files:
[text](page_name)[text](collection:page)Groups: Access control lists defining user membership
Export: Self-contained read-only directory:
Directory Scan
↓
Find Collections (.collection files)
↓
Parse Pages (extract metadata, parse links)
↓
Validate Links (check references exist)
↓
Process Includes (expand !!include directives)
↓
Enforce ACL (check group membership)
↓
Export (write to structured directory)
↓
Read Client (query exported collections)
This project was refactored from a multi-package workspace into a single unified package following Rust best practices:
Previous Structure (workspace with 3 crates):
lib/ - atlas-lib libraryatlas/ - atlas CLI binaryweb/ - atlas-web serverNew Structure (single package with multiple binaries):
hero_atlas package in Cargo.tomlsrc/bin/:
cli.rs → atlas binaryweb.rs → atlas-web binarysrc/:
cli/ - CLI command definitionsdoctree/ - Core document managementebook/ - Ebook parsingweb/ - HTTP server handlerswebsite/ - Website configurationBenefits:
atlas scan --path /path/to/docs
atlas scan --path /path/to/docs --ignore node_modules --ignore .git
# Export to default location (/tmp/atlas)
atlas export --path /path/to/docs
# Export with reset (clear destination first)
atlas export --path /path/to/docs --reset
# Export to custom location
atlas export --path /path/to/docs --destination /path/to/export
# Process include directives during export
atlas export --path /path/to/docs --include
atlas list --path /path/to/docs
atlas errors --path /path/to/docs
atlas page --key collection_name:page_name --path /path/to/docs
# List collections
atlas read collections
# List pages in a collection
atlas read pages --collection mycolection
# Get page content
atlas read page --collection mycollection --page mypage
# List images
atlas read images --collection mycollection
# List files
atlas read files --collection mycollection
docs/
├── collection1/
│ ├── .collection # Marks as collection (optional: name:custom_name)
│ ├── read.acl # Optional: group names for read access
│ ├── write.acl # Optional: group names for write access
│ ├── page1.md
│ ├── subdir/
│ │ └── page2.md
│ └── img/
│ └── logo.png
├── collection2/
│ ├── .collection
│ └── intro.md
└── groups/ # Special collection for ACL groups
├── .collection
├── admins.group
└── editors.group
/tmp/atlas/
├── content/
│ └── collection_name/
│ ├── page1.md # Pages at root of collection dir
│ ├── page2.md
│ ├── img/ # All images in img/ subdirectory
│ │ └── logo.png
│ └── files/ # All other files in files/ subdirectory
│ └── document.pdf
└── meta/
└── collection_name.json # Collection metadata
name:custom_collection_name
If empty or name not specified, uses directory name.
// Comments start with //
user@example.com
*@company.com
include:other_group
admins
editors
One group name per line.
[text](page_name) # Same collection
[text](collection:page) # Cross-collection
 # Same collection
 # Cross-collection
!!include page_name
!!include collection:page_name
Page and collection names are normalized:
- with _/ with _.md extension03_page → page).png, .jpg, .jpeg, .gif, .svg, .webp, .bmp, .tiff, .ico# Build release binaries
./build.sh
# Build with debug info
cargo build
# Run tests
cargo test
# Generate documentation
cargo doc --no-deps --open
# Run all tests
cargo test
# Run specific module tests
cargo test doctree
cargo test website
# Run with output
cargo test -- --nocapture
src/
├── lib.rs # Library exports
├── bin/
│ ├── cli.rs # CLI entry point (atlas binary)
│ └── web.rs # Web server entry point (atlas-web binary)
├── cli/ # CLI command implementation
├── doctree/ # Document management (1,975 LOC)
├── ebook/ # Ebook parsing
├── web/ # HTTP API handlers
└── website/ # Website configuration (1,522 LOC)
src/doctree/src/website/src/cli/mod.rssrc/web/mod.rsuse doctree::{DocTree, ExportArgs};
fn main() -> doctree::Result<()> {
// Create and scan
let mut doctree = DocTree::new("mydocs");
doctree.scan(Path::new("/path/to/docs"), &[])?;
doctree.init_post()?; // Validate links
// Access pages
let page = doctree.page_get("collection:page")?;
let content = page.content()?;
// Export
doctree.export(ExportArgs {
destination: PathBuf::from("/tmp/atlas"),
reset: true,
include: false,
})?;
Ok(())
}
use doctree::DocTreeClient;
fn main() -> doctree::Result<()> {
let client = DocTreeClient::new(Path::new("/tmp/atlas"))?;
// List collections
let collections = client.list_collections()?;
// Get page content
let content = client.get_page_content("collection", "page")?;
// Check existence
if client.page_exists("collection", "page") {
println!("Page exists!");
}
Ok(())
}
atlasserver_rust/
├── Cargo.toml # Package configuration
├── build.sh # Build script
├── install.sh # Install script
├── run.sh # Run script
├── README.md # This file
├── src/
│ ├── lib.rs # Library entry point and module declarations
│ ├── bin/
│ │ ├── cli.rs # CLI binary entry point
│ │ └── web.rs # Web server entry point
│ ├── cli/
│ │ └── mod.rs # CLI commands and handlers
│ ├── doctree/ # Document tree management
│ │ ├── mod.rs
│ │ ├── core.rs
│ │ ├── collection.rs
│ │ ├── page.rs
│ │ ├── group.rs
│ │ ├── link.rs
│ │ ├── client.rs
│ │ ├── types.rs
│ │ ├── error.rs
│ │ └── utils.rs
│ ├── ebook/ # Ebook parsing
│ │ └── mod.rs
│ ├── web/ # HTTP API routes and handlers
│ │ └── mod.rs
│ └── website/ # Website configuration
│ ├── mod.rs
│ ├── config.rs
│ ├── navbar.rs
│ ├── sidebar.rs
│ ├── footer.rs
│ ├── page.rs
│ └── theme.rs
└── target/
└── release/
├── atlas # CLI binary
└── atlas-web # Web server binary