M5c-1 plan: task 04, bxctl chat --speaker NAME, opt-in, no default
The speaker goes on every turn of the chat: interactive, --say and --say's retry. Without the flag it is None. A name that is empty or holds whitespace or a control character (Unicode), or a second --speaker, is a usage error: the usage text on stderr and exit status 2. The usage text gains the flag and one line explaining it. Given: chat_speaker.rs (new) and new versions of chat.rs, chat_approvals.rs and cli.rs. Task 01 now copies chat.rs-task01, the older chat.rs. Checks: every before block found once at ref 03; replayed from the task text on a fresh ref-03 worktree with its own build directory, byte-identical to the reference, gate ok with 1158 tests (1148 + 10); /tmp unchanged around the reference's and the replay's gate runs; 20 of 20 mutations caught; the new tests passed 40 of 40 runs under CPU load; given files pass fmt and the 500-line check; no chat-template tag in the plan or the given files. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -161,6 +161,7 @@ fn run_turn_delivers_every_event_in_order_then_the_answer() {
|
||||
&id("s1"),
|
||||
"what time is it?",
|
||||
false,
|
||||
None,
|
||||
&mut |e| seen.push(e.clone()),
|
||||
)
|
||||
.unwrap();
|
||||
@@ -189,7 +190,7 @@ fn an_error_frame_is_refused_with_its_code_and_detail() {
|
||||
End::Error(ErrorCode::SessionFull, "this conversation is full"),
|
||||
);
|
||||
let mut seen = 0;
|
||||
let err = run_turn(&fake.socket, &id("s1"), "x", true, &mut |_| seen += 1).unwrap_err();
|
||||
let err = run_turn(&fake.socket, &id("s1"), "x", true, None, &mut |_| seen += 1).unwrap_err();
|
||||
assert_eq!(seen, 1, "events before the error are still delivered");
|
||||
match err {
|
||||
ChatError::Refused(w) => {
|
||||
@@ -199,7 +200,7 @@ fn an_error_frame_is_refused_with_its_code_and_detail() {
|
||||
other => panic!("{other:?}"),
|
||||
}
|
||||
let e: Box<dyn std::error::Error> =
|
||||
Box::new(run_turn(&fake.socket, &id("s1"), "x", true, &mut |_| {}).unwrap_err());
|
||||
Box::new(run_turn(&fake.socket, &id("s1"), "x", true, None, &mut |_| {}).unwrap_err());
|
||||
assert!(e.to_string().contains("session full"), "{e}");
|
||||
}
|
||||
|
||||
@@ -207,7 +208,7 @@ fn an_error_frame_is_refused_with_its_code_and_detail() {
|
||||
fn no_loopd_is_a_connect_error() {
|
||||
let missing = std::env::temp_dir().join("bxctl-no-such-loopd.sock");
|
||||
assert!(matches!(
|
||||
run_turn(&missing, &id("s1"), "x", false, &mut |_| {}),
|
||||
run_turn(&missing, &id("s1"), "x", false, None, &mut |_| {}),
|
||||
Err(ChatError::Connect(_))
|
||||
));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user