Contributing
Thank you for your interest in contributing to Lore! This guide covers development setup and contribution guidelines.
Getting Started
Section titled “Getting Started”Prerequisites
Section titled “Prerequisites”- Rust 1.92 or later (install via rustup)
- Git
Development Setup
Section titled “Development Setup”# Clone the repositorygit clone https://github.com/varalys/lore.gitcd lore
# Build the projectcargo build
# Run testscargo test
# Run the CLIcargo run -- --helpCode Quality Checks
Section titled “Code Quality Checks”Before submitting changes, ensure all checks pass:
cargo check # No compiler errorscargo clippy --all-targets # No warnings (zero tolerance)cargo test # All tests passcargo fmt --check # Code is formattedProject Structure
Section titled “Project Structure”lore/├── src/│ ├── main.rs # CLI entry point│ ├── lib.rs # Library exports│ ├── cli/│ │ └── commands/ # CLI command implementations│ ├── capture/│ │ └── watchers/ # Tool-specific session parsers│ │ ├── mod.rs # Watcher trait and registry│ │ ├── common.rs # Shared parsing utilities│ │ ├── vscode_extension.rs # Generic VS Code watcher│ │ ├── claude_code.rs│ │ └── ... # Other tool watchers│ ├── daemon/ # Background service│ ├── git/ # Git integration│ └── storage/ # SQLite database layer├── tests/ # Integration tests└── docs/ # Design documentsAdding a New Watcher
Section titled “Adding a New Watcher”Watchers parse session files from AI coding tools. There are two approaches depending on the tool type.
For Tool Creators
Section titled “For Tool Creators”If you build an AI coding tool and want Lore to support it, open an issue with:
- Tool name and website
- Storage location: Where session files are stored (e.g.,
~/.yourtool/sessions/) - File format: JSON, JSONL, Markdown, SQLite, etc.
- Schema documentation or example session files (sanitized of sensitive data)
We can help build the watcher, or you can submit a PR yourself.
Option 1: VS Code Extension (Cline-style)
Section titled “Option 1: VS Code Extension (Cline-style)”If the tool is a VS Code extension using Cline-style task storage (with api_conversation_history.json files), use the generic VsCodeExtensionWatcher. This requires only ~25 lines of code:
//! My Extension session parser.
use super::vscode_extension::{VsCodeExtensionConfig, VsCodeExtensionWatcher};
/// Configuration for My Extension watcher.pub const CONFIG: VsCodeExtensionConfig = VsCodeExtensionConfig { name: "my-extension", description: "My Extension VS Code sessions", extension_id: "publisher.my-extension", // From VS Code marketplace};
/// Creates a new My Extension watcher instance.pub fn new_watcher() -> VsCodeExtensionWatcher { VsCodeExtensionWatcher::new(CONFIG)}
#[cfg(test)]mod tests { use super::*;
#[test] fn test_config() { assert_eq!(CONFIG.name, "my-extension"); assert_eq!(CONFIG.extension_id, "publisher.my-extension"); }}Then register it in mod.rs:
pub mod my_extension;
// In default_registry():registry.register(Box::new(my_extension::new_watcher()));Option 2: CLI Tool or Custom Format
Section titled “Option 2: CLI Tool or Custom Format”For tools with unique session formats, implement the Watcher trait directly:
use anyhow::Result;use std::path::{Path, PathBuf};
use crate::storage::models::{Message, Session};use super::{Watcher, WatcherInfo};use super::common::{parse_role, parse_timestamp_millis};
pub struct MyToolWatcher;
impl Watcher for MyToolWatcher { fn info(&self) -> WatcherInfo { WatcherInfo { name: "my-tool", description: "My Tool CLI sessions", default_paths: vec![my_tool_dir()], } }
fn is_available(&self) -> bool { my_tool_dir().exists() }
fn find_sources(&self) -> Result<Vec<PathBuf>> { // Return paths to session files find_session_files() }
fn parse_source(&self, path: &Path) -> Result<Vec<(Session, Vec<Message>)>> { // Parse the file and return sessions with messages let parsed = parse_my_tool_session(path)?; Ok(vec![(parsed.session, parsed.messages)]) }
fn watch_paths(&self) -> Vec<PathBuf> { vec![my_tool_dir()] }}
fn my_tool_dir() -> PathBuf { dirs::home_dir() .unwrap_or_else(|| PathBuf::from(".")) .join(".my-tool") .join("sessions")}Shared Utilities
Section titled “Shared Utilities”Use helpers from common.rs to avoid code duplication:
| Function | Purpose |
|---|---|
parse_role(s) | Convert “user”/“assistant”/“system” to MessageRole |
parse_timestamp_millis(ms) | Parse millisecond timestamps to DateTime<Utc> |
parse_timestamp_rfc3339(s) | Parse RFC3339 timestamp strings |
parse_uuid_or_generate(s) | Parse UUID string or generate a new one |
vscode_global_storage() | Get platform-specific VS Code global storage path |
Testing Your Watcher
Section titled “Testing Your Watcher”- Unit tests in your watcher file for parsing logic
- Trait tests are automatically run via
test_common.rs - Manual verification:
cargo run -- status # Check watcher appearscargo run -- import --dry-run # Check it finds sessionsCode Style
Section titled “Code Style”Rust Guidelines
Section titled “Rust Guidelines”- Follow standard Rust conventions and idioms
- Use
rustfmtfor formatting - Use
thiserrorfor custom error types - Use
anyhowfor application error handling - Keep functions focused and small
Documentation
Section titled “Documentation”- Add
///doc comments to all public items - Add
//!module-level docs to each module - Keep comments concise and focused on “why” not “what”
- No emojis in code or documentation
Testing
Section titled “Testing”- Write unit tests for new functions
- Test edge cases and error conditions
- Ensure tests are deterministic (no flaky tests)
Submitting Changes
Section titled “Submitting Changes”Branch Naming
Section titled “Branch Naming”feat/description # New featuresfix/description # Bug fixesrefactor/description # Code improvementsdocs/description # DocumentationCommit Messages
Section titled “Commit Messages”Use conventional commits:
feat: add support for new-tool sessionsfix: handle empty session files gracefullyrefactor: consolidate watcher parsing logicdocs: update architecture diagramPull Request Process
Section titled “Pull Request Process”- Create a feature branch from
main - Make your changes with tests
- Ensure all checks pass (
cargo test,cargo clippy,cargo fmt --check) - Open a PR with a clear description
- Address review feedback
AI-Assisted Contributions
Section titled “AI-Assisted Contributions”Contributions developed with AI assistance are welcome. All contributions, regardless of how they were created, must meet the same quality standards and pass the same review process. The contributor submitting the PR is responsible for understanding and standing behind the code.
Questions?
Section titled “Questions?”- Open an issue for bugs or feature requests
- Check existing issues before creating new ones