diff --git a/ROADMAP.md b/ROADMAP.md index cbd3c32e..4537de8c 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -7637,3 +7637,5 @@ Original filing (2026-04-18): the session emitted `SessionStart hook (completed) 734. **`agents show ` and `plugins show ` error envelopes had no `message` field when the target was not found — `skills show` had `"message": "skill 'X' not found"` but the other two omitted it, leaving callers with only `error_kind` and `requested` and no human-readable explanation in the same field shape** — dogfooded 2026-05-26 on `cc86f54d`. Added `"message": "agent 'X' not found"` to the `agent_not_found` branch in `commands/src/lib.rs` and `"message": "plugin 'X' not found"` to the `plugin_not_found` branch in `rusty-claude-cli/src/main.rs`; both now match the `skills show` shape. Source: Jobdori dogfood on `cc86f54d`, 2026-05-26. 735. **`claw /compact --output-format json` (and other interactive-only slash commands invoked outside a session) emitted `error_kind:"unknown"` instead of `error_kind:"interactive_only"` — `classify_error_kind` matched `"is a slash command"` and `"interactive_only:"` prefix but missed the `"slash command /X is interactive-only"` sentence pattern emitted by the interactive-only guard; automation branching on `error_kind` got `"unknown"` and couldn't distinguish "you called an interactive command outside a session" from a genuine unknown failure** — dogfooded 2026-05-26 on `d4494a8a`. Added `message.starts_with("slash command") && message.contains("interactive-only")` branch to `classify_error_kind` alongside the existing two matchers. Source: Jobdori dogfood on `d4494a8a`, 2026-05-26. + +736. **`claw doctor --output-format json` `boot_preflight` check `details[]` had `value: null` for `Required binary`, `Last failed boot`, `MCP eligible`, and `Plugin eligible` entries — all four used format strings with no double-space separator, so the prose-splitter that builds `{key, value}` objects (introduced in #701) could not split key from value and emitted the entire string as `key` with `value: null`** — dogfooded 2026-05-26 on `b3242e8c`. Fix: insert the two-space separator between the label and its value in each format string: `"Required binary {} available={}"` → `key="Required binary claw"` / `value="available=true"`; `"Last failed boot {}"` → `key="Last failed boot"` / `value=""`; MCP/Plugin eligible compound values use `" · "` intra-value separator since `splitn(2, " ")` splits only on the first double-space run. Source: Jobdori dogfood on `b3242e8c`, 2026-05-26. diff --git a/rust/crates/rusty-claude-cli/src/main.rs b/rust/crates/rusty-claude-cli/src/main.rs index f3b09f51..1f448a56 100644 --- a/rust/crates/rusty-claude-cli/src/main.rs +++ b/rust/crates/rusty-claude-cli/src/main.rs @@ -2760,16 +2760,26 @@ fn check_boot_preflight_health(context: &StatusContext) -> DiagnosticCheck { .map_or("unknown".to_string(), |v| v.to_string()) ), format!("Trusted roots {}", preflight.trusted_roots_count), + // #736: keep compound values readable but use " · " as intra-value separator + // so the two-space prose splitter yields key="MCP eligible" value="true · servers 0" format!( - "MCP eligible {} · servers {}", - preflight.mcp_startup_eligible, preflight.mcp_servers_configured + "MCP eligible {}", + format!( + "{} · servers {}", + preflight.mcp_startup_eligible, preflight.mcp_servers_configured + ) ), format!( - "Plugin eligible {} · configured {}", - preflight.plugin_startup_eligible, preflight.plugins_configured + "Plugin eligible {}", + format!( + "{} · configured {}", + preflight.plugin_startup_eligible, preflight.plugins_configured + ) ), format!( - "Last failed boot {}", + // #736: use two-space separator so the detail_entries prose splitter + // can extract key="Last failed boot" value="|" + "Last failed boot {}", preflight .last_failed_boot_reason .as_deref() @@ -2778,7 +2788,8 @@ fn check_boot_preflight_health(context: &StatusContext) -> DiagnosticCheck { ]; details.extend(preflight.required_binaries.iter().map(|binary| { format!( - "Required binary {} available={}", + // #736: two-space separator → key="Required binary " value="available=true|false" + "Required binary {} available={}", binary.name, binary.available ) }));