Skip to content

Commit 9b06f58

Browse files
cursoragentadmin
andcommitted
fix(tui): keep enter-during-cancel from re-queueing drafts
submit() while status is cancelling leaves the restored draft in the textarea so sendQueued cannot fire it into the cancelled session. Co-authored-by: admin <admin@21no.de>
1 parent 5472a2b commit 9b06f58

2 files changed

Lines changed: 38 additions & 0 deletions

File tree

‎internal/tui/input.go‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,13 @@ func (m *Model) submit() tea.Cmd {
237237
return m.noticeSweep()
238238
}
239239
if m.busy {
240+
if m.status == "cancelling" {
241+
// cancelRun handed the queue back to the input so it would
242+
// not fire into the cancelled session. Re-queueing here
243+
// would sendQueued it on the trailing done anyway.
244+
m.refresh()
245+
return m.transientNoteCmd("cancelling — draft stays in the input")
246+
}
240247
// Queue mid-turn prompts instead of dropping them; the queue drains
241248
// automatically when the running turn ends. Acknowledge the hold —
242249
// the input clearing silently reads as a lost message (same

‎internal/tui/promptflow_test.go‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,37 @@ func TestCancelRestoresQueue(t *testing.T) {
381381
}
382382
}
383383

384+
// Enter while cancelling must not re-queue the restored draft — that
385+
// would sendQueued it into the session the cancel just pulled it out of.
386+
func TestCancelEnterDoesNotRequeue(t *testing.T) {
387+
m := newTestModel()
388+
busyTurn(m)
389+
m.sessionID = "s1"
390+
m.queue = []string{"one", "two"}
391+
392+
m.Update(key("esc"))
393+
m.Update(key("y"))
394+
if m.status != "cancelling" {
395+
t.Fatalf("precondition: status = %q, want cancelling", m.status)
396+
}
397+
if got := m.ta.Value(); got != "one\ntwo" {
398+
t.Fatalf("precondition: input = %q", got)
399+
}
400+
401+
m.Update(key("enter"))
402+
if len(m.queue) != 0 {
403+
t.Fatalf("enter while cancelling re-queued: %v", m.queue)
404+
}
405+
if got := m.ta.Value(); got != "one\ntwo" {
406+
t.Errorf("draft must stay in the input, got %q", got)
407+
}
408+
409+
m.handleEvent(client.Event{Type: "done", Latency: 1})
410+
if len(m.msgs) != 2 {
411+
t.Error("no turn should start after enter-during-cancel")
412+
}
413+
}
414+
384415
// TestSendFailureFinalizesTurn verifies a failed send closes out the phantom
385416
// assistant turn sendPrompt opened, with the error inline in the transcript.
386417
func TestSendFailureFinalizesTurn(t *testing.T) {

0 commit comments

Comments
 (0)