@@ -4,6 +4,8 @@ use maabarium_core::{
44 ExportFormat , GitDependencyEnsureOutcome , Persistence , PromotionOutcome , SecretStore ,
55 UpdaterConfiguration , check_for_cli_update, default_db_path, default_log_path,
66 ensure_git_dependency, install_cli_update,
7+ ReadinessLevel , ReadinessScanner ,
8+ analyze_workspace, apply_all_fixes, detect_recommended_profile,
79} ;
810use maabarium_core:: error:: UpdaterError ;
911use secrecy:: { ExposeSecret , SecretString } ;
@@ -49,6 +51,21 @@ enum Commands {
4951 #[ command( subcommand) ]
5052 action : KeysAction ,
5153 } ,
54+ /// Check and fix setup readiness
55+ Setup {
56+ /// Non-interactive readiness check (exit 0 = ready, 1 = needs attention)
57+ #[ arg( long) ]
58+ check : bool ,
59+ /// Output readiness report as JSON
60+ #[ arg( long) ]
61+ json : bool ,
62+ /// Workspace path to analyze
63+ #[ arg( long) ]
64+ workspace : Option < String > ,
65+ /// Runtime strategy hint: local, mixed, remote
66+ #[ arg( long) ]
67+ strategy : Option < String > ,
68+ } ,
5269 /// Inspect and update the CLI binary itself
5370 #[ command( name = "self" ) ]
5471 SelfManage {
@@ -182,6 +199,60 @@ async fn main() -> anyhow::Result<()> {
182199 println ! ( "{}" , render_delete_key_message( & secret_store, & provider) ?) ;
183200 }
184201 } ,
202+ Commands :: Setup {
203+ check,
204+ json,
205+ workspace,
206+ strategy,
207+ } => {
208+ let workspace_ref = workspace. as_deref ( ) ;
209+ let strategy_ref = strategy. as_deref ( ) ;
210+ let report = ReadinessScanner :: scan ( workspace_ref, strategy_ref) ;
211+
212+ if json {
213+ println ! ( "{}" , serde_json:: to_string_pretty( & report) ?) ;
214+ } else {
215+ render_readiness_report ( & report, workspace_ref) ;
216+ }
217+
218+ if check {
219+ if !report. is_ready ( ) {
220+ std:: process:: exit ( 1 ) ;
221+ }
222+ } else {
223+ // Interactive: attempt fixes for items needing attention
224+ let needs_fix = report. needs_attention ( ) ;
225+ if needs_fix. is_empty ( ) {
226+ println ! ( "\n All checks passed. Maabarium is ready to run." ) ;
227+ } else {
228+ println ! ( "\n Attempting one-click fixes..." ) ;
229+ let outcomes = apply_all_fixes ( workspace_ref) ;
230+ for outcome in & outcomes {
231+ let icon = if outcome. success { "[OK]" } else { "[!!]" } ;
232+ println ! ( " {icon} {}" , outcome. message) ;
233+ }
234+ if outcomes. iter ( ) . any ( |o| !o. success ) {
235+ println ! ( "\n Some fixes require manual intervention. See messages above." ) ;
236+ } else {
237+ println ! ( "\n All automatic fixes applied successfully." ) ;
238+ }
239+ }
240+
241+ // Show workspace analysis if workspace provided
242+ if let Some ( ws) = workspace_ref {
243+ let analysis = analyze_workspace ( ws) ;
244+ render_workspace_analysis ( & analysis) ;
245+ }
246+
247+ // Show recommended profile
248+ let recommended = detect_recommended_profile ( ) ;
249+ println ! (
250+ "\n Recommended environment profile: {} - {}" ,
251+ recommended. label( ) ,
252+ recommended. description( )
253+ ) ;
254+ }
255+ }
185256 Commands :: SelfManage { action } => match action {
186257 SelfAction :: Version => {
187258 println ! ( "maabarium {}" , env!( "CARGO_PKG_VERSION" ) ) ;
@@ -435,6 +506,59 @@ fn render_delete_key_message(
435506 }
436507}
437508
509+ fn render_readiness_report ( report : & maabarium_core:: ReadinessReport , workspace : Option < & str > ) {
510+ println ! ( "Maabarium Setup Readiness Report" ) ;
511+ println ! ( "===============================" ) ;
512+ if let Some ( ws) = workspace {
513+ println ! ( "Workspace: {ws}" ) ;
514+ }
515+ println ! ( ) ;
516+
517+ for item in & report. items {
518+ let icon = match item. status {
519+ ReadinessLevel :: Ready => "[OK]" ,
520+ ReadinessLevel :: Optional => "[--]" ,
521+ ReadinessLevel :: NeedsAction => "[!!]" ,
522+ } ;
523+ println ! ( "{} {}" , icon, item. title) ;
524+ println ! ( " {}" , item. summary) ;
525+ if let Some ( fix) = & item. fix_label {
526+ println ! ( " Action: {fix}" ) ;
527+ }
528+ if let Some ( hint) = & item. fix_hint {
529+ println ! ( " Hint: {hint}" ) ;
530+ }
531+ println ! ( ) ;
532+ }
533+
534+ if report. is_ready ( ) {
535+ println ! ( "Status: READY - All checks passed." ) ;
536+ } else {
537+ let count = report. needs_attention ( ) . len ( ) ;
538+ println ! ( "Status: NEEDS ATTENTION - {count} item(s) require fixes." ) ;
539+ }
540+ }
541+
542+ fn render_workspace_analysis ( analysis : & maabarium_core:: WorkspaceAnalysis ) {
543+ println ! ( "\n Workspace Analysis: {}" , analysis. path) ;
544+ println ! ( " {}" , analysis. project_summary) ;
545+ if let Some ( lang) = & analysis. language {
546+ println ! ( " Language: {lang}" ) ;
547+ }
548+ if let Some ( cmd) = & analysis. test_command {
549+ println ! ( " Test command: {cmd}" ) ;
550+ }
551+ if !analysis. suggested_target_files . is_empty ( ) {
552+ println ! (
553+ " Suggested targets: {}" ,
554+ analysis. suggested_target_files. join( ", " )
555+ ) ;
556+ }
557+ if analysis. has_ci_config {
558+ println ! ( " CI configuration detected" ) ;
559+ }
560+ }
561+
438562#[ cfg( test) ]
439563mod tests {
440564 use super :: * ;
0 commit comments