intent_engine/setup/
mod.rs

1//! Setup module for configuring intent-engine integration with AI tools
2//!
3//! This module provides a unified setup command that configures both hooks and MCP servers
4//! for various AI assistant tools (Claude Code, Gemini CLI, Codex, etc.)
5
6use crate::error::{IntentError, Result};
7use serde::{Deserialize, Serialize};
8use std::path::PathBuf;
9use std::str::FromStr;
10
11pub mod claude_code;
12pub mod common;
13pub mod interactive;
14
15/// Installation scope for setup
16#[derive(Debug, Clone, Copy, PartialEq, Eq)]
17pub enum SetupScope {
18    /// User-level installation (recommended, works across all projects)
19    User,
20    /// Project-level installation (specific to current project)
21    Project,
22    /// Both user and project level
23    Both,
24}
25
26impl FromStr for SetupScope {
27    type Err = IntentError;
28
29    fn from_str(s: &str) -> Result<Self> {
30        match s.to_lowercase().as_str() {
31            "user" => Ok(SetupScope::User),
32            "project" => Ok(SetupScope::Project),
33            "both" => Ok(SetupScope::Both),
34            _ => Err(IntentError::InvalidInput(format!(
35                "Invalid scope: {}. Must be 'user', 'project', or 'both'",
36                s
37            ))),
38        }
39    }
40}
41
42/// Options for setup operations
43#[derive(Debug, Clone)]
44pub struct SetupOptions {
45    /// Installation scope
46    pub scope: SetupScope,
47    /// Dry run mode (show what would be done)
48    pub dry_run: bool,
49    /// Force overwrite existing configuration
50    pub force: bool,
51    /// Custom config file path (optional)
52    pub config_path: Option<PathBuf>,
53    /// Project directory for INTENT_ENGINE_PROJECT_DIR env var
54    pub project_dir: Option<PathBuf>,
55}
56
57impl Default for SetupOptions {
58    fn default() -> Self {
59        Self {
60            scope: SetupScope::User,
61            dry_run: false,
62            force: false,
63            config_path: None,
64            project_dir: None,
65        }
66    }
67}
68
69/// Result of a setup operation
70#[derive(Debug, Serialize, Deserialize)]
71pub struct SetupResult {
72    /// Whether the operation succeeded
73    pub success: bool,
74    /// Human-readable message
75    pub message: String,
76    /// Files that were created or modified
77    pub files_modified: Vec<PathBuf>,
78    /// Connectivity test result (if performed)
79    pub connectivity_test: Option<ConnectivityResult>,
80}
81
82/// Result of a connectivity test
83#[derive(Debug, Serialize, Deserialize)]
84pub struct ConnectivityResult {
85    /// Whether the test passed
86    pub passed: bool,
87    /// Test details
88    pub details: String,
89}
90
91/// Result of a diagnosis operation
92#[derive(Debug, Serialize, Deserialize)]
93pub struct DiagnosisReport {
94    /// Overall status (all checks passed?)
95    pub overall_status: bool,
96    /// Individual check results
97    pub checks: Vec<DiagnosisCheck>,
98    /// Suggested fixes for failed checks
99    pub suggested_fixes: Vec<String>,
100}
101
102/// Individual diagnosis check
103#[derive(Debug, Serialize, Deserialize)]
104pub struct DiagnosisCheck {
105    /// Check name
106    pub name: String,
107    /// Whether the check passed
108    pub passed: bool,
109    /// Details or error message
110    pub details: String,
111}
112
113/// Trait for setup modules
114pub trait SetupModule {
115    /// Module name (e.g., "claude-code")
116    fn name(&self) -> &str;
117
118    /// Perform setup
119    fn setup(&self, opts: &SetupOptions) -> Result<SetupResult>;
120
121    /// Diagnose existing setup
122    fn diagnose(&self) -> Result<DiagnosisReport>;
123
124    /// Test connectivity
125    fn test_connectivity(&self) -> Result<ConnectivityResult>;
126}