Development Guide
This page covers how to set up, run, and test Luminos. For a code-level walkthrough of how the AI pipeline actually works — the dir loop, the cache, the survey pass, where to add a tool — read Internals.
Running Luminos
# Base scan
python3 luminos.py <target>
# With AI analysis (requires ANTHROPIC_API_KEY)
source ~/luminos-env/bin/activate
python3 luminos.py --ai <target>
# Common flags
python3 luminos.py --ai --fresh --clear-cache <target> # force clean run
python3 luminos.py -x .git -x node_modules <target> # exclude dirs
python3 luminos.py -d 8 -a <target> # depth 8, include hidden
python3 luminos.py --json -o report.json <target> # JSON output
# Watch mode
python3 luminos.py --watch <target>
# Check optional dep status
python3 luminos.py --install-extras
Optional Dependencies Setup
# One-time setup
bash setup_env.sh
# Or manually
python3 -m venv ~/luminos-env
source ~/luminos-env/bin/activate
pip install anthropic tree-sitter tree-sitter-python \
tree-sitter-javascript tree-sitter-rust \
tree-sitter-go python-magic
Git Workflow
Every change starts on a branch. Nothing goes directly to main.
Branch naming
<type>/<short-description>
| Type | Use |
|---|---|
feat/ |
New feature or capability |
fix/ |
Bug fix |
refactor/ |
Restructure without behavior change |
chore/ |
Tooling, config, documentation |
test/ |
Tests |
Examples: feat/survey-pass, fix/cache-flush-on-error, refactor/synthesis-tiers
Commit messages
<type>: <short description>
Examples:
feat: add web_search tool to dir loop
fix: handle empty dir cache gracefully in synthesis
refactor: extract survey pass into _run_survey()
chore: update Architecture wiki page
One commit per logical unit of work, not one per file.
Merge procedure
git checkout main
git merge --no-ff <branch> -m "merge: <description>"
git branch -d <branch>
--no-ff preserves branch history. Delete branch after merging.
Testing
Running tests
python3 -m unittest discover -s tests/ -v
No dependencies needed — the test suite uses stdlib unittest only.
Test coverage
Tests live in tests/, one file per module:
| Test file | Module covered |
|---|---|
test_cache.py |
cache.py — entry validation, confidence fields, investigation IDs |
test_filetypes.py |
filetypes.py — extension classification, classify_files, summarize_categories |
test_code.py |
code.py — language detection, LOC counting, large file detection |
test_disk.py |
disk.py — disk usage parsing, _human_size, top_directories |
test_recency.py |
recency.py — recent file detection, output parsing |
test_tree.py |
tree.py — tree building, rendering, hidden/exclude logic |
test_report.py |
report.py — format_flags, format_report, all sections |
test_capabilities.py |
capabilities.py — _check_package |
Modules not covered (exempt from unit testing):
| Module | Reason |
|---|---|
ai.py |
Requires live Anthropic API |
ast_parser.py |
Requires tree-sitter optional dep |
watch.py |
Stateful filesystem event loop |
prompts.py |
String templates with no logic |
Test requirements
- Every change to a covered module must include or update its tests
- All 129 tests must pass before merging to main
- Subprocess-heavy functions (
wc,du,find,file) are tested viaunittest.mock— no real filesystem calls needed - Tests that require real filesystem interaction use
tempfile.mkdtemp()and clean up automatically
Adding tests for new modules
- Create
tests/test_<module>.py - Import from
luminos_lib.<module> - Use
unittest.TestCasesubclasses - Mock subprocess calls with
unittest.mock.patch("subprocess.run", ...) - Add the new file to the table above
Naming Conventions
| Context | Convention | Example |
|---|---|---|
| Functions / variables | snake_case | classify_files, dir_path |
| Classes | PascalCase | _TokenTracker, _CacheManager |
| Constants | UPPER_SNAKE_CASE | MAX_CONTEXT, CACHE_ROOT |
| Module files | snake_case | ast_parser.py, filetypes.py |
| CLI flags | kebab-case | --clear-cache, --install-extras |
| Private functions | leading underscore | _run_synthesis, _build_dir_context |
Project Structure
luminos/
├── luminos.py entry point
├── luminos_lib/
│ ├── ai.py AI pipeline (heaviest module)
│ ├── ast_parser.py tree-sitter parsing
│ ├── cache.py investigation cache management
│ ├── capabilities.py optional dep detection
│ ├── code.py language + LOC detection
│ ├── disk.py disk usage
│ ├── filetypes.py file classification
│ ├── prompts.py AI system prompt templates
│ ├── recency.py recently modified files
│ ├── report.py terminal report formatter
│ ├── tree.py directory tree
│ └── watch.py watch mode
├── tests/
│ ├── test_cache.py
│ ├── test_capabilities.py
│ ├── test_code.py
│ ├── test_disk.py
│ ├── test_filetypes.py
│ ├── test_recency.py
│ ├── test_report.py
│ └── test_tree.py
├── docs/wiki/ local clone of Forgejo wiki (gitignored)
├── setup_env.sh venv + AI dep setup script
├── CLAUDE.md Claude Code context (thin — points to wiki)
└── PLAN.md evolution plan and design notes
Wiki
Wiki lives at docs/wiki/ (gitignored — separate git repo).
# First time
git clone ssh://git@forgejo-claude/archeious/luminos.wiki.git docs/wiki/
# Returning
git -C docs/wiki pull
Wiki URL: https://forgejo.labbity.unbiasedgeek.com/archeious/luminos/wiki
When updating wiki pages:
cd docs/wiki
# edit pages
git add -A
git commit -m "wiki: <description>"
git push