Delete active chat in Claude.ai sidebar using Ctrl+Shift+Backspace
// ==UserScript==
// @name Claude.ai | Remove active (current) chat by CTRL+SHIFT+BACKSPACE
// @namespace http://tampermonkey.net/
// @version 1.1
// @description Delete active chat in Claude.ai sidebar using Ctrl+Shift+Backspace
// @author Saymonn
// @match https://claude.ai/chat*
// @icon https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQO8QnSw5ArwqF8PsafiMQ3EsH0Xr9LFLgNpwutam6-FN7UhoQvXeyqIHyNvj907vU5BKU&usqp=CAU
// @license MIT
// @grant none
// ==/UserScript==
(function() {
'use strict';
const DELETE_AUTOCONFIRM = true;
function waitForElement(selector, timeout = 5000) {
return new Promise((resolve, reject) => {
const startTime = Date.now();
function check() {
const element = document.querySelector(selector);
if (element) {
resolve(element);
} else if (Date.now() - startTime > timeout) {
reject(new Error(`Element ${selector} not found within ${timeout}ms`));
} else {
setTimeout(check, 50);
}
}
check();
});
}
function simulateRealClick(element) {
if (!element) return;
const rect = element.getBoundingClientRect();
const x = rect.left + rect.width / 2;
const y = rect.top + rect.height / 2;
const events = [
new PointerEvent('pointerdown', { bubbles: true, cancelable: true, pointerId: 1, clientX: x, clientY: y, button: 0 }),
new MouseEvent('mousedown', { bubbles: true, cancelable: true, clientX: x, clientY: y, button: 0 }),
new PointerEvent('pointerup', { bubbles: true, cancelable: true, pointerId: 1, clientX: x, clientY: y, button: 0 }),
new MouseEvent('mouseup', { bubbles: true, cancelable: true, clientX: x, clientY: y, button: 0 }),
new MouseEvent('click', { bubbles: true, cancelable: true, clientX: x, clientY: y, button: 0 })
];
events.forEach(event => element.dispatchEvent(event));
}
function findActiveMenuButton() {
const listItems = document.querySelectorAll('li');
for (let listItem of listItems) {
const link = listItem.querySelector('a');
if (link && link.classList.contains('!bg-bg-400')) {
const menuButton = listItem.querySelector('button[aria-haspopup="menu"]');
if (menuButton) {
return { button: menuButton, listItem: listItem };
}
}
}
return null;
}
function findDeleteButton() {
const selectors = [
'[data-testid="delete-chat-trigger"]',
'[data-testid*="delete"]',
'button[aria-label*="Delete"]',
'button[aria-label*="delete"]',
'[role="menuitem"]'
];
for (let selector of selectors) {
const elements = document.querySelectorAll(selector);
for (let element of elements) {
if (element.textContent.toLowerCase().includes('delete') ||
element.getAttribute('aria-label')?.toLowerCase().includes('delete')) {
return element;
}
}
}
const menuItems = document.querySelectorAll('[role="menuitem"]');
for (let item of menuItems) {
if (item.textContent.toLowerCase().includes('delete')) {
return item;
}
}
return null;
}
async function deleteActiveChat() {
try {
const activeElement = findActiveMenuButton();
if (!activeElement) {
console.log('No active chat found');
return;
}
const { button: activeMenuButton, listItem } = activeElement;
console.log('Found active chat, clicking menu button');
simulateRealClick(activeMenuButton);
await new Promise(resolve => setTimeout(resolve, 300));
const deleteButton = findDeleteButton();
if (!deleteButton) {
console.log('Delete button not found, trying alternative approach');
await new Promise(resolve => setTimeout(resolve, 100));
simulateRealClick(activeMenuButton);
await new Promise(resolve => setTimeout(resolve, 300));
const deleteButtonRetry = findDeleteButton();
if (deleteButtonRetry) {
deleteButtonRetry.click();
} else {
console.log('Still no delete button found');
return;
}
} else {
deleteButton.click();
}
if (DELETE_AUTOCONFIRM) {
try {
console.log('Waiting for confirmation modal...');
const confirmButton = await waitForElement('[data-testid="delete-modal-confirm"]', 3000);
console.log('Found confirmation button, clicking...');
confirmButton.click();
} catch (error) {
console.log('Confirmation button not found:', error.message);
const fallbackConfirmButton = document.querySelector('button[data-testid="delete-modal-confirm"]');
if (fallbackConfirmButton) {
console.log('Found confirmation button with fallback method');
fallbackConfirmButton.click();
} else {
console.log('No confirmation button found with any method');
}
}
}
} catch (error) {
console.error('Error during chat deletion:', error.message);
}
}
document.addEventListener('keydown', function(event) {
if (event.ctrlKey && event.shiftKey && event.code === 'Backspace') {
event.preventDefault();
console.log('Delete shortcut triggered');
deleteActiveChat();
}
});
console.log('Claude.ai chat deletion script loaded');
})();