1#![cfg_attr(
2 not(test),
3 deny(clippy::unwrap_used, clippy::panic, clippy::indexing_slicing)
4)]
5#![cfg_attr(
9 test,
10 allow(
11 clippy::disallowed_methods,
12 clippy::expect_used,
13 clippy::indexing_slicing,
14 clippy::panic,
15 clippy::unwrap_used,
16 reason = "ported fixtures use fail-fast assertions; TODO.md tracks replacing these test-only exceptions"
17 )
18)]
19pub use doctor::DoctorChecks;
69pub use license::LicenseType;
70pub use types::{DoctorCheck, RepoInfo};
71
72pub mod agent;
74pub mod agent_skill;
75pub mod app;
76pub mod binary;
77pub mod command;
78pub mod completions;
79pub mod doctor;
80pub mod error;
81pub mod json;
82pub mod license;
83pub mod meta;
84pub mod output;
85pub mod progress;
86pub mod prompt;
87pub mod runner;
88pub mod types;
89
90pub use agent::{
92 AGENT_TOKEN_ENV, AGENT_TOKEN_EXPECTED_ENV, AgentCapability, AgentDispatch, AgentModeContext,
93 AgentSkillError, AgentSurfaceSpec, CommandSelector, FlagSelector, ProcessEnv,
94 apply_agent_surface, parse_with_agent_surface_from, render_agent_help, render_agent_skill,
95};
96pub use agent::{AgentSubcommand, DescribeFormat, EmitScope, EmitTarget, ListFormat};
97pub use agent_skill::{
98 EmitDirError, render_describe, render_list, render_skill_md, resolve_emit_dir,
99 run_agent_subcommand, skill_name,
100};
101pub use app::{ContractError, ToolContract, ToolSpec, workspace_tool};
102pub use binary::{run_cli_from, run_cli_no_doctor_from};
103pub use command::{
104 NoDoctor, StandardCommand, StandardCommandMap, map_standard_command,
105 maybe_run_standard_command, maybe_run_standard_command_no_doctor,
106 parse_command_ref_with_agent_surface_from, parse_command_with_agent_surface_from,
107 run_standard_command_no_doctor,
108};
109pub use completions::{
110 CompletionOutput, generate_completions, generate_completions_from_command, render_completion,
111 render_completion_from_command, render_completion_instructions, write_completion,
112};
113pub use doctor::{
114 DoctorReport, print_doctor_report_json, print_doctor_report_text, run_doctor,
115 run_doctor_with_output,
116};
117pub use error::{fatal_error, print_error};
118pub use json::{
119 JsonOutput, err_response, ok_response, render_response, render_response_parts,
120 render_response_with,
121};
122pub use license::display_license;
123pub use meta::MetaCommand;
124pub use progress::make_spinner;
125pub use runner::{
126 FatalCliError, parse_and_exit, parse_and_run, run_with_display_error_handler,
127 run_with_fatal_handler,
128};
129
130#[cfg(test)]
131pub mod test_support {
133 use std::sync::{Mutex, MutexGuard, OnceLock};
134
135 static ENV_LOCK: OnceLock<Mutex<()>> = OnceLock::new();
136
137 pub fn env_lock() -> MutexGuard<'static, ()> {
139 ENV_LOCK
140 .get_or_init(|| Mutex::new(()))
141 .lock()
142 .unwrap_or_else(std::sync::PoisonError::into_inner)
143 }
144}
145
146#[cfg(test)]
147mod tests {
148 use super::*;
149
150 #[test]
151 fn test_repo_info_creation() {
152 let repo = RepoInfo::new("workhelix", "test");
153 assert_eq!(repo.owner, "workhelix");
154 assert_eq!(repo.name, "test");
155 }
156
157 #[test]
158 fn test_doctor_check_creation() {
159 let check = DoctorCheck::pass("test");
160 assert!(check.passed);
161
162 let check = DoctorCheck::fail("test", "failed");
163 assert!(!check.passed);
164 }
165
166 #[test]
167 fn test_license_type() {
168 assert_eq!(LicenseType::MIT.name(), "MIT");
169 assert_eq!(LicenseType::Apache2.name(), "Apache-2.0");
170 assert_eq!(LicenseType::CC0.name(), "CC0-1.0");
171 }
172}