Restore Rust formatting compliance

Run rustfmt from the Rust workspace so CI format checks pass without changing behavior.

Constraint: Scope is formatting-only across tracked Rust files

Confidence: high

Scope-risk: narrow

Tested: cd rust && cargo fmt --check

Tested: git diff --check
This commit is contained in:
Yeachan-Heo 2026-04-28 09:19:16 +00:00
parent 77afde768c
commit 74ea754d29
5 changed files with 140 additions and 87 deletions

View File

@ -753,14 +753,14 @@ mod tests {
#[test] #[test]
fn returns_context_window_metadata_for_kimi_models() { fn returns_context_window_metadata_for_kimi_models() {
// kimi-k2.5 // kimi-k2.5
let k25_limit = model_token_limit("kimi-k2.5") let k25_limit =
.expect("kimi-k2.5 should have token limit metadata"); model_token_limit("kimi-k2.5").expect("kimi-k2.5 should have token limit metadata");
assert_eq!(k25_limit.max_output_tokens, 16_384); assert_eq!(k25_limit.max_output_tokens, 16_384);
assert_eq!(k25_limit.context_window_tokens, 256_000); assert_eq!(k25_limit.context_window_tokens, 256_000);
// kimi-k1.5 // kimi-k1.5
let k15_limit = model_token_limit("kimi-k1.5") let k15_limit =
.expect("kimi-k1.5 should have token limit metadata"); model_token_limit("kimi-k1.5").expect("kimi-k1.5 should have token limit metadata");
assert_eq!(k15_limit.max_output_tokens, 16_384); assert_eq!(k15_limit.max_output_tokens, 16_384);
assert_eq!(k15_limit.context_window_tokens, 256_000); assert_eq!(k15_limit.context_window_tokens, 256_000);
} }
@ -768,11 +768,13 @@ mod tests {
#[test] #[test]
fn kimi_alias_resolves_to_kimi_k25_token_limits() { fn kimi_alias_resolves_to_kimi_k25_token_limits() {
// The "kimi" alias resolves to "kimi-k2.5" via resolve_model_alias() // The "kimi" alias resolves to "kimi-k2.5" via resolve_model_alias()
let alias_limit = model_token_limit("kimi") let alias_limit =
.expect("kimi alias should resolve to kimi-k2.5 limits"); model_token_limit("kimi").expect("kimi alias should resolve to kimi-k2.5 limits");
let direct_limit = model_token_limit("kimi-k2.5") let direct_limit = model_token_limit("kimi-k2.5").expect("kimi-k2.5 should have limits");
.expect("kimi-k2.5 should have limits"); assert_eq!(
assert_eq!(alias_limit.max_output_tokens, direct_limit.max_output_tokens); alias_limit.max_output_tokens,
direct_limit.max_output_tokens
);
assert_eq!( assert_eq!(
alias_limit.context_window_tokens, alias_limit.context_window_tokens,
direct_limit.context_window_tokens direct_limit.context_window_tokens

View File

@ -2195,9 +2195,16 @@ mod tests {
#[test] #[test]
fn provider_specific_size_limits_are_correct() { fn provider_specific_size_limits_are_correct() {
assert_eq!(OpenAiCompatConfig::dashscope().max_request_body_bytes, 6_291_456); // 6MB assert_eq!(
assert_eq!(OpenAiCompatConfig::openai().max_request_body_bytes, 104_857_600); // 100MB OpenAiCompatConfig::dashscope().max_request_body_bytes,
assert_eq!(OpenAiCompatConfig::xai().max_request_body_bytes, 52_428_800); // 50MB 6_291_456
); // 6MB
assert_eq!(
OpenAiCompatConfig::openai().max_request_body_bytes,
104_857_600
); // 100MB
assert_eq!(OpenAiCompatConfig::xai().max_request_body_bytes, 52_428_800);
// 50MB
} }
#[test] #[test]

View File

@ -2623,10 +2623,8 @@ fn render_mcp_report_json_for(
// runs, the existing serializer adds `status: "ok"` below. // runs, the existing serializer adds `status: "ok"` below.
match loader.load() { match loader.load() {
Ok(runtime_config) => { Ok(runtime_config) => {
let mut value = render_mcp_summary_report_json( let mut value =
cwd, render_mcp_summary_report_json(cwd, runtime_config.mcp().servers());
runtime_config.mcp().servers(),
);
if let Some(map) = value.as_object_mut() { if let Some(map) = value.as_object_mut() {
map.insert("status".to_string(), Value::String("ok".to_string())); map.insert("status".to_string(), Value::String("ok".to_string()));
map.insert("config_load_error".to_string(), Value::Null); map.insert("config_load_error".to_string(), Value::Null);

View File

@ -228,8 +228,10 @@ fn main() {
// don't need to regex-scrape the prose. // don't need to regex-scrape the prose.
let kind = classify_error_kind(&message); let kind = classify_error_kind(&message);
if message.contains("`claw --help`") { if message.contains("`claw --help`") {
eprintln!("[error-kind: {kind}] eprintln!(
error: {message}"); "[error-kind: {kind}]
error: {message}"
);
} else { } else {
eprintln!( eprintln!(
"[error-kind: {kind}] "[error-kind: {kind}]
@ -419,19 +421,17 @@ fn run() -> Result<(), Box<dyn std::error::Error>> {
CliAction::Config { CliAction::Config {
section, section,
output_format, output_format,
} => { } => match output_format {
match output_format { CliOutputFormat::Text => {
CliOutputFormat::Text => { println!("{}", render_config_report(section.as_deref())?);
println!("{}", render_config_report(section.as_deref())?);
}
CliOutputFormat::Json => {
println!(
"{}",
serde_json::to_string_pretty(&render_config_json(section.as_deref())?)?
);
}
} }
} CliOutputFormat::Json => {
println!(
"{}",
serde_json::to_string_pretty(&render_config_json(section.as_deref())?)?
);
}
},
CliAction::Diff { output_format } => match output_format { CliAction::Diff { output_format } => match output_format {
CliOutputFormat::Text => { CliOutputFormat::Text => {
println!("{}", render_diff_report()?); println!("{}", render_diff_report()?);
@ -635,13 +635,7 @@ fn parse_args(args: &[String]) -> Result<CliAction, String> {
} }
"--help" | "-h" "--help" | "-h"
if !rest.is_empty() if !rest.is_empty()
&& matches!( && matches!(rest[0].as_str(), "prompt" | "commit" | "pr" | "issue") =>
rest[0].as_str(),
"prompt"
| "commit"
| "pr"
| "issue"
) =>
{ {
// `--help` following a subcommand that would otherwise forward // `--help` following a subcommand that would otherwise forward
// the arg to the API (e.g. `claw prompt --help`) should show // the arg to the API (e.g. `claw prompt --help`) should show
@ -1327,7 +1321,6 @@ fn suggest_closest_term<'a>(input: &str, candidates: &'a [&'a str]) -> Option<&'
ranked_suggestions(input, candidates).into_iter().next() ranked_suggestions(input, candidates).into_iter().next()
} }
fn suggest_similar_subcommand(input: &str) -> Option<Vec<String>> { fn suggest_similar_subcommand(input: &str) -> Option<Vec<String>> {
const KNOWN_SUBCOMMANDS: &[&str] = &[ const KNOWN_SUBCOMMANDS: &[&str] = &[
"help", "help",
@ -1357,8 +1350,7 @@ fn suggest_similar_subcommand(input: &str) -> Option<Vec<String>> {
let prefix_match = common_prefix_len(&normalized_input, &normalized_candidate) >= 4; let prefix_match = common_prefix_len(&normalized_input, &normalized_candidate) >= 4;
let substring_match = normalized_candidate.contains(&normalized_input) let substring_match = normalized_candidate.contains(&normalized_input)
|| normalized_input.contains(&normalized_candidate); || normalized_input.contains(&normalized_candidate);
((distance <= 2) || prefix_match || substring_match) ((distance <= 2) || prefix_match || substring_match).then_some((distance, *candidate))
.then_some((distance, *candidate))
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
ranked.sort_by(|left, right| left.cmp(right).then_with(|| left.1.cmp(right.1))); ranked.sort_by(|left, right| left.cmp(right).then_with(|| left.1.cmp(right.1)));
@ -1378,7 +1370,6 @@ fn common_prefix_len(left: &str, right: &str) -> usize {
.count() .count()
} }
fn looks_like_subcommand_typo(input: &str) -> bool { fn looks_like_subcommand_typo(input: &str) -> bool {
!input.is_empty() !input.is_empty()
&& input && input
@ -1487,13 +1478,11 @@ fn validate_model_syntax(model: &str) -> Result<(), String> {
err_msg.push_str("\nDid you mean `openai/"); err_msg.push_str("\nDid you mean `openai/");
err_msg.push_str(trimmed); err_msg.push_str(trimmed);
err_msg.push_str("`? (Requires OPENAI_API_KEY env var)"); err_msg.push_str("`? (Requires OPENAI_API_KEY env var)");
} } else if trimmed.starts_with("qwen") {
else if trimmed.starts_with("qwen") {
err_msg.push_str("\nDid you mean `qwen/"); err_msg.push_str("\nDid you mean `qwen/");
err_msg.push_str(trimmed); err_msg.push_str(trimmed);
err_msg.push_str("`? (Requires DASHSCOPE_API_KEY env var)"); err_msg.push_str("`? (Requires DASHSCOPE_API_KEY env var)");
} } else if trimmed.starts_with("grok") {
else if trimmed.starts_with("grok") {
err_msg.push_str("\nDid you mean `xai/"); err_msg.push_str("\nDid you mean `xai/");
err_msg.push_str(trimmed); err_msg.push_str(trimmed);
err_msg.push_str("`? (Requires XAI_API_KEY env var)"); err_msg.push_str("`? (Requires XAI_API_KEY env var)");
@ -4338,7 +4327,6 @@ impl LiveCli {
Ok(()) Ok(())
} }
fn run_prompt_compact_json(&mut self, input: &str) -> Result<(), Box<dyn std::error::Error>> { fn run_prompt_compact_json(&mut self, input: &str) -> Result<(), Box<dyn std::error::Error>> {
let (mut runtime, hook_abort_monitor) = self.prepare_turn_runtime(false)?; let (mut runtime, hook_abort_monitor) = self.prepare_turn_runtime(false)?;
let mut permission_prompter = CliPermissionPrompter::new(self.permission_mode); let mut permission_prompter = CliPermissionPrompter::new(self.permission_mode);
@ -5457,7 +5445,13 @@ fn print_status_snapshot(
match output_format { match output_format {
CliOutputFormat::Text => println!( CliOutputFormat::Text => println!(
"{}", "{}",
format_status_report(&provenance.resolved, usage, permission_mode.as_str(), &context, Some(&provenance)) format_status_report(
&provenance.resolved,
usage,
permission_mode.as_str(),
&context,
Some(&provenance)
)
), ),
CliOutputFormat::Json => println!( CliOutputFormat::Json => println!(
"{}", "{}",
@ -9031,26 +9025,24 @@ fn print_help(output_format: CliOutputFormat) -> Result<(), Box<dyn std::error::
mod tests { mod tests {
use super::{ use super::{
build_runtime_plugin_state_with_loader, build_runtime_with_plugin_state, build_runtime_plugin_state_with_loader, build_runtime_with_plugin_state,
collect_session_prompt_history, create_managed_session_handle, describe_tool_progress, classify_error_kind, collect_session_prompt_history, create_managed_session_handle,
filter_tool_specs, format_bughunter_report, format_commit_preflight_report, describe_tool_progress, filter_tool_specs, format_bughunter_report,
format_commit_skipped_report, format_compact_report, format_connected_line, format_commit_preflight_report, format_commit_skipped_report, format_compact_report,
format_cost_report, format_history_timestamp, format_internal_prompt_progress_line, format_connected_line, format_cost_report, format_history_timestamp,
format_issue_report, format_model_report, format_model_switch_report, format_internal_prompt_progress_line, format_issue_report, format_model_report,
format_permissions_report, format_permissions_switch_report, format_pr_report, format_model_switch_report, format_permissions_report, format_permissions_switch_report,
format_resume_report, format_status_report, format_tool_call_start, format_tool_result, format_pr_report, format_resume_report, format_status_report, format_tool_call_start,
format_ultraplan_report, format_unknown_slash_command, format_tool_result, format_ultraplan_report, format_unknown_slash_command,
format_unknown_slash_command_message, format_user_visible_api_error, format_unknown_slash_command_message, format_user_visible_api_error,
classify_error_kind,
merge_prompt_with_stdin, normalize_permission_mode, parse_args, parse_export_args, merge_prompt_with_stdin, normalize_permission_mode, parse_args, parse_export_args,
parse_git_status_branch, parse_git_status_metadata_for, parse_git_workspace_summary, parse_git_status_branch, parse_git_status_metadata_for, parse_git_workspace_summary,
parse_history_count, permission_policy, print_help_to, push_output_block, parse_history_count, permission_policy, print_help_to, push_output_block,
render_config_report, render_diff_report, render_diff_report_for, render_memory_report, render_config_report, render_diff_report, render_diff_report_for, render_help_topic,
split_error_hint, render_memory_report, render_prompt_history_report, render_repl_help, render_resume_usage,
render_help_topic, render_prompt_history_report, render_repl_help, render_resume_usage,
render_session_markdown, resolve_model_alias, resolve_model_alias_with_config, render_session_markdown, resolve_model_alias, resolve_model_alias_with_config,
resolve_repl_model, resolve_session_reference, response_to_events, resolve_repl_model, resolve_session_reference, response_to_events,
resume_supported_slash_commands, run_resume_command, short_tool_id, resume_supported_slash_commands, run_resume_command, short_tool_id,
slash_command_completion_candidates_with_sessions, status_context, slash_command_completion_candidates_with_sessions, split_error_hint, status_context,
summarize_tool_payload_for_markdown, try_resolve_bare_skill_prompt, validate_no_args, summarize_tool_payload_for_markdown, try_resolve_bare_skill_prompt, validate_no_args,
write_mcp_server_fixture, CliAction, CliOutputFormat, CliToolExecutor, GitWorkspaceSummary, write_mcp_server_fixture, CliAction, CliOutputFormat, CliToolExecutor, GitWorkspaceSummary,
InternalPromptProgressEvent, InternalPromptProgressState, LiveCli, LocalHelpTopic, InternalPromptProgressEvent, InternalPromptProgressState, LiveCli, LocalHelpTopic,
@ -10043,8 +10035,8 @@ mod tests {
// with a specific error instead of falling through to the prompt // with a specific error instead of falling through to the prompt
// path (where they surface a misleading "missing Anthropic // path (where they surface a misleading "missing Anthropic
// credentials" error or burn API tokens on an empty prompt). // credentials" error or burn API tokens on an empty prompt).
let empty_err = parse_args(&["".to_string()]) let empty_err =
.expect_err("empty positional arg should be rejected"); parse_args(&["".to_string()]).expect_err("empty positional arg should be rejected");
assert!( assert!(
empty_err.starts_with("empty prompt:"), empty_err.starts_with("empty prompt:"),
"empty-arg error should be specific, got: {empty_err}" "empty-arg error should be specific, got: {empty_err}"
@ -10261,7 +10253,8 @@ mod tests {
.expect("write malformed .claw.json"); .expect("write malformed .claw.json");
let context = with_current_dir(&cwd, || { let context = with_current_dir(&cwd, || {
super::status_context(None).expect("status_context should not hard-fail on config parse errors (#143)") super::status_context(None)
.expect("status_context should not hard-fail on config parse errors (#143)")
}); });
// Phase 1 contract: config_load_error is populated with the parse error. // Phase 1 contract: config_load_error is populated with the parse error.
@ -10322,15 +10315,23 @@ mod tests {
json.get("model").and_then(|v| v.as_str()), json.get("model").and_then(|v| v.as_str()),
Some("test-model") Some("test-model")
); );
assert!(json.get("workspace").is_some(), "workspace field still reported"); assert!(
assert!(json.get("sandbox").is_some(), "sandbox field still reported"); json.get("workspace").is_some(),
"workspace field still reported"
);
assert!(
json.get("sandbox").is_some(),
"sandbox field still reported"
);
assert_eq!( assert_eq!(
json.pointer("/allowed_tools/source").and_then(|v| v.as_str()), json.pointer("/allowed_tools/source")
.and_then(|v| v.as_str()),
Some("default"), Some("default"),
"default status should expose unrestricted tool source: {json}" "default status should expose unrestricted tool source: {json}"
); );
assert_eq!( assert_eq!(
json.pointer("/allowed_tools/restricted").and_then(|v| v.as_bool()), json.pointer("/allowed_tools/restricted")
.and_then(|v| v.as_bool()),
Some(false), Some(false),
"default status should expose unrestricted tool state: {json}" "default status should expose unrestricted tool state: {json}"
); );
@ -10477,11 +10478,18 @@ mod tests {
// Other unrecognized args should NOT trigger the --json hint. // Other unrecognized args should NOT trigger the --json hint.
let err_other = parse_args(&["doctor".to_string(), "garbage".to_string()]) let err_other = parse_args(&["doctor".to_string(), "garbage".to_string()])
.expect_err("`doctor garbage` should fail without --json hint"); .expect_err("`doctor garbage` should fail without --json hint");
assert!(!err_other.contains("--output-format json"), assert!(
"unrelated args should not trigger --json hint: {err_other}"); !err_other.contains("--output-format json"),
"unrelated args should not trigger --json hint: {err_other}"
);
// #154: model syntax error should hint at provider prefix when applicable // #154: model syntax error should hint at provider prefix when applicable
let err_gpt = parse_args(&["prompt".to_string(), "test".to_string(), "--model".to_string(), "gpt-4".to_string()]) let err_gpt = parse_args(&[
.expect_err("`--model gpt-4` should fail with OpenAI hint"); "prompt".to_string(),
"test".to_string(),
"--model".to_string(),
"gpt-4".to_string(),
])
.expect_err("`--model gpt-4` should fail with OpenAI hint");
assert!( assert!(
err_gpt.contains("Did you mean `openai/gpt-4`?"), err_gpt.contains("Did you mean `openai/gpt-4`?"),
"GPT model error should hint openai/ prefix: {err_gpt}" "GPT model error should hint openai/ prefix: {err_gpt}"
@ -10490,8 +10498,13 @@ mod tests {
err_gpt.contains("OPENAI_API_KEY"), err_gpt.contains("OPENAI_API_KEY"),
"GPT model error should mention env var: {err_gpt}" "GPT model error should mention env var: {err_gpt}"
); );
let err_qwen = parse_args(&["prompt".to_string(), "test".to_string(), "--model".to_string(), "qwen-plus".to_string()]) let err_qwen = parse_args(&[
.expect_err("`--model qwen-plus` should fail with DashScope hint"); "prompt".to_string(),
"test".to_string(),
"--model".to_string(),
"qwen-plus".to_string(),
])
.expect_err("`--model qwen-plus` should fail with DashScope hint");
assert!( assert!(
err_qwen.contains("Did you mean `qwen/qwen-plus`?"), err_qwen.contains("Did you mean `qwen/qwen-plus`?"),
"Qwen model error should hint qwen/ prefix: {err_qwen}" "Qwen model error should hint qwen/ prefix: {err_qwen}"
@ -10501,8 +10514,13 @@ mod tests {
"Qwen model error should mention env var: {err_qwen}" "Qwen model error should mention env var: {err_qwen}"
); );
// Unrelated invalid model should NOT get a hint // Unrelated invalid model should NOT get a hint
let err_garbage = parse_args(&["prompt".to_string(), "test".to_string(), "--model".to_string(), "asdfgh".to_string()]) let err_garbage = parse_args(&[
.expect_err("`--model asdfgh` should fail"); "prompt".to_string(),
"test".to_string(),
"--model".to_string(),
"asdfgh".to_string(),
])
.expect_err("`--model asdfgh` should fail");
assert!( assert!(
!err_garbage.contains("Did you mean"), !err_garbage.contains("Did you mean"),
"Unrelated model errors should not get a hint: {err_garbage}" "Unrelated model errors should not get a hint: {err_garbage}"
@ -10512,15 +10530,42 @@ mod tests {
#[test] #[test]
fn classify_error_kind_returns_correct_discriminants() { fn classify_error_kind_returns_correct_discriminants() {
// #77: error kind classification for JSON error payloads // #77: error kind classification for JSON error payloads
assert_eq!(classify_error_kind("missing Anthropic credentials; export ..."), "missing_credentials"); assert_eq!(
assert_eq!(classify_error_kind("no worker state file found at /tmp/..."), "missing_worker_state"); classify_error_kind("missing Anthropic credentials; export ..."),
assert_eq!(classify_error_kind("session not found: abc123"), "session_not_found"); "missing_credentials"
assert_eq!(classify_error_kind("failed to restore session: no managed sessions found"), "session_load_failed"); );
assert_eq!(classify_error_kind("unrecognized argument `--foo` for subcommand `doctor`"), "cli_parse"); assert_eq!(
assert_eq!(classify_error_kind("invalid model syntax: 'gpt-4'. Expected ..."), "invalid_model_syntax"); classify_error_kind("no worker state file found at /tmp/..."),
assert_eq!(classify_error_kind("unsupported resumed command: /blargh"), "unsupported_resumed_command"); "missing_worker_state"
assert_eq!(classify_error_kind("api failed after 3 attempts: ..."), "api_http_error"); );
assert_eq!(classify_error_kind("something completely unknown"), "unknown"); assert_eq!(
classify_error_kind("session not found: abc123"),
"session_not_found"
);
assert_eq!(
classify_error_kind("failed to restore session: no managed sessions found"),
"session_load_failed"
);
assert_eq!(
classify_error_kind("unrecognized argument `--foo` for subcommand `doctor`"),
"cli_parse"
);
assert_eq!(
classify_error_kind("invalid model syntax: 'gpt-4'. Expected ..."),
"invalid_model_syntax"
);
assert_eq!(
classify_error_kind("unsupported resumed command: /blargh"),
"unsupported_resumed_command"
);
assert_eq!(
classify_error_kind("api failed after 3 attempts: ..."),
"api_http_error"
);
assert_eq!(
classify_error_kind("something completely unknown"),
"unknown"
);
} }
#[test] #[test]
@ -10991,7 +11036,6 @@ mod tests {
assert!(report.contains("Use /help")); assert!(report.contains("Use /help"));
} }
#[test] #[test]
fn typoed_doctor_subcommand_returns_did_you_mean_error() { fn typoed_doctor_subcommand_returns_did_you_mean_error() {
let error = parse_args(&["doctorr".to_string()]).expect_err("doctorr should error"); let error = parse_args(&["doctorr".to_string()]).expect_err("doctorr should error");
@ -11074,7 +11118,6 @@ mod tests {
); );
} }
#[test] #[test]
fn punctuation_bearing_single_token_still_dispatches_to_prompt() { fn punctuation_bearing_single_token_still_dispatches_to_prompt() {
// #140: Guard against test pollution — isolate cwd + env so this test // #140: Guard against test pollution — isolate cwd + env so this test

View File

@ -172,7 +172,10 @@ stderr:
); );
let stdout = String::from_utf8(output.stdout).expect("stdout should be utf8"); let stdout = String::from_utf8(output.stdout).expect("stdout should be utf8");
let parsed: Value = serde_json::from_str(&stdout).expect("compact json stdout should parse"); let parsed: Value = serde_json::from_str(&stdout).expect("compact json stdout should parse");
assert_eq!(parsed["message"], "Mock streaming says hello from the parity harness."); assert_eq!(
parsed["message"],
"Mock streaming says hello from the parity harness."
);
assert_eq!(parsed["compact"], true); assert_eq!(parsed["compact"], true);
assert_eq!(parsed["model"], "claude-sonnet-4-6"); assert_eq!(parsed["model"], "claude-sonnet-4-6");
assert!(parsed["usage"].is_object()); assert!(parsed["usage"].is_object());