From 7587f2c1ebff72e95949decde9c97c4974623d8b Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Thu, 9 Apr 2026 23:35:25 +0900 Subject: [PATCH] fix(cli): JSON parity for /memory and /providers in resume mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two gaps closed: 1. /memory (resume): json field was None, emitting prose regardless of --output-format json. Now emits: {kind:memory, cwd, instruction_files:N, files:[{path,lines,preview}...]} 2. /providers (resume): had a spec entry but no parse arm, producing the circular 'Unknown slash command: /providers — Did you mean /providers'. Added 'providers' as an alias for 'doctor' in the parse match so /providers dispatches to the same structured diagnostic output. 3. /doctor (resume): also wired json_value() so --output-format json returns the structured doctor report instead of None. Continues ROADMAP #26 resumed-command JSON parity track. 159 CLI tests pass, fmt clean. --- rust/crates/commands/src/lib.rs | 2 +- rust/crates/rusty-claude-cli/src/main.rs | 37 ++++++++++++++++++++---- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/rust/crates/commands/src/lib.rs b/rust/crates/commands/src/lib.rs index d68b486..df76813 100644 --- a/rust/crates/commands/src/lib.rs +++ b/rust/crates/commands/src/lib.rs @@ -1320,7 +1320,7 @@ pub fn validate_slash_command_input( "skills" | "skill" => SlashCommand::Skills { args: parse_skills_args(remainder.as_deref())?, }, - "doctor" => { + "doctor" | "providers" => { validate_no_args(command, &args)?; SlashCommand::Doctor } diff --git a/rust/crates/rusty-claude-cli/src/main.rs b/rust/crates/rusty-claude-cli/src/main.rs index 601999b..e7ced4a 100644 --- a/rust/crates/rusty-claude-cli/src/main.rs +++ b/rust/crates/rusty-claude-cli/src/main.rs @@ -2773,7 +2773,7 @@ fn run_resume_command( SlashCommand::Memory => Ok(ResumeCommandOutcome { session: session.clone(), message: Some(render_memory_report()?), - json: None, + json: Some(render_memory_json()?), }), SlashCommand::Init => { let message = init_claude_md()?; @@ -2829,11 +2829,14 @@ fn run_resume_command( json: Some(handle_skills_slash_command_json(args.as_deref(), &cwd)?), }) } - SlashCommand::Doctor => Ok(ResumeCommandOutcome { - session: session.clone(), - message: Some(render_doctor_report()?.render()), - json: None, - }), + SlashCommand::Doctor => { + let report = render_doctor_report()?; + Ok(ResumeCommandOutcome { + session: session.clone(), + message: Some(report.render()), + json: Some(report.json_value()), + }) + } SlashCommand::Stats => { let usage = UsageTracker::from_session(session).cumulative_usage(); Ok(ResumeCommandOutcome { @@ -5421,6 +5424,28 @@ fn render_memory_report() -> Result> { )) } +fn render_memory_json() -> Result> { + let cwd = env::current_dir()?; + let project_context = ProjectContext::discover(&cwd, DEFAULT_DATE)?; + let files: Vec<_> = project_context + .instruction_files + .iter() + .map(|f| { + json!({ + "path": f.path.display().to_string(), + "lines": f.content.lines().count(), + "preview": f.content.lines().next().unwrap_or("").trim(), + }) + }) + .collect(); + Ok(json!({ + "kind": "memory", + "cwd": cwd.display().to_string(), + "instruction_files": files.len(), + "files": files, + })) +} + fn init_claude_md() -> Result> { let cwd = env::current_dir()?; Ok(initialize_repo(&cwd)?.render())