From 749a826f2e7359a0fd4f7536e3edf113c587674d Mon Sep 17 00:00:00 2001 From: Alex Netsch Date: Fri, 17 Oct 2025 15:46:37 +0100 Subject: [PATCH] Fix queue not working (vibe-kanban) (#1047) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * The regression came from the big FE reshape in `518230f8a`. That commit remapped “open details” to `⌘/Ctrl+Enter` in the Kanban scope; the follow‑up submit has always lived on the same shortcut. When the textarea is focused both scopes (`kanban` and `follow-up-ready`) are active, so pressing `⌘/Ctrl+Enter` fires the Kanban handler first, cycling the view instead of calling the queue submit. That’s why the queue no longer “auto triggers” unless you click the button. I left the backend untouched (per your revert) and fixed the shortcut conflict instead: - `frontend/src/pages/project-tasks.tsx:379` – detect when the follow-up scope is active (`activeScopes.includes(Scope.FOLLOW_UP_READY)`) and only register the Kanban `useKeyOpenDetails` handler when it isn’t. This keeps the new navigation shortcut for the board while letting the follow-up queue reclaim `⌘/Ctrl+Enter` whenever the editor is focused. Tests (pre-existing warnings only): - `pnpm lint` Give it a try: with the follow-up editor focused, `⌘/Ctrl+Enter` should queue (or send) again, while the view-cycle shortcut still works elsewhere. Natural next step would be a quick manual smoke test to confirm both shortcuts behave as expected. * You were right: the queue still wouldn’t drain when the Preview tab was open because the dev‑server process stays “running” in the background. Our follow-up queue logic refuses to start if *any* process for the attempt is running, so it kept treating that long-lived DevServer process as a blocker—even after you clicked Queue or Send. I tightened the check so we ignore DevServer runs when deciding whether it’s safe to kick off the next follow-up: - `crates/services/src/services/drafts.rs:152` – when `has_running_processes_for_attempt` scans the execution list, it now filters out processes whose `run_reason` is `DevServer`. That way only real CodingAgent/cleanup activity blocks the queue. Verification: - `cargo check -p services` With this change you can keep the preview pane (and its dev server) open and queued follow-ups will still fire as soon as the current coding run finishes. --- crates/services/src/services/drafts.rs | 11 ++++++----- frontend/src/pages/project-tasks.tsx | 6 ++++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/crates/services/src/services/drafts.rs b/crates/services/src/services/drafts.rs index 40002330..07bda6d0 100644 --- a/crates/services/src/services/drafts.rs +++ b/crates/services/src/services/drafts.rs @@ -4,7 +4,10 @@ use db::{ DBService, models::{ draft::{Draft, DraftType, UpsertDraft}, - execution_process::{ExecutionProcess, ExecutionProcessError, ExecutionProcessRunReason}, + execution_process::{ + ExecutionProcess, ExecutionProcessError, ExecutionProcessRunReason, + ExecutionProcessStatus, + }, image::TaskImage, task_attempt::TaskAttempt, }, @@ -155,10 +158,8 @@ impl DraftsService { let processes = ExecutionProcess::find_by_task_attempt_id(self.pool(), attempt_id, false).await?; Ok(processes.into_iter().any(|p| { - matches!( - p.status, - db::models::execution_process::ExecutionProcessStatus::Running - ) + matches!(p.status, ExecutionProcessStatus::Running) + && !matches!(p.run_reason, ExecutionProcessRunReason::DevServer) })) } diff --git a/frontend/src/pages/project-tasks.tsx b/frontend/src/pages/project-tasks.tsx index b6b28d19..8b0267e8 100644 --- a/frontend/src/pages/project-tasks.tsx +++ b/frontend/src/pages/project-tasks.tsx @@ -116,7 +116,7 @@ export function ProjectTasks() { attemptId?: string; }>(); const navigate = useNavigate(); - const { enableScope, disableScope } = useHotkeysContext(); + const { enableScope, disableScope, activeScopes } = useHotkeysContext(); const [searchParams, setSearchParams] = useSearchParams(); const isXL = useMediaQuery('(min-width: 1280px)'); const isMobile = !isXL; @@ -383,6 +383,8 @@ export function ProjectTasks() { ); // meta/ctrl+enter → open details or cycle forward + const isFollowUpReadyActive = activeScopes.includes(Scope.FOLLOW_UP_READY); + useKeyOpenDetails( () => { if (isPanelOpen) { @@ -391,7 +393,7 @@ export function ProjectTasks() { handleViewTaskDetails(selectedTask); } }, - { scope: Scope.KANBAN } + { scope: Scope.KANBAN, when: () => !isFollowUpReadyActive } ); // meta/ctrl+shift+enter → cycle backward