AI-powered code snippet & context manager with local semantic search
Project description
SnipContext
AI-powered code snippet & context manager.
Save, search, tag, and instantly inject your best boilerplate, patterns, and context into any LLM (Claude, Cursor, Grok, Windsurf, etc.).
Local-first โ Open source โ Built for humans + AI agents
๐ง Stop Feeding Your AI Clipboard Garbage โ Why SnipContext exists.
Searching, tagging, and exporting code snippets โ all from the terminal. Watch the animated demo (GIF)
Why SnipContext?
- Stop rewriting the same auth flows, component patterns, or utility functions
- Stop feeding LLMs messy or outdated code from your clipboard history
- Build your personal/team "second brain" of high-quality, reusable code
- Semantic search finds code by meaning, not just keywords
- LLM-optimized exports format your snippets for maximum comprehension
Key Features
| Feature | Status | Description |
|---|---|---|
| Rich snippet saving with tags, metadata, and versioning | โ | Full CRUD with soft-delete and encryption |
| Semantic search with local embeddings | โ | sentence-transformers + FAISS, runs offline |
| Hybrid search โ semantic + keyword fusion | โ | Configurable weights, TF-IDF + embeddings |
| LLM-optimized export providers | โ | Claude XML, Cursor, OpenAI, Generic Markdown |
| Auto-tagging via embeddings | โ | Suggests tags based on similar snippets |
| Similarity-based deduplication | โ | Warns when adding near-duplicate snippets |
| Encryption at rest | โ | Fernet (AES-128) with PBKDF2 key derivation |
| File watchdog / real-time indexing | โ | Auto-reindex on file changes |
| Plugin system | โ | Entry points for providers and exporters |
| CLI + Python library | โ | Use from terminal or import as a module |
| Git-friendly local-first storage | โ | One JSON file per snippet, easy to version |
Supported LLM Providers
| Provider | Format | Best For |
|---|---|---|
| Generic | Markdown | Universal compatibility |
| Claude | XML documents | Anthropic Claude |
| Cursor | File-style headers | Cursor IDE |
| OpenAI | Delineated sections | ChatGPT / GPT-4 |
Quick Start
Installation
# From PyPI with uv (recommended โ faster installs, better dependency resolution)
uv tool install snipcontext
# From PyPI with pip
pip install snipcontext
# From source (after cloning)
cd snipcontext
uv sync # install all deps (including dev)
uv run sc --help # run without activating venv
# Or with pip (traditional)
pip install -e ".[dev]"
๐ก Why uv? This project uses `uv` for dependency management (`uv.lock` pinned). `uv sync` guarantees reproducible installs. `pip install` works but may resolve dependencies differently.
Or install directly from GitHub
pip install git+https://github.com/billybox1926-jpg/snipcontext.git
> **๐ฆ Dependency Footprint:** SnipContext's core (add, list, edit, delete, keyword search, export) has no heavy dependencies. Optional features are split into extras:
> - `pip install snipcontext[semantic]` โ semantic search with sentence-transformers + FAISS (~500MB, requires Rust toolchain on ARM)
> - `pip install snipcontext[encryption]` โ encryption at rest with Fernet/AES-128 (requires Rust toolchain on ARM)
> - `pip install snipcontext[tui]` โ interactive terminal UI
> - `pip install snipcontext[all]` โ all optional features
>
> **Lighter embedding model:** The default model is `all-MiniLM-L6-v2` (~80MB). For a lighter alternative, set `SNIPCONTEXT_EMBED_MODEL_NAME=all-MiniLM-L4-v2` (~30MB) or `SNIPCONTEXT_EMBED_MODEL_NAME=paraphrase-MiniLM-L3-v2` (~20MB) before searching.
>
> **Skip semantic at runtime:** Even with `pip install snipcontext[semantic]`, use `--no-semantic` to force keyword-only search for faster results:
> ```bash
> snipcontext search "hello world" --no-semantic
> ```
>
> **ARM / Android / Termux:** The `semantic` and `encryption` extras require Rust to build native wheels. On platforms without pre-built wheels (ARM64, Android/Termux), install the core package only and use keyword search + export features. Semantic search and encryption gracefully degrade with clear error messages when their dependencies are missing.
> **Windows Users:** The short alias `sc` is shadowed by the Windows built-in `sc.exe` (Service Control). Three workarounds are available:
>
> 1. **Full command name** โ always works after installation:
> ```powershell
> snipcontext add "print('hello')" --title "Hello" --tag python
> ```
> 2. **Wrapper script** โ shipped automatically with `pip install`; adds `snipcontext.cmd` to your Scripts directory:
> ```powershell
> snipcontext.cmd search "hello world"
> ```
> 3. **Shell alias** โ for quick access in the current session:
> ```cmd
> doskey snip=python -m snipcontext $*
> ```
### Standalone Binary
Two options for running without a Python environment:
**Option 1 โ `uv tool` (recommended, lightweight):**
```bash
# Core features only (keyword search, export)
uv tool install snipcontext
# All features (semantic search, encryption, TUI, web)
uv tool install "snipcontext[all]"
# Use directly โ uv manages the venv invisibly
snipcontext add "print('hello')" --title "Hello"
Option 2 โ Pre-built binary (no Python needed):
Download from the latest GitHub Release. Two variants are available for each platform:
| Variant | Includes | Size (approx.) |
|---|---|---|
snipcontext-<platform> |
Everything (semantic, encryption, TUI, web) | ~200MB |
snipcontext-<platform>-minimal |
Core only (keyword search, export) | ~80MB |
# Linux / macOS
chmod +x snipcontext
./snipcontext search "hello world"
# Windows
snipcontext.exe search "hello world"
Build from source:
# Using Make
make build-binary # full build
make build-binary-minimal # core-only build
# Using PyInstaller directly
pip install pyinstaller
pyinstaller snipcontext.spec
# Output: dist/snipcontext (or dist/snipcontext.exe)
Security Considerations
- Encryption at rest: Uses Fernet (AES-128-CBC with HMAC) with PBKDF2 key derivation (100k iterations). Passphrase is read from
SNIPCONTEXT_ENCRYPTION_PASSPHRASEenv var โ never pass it on the command line (shell history leak). - No default passphrase: If encryption is enabled but
SNIPCONTEXT_ENCRYPTION_PASSPHRASEis not set, the tool raises an error rather than falling back to a known default. This prevents a false sense of security. - stdin for sensitive content: Use
sc add --file secret.pyor pipe via stdin (cat secret.py | sc add --file) to avoid shell history leaks with--encrypt. - Salt: Auto-generated on first use and persisted to the config file. Back up your config file to avoid losing access to encrypted snippets.
- No network calls: All processing is local. No data leaves your machine.
# Windows: use the full command name or the .cmd wrapper
snipcontext add "print('hello')" --title "Hello" --tag python
snipcontext search "hello world"
snipcontext list
snipcontext stats
# Or run via module
python -m snipcontext add "print('hello')" --title "Hello" --tag python
Verify Installation
snipcontext --help # or: python -m snipcontext --help
snipcontext providers # List available export providers
CLI Usage
# Add a snippet
snipcontext add "def authenticate(token):\n return jwt.decode(token, SECRET)" \
--title "JWT Authentication" \
--desc "Decode and verify JWT tokens" \
--lang python \
--tag auth --tag jwt --tag security
# Search semantically
snipcontext search "how to validate auth tokens"
# Search by tag
snipcontext search "auth" --mode tag
# Export for Claude
snipcontext search "authentication" --provider claude --output context.xml
# List all snippets
snipcontext list
# Show stats
snipcontext stats
# Delete a snippet
snipcontext delete <snippet-id>
# Edit a snippet
snipcontext edit <snippet-id> --title "New Title" --add-tag python
# Rebuild search index
snipcontext build-index --force
# Watch for file changes and auto-reindex
snipcontext watch
# Run the demo
snipcontext demo
Library Usage
from snipcontext.core.models import Snippet, SnippetMetadata, Language
from snipcontext.core.storage import StorageEngine
from snipcontext.core.search import HybridSearch
from snipcontext.config.settings import get_config
# Initialize
config = get_config()
storage = StorageEngine(config)
# Create and save a snippet
snippet = Snippet(
content="def memoize(fn):\n cache = {}\n ...",
metadata=SnippetMetadata(
title="Memoization Decorator",
description="Cache function results",
language=Language.PYTHON,
),
tags=["python", "decorator", "performance"],
)
storage.save(snippet)
# Search with semantic understanding
searcher = HybridSearch(config)
searcher.index_snippets(storage.list_all())
results = searcher.search("cache function results decorator")
for r in results:
print(f"{r.score:.3f} | {r.snippet.metadata.title}")
๐ Encryption at Rest
SnipContext supports Fernet (AES-128) encryption for sensitive snippets. When enabled, snippet content is encrypted at rest using a key derived from a passphrase via PBKDF2 (100k iterations).
Enable Encryption
# Enable encryption (required)
export SNIPCONTEXT_ENCRYPT_ENABLED=true
# Set passphrase (used for key derivation)
export SNIPCONTEXT_ENCRYPTION_PASSPHRASE="your-secure-passphrase"
# Optional: persist salt to config (auto-generated if omitted)
export SNIPCONTEXT_ENCRYPT_KEY_SALT="base64-encoded-salt"
Encrypt Snippets
# Encrypt a new snippet
snipcontext add "api_key = 'sk-12345'" \
--title "API Key" \
--tag secret \
--encrypt
# Mark as sensitive (auto-enables encryption)
snipcontext add "password = 'secret123'" \
--title "DB Password" \
--sensitive
Decrypt for Viewing/Editing
# Decrypt for viewing
snipcontext decrypt <snippet-id>
# Encrypt an existing snippet
snipcontext encrypt <snippet-id>
Note: When encrypted, the plaintext
contentis cleared from storage. Theencrypted_contentfield stores the encrypted data. Usesnipcontext decrypt <id>to restore plaintext for editing.
๐ Index Rebuild & Resilience
SnipContext automatically detects and recovers from index corruption. The HybridSearch engine validates index integrity on load and rebuilds automatically when needed.
Manual Rebuild
# Build or rebuild the semantic search index
snipcontext build-index
# Force rebuild (useful after corruption, dependency changes, or mode switches)
snipcontext build-index --force
Auto-Recovery
The search engine automatically:
- Validates index integrity on load (checks ID map lengths, matrix dimensions)
- Cleans up corrupted files (deletes mismatched/corrupted index files)
- Falls back gracefully โ if semantic index unavailable, runs keyword-only search
- Rebuilds on demand โ
index_snippets()auto-loads existing indices before rebuilding
Watchdog / Real-time Indexing
Run snipcontext watch to monitor the snippets directory and automatically reindex when files change:
snipcontext watch
Disable via config if you prefer manual rebuilds only:
export SNIPCONTEXT_WATCHDOG_ENABLED=false
Architecture
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ CLI (Typer + Rich) โ
โโโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโค
โ add โ search โ export โ edit/delete โ
โ list โ stats โ watch โ demo โ
โโโโโโฌโโโโโโดโโโโโฌโโโโโโดโโโโโฌโโโโโโดโโโโโโโโฌโโโโโโโโโ
โ โ โ โ
โผ โผ โผ โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Search Engine (HybridSearch) โ
โ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Semantic โ โ Keyword โ โ
โ โ FAISS Index โ โ TF-IDF (sklearn) โ โ
โ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Storage Engine โ
โ Git-friendly JSON per snippet โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Data Models (Pydantic v2) โ
โ Snippet / SnippetMetadata / Language โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
See docs/ARCHITECTURE.md for detailed design documentation.
Configuration
SnipContext uses environment variables and a YAML config file:
# Use GPU for embeddings
export SNIPCONTEXT_EMBED_DEVICE="cuda"
# Change embedding model
export SNIPCONTEXT_EMBED_MODEL_NAME="all-mpnet-base-v2"
# Adjust search weights
export SNIPCONTEXT_SEARCH_SEMANTIC_WEIGHT="0.8"
# Enable auto-tagging
export SNIPCONTEXT_AUTO_TAG_ENABLED=true
# Enable deduplication
export SNIPCONTEXT_DEDUP_ENABLED=true
export SNIPCONTEXT_DEDUP_THRESHOLD="0.95"
Or edit ~/.config/SnipContext/snipcontext.yaml:
embedding:
model_name: "all-MiniLM-L6-v2"
device: "cpu"
search:
default_mode: "hybrid"
semantic_weight: 0.7
keyword_weight: 0.3
top_k: 10
auto_tag:
enabled: true
threshold: 0.75
dedup:
enabled: true
threshold: 0.95
Development
# Clone
git clone https://github.com/billybox1926-jpg/snipcontext.git
cd snipcontext
# Install dev dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Run with coverage
pytest --cov=snipcontext
# Linting
ruff check .
mypy .
# Install pre-commit hooks
pre-commit install
Roadmap
- Core snippet CRUD with git-friendly storage
- Semantic + hybrid search with local embeddings
- LLM-optimized export providers (Claude, Cursor, OpenAI, Generic)
- Rich CLI with Typer
- Plugin system with entry points
- Python library distribution (PyPI)
- Auto-tagging and deduplication
- Encryption at rest
- File watchdog / real-time indexing
- Import from GitHub Gists
- Import from Git repositories
- Snippet templates and scaffolding
- Team sharing via git-sync
- VS Code extension
Project Structure
snipcontext/
โโโ src/snipcontext/ # Python package
โ โโโ __init__.py
โ โโโ __main__.py # python -m snipcontext
โ โโโ cli/
โ โ โโโ main.py # Typer CLI commands
โ โโโ config/
โ โ โโโ settings.py # Pydantic Settings
โ โโโ core/
โ โ โโโ models.py # Pydantic data models
โ โ โโโ storage.py # Git-friendly JSON storage
โ โ โโโ search.py # Semantic + hybrid search
โ โ โโโ auto_tag.py # Embedding-based auto-tagging
โ โ โโโ watcher.py # File watchdog
โ โโโ plugins/
โ โ โโโ base.py # Plugin base + manager
โ โโโ providers/
โ โโโ base.py # Provider interface
โ โโโ claude.py # Anthropic Claude XML
โ โโโ cursor.py # Cursor IDE format
โ โโโ openai.py # OpenAI format
โ โโโ generic.py # Universal Markdown
โโโ tests/ # Test suite
โโโ docs/ # Documentation
โ โโโ ARCHITECTURE.md
โ โโโ API.md
โ โโโ MAINTAINER.md
โโโ pyproject.toml
โโโ CHANGELOG.md
โโโ README.md
License & Contributing
MIT License โ see LICENSE for details.
Contributions are welcome! Please read CONTRIBUTING.md and CODE_OF_CONDUCT.md first. New contributors should check out our Good First Issues.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file snipcontext-0.3.0.tar.gz.
File metadata
- Download URL: snipcontext-0.3.0.tar.gz
- Upload date:
- Size: 67.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1d6d1b5b99a58db52e154c42b8da010ee33e01386d65c2fda52d2379e1f0917c
|
|
| MD5 |
1309885829a8fc8c07ee53dff90afc64
|
|
| BLAKE2b-256 |
e637d93fdc3159320f7d05af64eb3d0d51dd85f8d997468386ccfb33bb63e61a
|
Provenance
The following attestation bundles were made for snipcontext-0.3.0.tar.gz:
Publisher:
release.yml on billybox1926-jpg/snipcontext
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
snipcontext-0.3.0.tar.gz -
Subject digest:
1d6d1b5b99a58db52e154c42b8da010ee33e01386d65c2fda52d2379e1f0917c - Sigstore transparency entry: 1901577822
- Sigstore integration time:
-
Permalink:
billybox1926-jpg/snipcontext@5048e4e416ce44e924d08fae88e3eef4ea5e8ad3 -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/billybox1926-jpg
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@5048e4e416ce44e924d08fae88e3eef4ea5e8ad3 -
Trigger Event:
push
-
Statement type:
File details
Details for the file snipcontext-0.3.0-py3-none-any.whl.
File metadata
- Download URL: snipcontext-0.3.0-py3-none-any.whl
- Upload date:
- Size: 84.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0ef87f2b555993abd877fb70c7481238deabe619b4777a0da9238d6d6b0227cf
|
|
| MD5 |
7281a9a5eb7cde1fb0e70b3af2531dc4
|
|
| BLAKE2b-256 |
2e5d92cbf691669a7e4067ddcd252ceedf4c8a0c910c882fe251660460338c0d
|
Provenance
The following attestation bundles were made for snipcontext-0.3.0-py3-none-any.whl:
Publisher:
release.yml on billybox1926-jpg/snipcontext
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
snipcontext-0.3.0-py3-none-any.whl -
Subject digest:
0ef87f2b555993abd877fb70c7481238deabe619b4777a0da9238d6d6b0227cf - Sigstore transparency entry: 1901577962
- Sigstore integration time:
-
Permalink:
billybox1926-jpg/snipcontext@5048e4e416ce44e924d08fae88e3eef4ea5e8ad3 -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/billybox1926-jpg
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@5048e4e416ce44e924d08fae88e3eef4ea5e8ad3 -
Trigger Event:
push
-
Statement type: