mirror of
https://github.com/instructkr/claw-code.git
synced 2026-04-07 00:24:50 +08:00
merge fix/p0-10-json-status
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -5,6 +5,7 @@ use std::sync::atomic::{AtomicU64, Ordering};
|
|||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
use runtime::Session;
|
use runtime::Session;
|
||||||
|
use serde_json::Value;
|
||||||
|
|
||||||
static TEMP_COUNTER: AtomicU64 = AtomicU64::new(0);
|
static TEMP_COUNTER: AtomicU64 = AtomicU64::new(0);
|
||||||
|
|
||||||
@@ -37,6 +38,64 @@ fn status_command_applies_model_and_permission_mode_flags() {
|
|||||||
fs::remove_dir_all(temp_dir).expect("cleanup temp dir");
|
fs::remove_dir_all(temp_dir).expect("cleanup temp dir");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn status_command_emits_structured_json_when_requested() {
|
||||||
|
// given
|
||||||
|
let temp_dir = unique_temp_dir("status-json");
|
||||||
|
fs::create_dir_all(&temp_dir).expect("temp dir should exist");
|
||||||
|
|
||||||
|
// when
|
||||||
|
let output = Command::new(env!("CARGO_BIN_EXE_claw"))
|
||||||
|
.current_dir(&temp_dir)
|
||||||
|
.args([
|
||||||
|
"--model",
|
||||||
|
"sonnet",
|
||||||
|
"--permission-mode",
|
||||||
|
"read-only",
|
||||||
|
"--output-format",
|
||||||
|
"json",
|
||||||
|
"status",
|
||||||
|
])
|
||||||
|
.output()
|
||||||
|
.expect("claw should launch");
|
||||||
|
|
||||||
|
// then
|
||||||
|
assert_success(&output);
|
||||||
|
let stdout = String::from_utf8(output.stdout).expect("stdout should be utf8");
|
||||||
|
let parsed: Value = serde_json::from_str(stdout.trim()).expect("status output should be json");
|
||||||
|
assert_eq!(parsed["kind"], "status");
|
||||||
|
assert_eq!(parsed["model"], "claude-sonnet-4-6");
|
||||||
|
assert_eq!(parsed["permission_mode"], "read-only");
|
||||||
|
assert_eq!(parsed["workspace"]["session"], "live-repl");
|
||||||
|
assert!(parsed["sandbox"].is_object());
|
||||||
|
|
||||||
|
fs::remove_dir_all(temp_dir).expect("cleanup temp dir");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sandbox_command_emits_structured_json_when_requested() {
|
||||||
|
// given
|
||||||
|
let temp_dir = unique_temp_dir("sandbox-json");
|
||||||
|
fs::create_dir_all(&temp_dir).expect("temp dir should exist");
|
||||||
|
|
||||||
|
// when
|
||||||
|
let output = Command::new(env!("CARGO_BIN_EXE_claw"))
|
||||||
|
.current_dir(&temp_dir)
|
||||||
|
.args(["--output-format", "json", "sandbox"])
|
||||||
|
.output()
|
||||||
|
.expect("claw should launch");
|
||||||
|
|
||||||
|
// then
|
||||||
|
assert_success(&output);
|
||||||
|
let stdout = String::from_utf8(output.stdout).expect("stdout should be utf8");
|
||||||
|
let parsed: Value = serde_json::from_str(stdout.trim()).expect("sandbox output should be json");
|
||||||
|
assert_eq!(parsed["kind"], "sandbox");
|
||||||
|
assert!(parsed["sandbox"].is_object());
|
||||||
|
assert!(parsed["sandbox"]["requested"].is_object());
|
||||||
|
|
||||||
|
fs::remove_dir_all(temp_dir).expect("cleanup temp dir");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn resume_flag_loads_a_saved_session_and_dispatches_status() {
|
fn resume_flag_loads_a_saved_session_and_dispatches_status() {
|
||||||
// given
|
// given
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use std::time::{SystemTime, UNIX_EPOCH};
|
|||||||
|
|
||||||
use runtime::ContentBlock;
|
use runtime::ContentBlock;
|
||||||
use runtime::Session;
|
use runtime::Session;
|
||||||
|
use serde_json::Value;
|
||||||
|
|
||||||
static TEMP_COUNTER: AtomicU64 = AtomicU64::new(0);
|
static TEMP_COUNTER: AtomicU64 = AtomicU64::new(0);
|
||||||
|
|
||||||
@@ -221,6 +222,52 @@ fn resume_latest_restores_the_most_recent_managed_session() {
|
|||||||
assert!(stdout.contains(newer_path.to_str().expect("utf8 path")));
|
assert!(stdout.contains(newer_path.to_str().expect("utf8 path")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn resumed_status_command_emits_structured_json_when_requested() {
|
||||||
|
// given
|
||||||
|
let temp_dir = unique_temp_dir("resume-status-json");
|
||||||
|
fs::create_dir_all(&temp_dir).expect("temp dir should exist");
|
||||||
|
let session_path = temp_dir.join("session.jsonl");
|
||||||
|
|
||||||
|
let mut session = Session::new();
|
||||||
|
session
|
||||||
|
.push_user_text("resume status json fixture")
|
||||||
|
.expect("session write should succeed");
|
||||||
|
session
|
||||||
|
.save_to_path(&session_path)
|
||||||
|
.expect("session should persist");
|
||||||
|
|
||||||
|
// when
|
||||||
|
let output = run_claw(
|
||||||
|
&temp_dir,
|
||||||
|
&[
|
||||||
|
"--output-format",
|
||||||
|
"json",
|
||||||
|
"--resume",
|
||||||
|
session_path.to_str().expect("utf8 path"),
|
||||||
|
"/status",
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assert!(
|
||||||
|
output.status.success(),
|
||||||
|
"stdout:\n{}\n\nstderr:\n{}",
|
||||||
|
String::from_utf8_lossy(&output.stdout),
|
||||||
|
String::from_utf8_lossy(&output.stderr)
|
||||||
|
);
|
||||||
|
|
||||||
|
let stdout = String::from_utf8(output.stdout).expect("stdout should be utf8");
|
||||||
|
let parsed: Value =
|
||||||
|
serde_json::from_str(stdout.trim()).expect("resume status output should be json");
|
||||||
|
assert_eq!(parsed["kind"], "status");
|
||||||
|
assert_eq!(parsed["messages"], 1);
|
||||||
|
assert_eq!(
|
||||||
|
parsed["workspace"]["session"],
|
||||||
|
session_path.to_str().expect("utf8 path")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
fn run_claw(current_dir: &Path, args: &[&str]) -> Output {
|
fn run_claw(current_dir: &Path, args: &[&str]) -> Output {
|
||||||
run_claw_with_env(current_dir, args, &[])
|
run_claw_with_env(current_dir, args, &[])
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user