cai_core/lib.rs
1//! # CAI Core - Shared types, traits, and utilities
2//!
3//! This crate provides the foundational data structures and shared utilities
4//! used throughout the CAI (Coding Agent Insights) workspace.
5//!
6//! ## Overview
7//!
8//! `cai-core` defines the core domain model for representing AI coding interactions.
9//! All other crates in the workspace depend on these types to ensure consistency
10//! across the system.
11//!
12//! ## Core Types
13//!
14//! - [`Entry`] - Represents a single AI coding interaction with all associated data
15//! - [`Source`] - Identifies the origin system (Claude, Codex, Git, etc.)
16//! - [`Metadata`] - Extensible metadata for additional context
17//! - [`Error`] - Unified error type for CAI operations
18//! - [`Result<T>`] - Type alias for `Result<T, Error>`
19//!
20//! ## Usage
21//!
22//! Creating a basic entry:
23//!
24//! ```rust
25//! use cai_core::{Entry, Source, Metadata};
26//! use chrono::Utc;
27//!
28//! let entry = Entry {
29//! id: "test-entry-123".to_string(),
30//! source: Source::Claude,
31//! timestamp: Utc::now(),
32//! prompt: "Help me refactor this function".to_string(),
33//! response: "Here's the improved version...".to_string(),
34//! metadata: Metadata::default(),
35//! };
36//! ```
37//!
38//! Working with metadata:
39//!
40//! ```rust
41//! use cai_core::Metadata;
42//! use std::collections::HashMap;
43//!
44//! let mut metadata = Metadata {
45//! file_path: Some("src/main.rs".to_string()),
46//! repo_url: Some("https://github.com/user/repo".to_string()),
47//! commit_hash: Some("abc123def".to_string()),
48//! language: Some("Rust".to_string()),
49//! extra: HashMap::new(),
50//! };
51//!
52//! // Add custom fields
53//! metadata.extra.insert("complexity".to_string(), "high".to_string());
54//! metadata.extra.insert("reviewed".to_string(), "true".to_string());
55//! ```
56//!
57//! Error handling:
58//!
59//! ```rust
60//! use cai_core::{Error, Result, Entry};
61//!
62//! fn process_entry(entry: &Entry) -> Result<()> {
63//! if entry.prompt.is_empty() {
64//! return Err(Error::Message("Prompt cannot be empty".to_string()));
65//! }
66//! // Process the entry...
67//! Ok(())
68//! }
69//! ```
70//!
71//! ## Design Principles
72//!
73//! - **Minimal dependencies**: Only essential dependencies (serde, chrono)
74//! - **Serialization**: All public types implement `Serialize` and `Deserialize`
75//! - **Extensibility**: `Metadata.extra` allows custom fields without breaking changes
76//! - **Type safety**: Enums use `#[non_exhaustive]` for future-proofing
77//!
78//! ## Testing
79//!
80//! ```bash
81//! # Run all tests
82//! cargo test -p cai-core
83//!
84//! # Run with coverage
85//! cargo llvm-cov -p cai-core
86//! ```
87
88#![warn(missing_docs)]
89
90use chrono::{DateTime, Utc};
91use serde::{Deserialize, Serialize};
92
93/// Core entry representing a single AI coding interaction
94#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
95pub struct Entry {
96 /// Unique identifier
97 pub id: String,
98 /// Source system (claude, codex, git, etc.)
99 pub source: Source,
100 /// Timestamp of the interaction
101 pub timestamp: DateTime<Utc>,
102 /// The prompt/input provided
103 pub prompt: String,
104 /// The response/output received
105 pub response: String,
106 /// Associated metadata
107 pub metadata: Metadata,
108}
109
110/// Source system identifier
111#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
112#[non_exhaustive]
113pub enum Source {
114 /// Claude Code conversations
115 Claude,
116 /// Codex CLI history
117 Codex,
118 /// Git repository activity
119 Git,
120 /// Other source
121 Other(String),
122}
123
124/// Metadata associated with an entry
125#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
126pub struct Metadata {
127 /// Optional file path if applicable
128 pub file_path: Option<String>,
129 /// Optional repository URL
130 pub repo_url: Option<String>,
131 /// Optional commit hash
132 pub commit_hash: Option<String>,
133 /// Optional language/technology
134 pub language: Option<String>,
135 /// Additional custom fields (as key-value pairs)
136 #[serde(default)]
137 pub extra: std::collections::HashMap<String, String>,
138}
139
140/// Result type for CAI operations
141pub type Result<T> = std::result::Result<T, Error>;
142
143/// Core error types
144#[derive(Debug, thiserror::Error)]
145#[non_exhaustive]
146pub enum Error {
147 /// I/O error
148 #[error("I/O error: {0}")]
149 Io(#[from] std::io::Error),
150
151 /// JSON parsing error
152 #[error("JSON error: {0}")]
153 Json(#[from] serde_json::Error),
154
155 /// Generic error message
156 #[error("{0}")]
157 Message(String),
158}