Metadata-Version: 2.4
Name: shannon-cortex
Version: 0.1.0
Summary: Persistent long-term memory for Claude Code — episodic, semantic, and procedural memory augmentation
Project-URL: Homepage, https://github.com/shiloht1/shannon-cortex
Project-URL: Repository, https://github.com/shiloht1/shannon-cortex
Project-URL: Issues, https://github.com/shiloht1/shannon-cortex/issues
Author: Shiloh
License-Expression: AGPL-3.0-or-later
License-File: LICENSE
Keywords: claude-code,embeddings,llm,memory,rag,vector-search
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.11
Requires-Dist: fastapi>=0.115.0
Requires-Dist: httpx>=0.28.0
Requires-Dist: pydantic-settings>=2.6.0
Requires-Dist: pydantic>=2.10.0
Requires-Dist: pyyaml>=6.0
Requires-Dist: qdrant-client>=1.12.0
Requires-Dist: sentence-transformers>=3.3.0
Requires-Dist: tiktoken>=0.8.0
Requires-Dist: uvicorn[standard]>=0.32.0
Provides-Extra: all
Requires-Dist: accelerate>=1.1.0; extra == 'all'
Requires-Dist: pytest-asyncio>=0.24.0; extra == 'all'
Requires-Dist: pytest-cov>=6.0; extra == 'all'
Requires-Dist: pytest>=8.0; extra == 'all'
Requires-Dist: ruff>=0.8.0; extra == 'all'
Requires-Dist: transformers>=4.46.0; extra == 'all'
Requires-Dist: tree-sitter-bash>=0.23.0; extra == 'all'
Requires-Dist: tree-sitter-javascript>=0.23.0; extra == 'all'
Requires-Dist: tree-sitter-python>=0.23.0; extra == 'all'
Requires-Dist: tree-sitter-typescript>=0.23.0; extra == 'all'
Requires-Dist: tree-sitter-yaml>=0.6.0; extra == 'all'
Requires-Dist: tree-sitter>=0.23.0; extra == 'all'
Provides-Extra: code
Requires-Dist: tree-sitter-bash>=0.23.0; extra == 'code'
Requires-Dist: tree-sitter-javascript>=0.23.0; extra == 'code'
Requires-Dist: tree-sitter-python>=0.23.0; extra == 'code'
Requires-Dist: tree-sitter-typescript>=0.23.0; extra == 'code'
Requires-Dist: tree-sitter-yaml>=0.6.0; extra == 'code'
Requires-Dist: tree-sitter>=0.23.0; extra == 'code'
Provides-Extra: consolidation
Requires-Dist: accelerate>=1.1.0; extra == 'consolidation'
Requires-Dist: transformers>=4.46.0; extra == 'consolidation'
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
Requires-Dist: pytest-cov>=6.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.8.0; extra == 'dev'
Description-Content-Type: text/markdown

# Shannon-Cortex

