mirror of
https://github.com/instructkr/claw-code.git
synced 2026-04-08 00:54:49 +08:00
feat: b5-git-aware — batch 5 upstream parity
This commit is contained in:
@@ -86,6 +86,7 @@ const CLI_OPTION_SUGGESTIONS: &[&str] = &[
|
||||
"--allowed-tools",
|
||||
"--resume",
|
||||
"--print",
|
||||
"--compact",
|
||||
"-p",
|
||||
];
|
||||
|
||||
@@ -156,8 +157,9 @@ fn run() -> Result<(), Box<dyn std::error::Error>> {
|
||||
output_format,
|
||||
allowed_tools,
|
||||
permission_mode,
|
||||
compact,
|
||||
} => LiveCli::new(model, true, allowed_tools, permission_mode)?
|
||||
.run_turn_with_output(&prompt, output_format)?,
|
||||
.run_turn_with_output(&prompt, output_format, compact)?,
|
||||
CliAction::Login { output_format } => run_login(output_format)?,
|
||||
CliAction::Logout { output_format } => run_logout(output_format)?,
|
||||
CliAction::Doctor { output_format } => run_doctor(output_format)?,
|
||||
@@ -225,6 +227,7 @@ enum CliAction {
|
||||
output_format: CliOutputFormat,
|
||||
allowed_tools: Option<AllowedToolSet>,
|
||||
permission_mode: PermissionMode,
|
||||
compact: bool,
|
||||
},
|
||||
Login {
|
||||
output_format: CliOutputFormat,
|
||||
@@ -283,6 +286,7 @@ fn parse_args(args: &[String]) -> Result<CliAction, String> {
|
||||
let mut wants_help = false;
|
||||
let mut wants_version = false;
|
||||
let mut allowed_tool_values = Vec::new();
|
||||
let mut compact = false;
|
||||
let mut rest = Vec::new();
|
||||
let mut index = 0;
|
||||
|
||||
@@ -333,6 +337,10 @@ fn parse_args(args: &[String]) -> Result<CliAction, String> {
|
||||
permission_mode_override = Some(PermissionMode::DangerFullAccess);
|
||||
index += 1;
|
||||
}
|
||||
"--compact" => {
|
||||
compact = true;
|
||||
index += 1;
|
||||
}
|
||||
"-p" => {
|
||||
// Claw Code compat: -p "prompt" = one-shot prompt
|
||||
let prompt = args[index + 1..].join(" ");
|
||||
@@ -346,6 +354,7 @@ fn parse_args(args: &[String]) -> Result<CliAction, String> {
|
||||
allowed_tools: normalize_allowed_tools(&allowed_tool_values)?,
|
||||
permission_mode: permission_mode_override
|
||||
.unwrap_or_else(default_permission_mode),
|
||||
compact,
|
||||
});
|
||||
}
|
||||
"--print" => {
|
||||
@@ -439,6 +448,7 @@ fn parse_args(args: &[String]) -> Result<CliAction, String> {
|
||||
output_format,
|
||||
allowed_tools,
|
||||
permission_mode,
|
||||
compact,
|
||||
}),
|
||||
SkillSlashDispatch::Local => Ok(CliAction::Skills {
|
||||
args,
|
||||
@@ -461,6 +471,7 @@ fn parse_args(args: &[String]) -> Result<CliAction, String> {
|
||||
output_format,
|
||||
allowed_tools,
|
||||
permission_mode,
|
||||
compact,
|
||||
})
|
||||
}
|
||||
other if other.starts_with('/') => parse_direct_slash_cli_action(
|
||||
@@ -469,6 +480,7 @@ fn parse_args(args: &[String]) -> Result<CliAction, String> {
|
||||
output_format,
|
||||
allowed_tools,
|
||||
permission_mode,
|
||||
compact,
|
||||
),
|
||||
_other => Ok(CliAction::Prompt {
|
||||
prompt: rest.join(" "),
|
||||
@@ -476,6 +488,7 @@ fn parse_args(args: &[String]) -> Result<CliAction, String> {
|
||||
output_format,
|
||||
allowed_tools,
|
||||
permission_mode,
|
||||
compact,
|
||||
}),
|
||||
}
|
||||
}
|
||||
@@ -565,6 +578,7 @@ fn parse_direct_slash_cli_action(
|
||||
output_format: CliOutputFormat,
|
||||
allowed_tools: Option<AllowedToolSet>,
|
||||
permission_mode: PermissionMode,
|
||||
compact: bool,
|
||||
) -> Result<CliAction, String> {
|
||||
let raw = rest.join(" ");
|
||||
match SlashCommand::parse(&raw) {
|
||||
@@ -590,6 +604,7 @@ fn parse_direct_slash_cli_action(
|
||||
output_format,
|
||||
allowed_tools,
|
||||
permission_mode,
|
||||
compact,
|
||||
}),
|
||||
SkillSlashDispatch::Local => Ok(CliAction::Skills {
|
||||
args,
|
||||
@@ -3204,13 +3219,28 @@ impl LiveCli {
|
||||
&mut self,
|
||||
input: &str,
|
||||
output_format: CliOutputFormat,
|
||||
compact: bool,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
match output_format {
|
||||
CliOutputFormat::Text if compact => self.run_prompt_compact(input),
|
||||
CliOutputFormat::Text => self.run_turn(input),
|
||||
CliOutputFormat::Json => self.run_prompt_json(input),
|
||||
}
|
||||
}
|
||||
|
||||
fn run_prompt_compact(&mut self, input: &str) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let (mut runtime, hook_abort_monitor) = self.prepare_turn_runtime(false)?;
|
||||
let mut permission_prompter = CliPermissionPrompter::new(self.permission_mode);
|
||||
let result = runtime.run_turn(input, Some(&mut permission_prompter));
|
||||
hook_abort_monitor.stop();
|
||||
let summary = result?;
|
||||
self.replace_runtime(runtime)?;
|
||||
self.persist_session()?;
|
||||
let final_text = final_assistant_text(&summary);
|
||||
println!("{final_text}");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run_prompt_json(&mut self, input: &str) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let (mut runtime, hook_abort_monitor) = self.prepare_turn_runtime(false)?;
|
||||
let mut permission_prompter = CliPermissionPrompter::new(self.permission_mode);
|
||||
@@ -7007,6 +7037,10 @@ fn print_help_to(out: &mut impl Write) -> io::Result<()> {
|
||||
out,
|
||||
" --output-format FORMAT Non-interactive output format: text or json"
|
||||
)?;
|
||||
writeln!(
|
||||
out,
|
||||
" --compact Strip tool call details; print only the final assistant text (text mode only; useful for piping)"
|
||||
)?;
|
||||
writeln!(
|
||||
out,
|
||||
" --permission-mode MODE Set read-only, workspace-write, or danger-full-access"
|
||||
@@ -7053,6 +7087,10 @@ fn print_help_to(out: &mut impl Write) -> io::Result<()> {
|
||||
out,
|
||||
" claw --output-format json prompt \"explain src/main.rs\""
|
||||
)?;
|
||||
writeln!(
|
||||
out,
|
||||
" claw --compact \"summarize Cargo.toml\" | wc -l"
|
||||
)?;
|
||||
writeln!(
|
||||
out,
|
||||
" claw --allowedTools read,glob \"summarize Cargo.toml\""
|
||||
@@ -7595,6 +7633,7 @@ mod tests {
|
||||
output_format: CliOutputFormat::Text,
|
||||
allowed_tools: None,
|
||||
permission_mode: PermissionMode::DangerFullAccess,
|
||||
compact: false,
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -7618,10 +7657,56 @@ mod tests {
|
||||
output_format: CliOutputFormat::Json,
|
||||
allowed_tools: None,
|
||||
permission_mode: PermissionMode::DangerFullAccess,
|
||||
compact: false,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parses_compact_flag_for_prompt_mode() {
|
||||
// given a bare prompt invocation that includes the --compact flag
|
||||
let _guard = env_lock();
|
||||
std::env::remove_var("RUSTY_CLAUDE_PERMISSION_MODE");
|
||||
let args = vec![
|
||||
"--compact".to_string(),
|
||||
"summarize".to_string(),
|
||||
"this".to_string(),
|
||||
];
|
||||
|
||||
// when parse_args interprets the flag
|
||||
let parsed = parse_args(&args).expect("args should parse");
|
||||
|
||||
// then compact mode is propagated and other defaults stay unchanged
|
||||
assert_eq!(
|
||||
parsed,
|
||||
CliAction::Prompt {
|
||||
prompt: "summarize this".to_string(),
|
||||
model: DEFAULT_MODEL.to_string(),
|
||||
output_format: CliOutputFormat::Text,
|
||||
allowed_tools: None,
|
||||
permission_mode: PermissionMode::DangerFullAccess,
|
||||
compact: true,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn prompt_subcommand_defaults_compact_to_false() {
|
||||
// given a `prompt` subcommand invocation without --compact
|
||||
let _guard = env_lock();
|
||||
std::env::remove_var("RUSTY_CLAUDE_PERMISSION_MODE");
|
||||
let args = vec!["prompt".to_string(), "hello".to_string()];
|
||||
|
||||
// when parse_args runs
|
||||
let parsed = parse_args(&args).expect("args should parse");
|
||||
|
||||
// then compact stays false (opt-in flag)
|
||||
match parsed {
|
||||
CliAction::Prompt { compact, .. } => assert!(!compact),
|
||||
other => panic!("expected Prompt action, got {other:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolves_model_aliases_in_args() {
|
||||
let _guard = env_lock();
|
||||
@@ -7640,6 +7725,7 @@ mod tests {
|
||||
output_format: CliOutputFormat::Text,
|
||||
allowed_tools: None,
|
||||
permission_mode: PermissionMode::DangerFullAccess,
|
||||
compact: false,
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -7791,6 +7877,7 @@ mod tests {
|
||||
output_format: CliOutputFormat::Text,
|
||||
allowed_tools: None,
|
||||
permission_mode: crate::default_permission_mode(),
|
||||
compact: false,
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -7898,6 +7985,7 @@ mod tests {
|
||||
output_format: CliOutputFormat::Text,
|
||||
allowed_tools: None,
|
||||
permission_mode: PermissionMode::DangerFullAccess,
|
||||
compact: false,
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -7962,6 +8050,7 @@ mod tests {
|
||||
output_format: CliOutputFormat::Text,
|
||||
allowed_tools: None,
|
||||
permission_mode: crate::default_permission_mode(),
|
||||
compact: false,
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -7985,6 +8074,7 @@ mod tests {
|
||||
output_format: CliOutputFormat::Text,
|
||||
allowed_tools: None,
|
||||
permission_mode: crate::default_permission_mode(),
|
||||
compact: false,
|
||||
}
|
||||
);
|
||||
let error = parse_args(&["/status".to_string()])
|
||||
|
||||
Reference in New Issue
Block a user