1pub use doctor::DoctorChecks;
51pub use license::LicenseType;
52pub use types::{DoctorCheck, RepoInfo};
53
54pub mod agent;
56pub mod app;
57pub mod command;
58pub mod completions;
59pub mod doctor;
60pub mod error;
61pub mod json;
62pub mod license;
63pub mod output;
64pub mod progress;
65pub mod runner;
66pub mod types;
67pub mod update;
68
69pub use agent::{
71 AGENT_TOKEN_ENV, AGENT_TOKEN_EXPECTED_ENV, AgentCapability, AgentDispatch, AgentModeContext,
72 AgentSkillError, AgentSurfaceSpec, CommandSelector, FlagSelector, apply_agent_surface,
73 parse_with_agent_surface, parse_with_agent_surface_from, render_agent_help, render_agent_skill,
74};
75pub use app::{ToolSpec, workspace_tool};
76pub use command::{
77 NoDoctor, StandardCommand, StandardCommandMap, map_standard_command,
78 maybe_run_standard_command, maybe_run_standard_command_no_doctor,
79 parse_command_ref_with_agent_surface_from, parse_command_with_agent_surface,
80 parse_command_with_agent_surface_from, run_standard_command_no_doctor,
81};
82pub use completions::{
83 CompletionOutput, generate_completions, generate_completions_from_command, render_completion,
84 render_completion_from_command, render_completion_instructions, write_completion,
85};
86pub use doctor::{DoctorReport, print_doctor_report_json, print_doctor_report_text, run_doctor};
87pub use error::{fatal_error, print_error};
88pub use json::{
89 err_response, ok_response, render_response, render_response_parts, render_response_with,
90};
91pub use license::display_license;
92pub use progress::make_spinner;
93pub use runner::{
94 FatalCliError, parse_and_exit, parse_and_run, run_with_display_error_handler,
95 run_with_fatal_handler,
96};
97
98#[cfg(test)]
99pub mod test_support {
101 use std::sync::{Mutex, MutexGuard, OnceLock};
102
103 static ENV_LOCK: OnceLock<Mutex<()>> = OnceLock::new();
104
105 pub fn env_lock() -> MutexGuard<'static, ()> {
107 ENV_LOCK
108 .get_or_init(|| Mutex::new(()))
109 .lock()
110 .unwrap_or_else(std::sync::PoisonError::into_inner)
111 }
112}
113
114#[cfg(test)]
115mod tests {
116 use super::*;
117
118 #[test]
119 fn test_repo_info_creation() {
120 let repo = RepoInfo::new("workhelix", "test");
121 assert_eq!(repo.owner, "workhelix");
122 assert_eq!(repo.name, "test");
123 }
124
125 #[test]
126 fn test_doctor_check_creation() {
127 let check = DoctorCheck::pass("test");
128 assert!(check.passed);
129
130 let check = DoctorCheck::fail("test", "failed");
131 assert!(!check.passed);
132 }
133
134 #[test]
135 fn test_license_type() {
136 assert_eq!(LicenseType::MIT.name(), "MIT");
137 assert_eq!(LicenseType::Apache2.name(), "Apache-2.0");
138 assert_eq!(LicenseType::CC0.name(), "CC0-1.0");
139 }
140}