Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions COVEN.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ are rebranded. This boundary is explicit and documented below.
| Binary name | `src-rust/crates/cli/src/main.rs`, `src-rust/crates/cli/src/bin/coven-cave.rs` | `coven-code`; `coven-cave` alias |
| npm package | `npm/package.json` | `@opencoven/coven-code` |
| Data/cache dirs | `src-rust/crates/core/src/snapshot/`, `skill_discovery.rs`, `update_check.rs`, `app.rs` | `coven-code/` |
| Engine home (standalone) | `src-rust/crates/core/src/lib.rs` (`config_home`) | `~/.coven-code/` |
| Engine home (under coven CLI) | `src-rust/crates/core/src/lib.rs` (`config_home`) | `~/.coven/code/` — migrated in-place from `~/.coven-code/` on first launch; legacy path is symlinked to new location |
| Env var prefix | throughout `src-rust/` | `COVEN_CODE_*` |
| User-Agent | `src-rust/crates/tools/src/web_search.rs`, `update_check.rs` | `CovenCode/x.y` |
| System prompt identity | `src-rust/crates/core/src/system_prompt.rs` | "You are Coven Code…" |
Expand Down
5 changes: 5 additions & 0 deletions src-rust/crates/cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,11 @@ fn handle_exit_key(
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// Perform a best-effort, non-fatal relocation of the engine home from the
// legacy ~/.coven-code/ to ~/.coven/code/ when running under the unified
// coven CLI. Must run before any Settings::load() or auth/config access.
claurst_core::home_migration::migrate_if_needed();

let raw_args: Vec<String> = std::env::args().collect();

// Fast-path: `coven-code upgrade [--version <v>] [--force]` — self-update.
Expand Down
4 changes: 1 addition & 3 deletions src-rust/crates/core/src/accounts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,9 +255,7 @@ pub fn ensure_unique_profile_id(registry: &AccountRegistry, provider: &str, base

/// `~/.coven-code/`.
pub fn claurst_dir() -> PathBuf {
dirs::home_dir()
.unwrap_or_else(|| PathBuf::from("."))
.join(".coven-code")
crate::config::config_home()
}

/// `~/.coven-code/accounts/<provider>/<id>/`.
Expand Down
2 changes: 1 addition & 1 deletion src-rust/crates/core/src/attachments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ pub fn get_attachments(ctx: &AttachmentContext<'_>) -> Vec<Attachment> {
/// Returns a formatted string like:
/// `IDE: VS Code, workspace: /path/to/project, selection: L10-L20 in foo.rs`
pub fn get_ide_context() -> Option<String> {
let lockfile_dir = dirs::home_dir()?.join(".coven-code").join("ide");
let lockfile_dir = crate::config::config_home().join("ide");
let entries = std::fs::read_dir(&lockfile_dir).ok()?;

for entry in entries.flatten() {
Expand Down
5 changes: 1 addition & 4 deletions src-rust/crates/core/src/auth_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,7 @@ pub struct AuthStore {
impl AuthStore {
/// Path to the auth store file.
pub fn path() -> PathBuf {
let dir = dirs::home_dir()
.unwrap_or_else(|| PathBuf::from("."))
.join(".coven-code");
dir.join("auth.json")
crate::config::config_home().join("auth.json")
}

/// Load the store from disk (returns default if missing or invalid).
Expand Down
23 changes: 10 additions & 13 deletions src-rust/crates/core/src/claudemd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -911,9 +911,10 @@ pub fn load_all_memory_files_with_options(
let mut files = Vec::new();

// 1. Managed: ~/.coven-code/rules/*.md
if let Some(home) = memory_home_dir() {
{
let config_home = crate::config::config_home();
if options.allow_managed_rules {
let rules_dir = home.join(".coven-code/rules");
let rules_dir = config_home.join("rules");
if let Ok(entries) = std::fs::read_dir(&rules_dir) {
let mut paths: Vec<PathBuf> = entries
.flatten()
Expand All @@ -937,7 +938,7 @@ pub fn load_all_memory_files_with_options(

// 2. User: ~/.coven-code/AGENTS.md then ~/.coven-code/CLAUDE.md
if options.allow_user_memory {
load_scope_files(&home.join(".coven-code"), MemoryScope::User, &mut files);
load_scope_files(&config_home, MemoryScope::User, &mut files);
}
}

Expand Down Expand Up @@ -973,16 +974,12 @@ pub fn enumerate_context_memory_files(
let mut files: Vec<MemoryFileInfo> = Vec::new();

if options.allow_user_memory {
if let Some(home) = dirs::home_dir() {
let global = home
.join(".coven-code")
.join(crate::constants::CLAUDE_MD_FILENAME);
if global.exists() {
if let Some(file) = load_memory_file(&global, MemoryScope::User)
.filter(|file| memory_file_allowed_for_options(file, options))
{
files.push(file);
}
let global = crate::config::config_home().join(crate::constants::CLAUDE_MD_FILENAME);
if global.exists() {
if let Some(file) = load_memory_file(&global, MemoryScope::User)
.filter(|file| memory_file_allowed_for_options(file, options))
{
files.push(file);
}
}
}
Expand Down
9 changes: 2 additions & 7 deletions src-rust/crates/core/src/context_collapse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,7 @@ fn summarize_messages(messages: Vec<Message>, _max_tokens: u64) -> (Vec<Message>
/// Persist collapse state to ~/.coven-code/context_collapse_state.json
#[cfg(feature = "cached_microcompact")]
pub fn save_collapse_state(_session_id: &str, state: &CollapseState) -> anyhow::Result<()> {
let path = dirs::home_dir()
.ok_or_else(|| anyhow::anyhow!("Could not determine home directory"))?
.join(".coven-code")
.join("context_collapse_state.json");
let path = crate::config::config_home().join("context_collapse_state.json");

std::fs::create_dir_all(path.parent().unwrap())?;
let json = serde_json::to_string(state)?;
Expand All @@ -167,9 +164,7 @@ pub fn save_collapse_state(_session_id: &str, state: &CollapseState) -> anyhow::
/// Load collapse state from ~/.coven-code/context_collapse_state.json
#[cfg(feature = "cached_microcompact")]
pub fn load_collapse_state(_session_id: &str) -> Option<CollapseState> {
let path = dirs::home_dir()?
.join(".coven-code")
.join("context_collapse_state.json");
let path = crate::config::config_home().join("context_collapse_state.json");

if !path.exists() {
return None;
Expand Down
28 changes: 17 additions & 11 deletions src-rust/crates/core/src/feature_flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ pub struct FeatureFlagManager {
http_client: reqwest::Client,
}

impl FeatureFlagManager {
impl FeatureFlagManager {
/// Create a new feature flag manager
///
/// The API key is automatically fetched from the GROWTHBOOK_API_KEY environment variable.
Expand All @@ -66,12 +66,11 @@ impl FeatureFlagManager {
cache_ttl,
http_client: reqwest::Client::new(),
}
}
}

/// Get the cache file path (~/.coven-code/feature_flags.json)
fn get_cache_path() -> PathBuf {
let home = dirs::home_dir().unwrap_or_else(|| PathBuf::from("."));
home.join(".coven-code").join("feature_flags.json")
crate::config::config_home().join("feature_flags.json")
}

/// Check if a feature flag is enabled
Expand Down Expand Up @@ -213,13 +212,13 @@ impl FeatureFlagManager {
}
debug!("Loaded {} feature flags", flags.len());
}
}

impl Default for FeatureFlagManager {
fn default() -> Self {
Self::new()
}
}
}
impl Default for FeatureFlagManager {
fn default() -> Self {
Self::new()
}
}

/// Response from GrowthBook API
#[derive(Debug, Deserialize)]
Expand All @@ -228,6 +227,13 @@ struct GrowthBookApiResponse {
pub features: Vec<FeatureFlag>,
}

/// Test accessor — exposes the private cache path for cross-module
/// consolidation tests (Phase 4.1).
#[cfg(test)]
pub(crate) fn feature_flags_cache_path_for_test() -> PathBuf {
FeatureFlagManager::get_cache_path()
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
16 changes: 13 additions & 3 deletions src-rust/crates/core/src/goal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,13 +161,13 @@ impl GoalStore {
}

/// Default path: `~/.coven-code/goals.sqlite`.
pub fn default_path() -> Option<PathBuf> {
dirs::home_dir().map(|h| h.join(".coven-code").join("goals.sqlite"))
pub fn default_path() -> PathBuf {
crate::config::config_home().join("goals.sqlite")
}

/// Open using the default path (best-effort; returns None on failure).
pub fn open_default() -> Option<Self> {
Self::default_path().and_then(|p| Self::open(&p).ok())
Self::open(&Self::default_path()).ok()
}

fn now_ms() -> u64 {
Expand Down Expand Up @@ -697,4 +697,14 @@ mod tests {
std::env::remove_var("COVEN_CODE_GOALS");
}
}

#[test]
fn default_path_derives_from_config_home() {
let path = GoalStore::default_path();
assert!(
path.starts_with(crate::config::config_home()),
"default_path {path:?} should start with config_home()"
);
assert_eq!(path.file_name().unwrap(), "goals.sqlite");
}
}
Loading