mod harness;
mod queue;
mod window;
use super::fixture::{fake_lernie, seed_world};
use super::screen::Screen;
use harness::{
MINTED_FIRST, SAID, branches, converge_ws, faded_user, fills, quick, rows_named, say, shot,
world,
};
use tempfile::tempdir;
#[test]
fn a_start_is_a_row_in_the_operators_own_words_on_the_next_frame() {
let bin = tempdir().unwrap();
let mut world = quick(world());
seed_world(&world);
let screen = Screen::with_lernie(fake_lernie(bin.path()));
assert!(screen.idle(&mut world), "the cursor starts in the composer");
let worktrees = branches(&world);
let before = screen.text(&mut world);
assert!(
!before.contains(SAID),
"nothing says it before the operator does:\n{before}"
);
say(&screen, &mut world);
assert_eq!(
branches(&world),
worktrees,
"the driver has written nothing: no branch for a derivation to carry"
);
let painted = screen.text(&mut world);
assert!(
painted.contains(SAID),
"the frame immediately after Enter carries what was typed:\n{painted}"
);
assert_eq!(
world.model.focus().agent.as_deref(),
Some(MINTED_FIRST),
"the start selected what it started, by the minted name its row wears"
);
assert!(
!painted.contains("select a conversation"),
"so the centre is that conversation, not the placeholder:\n{painted}"
);
let pending = rows_named(&world, MINTED_FIRST);
assert_eq!(
pending.len(),
1,
"exactly one row for the started conversation"
);
assert_eq!(
pending[0].root_id, MINTED_FIRST,
"keyed by the minted §3.3 name — the only identity a start has yet"
);
assert_eq!(
pending[0].subtitle(),
SAID,
"and its preview is the operator's text verbatim"
);
assert_eq!(
pending[0].tone,
crate::transcript::Tone::Weak,
"faded: yog's own word for it, not yet a statement (§11)"
);
world.add_root("c-2", MINTED_FIRST);
let messages = world.ws.join("agents/c-2/messages");
std::fs::create_dir_all(&messages).unwrap();
std::fs::write(messages.join("001-user.md"), SAID).unwrap();
std::fs::write(world.ws.join("agents/c-2/goal.md"), SAID).unwrap();
std::fs::write(
world.ws.join("steps/c-2/001/request.json"),
br#"{"model":"m","messages":[{"role":"user","content":[{"type":"text","text":"<file path=\"instructions/00/AGENTS.md\">\nhouse rules\n</file>"},{"type":"text","text":"---\nfrom: operator\n---\n\nunbar it"}]}]}"#,
)
.unwrap();
converge_ws(&mut world);
let landed = rows_named(&world, MINTED_FIRST);
assert_eq!(
landed.len(),
1,
"still one row — the echo gave its seat up rather than doubling it"
);
assert_eq!(
landed[0].tone,
crate::transcript::Tone::Plain,
"and it brightened: the derivation made it a statement"
);
assert_eq!(
landed[0].root_id, "c-2",
"the row is now the real branch, keyed by its agent id"
);
assert_eq!(
landed[0].subtitle(),
SAID,
"and the flip changed nothing about what it says: still the operator's \
text, not the assembled context's head"
);
}
#[test]
fn a_message_joins_the_inbox_queue_faded_and_brightens_when_it_lands() {
let bin = tempdir().unwrap();
let mut world = quick(world());
seed_world(&world);
let screen = Screen::with_lernie(fake_lernie(bin.path()));
let ws = world.ws.clone();
world.model.focus_agent(&ws, "c-1");
world
.model
.select_tab(crate::keymap::InspectorTab::Transcript);
screen.text(&mut world);
let before = world
.model
.tree(&ws)
.and_then(|t| t.agents.iter().find(|a| a.agent_id == "c-1").cloned())
.expect("the fixture's conversation");
assert_eq!(before.pending.len(), 1, "the fixture's one landed deposit");
let landed_messages = before.messages;
say(&screen, &mut world);
assert_eq!(
std::fs::read_dir(world.ws.join("agents/c-1/messages")).map_or(0, |d| d.flatten().count()),
landed_messages,
"no message has landed: the transcript directory is exactly where it was"
);
let out = shot(&screen, &mut world);
let text = crate::paint_probe::text_of(&out);
assert!(
text.contains(SAID),
"the frame immediately after Enter carries what was typed:\n{text}"
);
assert!(
fills(&out).contains(&faded_user()),
"and it is faded — yog's own word for it, not yet a statement (§11)"
);
let messages = world.ws.join("agents/c-1/messages");
std::fs::write(messages.join("003-user.md"), SAID).unwrap();
converge_ws(&mut world);
let after = shot(&screen, &mut world);
assert!(
!fills(&after).contains(&faded_user()),
"the faded row is gone: the echo retired onto the landed message"
);
assert!(
crate::paint_probe::text_of(&after).contains(SAID),
"and the words are still on screen — now the derivation's, not yog's:\n{}",
crate::paint_probe::text_of(&after)
);
}