From 2dfb7af66ead00349c29cf9e70ff1fc6da004be7 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Tue, 26 May 2026 19:38:09 +0900 Subject: [PATCH] fix+test(#749): compact interactive-only hint now non-null; extend compact JSON test for hint contract --- ROADMAP.md | 2 ++ rust/crates/rusty-claude-cli/src/main.rs | 3 ++- rust/crates/rusty-claude-cli/tests/compact_output.rs | 10 ++++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/ROADMAP.md b/ROADMAP.md index baa68a99..43c97f5e 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -7663,3 +7663,5 @@ Original filing (2026-04-18): the session emitted `SessionStart hook (completed) 747. **ROADMAP #745 has no regression test: `claw issue/pr/commit --output-format json hint` could silently regress to null** — confirmed by gaebal-gajae on `3c5459a33`. Same pattern as #737, #742, #744. Fix: add `bare_slash_command_hint_745` test iterating `issue`, `pr`, `commit` and asserting `error_kind:"interactive_only"` + non-empty `hint` field. Source: gaebal-gajae dogfood on `3c5459a33`, fixed on `18e7744e`, 2026-05-26. 748. **`claw mcp bogussubcmd --output-format json` returned `error_kind: null` when an unknown subcommand was passed — `render_mcp_usage_json(Some("bogus"))` set `status:"error"` but left `error_kind` absent — while `agents bogussubcmd` emits `error_kind:"unknown_agents_subcommand"`** — dogfooded 2026-05-26 on `04eb661e`. Fix: add `error_kind: "unknown_mcp_action"` to `render_mcp_usage_json` when `unexpected.is_some()`; remains `null` for the `help` path (`unexpected: null`). Source: Jobdori dogfood on `04eb661e`, 2026-05-26. + +749. **`claw compact --output-format json` returned `hint: null` — `compact_interactive_only_error()` returned a single-line string with no `\n` between short error and remediation text, so `split_error_hint` couldn't populate the hint field** — identified by gaebal-gajae on `04eb661e`. Same class as #738 / #745 / #746. Fix: add `\n` before the remediation text in `compact_interactive_only_error`. Regression guard: extended `compact_subcommand_json_help_fails_fast_when_stdin_closed` to also assert `hint` is non-empty and mentions `/compact` or `--resume`. Source: gaebal-gajae dogfood on `04eb661e`, 2026-05-26. diff --git a/rust/crates/rusty-claude-cli/src/main.rs b/rust/crates/rusty-claude-cli/src/main.rs index 7debc727..81489b30 100644 --- a/rust/crates/rusty-claude-cli/src/main.rs +++ b/rust/crates/rusty-claude-cli/src/main.rs @@ -1422,7 +1422,8 @@ fn bare_slash_command_guidance(command_name: &str) -> Option { } fn compact_interactive_only_error() -> String { - "interactive_only: `claw compact` is an interactive/session command. Start `claw` and run `/compact`, or use `claw --resume SESSION.jsonl /compact` to compact an existing session." + // #749: newline before remediation so split_error_hint populates hint field + "interactive_only: `claw compact` is an interactive/session command.\nStart `claw` and run `/compact`, or use `claw --resume SESSION.jsonl /compact` to compact an existing session." .to_string() } diff --git a/rust/crates/rusty-claude-cli/tests/compact_output.rs b/rust/crates/rusty-claude-cli/tests/compact_output.rs index 26cf85bb..8b3ccbfa 100644 --- a/rust/crates/rusty-claude-cli/tests/compact_output.rs +++ b/rust/crates/rusty-claude-cli/tests/compact_output.rs @@ -283,6 +283,16 @@ fn compact_subcommand_json_help_fails_fast_when_stdin_closed() { .contains("claw compact"), "message should name compact: {parsed}" ); + // #749: hint must be non-empty (was null before fix — same class as #738/#745/#746) + let hint = parsed["hint"].as_str().unwrap_or(""); + assert!( + !hint.is_empty(), + "compact interactive-only JSON must have non-empty hint (#749); got: {parsed}" + ); + assert!( + hint.contains("/compact") || hint.contains("--resume"), + "hint should mention /compact or --resume: {hint}" + ); fs::remove_dir_all(&workspace).expect("workspace cleanup should succeed"); }