From eb86f4d2c341bed7856b302c2389299af8d01af8 Mon Sep 17 00:00:00 2001 From: bellman Date: Fri, 5 Jun 2026 07:25:49 +0900 Subject: [PATCH] fix: reject --compact for non-prompt subcommands (#98) --compact was silently ignored when used with non-prompt commands like claw --compact status or claw --compact config. Now returns a typed error with guidance on proper usage. Generated with https://github.com/Yeachan-Heo/gajae-code Co-authored-by: Gajae Code --- ROADMAP.md | 2 +- rust/crates/rusty-claude-cli/src/main.rs | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/ROADMAP.md b/ROADMAP.md index d3704a15..60d27637 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -2257,7 +2257,7 @@ ear], /color [scheme], /effort [low|medium|high], /fast, /summary, /tag [label], **Source.** Jobdori dogfood 2026-04-18 against `/tmp/cdL` on main HEAD `3ab920a` in response to Clawhip pinpoint nudge at `1494759381068419115`. Joins the **permission-audit sweep** (#50 / #87 / #91 / #94) on a new axis: those four cover permission *modes* and *rules*; #97 covers the *tool-allow-list* knob with the same class of problem (silent input handling + missing diagnostic visibility). Also sibling of **#86** (corrupt `.claw.json` silently dropped, doctor reports ok) on the truth-audit side: both are "misconfigured claws have no observable signal." Natural 3-way bundle: **#86 + #94 + #97** all add diagnostic coverage to `claw doctor` for configuration hygiene the current surface silently swallows. -98. **`--compact` is silently ignored outside the `Prompt → Text` path: `--compact --output-format json` (explicitly documented as "text mode only" in `--help` but unenforced), `--compact status`, `--compact doctor`, `--compact sandbox`, `--compact init`, `--compact export`, `--compact mcp`, `--compact skills`, `--compact agents`, and `claw --compact` with piped stdin (hardcoded `compact: false` at the stdin fallthrough). No error, no warning, no diagnostic trace anywhere** — dogfooded 2026-04-18 on main HEAD `7a172a2` from `/tmp/cdM`. `--help` at `main.rs:8251` explicitly documents "`--compact` (text mode only; useful for piping)"; the implementation *knows* the flag is only meaningful for the text branch of the prompt turn output, but does not refuse or warn in any other case. A claw piping output through `claw --compact --output-format json prompt "..."` gets the same verbose JSON blob as without the flag, silently, with no indication that its documented behavior was discarded. +98. **DONE — `--compact` is silently ignored outside the `Prompt → Text` path: `--compact --output-format json` (explicitly documented as "text mode only" in `--help` but unenforced), `--compact status`, `--compact doctor`, `--compact sandbox`, `--compact init`, `--compact export`, `--compact mcp`, `--compact skills`, `--compact agents`, and `claw --compact` with piped stdin (hardcoded `compact: false` at the stdin fallthrough). No error, no warning, no diagnostic trace anywhere** — dogfooded 2026-04-18 on main HEAD `7a172a2` from `/tmp/cdM`. `--help` at `main.rs:8251` explicitly documents "`--compact` (text mode only; useful for piping)"; the implementation *knows* the flag is only meaningful for the text branch of the prompt turn output, but does not refuse or warn in any other case. A claw piping output through `claw --compact --output-format json prompt "..."` gets the same verbose JSON blob as without the flag, silently, with no indication that its documented behavior was discarded. **Concrete repro.** ``` diff --git a/rust/crates/rusty-claude-cli/src/main.rs b/rust/crates/rusty-claude-cli/src/main.rs index 2c677c80..df6e4474 100644 --- a/rust/crates/rusty-claude-cli/src/main.rs +++ b/rust/crates/rusty-claude-cli/src/main.rs @@ -1919,6 +1919,25 @@ fn parse_args(args: &[String]) -> Result { .unwrap_or_else(permission_mode_provenance_for_current_dir) }; + // #98: --compact is only meaningful for prompt mode. When a known non-prompt + // subcommand is being dispatched, reject --compact so callers don't silently + // lose the flag. + if compact + && rest + .first() + .map(|s| s.as_str()) + .is_some_and(|s| s != "prompt") + { + // Allow compact for the default prompt fallback (unknown tokens). + // Only reject for known top-level subcommands that don't use compact. + let first = rest[0].as_str(); + if is_known_top_level_subcommand(first) && first != "prompt" { + return Err(format!( + "invalid_flag_value: --compact is only supported with prompt mode.\nUsage: claw --compact \"\" or echo \"\" | claw --compact" + )); + } + } + match rest[0].as_str() { "dump-manifests" => parse_dump_manifests_args(&rest[1..], output_format), "bootstrap-plan" => Ok(CliAction::BootstrapPlan { output_format }),