This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
All feature development follows Red-Green-Refactor:
- Write a failing test first
- Write minimal code to make it pass
- Refactor while keeping tests green
All functionality must have .feature files in features/ with exhaustive scenarios. Use WhiteBread for Elixir Gherkin support. Run with mix white_bread.run.
Code coverage is enforced via ExCoveralls with a 95% threshold. Run mix coveralls to verify. PRs below threshold will fail CI.
Only these documentation files are permitted:
README.md- Project overview and quick startCLAUDE.md- AI assistant guidance (this file)CHANGELOG.md- Version history following Keep a Changelog formatdocs/adr/*.md- Architecture Decision Records
No other markdown files, wikis, or documentation directories.
# Install dependencies and set up project
mix setup
# Start the Phoenix server (localhost:4000)
mix phx.server
# Run all tests (excludes integration tests by default)
mix test
# Run a single test file
mix test test/unit/storage/git_test.exs
# Run a specific test by line number
mix test test/unit/storage/git_test.exs:10
# Run integration tests (requires Ollama, IMAP server)
mix test --include integration
# Run with coverage
mix coveralls
# Lint with Credo
mix credo
# Type checking with Dialyzer
mix dialyxir
# Database commands
mix ecto.migrate
mix ecto.reset
# Evaluate LLM models for classification
mix evaluate_models --account gmail --limit 10Configuration is loaded from .env files via dotenvy at runtime. Copy .env.example to .env and fill in values.
Load precedence (last wins): .env < .env.{MIX_ENV} < system env vars
Key variables:
NEXUS_EMAIL_ACCOUNTS- JSON array of IMAP account configsCARDDAV_URL,CALDAV_URL,DAV_USER,DAV_PASSWORD- DAV syncOLLAMA_*- LLM model configurationNEXUS_GIT_PATH,NEXUS_DATA_PATH- Storage locations
The Nexus.Config module provides type-safe parsing helpers for complex env vars.
Nexus is an Elixir/OTP application with actor-based architecture for processing communications from multiple channels.
The application starts these services in order (see lib/nexus/application.ex):
- Nexus.Repo - SQLite database via Ecto
- Nexus.Storage.Manager - Initializes Git repository for message storage
- Nexus.Contacts.Resolver - GenServer for contact lookup with caching
- Nexus.Pipeline.Supervisor - GenStage message processing pipeline
- Nexus.Channels.IMAP.Supervisor - DynamicSupervisor for IMAP workers
- Nexus.DAV.Supervisor - CardDAV/CalDAV sync workers
- NexusWeb.Endpoint - Phoenix web server
The pipeline uses GenStage for backpressure-aware processing (lib/nexus/pipeline/):
Producer → Normalizer → GitStore → Classifier → Embedder → SymlinkManager → Consumer
- Producer: Receives messages from channel workers (IMAP, Telegram, etc.)
- Normalizer: Converts channel-specific formats to unified structure
- GitStore: Persists raw content to date-partitioned Git storage
- Classifier: Calls Ollama LLM for intent/priority/action classification
- Embedder: Generates vector embeddings via Ollama
- SymlinkManager: Creates symlink aggregates (by_contact/, by_topic/, etc.)
- Consumer: Indexes metadata in SQLite
Dual storage system:
- Git repository (
data/messages.git/): Raw content with Hive-style partitioning (raw/year=YYYY/month=MM/day=DD/) and symlink aggregates for fast lookups - SQLite (
data/nexus.db): Lightweight metadata index, contact graph, vector embeddings
The LLM client uses a behaviour pattern (Nexus.LLM.Behaviour) for easy mocking:
Nexus.LLM.Ollama- Production implementationNexus.LLM.OllamaMock- Test mock (defined intest/test_helper.exs)
Configure via config/test.exs:
config :nexus, ollama_client: Nexus.LLM.OllamaMockNexus.Contacts.Resolver- Resolves email/phone to contacts, creates new contacts for unknown sendersNexus.Storage.Git- Path generation and symlink management for Git storageNexus.Channels.IMAP.AccountWorker- Per-account GenServer with IDLE/poll supportNexus.Channels.IMAP.Parser- RFC 2822 email parsing
Phoenix LiveView pages in lib/nexus_web/live/:
InboxLive- Message list with real-time updates via PubSubMessageLive- Single message with LLM classificationContactsLive/ContactLive- Contact managementSearchLive- Hybrid search (text + semantic combined), with text-only and semantic-only modesDeduplicationLive- LLM-assisted contact merge review at/contacts/deduplication
JSON API in lib/nexus_web/controllers/api/.
MCP (Model Context Protocol) server in lib/nexus/mcp/:
Server- JSON-RPC 2.0 over stdio, handles protocol handshakeTools- Tool implementations (search, import, reprocess, create_contact)Resources- Resource handlers (messages, contacts, status)
Start with: mix run --no-halt -e "Nexus.MCP.Server.start()"