chant/lib.rs
1//! # Chant - Intent Driven Development
2//!
3//! Chant is a specification-driven development tool that enables reproducible,
4//! auditable AI-assisted development workflows.
5//!
6//! ## Overview
7//!
8//! Specs define work intentions as markdown files with YAML frontmatter. The chant
9//! CLI executes them in isolated git worktrees, ensuring reproducibility and
10//! auditability of all changes.
11//!
12//! ## Core Concepts
13//!
14//! - **Specs**: Markdown files describing work to be done, with acceptance criteria
15//! - **Worktrees**: Isolated git worktrees for spec execution
16//! - **Providers**: Pluggable AI model backends (Claude, Ollama, OpenAI)
17//!
18//! ## Modules
19//!
20//! - [`spec`] - Spec parsing, frontmatter handling, and lifecycle management
21//! - [`spec_group`] - Spec group/driver orchestration logic
22//! - [`config`] - Configuration management for chant projects
23//! - [`git`] - Git provider abstraction for PR creation
24//! - [`provider`] - AI model provider abstraction
25//! - [`worktree`] - Isolated git worktree operations
26//! - [`id`] - Spec ID generation with date-based sequencing
27//! - [`prompt`] - Prompt template management
28//! - [`merge`] - Spec merge logic and utilities
29//!
30//! ## Example
31//!
32//! ```no_run
33//! use std::path::Path;
34//! use chant::spec::{Spec, SpecStatus};
35//! use chant::config::Config;
36//!
37//! // Load project configuration
38//! let config = Config::load().expect("Failed to load config");
39//!
40//! // Load a spec from a file
41//! let spec = Spec::load(Path::new(".chant/specs/2026-01-24-01m-q7e.md"))
42//! .expect("Failed to load spec");
43//!
44//! // Check spec status
45//! match spec.frontmatter.status {
46//! SpecStatus::Pending => println!("Spec is pending"),
47//! SpecStatus::Completed => println!("Spec is complete"),
48//! _ => {}
49//! }
50//! ```
51
52// Re-export all public modules
53pub mod agent;
54pub mod config;
55pub mod conflict;
56pub mod deps;
57pub mod derivation;
58pub mod diagnose;
59pub mod domain;
60pub mod formatters;
61pub mod git;
62pub mod id;
63pub mod mcp;
64pub mod merge;
65pub mod merge_driver;
66pub mod merge_errors;
67pub mod operations;
68pub mod output;
69pub mod pid;
70pub mod prompt;
71pub mod prompts;
72pub mod provider;
73pub mod repository;
74pub mod retry;
75pub mod score;
76pub mod scoring;
77pub mod site;
78pub mod spec;
79pub mod spec_group;
80pub mod spec_template;
81pub mod status;
82pub mod takeover;
83pub mod tools;
84pub mod ui;
85pub mod validation;
86pub mod worktree;
87
88/// Default path constants for chant directory structure.
89pub mod paths {
90 /// Directory containing spec files: `.chant/specs`
91 pub const SPECS_DIR: &str = ".chant/specs";
92 /// Directory containing prompt templates: `.chant/prompts`
93 pub const PROMPTS_DIR: &str = ".chant/prompts";
94 /// Directory containing execution logs: `.chant/logs`
95 pub const LOGS_DIR: &str = ".chant/logs";
96 /// Directory containing archived specs: `.chant/archive`
97 pub const ARCHIVE_DIR: &str = ".chant/archive";
98 /// Directory containing lock files: `.chant/.locks`
99 pub const LOCKS_DIR: &str = ".chant/.locks";
100 /// Directory containing internal store: `.chant/.store`
101 pub const STORE_DIR: &str = ".chant/.store";
102}
103
104/// Generate a UTC timestamp in ISO 8601 format: `YYYY-MM-DDTHH:MM:SSZ`
105///
106/// This function uses `chrono::Utc::now()` to ensure the timestamp is truly in UTC,
107/// not local time with a misleading `Z` suffix.
108pub fn utc_now_iso() -> String {
109 chrono::Utc::now().format("%Y-%m-%dT%H:%M:%SZ").to_string()
110}