Keep resumed JSON command surfaces machine-readable

Resumed slash dispatch was still dropping back to prose for several JSON-capable local commands, which forced automation to special-case direct CLI invocations versus --resume flows. This routes resumed local-command handlers through the same structured JSON payloads used by direct status, sandbox, inventory, version, and init commands, and records the inventory parity audit result in the roadmap.

Constraint: Text-mode resumed output must stay unchanged for existing shell users
Rejected: Teach callers to scrape resumed text output | brittle and defeats the JSON contract
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: When a direct local command has a JSON renderer, keep resumed slash dispatch on the same serializer instead of adding one-off format branches
Tested: cargo fmt --check; cargo test --workspace; cargo clippy --workspace --all-targets -- -D warnings
Not-tested: Live provider-backed REPL resume flows outside the local test harness
This commit is contained in:
Yeachan-Heo
2026-04-06 01:44:30 +00:00
parent 53d6909b9b
commit fe4da2aa65
4 changed files with 233 additions and 61 deletions

View File

@@ -259,6 +259,104 @@ fn doctor_and_resume_status_emit_json_when_requested() {
assert!(resumed["sandbox"]["filesystem_mode"].as_str().is_some());
}
#[test]
fn resumed_inventory_commands_emit_structured_json_when_requested() {
let root = unique_temp_dir("resume-inventory-json");
let config_home = root.join("config-home");
let home = root.join("home");
fs::create_dir_all(&config_home).expect("config home should exist");
fs::create_dir_all(&home).expect("home should exist");
let session_path = root.join("session.jsonl");
fs::write(
&session_path,
"{\"type\":\"session_meta\",\"version\":3,\"session_id\":\"resume-inventory-json\",\"created_at_ms\":0,\"updated_at_ms\":0}\n{\"type\":\"message\",\"message\":{\"role\":\"user\",\"blocks\":[{\"type\":\"text\",\"text\":\"inventory\"}]}}\n",
)
.expect("session should write");
let mcp = assert_json_command_with_env(
&root,
&[
"--output-format",
"json",
"--resume",
session_path.to_str().expect("utf8 session path"),
"/mcp",
],
&[
(
"CLAW_CONFIG_HOME",
config_home.to_str().expect("utf8 config home"),
),
("HOME", home.to_str().expect("utf8 home")),
],
);
assert_eq!(mcp["kind"], "mcp");
assert_eq!(mcp["action"], "list");
assert!(mcp["servers"].is_array());
let skills = assert_json_command_with_env(
&root,
&[
"--output-format",
"json",
"--resume",
session_path.to_str().expect("utf8 session path"),
"/skills",
],
&[
(
"CLAW_CONFIG_HOME",
config_home.to_str().expect("utf8 config home"),
),
("HOME", home.to_str().expect("utf8 home")),
],
);
assert_eq!(skills["kind"], "skills");
assert_eq!(skills["action"], "list");
assert!(skills["summary"]["total"].is_number());
assert!(skills["skills"].is_array());
}
#[test]
fn resumed_version_and_init_emit_structured_json_when_requested() {
let root = unique_temp_dir("resume-version-init-json");
fs::create_dir_all(&root).expect("temp dir should exist");
let session_path = root.join("session.jsonl");
fs::write(
&session_path,
"{\"type\":\"session_meta\",\"version\":3,\"session_id\":\"resume-version-init-json\",\"created_at_ms\":0,\"updated_at_ms\":0}\n",
)
.expect("session should write");
let version = assert_json_command(
&root,
&[
"--output-format",
"json",
"--resume",
session_path.to_str().expect("utf8 session path"),
"/version",
],
);
assert_eq!(version["kind"], "version");
assert_eq!(version["version"], env!("CARGO_PKG_VERSION"));
let init = assert_json_command(
&root,
&[
"--output-format",
"json",
"--resume",
session_path.to_str().expect("utf8 session path"),
"/init",
],
);
assert_eq!(init["kind"], "init");
assert!(root.join("CLAUDE.md").exists());
}
fn assert_json_command(current_dir: &Path, args: &[&str]) -> Value {
assert_json_command_with_env(current_dir, args, &[])
}