// ==UserScript== // @name Prefix ChatGPT chats with "S:" // @namespace http://tampermonkey.net/ // @version 2024-11-23T16:11:30+05:30 // @description For TOTALLY legit usage reasons... // @author Sangeeth Sudheer // @match https://chatgpt.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=chatgpt.com // @updateURL https://git.sangeeth.dev/x/userscripts/raw/branch/main/chatgpt-chat-prefixer/ChatGPTChatPrefixer.user.js // @downloadURL https://git.sangeeth.dev/x/userscripts/raw/branch/main/chatgpt-chat-prefixer/ChatGPTChatPrefixer.user.js // @grant none // ==/UserScript== (function() { 'use strict'; const PREFIX = "S: "; const sels = { activeChatSidebarItem: '[data-testid^="history-item"]:has(> [class~="bg-token-sidebar-surface-secondary"])', renamePopoverItem: '[data-testid="share-chat-menu-item"] + div', } function triggerEnterKey(el) { const event = new KeyboardEvent('keydown', { key: 'Enter', code: 'Enter', bubbles: true }); el.dispatchEvent(event); } function wait(ms) { const { resolve, reject, promise } = Promise.withResolvers(); setTimeout(resolve, ms); return promise; } function waitFor(sel, el = document) { const { resolve, reject, promise } = Promise.withResolvers(); let count = 0; function _wait() { if (el.querySelector(sel)) { resolve(); } ++count; if (count >= 5) { reject(); } setTimeout(_wait, 1000); } _wait(); } async function getStableLabelText(el) { while (true) { const prev = el.textContent.trim(); await wait(1000); const curr = el.textContent.trim(); if (prev === curr) { return curr; } } } async function main() { try { const menuItem = document.querySelector(sels.activeChatSidebarItem); if (!menuItem) { console.log("Active chat menu item wasn't found. You're either not on the regular chat page or the markup has changed"); return; } const label = await getStableLabelText(menuItem.querySelector("a")); if (/new chat/i.test(label)) { console.log("Chat label isn't yet autopopulated by LLM"); return; } if (label.startsWith(PREFIX)) { console.log("No need to rename chat"); return; } triggerEnterKey(menuItem.querySelector("button")); await wait(100); document.querySelector(sels.renamePopoverItem).click(); await wait(500); const input = menuItem.querySelector("input"); const prevValue = input.value; input.focus(); await wait(100); input.value = `${PREFIX}${label}`; if (input._valueTracker) { input._valueTracker.setValue(prevValue); } const inputEvent = new Event('input', { bubbles: true }); input.dispatchEvent(inputEvent); triggerEnterKey(input); await wait(100); console.log("Renamed chat"); } finally { setTimeout(main, 5000); } } setTimeout(main, 5000); })();