Skip to content

Commit e932713

Browse files
committed
fix+test(#753): claw -p (no arg) parity with #750: error_kind:missing_prompt with non-null hint
1 parent cfc2672 commit e932713

3 files changed

Lines changed: 51 additions & 1 deletion

File tree

ROADMAP.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7671,3 +7671,5 @@ Original filing (2026-04-18): the session emitted `SessionStart hook (completed)
76717671
751. **ROADMAP #750 has no regression test: `claw prompt --output-format json` no-arg `error_kind` and `hint` could silently regress** — confirmed by gaebal-gajae on `ac925ed4`. Fix: add `prompt_no_arg_json_error_kind_750` test asserting nonzero exit, `error_kind:"missing_prompt"`, non-empty `hint` mentioning `claw prompt` or `echo`. Source: gaebal-gajae dogfood on `ac925ed4`, 2026-05-26.
76727672

76737673
752. **`claw <subcommand> --output-format json <bogus-arg>` returned `hint: null` for all `cli_parse` errors when an unrecognized positional arg was supplied** — dogfooded 2026-05-26 on `ddc71b56`. Generic `unrecognized argument` format string had no `\n` so `split_error_hint` emitted null hint (only the `--json` special-case added a hint). Fix: add else-branch appending `\nRun `claw <verb> --help` for usage.` to the generic arm. Affected surfaces: `sandbox`, `doctor`, `version`, and any other subcommand routing through the same unrecognized-arg path. Source: Jobdori dogfood on `ddc71b56`, 2026-05-26.
7674+
7675+
753. **`claw --output-format json -p` (no prompt arg) returned `error_kind:"unknown"` and `hint: null`** — parity gap with #750/#751 which fixed the explicit `prompt` verb. Identified by gaebal-gajae on `ddc71b56`. Fix: same `missing_prompt:` prefix + newline usage hint as #750. Regression guard: `short_p_flag_no_arg_json_error_kind_753` asserting nonzero exit, `error_kind:"missing_prompt"`, non-empty hint mentioning `claw -p` or `claw prompt`. Source: gaebal-gajae dogfood on `ddc71b56`, 2026-05-26.

rust/crates/rusty-claude-cli/src/main.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -861,7 +861,8 @@ fn parse_args(args: &[String]) -> Result<CliAction, String> {
861861
// Claw Code compat: -p "prompt" = one-shot prompt
862862
let prompt = args[index + 1..].join(" ");
863863
if prompt.trim().is_empty() {
864-
return Err("-p requires a prompt string".to_string());
864+
// #753: same missing_prompt shape as claw prompt (no arg) fix in #750
865+
return Err("missing_prompt: -p requires a prompt string.\nUsage: claw -p <text> or claw prompt <text>".to_string());
865866
}
866867
return Ok(CliAction::Prompt {
867868
prompt,

rust/crates/rusty-claude-cli/tests/output_format_contract.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1504,6 +1504,53 @@ fn prompt_no_arg_json_error_kind_750() {
15041504
);
15051505
}
15061506

1507+
#[test]
1508+
fn short_p_flag_no_arg_json_error_kind_753() {
1509+
// #753: `claw --output-format json -p` (no prompt) must emit error_kind:"missing_prompt"
1510+
// and non-empty hint. Before #753 it returned error_kind:"unknown" + hint:null.
1511+
// Parity with #750 which fixed the explicit `prompt` verb.
1512+
use std::process::Command;
1513+
let root = unique_temp_dir("short-p-no-arg");
1514+
fs::create_dir_all(&root).expect("temp dir");
1515+
let bin = env!("CARGO_BIN_EXE_claw");
1516+
1517+
let output = Command::new(bin)
1518+
.current_dir(&root)
1519+
.args(["--output-format", "json", "-p"])
1520+
.output()
1521+
.expect("claw -p should run");
1522+
assert!(
1523+
!output.status.success(),
1524+
"claw -p with no arg must exit non-zero"
1525+
);
1526+
let stdout = String::from_utf8_lossy(&output.stdout);
1527+
let raw = if stdout.trim().starts_with('{') {
1528+
stdout.trim().to_string()
1529+
} else {
1530+
String::from_utf8_lossy(&output.stderr)
1531+
.lines()
1532+
.filter(|l| l.starts_with('{'))
1533+
.collect::<Vec<_>>()
1534+
.join("")
1535+
};
1536+
let parsed: serde_json::Value = serde_json::from_str(&raw).unwrap_or_else(|_| {
1537+
panic!("claw -p (no arg) --output-format json must emit valid JSON; got: {raw}")
1538+
});
1539+
assert_eq!(
1540+
parsed["error_kind"], "missing_prompt",
1541+
"claw -p no-arg must have error_kind:missing_prompt (#753); got: {parsed}"
1542+
);
1543+
let hint = parsed["hint"].as_str().unwrap_or("");
1544+
assert!(
1545+
!hint.is_empty(),
1546+
"claw -p no-arg hint must be non-empty (#753)"
1547+
);
1548+
assert!(
1549+
hint.contains("claw -p") || hint.contains("claw prompt"),
1550+
"hint should mention 'claw -p' or 'claw prompt': {hint}"
1551+
);
1552+
}
1553+
15071554
#[test]
15081555
fn bare_slash_command_hint_745() {
15091556
// #747/#745: claw <slash-cmd> --output-format json must return non-null hint.

0 commit comments

Comments
 (0)