use super::ShellState;
use crate::AppModel;
use crate::start::{self, StartInputs};
use lernie::mint::SplitMix64;
pub(super) fn run_prepare(model: &mut AppModel, state: &mut ShellState, inputs: StartInputs) {
super::acting::start::prepare(model, state, &inputs);
}
pub fn composer(ui: &mut egui::Ui, model: &mut AppModel, state: &mut ShellState) {
let mint_seed = state.start.mint_seed;
let Some(pending) = state.start.pending.as_mut() else {
return;
};
let (mut send, mut cancel) = (false, false);
let names = crate::nav::convs::names_in_rows(
&super::convs::of(model, pending.workspace.clone())
.value
.unwrap_or_default(),
);
ui.weak(start::identity_preview(
&names,
&SplitMix64::from_seed(mint_seed),
));
ui.label(format!("Start goal → {}", pending.workspace));
let row = ui.spacing().interact_size.y + 2.0 * ui.spacing().item_spacing.y;
let box_height = (ui.available_height() - row).max(row);
egui::ScrollArea::vertical()
.max_height(box_height)
.show(ui, |ui| {
ui.add_sized(
[ui.available_width(), box_height],
egui::TextEdit::multiline(&mut pending.goal),
)
.on_hover_text(
"The goal this conversation starts with — the agent's first instruction. \
Edit it freely; it is only read when you press Send — or Enter, which \
is the same fire. Typed whole, it is `/prompt <goal…>`.",
);
});
let armed = crate::actions::goal_present(&pending.goal);
ui.horizontal(|ui| {
send = ui
.add_enabled(armed, egui::Button::new("Send (detached prompt)"))
.on_hover_text(
"Launch the conversation: `lernie prompt`, detached, in the workspace \
named above. It keeps running whatever yog does afterwards (Enter).",
)
.on_disabled_hover_text(
"The goal above is empty — say what you want done before this can \
launch anything.",
)
.clicked();
cancel = ui
.button("Cancel")
.on_hover_text(
"Drop this goal without launching anything. A ball claimed on the way \
here stays claimed. Escape does the same.",
)
.clicked();
});
if send {
send_pending(model, state);
}
if cancel {
state.start.pending = None;
super::focus::request(state);
}
}
pub(super) fn send_pending(model: &mut AppModel, state: &mut ShellState) {
let Some(p) = state
.start
.pending
.clone()
.filter(|p| crate::actions::goal_present(&p.goal))
else {
return;
};
let ws = model.snap.ws_path(&p.workspace).unwrap_or_default();
super::acting::start::prompt(model, state, &ws, &p, &p.goal);
}