Skip to main content

chronicle/cli/
init.rs

1use std::path::PathBuf;
2
3use crate::error::chronicle_error::{GitSnafu, IoSnafu};
4use crate::error::Result;
5use crate::git::CliOps;
6use crate::git::GitOps;
7use crate::hooks::install_hooks;
8use crate::sync::enable_sync;
9use snafu::ResultExt;
10
11use super::util::find_git_dir;
12
13pub fn run(no_sync: bool, no_hooks: bool) -> Result<()> {
14    // Find the git directory
15    let git_dir = find_git_dir()?;
16
17    // Create .git/chronicle/ directory
18    let chronicle_dir = git_dir.join("chronicle");
19    std::fs::create_dir_all(&chronicle_dir).context(IoSnafu)?;
20
21    // Set up git config
22    let repo_dir = git_dir.parent().unwrap_or(&git_dir).to_path_buf();
23    let ops = CliOps::new(repo_dir.clone());
24
25    ops.config_set("chronicle.enabled", "true")
26        .context(GitSnafu)?;
27
28    // Install hooks unless --no-hooks
29    if !no_hooks {
30        install_hooks(&git_dir)?;
31        eprintln!("installed post-commit hook");
32    }
33
34    // Enable notes sync by default (push/fetch refspecs on origin)
35    if !no_sync {
36        ops.config_set("chronicle.sync", "true").context(GitSnafu)?;
37        let remote = "origin";
38        match enable_sync(&repo_dir, remote) {
39            Ok(()) => eprintln!("notes sync enabled for remote '{remote}'"),
40            Err(e) => eprintln!("warning: could not enable notes sync: {e}"),
41        }
42    }
43
44    eprintln!("chronicle initialized in {}", chronicle_dir.display());
45
46    // Check if global skills are installed
47    if let Ok(home) = std::env::var("HOME") {
48        let skills_dir = PathBuf::from(&home)
49            .join(".claude")
50            .join("skills")
51            .join("chronicle");
52        if !skills_dir.exists() {
53            eprintln!();
54            eprintln!("TIP: Run `git chronicle setup` to install Claude Code skills globally.");
55        }
56    }
57
58    Ok(())
59}