Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions apps/code/src/renderer/features/tasks/hooks/useArchiveTask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,21 @@ export async function archiveTaskImperative(
}
}

const terminalStatesSnapshot = Object.fromEntries(
Object.entries(useTerminalStore.getState().terminalStates).filter(
([key]) => key === taskId || key.startsWith(`${taskId}-`),
),
);
const commandCenterState = useCommandCenterStore.getState();
const commandCenterIndex = commandCenterState.cells.indexOf(taskId);
const wasActiveInCommandCenter = commandCenterState.activeTaskId === taskId;

pinnedTasksApi.unpin(taskId);
useTerminalStore.getState().clearTerminalStatesForTask(taskId);
useCommandCenterStore.getState().removeTaskById(taskId);

await queryClient.cancelQueries(trpc.archive.pathFilter());

queryClient.setQueryData<string[]>(
trpc.archive.archivedTaskIds.queryKey(),
(old) => (old ? [...old, taskId] : [taskId]),
Expand Down Expand Up @@ -87,6 +98,20 @@ export async function archiveTaskImperative(
if (wasPinned) {
pinnedTasksApi.togglePin(taskId);
}
if (Object.keys(terminalStatesSnapshot).length > 0) {
useTerminalStore.setState((s) => ({
terminalStates: { ...s.terminalStates, ...terminalStatesSnapshot },
}));
}
if (commandCenterIndex !== -1) {
useCommandCenterStore.setState((s) => {
const cells = [...s.cells];
cells[commandCenterIndex] = taskId;
return wasActiveInCommandCenter
? { cells, activeTaskId: taskId }
: { cells };
});
}
Comment on lines +106 to +114
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 assignTask unconditionally steals active-task focus during error recovery

assignTask always sets activeTaskId to the newly assigned task (see commandCenterStore.ts line 113). In the error path this means: if the archived task was visible in the command center but was not the active cell, recovery will incorrectly steal focus to it. For example — user focuses cell 0 (task A), right-clicks task B in cell 2 and archives it, mutation fails → assignTask(2, taskB) fires and makes task B the active task, silently stealing focus from task A. The snapshot should also capture the pre-archive activeTaskId and restore it explicitly instead of relying on assignTask's side-effect.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/code/src/renderer/features/tasks/hooks/useArchiveTask.ts
Line: 106-108

Comment:
**`assignTask` unconditionally steals active-task focus during error recovery**

`assignTask` always sets `activeTaskId` to the newly assigned task (see `commandCenterStore.ts` line 113). In the error path this means: if the archived task was visible in the command center but was *not* the active cell, recovery will incorrectly steal focus to it. For example — user focuses cell 0 (task A), right-clicks task B in cell 2 and archives it, mutation fails → `assignTask(2, taskB)` fires and makes task B the active task, silently stealing focus from task A. The snapshot should also capture the pre-archive `activeTaskId` and restore it explicitly instead of relying on `assignTask`'s side-effect.

How can I resolve this? If you propose a fix, please make it concise.


throw error;
}
Expand Down
Loading