// ==UserScript==
// @name Claude.ai | Remove active (current) chat by CTRL+SHIFT+BACKSPACE
// @namespace http://tampermonkey.net/
// @version 1.0
// @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 = false;
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) {
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('nav li');
for (let listItem of listItems) {
const link = listItem.querySelector('a');
if (link && link.classList.contains('!bg-bg-300')) {
const menuButton = listItem.querySelector('button[aria-haspopup="menu"]');
if (menuButton) {
return { button: menuButton, listItem: listItem };
}
}
}
return null;
}
async function deleteActiveChat() {
try {
const activeElement = findActiveMenuButton();
if (!activeElement) return;
const { button: activeMenuButton, listItem } = activeElement;
listItem.dispatchEvent(new MouseEvent('mouseenter', { bubbles: true }));
listItem.classList.add('group-hover');
await new Promise(resolve => setTimeout(resolve, 100));
simulateRealClick(activeMenuButton);
await new Promise(resolve => setTimeout(resolve, 200));
let menuDeleteButton = document.querySelector('[data-testid="delete-chat-trigger"]');
if (!menuDeleteButton) {
listItem.dispatchEvent(new MouseEvent('mouseover', { bubbles: true }));
listItem.dispatchEvent(new MouseEvent('mouseenter', { bubbles: true }));
await new Promise(resolve => setTimeout(resolve, 100));
activeMenuButton.click();
await new Promise(resolve => setTimeout(resolve, 200));
}
const deleteButton = await waitForElement('[data-testid="delete-chat-trigger"]', 3000);
deleteButton.click();
if (DELETE_AUTOCONFIRM) {
const confirmButton = await waitForElement('[data-testid="delete-modal-confirm"]', 3000);
confirmButton.click();
}
} 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();
deleteActiveChat();
}
});
})();