Persistent long-term memory for [Claude Code](https://docs.anthropic.com/en/docs/build-with-claude/claude-code). Gives your AI development agent human-like episodic, semantic, and procedural memory that persists across sessions.

Inspired by [OpenClaw](https://github.com/openclaw/openclaw) and [memsearch](https://github.com/zilliztech/memsearch), Shannon-Cortex runs entirely local — no API keys for memory, no cloud dependencies, no token costs for retrieval.

## What it does

Shannon-Cortex runs as a lightweight background daemon that hooks into Claude Code's lifecycle:

- **Remember** what happened in past sessions (episodic memory)
- **Know** facts about your projects, preferences, and patterns (semantic memory)
- **Recall** how to perform recurring tasks and debug common issues (procedural memory)

Memories are automatically captured, scored for importance, and retrieved using hybrid vector search (dense + BM25 + RRF) with optional neural re-ranking — surfacing the right context at the right time without saturating the context window.

## How it works

```
You send a prompt → Shannon-Cortex searches memory → injects relevant context
                                                       ↓
Claude responds    → Shannon-Cortex extracts memories → stores important ones
                                                       ↓
Overnight          → Consolidation clusters memories  → synthesizes knowledge
```

Every prompt triggers a <150ms memory search. Every response is scored for importance and stored if valuable. Nightly, episodic memories are clustered and synthesized into semantic knowledge using a local LLM.

## Quick Start

### Prerequisites

- Python 3.11+
- Docker (for Qdrant, or bring your own Qdrant instance)
- `jq` and `curl` (the installer will prompt if missing)
- CUDA GPU recommended (works on CPU too, just slower embeddings)

### Install

```bash
git clone https://github.com/shiloht1/shannon-cortex.git
cd shannon-cortex
bash scripts/install.sh        # Auto-detects GPU, Qdrant, reranker
```

The installer will:
1. Check dependencies (python, jq, curl, GPU, Qdrant)
2. Create a virtualenv at `~/.venvs/shannon-cortex/`
3. Install the package and download the embedding model (~1.2 GB first run)
4. Create `~/.shannon-cortex/config.yaml` (auto-configured for your system)
5. Set up the Qdrant collection
6. Install systemd services
7. Print the hooks config to add to Claude Code

### If you don't have Qdrant running

```bash
docker compose up -d                   # Starts Qdrant on localhost:6333
python scripts/setup-qdrant.py         # Creates the memory collection
```

### Start the daemon

```bash
systemctl --user start shannon-cortex
systemctl --user enable shannon-cortex   # Auto-start on login
```

Or run in foreground for debugging:
```bash
source ~/.venvs/shannon-cortex/bin/activate
shannon-cortex start -f
```

### Register Claude Code hooks

Add this to your `~/.claude/settings.json` (the installer prints the exact paths):

```json
{
  "hooks": {
    "SessionStart": [{"hooks": [{"type": "command", "command": "/path/to/shannon-cortex/hooks/session-start.sh"}]}],
    "UserPromptSubmit": [{"hooks": [{"type": "command", "command": "/path/to/shannon-cortex/hooks/user-prompt-submit.sh"}]}],
    "PreCompact": [{"hooks": [{"type": "command", "command": "/path/to/shannon-cortex/hooks/pre-compact.sh"}]}],
    "Stop": [{"hooks": [{"type": "command", "command": "/path/to/shannon-cortex/hooks/stop.sh", "async": true}]}],
    "SessionEnd": [{"hooks": [{"type": "command", "command": "/path/to/shannon-cortex/hooks/session-end.sh", "async": true}]}]
  }
}
```

### Verify

```bash
shannon-cortex status
```

You should see: embedding model loaded, Qdrant connected, memory count.

## CPU-only mode

No GPU? No problem:

```bash
bash scripts/install.sh --cpu
```

Or set in `~/.shannon-cortex/config.yaml`:
```yaml
embedding:
  device: cpu
```

Embeddings will be slower (~200ms vs ~10ms) but everything works.

## Architecture

| Component | Technology | Purpose |
|-----------|-----------|---------|
| Embedding | Qwen3-Embedding-0.6B | 768-dim vectors via sentence-transformers |
| Vector DB | Qdrant | Hybrid dense + BM25 search with RRF fusion |
| Re-ranking | NVIDIA NIM (optional) | Cross-encoder re-ranking of search candidates |
| Storage | Markdown files | Human-readable source of truth, git-friendly |
| Daemon | FastAPI on Unix socket | Serves search/ingest, loads model once |
| Consolidation | Qwen3-0.6B (local) | Nightly episodic-to-semantic reflection |

### Memory types (modeled after human cognition)

| Type | What it stores | Decay | Example |
|------|---------------|-------|---------|
| **Episodic** | Session events | 30-day half-life | "Debugged a race condition by adding a mutex" |
| **Semantic** | Consolidated facts | 365-day half-life | "Project uses Redpanda for streaming" |
| **Procedural** | How-to patterns | Never decays | "To deploy: stop container, pull, clear cache, restart" |

### Hook lifecycle

| Hook | Timing | What happens |
|------|--------|-------------|
| SessionStart | Sync | Prefetch recent project memories |
| UserPromptSubmit | Sync (<150ms) | Search + inject top 3 memories |
| Stop | Async | Extract + score + store new memories |
| PreCompact | Sync | Flush before context compression |
| SessionEnd | Async | Generate session summary |

## CLI Commands

```bash
shannon-cortex start [-f]              # Start daemon (foreground with -f)
shannon-cortex stop                    # Stop daemon
shannon-cortex status                  # Show health, memory counts
shannon-cortex search "query"          # Search memories manually
shannon-cortex forget <memory-id>      # Delete a specific memory
shannon-cortex reindex                 # Rebuild Qdrant from Markdown files
shannon-cortex consolidate [--dry-run] # Run nightly consolidation manually
```

## Configuration

See [config.example.yaml](config.example.yaml) for all options. Key settings:

```yaml
embedding:
  device: cuda          # or "cpu"
reranker:
  enabled: false        # true if you have NVIDIA NIM
scoring:
  min_importance_for_injection: 5   # Higher = fewer, more relevant memories
hooks:
  max_injected_memories: 3          # Memories per prompt (more = richer but noisier)
```

Full docs: [docs/configuration.md](docs/configuration.md)

## How memories are scored

Every piece of content gets an importance score (1-10):

| Score | Signal | Example |
|-------|--------|---------|
| 9-10 | User correction | "Actually, use port 8080 not 8081" |
| 8-9 | Explicit preference | "I prefer functional style" |
| 7-8 | Error resolution | "Fixed by updating the import path" |
| 7-8 | Architecture decision | "Let's use event sourcing" |
| 2-3 | Routine code gen | Generic boilerplate |
| 1 | Trivial | "hello", "thanks", "ok" |

Memories scoring below 3 are discarded. Below 5 are stored but not injected into prompts.

## Documentation

- [Architecture](docs/architecture.md) — System design, data flow, scoring formula
- [Configuration](docs/configuration.md) — All settings with examples
- [Installation](docs/installation.md) — Detailed install guide
- [Hooks Integration](docs/hooks-integration.md) — How Claude Code hooks work

## Monitoring

Shannon-Cortex exposes a Prometheus metrics endpoint at `/metrics` on the Unix socket. A Grafana dashboard is included in `monitoring/grafana-dashboard.json`.

## License

AGPL-3.0 — Free to use, modify, and distribute. If you run a modified version as a network service, you must share your source code. See [LICENSE](LICENSE) for details.
