Skip to content

Conversation

@rabanspiegel
Copy link
Contributor

@rabanspiegel rabanspiegel commented Feb 1, 2026

Summary

Adds the ability to archive tasks instead of permanently deleting them. Archived tasks are hidden from the main task list but remain accessible for reference or restoration.

Closes #695

Changes

  • Add archivedAt column to tasks table with migration
  • Add archive/restore/getArchivedTasks methods to DatabaseService
  • Add IPC handlers and expose via preload
  • Add "Archive" option to task context menu in sidebar
  • Add collapsible "Archived" section in sidebar showing archived tasks per project
  • Add restore and delete buttons for archived tasks
  • Add archive button to ProjectMainView (individual and bulk)
  • Archived tasks are filtered out of main task list by default
  • Restored tasks appear at top of list (updatedAt is refreshed)

Test Plan

  • Archive from sidebar: Right-click a task → "Archive" → task disappears from list
  • Archived section appears: After archiving, "Archived (N)" section appears under project tasks
  • Restore task: Hover archived task → click restore button → task reappears at top of active list
  • Delete archived task: Hover archived task → click delete button → task is permanently removed
  • Archive from ProjectMainView: Click archive button next to delete on task card
  • Bulk archive: Select mode → select multiple tasks → click "Archive" → all selected archived
  • Archive active task: Select a task, archive it → UI clears active state properly
  • Tooltips work: Hover restore/delete buttons on archived tasks → tooltips appear
  • Database migration: App starts without errors (migration runs automatically)

Note

Medium Risk
Moderate risk: changes touch the persisted task schema and default task queries (archived filtering), plus new IPC surface and UI state updates that could cause tasks to disappear/reappear incorrectly if edge cases aren’t handled.

Overview
Adds task archiving as a soft-delete via a new tasks.archived_at column + Drizzle migration, and updates the DB layer so getTasks excludes archived tasks while new getArchivedTasks/archiveTask/restoreTask APIs manage them.

Exposes these operations over Electron IPC/preload and wires them into the UI: tasks can be archived from the sidebar context menu and from ProjectMainView (including bulk archive), with a per-project collapsible Archived section that supports restore and permanent delete, plus telemetry/toast handling and optimistic UI updates.

Written by Cursor Bugbot for commit 7d31f03. This will update automatically on new commits. Configure here.

- Add archivedAt column to tasks table with migration
- Add archive/restore/getArchivedTasks methods to DatabaseService
- Add IPC handlers and expose via preload
- Add Archive option to task context menu in sidebar
- Add collapsible Archived section showing archived tasks per project
- Add restore button on hover for archived tasks
- Archived tasks are hidden from main list but preserved in database
- Restored tasks appear at top of list (updatedAt is refreshed)
- Add delete button next to restore button in archived tasks section
- Use same Trash icon and styling as other delete buttons
- Add proper Radix UI tooltips for both restore and delete buttons
- Add archive button next to delete for individual tasks
- Add bulk archive in select mode (Archive button next to Delete)
- Pass onArchiveTask prop from App to ProjectMainView
- Edge case already handled: archiving active task clears active state
@vercel
Copy link

vercel bot commented Feb 1, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview, Comment Feb 1, 2026 3:23am

Request Review

- Add silent option to handleArchiveTask for bulk operations
- Pass silent: true from bulk archive to prevent duplicate toasts
- Add restoringTaskIdsRef to prevent duplicate restore operations
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 3 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

}
} catch (refreshError) {
log.error('Failed to refresh tasks after archive failure:', refreshError as any);
}
Copy link

Choose a reason for hiding this comment

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

Archive error recovery lacks fallback for task restoration

Low Severity

The handleArchiveTask function optimistically removes the task from the UI, but if the archive operation fails AND the subsequent getTasks refresh also fails, the task disappears from the UI with no fallback restoration. Unlike handleDeleteTask which has a taskSnapshot fallback to restore the task if refresh fails, handleArchiveTask only logs the error. The task data remains safe in the database but becomes invisible until manual refresh.

Fix in Cursor Fix in Web

variant: 'destructive',
});
}
};
Copy link

Choose a reason for hiding this comment

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

Archiving running tasks leaves orphaned terminal processes

High Severity

The handleArchiveTask function doesn't stop running agents or clean up terminal resources before archiving. Unlike handleDeleteTask which calls ptyKill, terminalSessionRegistry.dispose, and ptyClearSnapshot, handleArchiveTask performs no cleanup. If a task with active agents is archived, the PTY processes continue running in the background with no way for the user to stop them (the task is hidden from the UI). This causes resource leaks and potential unwanted file modifications.

Fix in Cursor Fix in Web

archivedNames.push(ws.name);
} catch {
// Continue archiving remaining tasks
}
Copy link

Choose a reason for hiding this comment

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

Bulk archive counts failed tasks as successfully archived

Medium Severity

The handleBulkArchive function relies on onArchiveTask throwing an error to skip adding failed tasks to archivedNames. However, handleArchiveTask returns Promise<void> and catches errors internally without re-throwing, so it always returns normally. This means failed archives are still counted in the success summary toast, misleading users about which tasks were actually archived.

Additional Locations (1)

Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants