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 <dev@gajae-code.com>
This commit is contained in:
bellman
2026-06-05 07:25:49 +09:00
parent 6c3d7be370
commit eb86f4d2c3
2 changed files with 20 additions and 1 deletions

View File

@@ -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. **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.** **Concrete repro.**
``` ```

View File

@@ -1919,6 +1919,25 @@ fn parse_args(args: &[String]) -> Result<CliAction, String> {
.unwrap_or_else(permission_mode_provenance_for_current_dir) .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 \"<prompt>\" or echo \"<prompt>\" | claw --compact"
));
}
}
match rest[0].as_str() { match rest[0].as_str() {
"dump-manifests" => parse_dump_manifests_args(&rest[1..], output_format), "dump-manifests" => parse_dump_manifests_args(&rest[1..], output_format),
"bootstrap-plan" => Ok(CliAction::BootstrapPlan { output_format }), "bootstrap-plan" => Ok(CliAction::BootstrapPlan { output_format }),