fix(tui): only say "Goal cleared." when there was a goal to clear

/clear and /new always queue a goal clear so the engine's goal state
can't outlive the conversation, and the engine answered every clear
with a "Goal cleared." status. In a session that never had a goal the
footer said so right under "Conversation cleared". Note whether a goal
existed (in the shared goal state, or the configured fallback the clear
also wipes) before clearing, and skip the status when there was none.
The empty goal snapshot is still published, and clearing a goal that
was set, through /goal clear or /clear, still says "Goal cleared.".

Signed-off-by: Lstarsky0 <[email protected]>
This commit is contained in:
Lstarsky0 committed 2026-10-23 21:43:38 +08:00
1 parent 262496dee7
commit e11bd43a42
1 file changed
+9 -6
+9 -6
View File
@@ -5596,12 +5596,13 @@ impl Engine {
if clear || status != GoalStatus::Active {
self.cancel_scheduled_goal_continuation(true).await;
}
let was_active = self
let (was_active, had_objective) = self
.config
.goal_state
.lock()
.map(|state| state.is_active())
.unwrap_or(false);
.map(|state| (state.is_active(), state.objective().is_some()))
.unwrap_or((false, false));
let had_goal = had_objective || self.config.goal_objective.is_some();
let snapshot = match self.config.goal_state.lock() {
Ok(mut state) => {
if clear {
@@ -5661,9 +5662,11 @@ impl Engine {
GoalStatus::Blocked => "blocked",
}
};
let _ = self
.send_event(Event::status(format!("Goal {label}.")))
.await;
if !clear || had_goal {
let _ = self
.send_event(Event::status(format!("Goal {label}.")))
.await;
}
// Resuming an objective-bearing goal restarts the runtime's own
// steering loop — the kickoff is a continuation turn, never a raw