ChatGPT Condenser

精简chatGPT 里面的对话,只剩下最新的4个对话

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==UserScript==
// @name         ChatGPT Condenser
// @namespace    http://tampermonkey.net/
// @version      2026-02-27
// @description  精简chatGPT 里面的对话,只剩下最新的4个对话
// @author       You
// @match        https://chatgpt.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=chatgpt.com
// @license All Rights Reserved
// @run-at       document-end
// ==/UserScript==
(function () {
  'use strict';

  // 插入样式
  const style = document.createElement('style');
  style.textContent = `
    #tm-float-btn {
      position: fixed;
      right: 20px;
      bottom: 90px; /* 右下角往上一点:数值越大越靠上 */
      z-index: 2147483647;

      padding: 10px 14px;
      border: 0;
      border-radius: 999px;
      background: #57c7ff; /* 天蓝色 */
      color: #0b2a3a;
      font-size: 14px;
      line-height: 1;
      cursor: pointer;
      box-shadow: 0 6px 18px rgba(0,0,0,.25);
      user-select: none;
    }
    #tm-float-btn:hover { filter: brightness(0.95); }
    #tm-float-btn:active { transform: scale(.98); }
  `;
  (document.head || document.documentElement).appendChild(style);

  // 创建按钮
  const btn = document.createElement('button');
  btn.id = 'tm-float-btn';
  btn.type = 'button';
  btn.textContent = '点击触发';

  btn.addEventListener('click', () => {
     // 这里就有两个严重逻辑漏洞
      /*
         1. 删除element时候 循环里面判断变量用的是ele.length 删一个少一个。所以像删只剩下4个,但是删除的更少
         2. 换个变量存储总大小,在删除。此时删除的是ele[i] 此时因为ele少了,所以删到最后 i越来越大 ele数组大小越来越少 就越界了
      */
    var ele = document.getElementsByClassName("text-token-text-primary w-full");
    console.log(ele.length);
    var ele_length = ele.length - 4;
    for(var i = 0; i < ele_length; i++){
       ele[0].remove();
    }
  });

  (document.body || document.documentElement).appendChild(btn);
})();

(function () {
  'use strict';

  // ====== Styles ======
  const style = document.createElement('style');
  style.textContent = `
    #tm-float-btn {
      position: fixed;
      right: 20px;
      bottom: 20%; /* 越大越靠上 */
      z-index: 2147483647;

      padding: 10px 14px;
      border: 0;
      border-radius: 999px;
      background: #57c7ff; /* 天蓝色 */
      color: #0b2a3a;
      font-size: 14px;
      line-height: 1;
      cursor: pointer;
      box-shadow: 0 6px 18px rgba(0,0,0,.25);
      user-select: none;
    }
    #tm-float-btn:hover { filter: brightness(0.95); }
    #tm-float-btn:active { transform: scale(.98); }

    /* Toast */
    .tm-toast {
      position: fixed;
      top: 18%;
      left: 50%;
      transform: translateX(-50%);
      z-index: 2147483647;

      padding: 12px 16px;
      border-radius: 12px;
      background: rgba(0, 0, 0, 0.78);
      color: #fff;
      font-size: 40px;
      line-height: 1.4;
      box-shadow: 0 10px 28px rgba(0,0,0,.28);

      opacity: 0;
      transition: opacity 240ms ease, transform 240ms ease;
      pointer-events: none;
      white-space: nowrap;
    }
    .tm-toast.tm-toast-show {
      opacity: 1;
      transform: translateX(-50%) translateY(0);
    }
    .tm-toast.tm-toast-hide {
      opacity: 0;
      transform: translateX(-50%) translateY(-8px);
    }
  `;
  (document.head || document.documentElement).appendChild(style);

  // ====== Toast helper ======
  let toastEl = null;
  let toastTimer1 = null;
  let toastTimer2 = null;

  function showToast(message, waitMs = 2000, fadeMs = 600) {
    // 若已有 toast,先清理
    if (toastEl) {
      toastEl.remove();
      toastEl = null;
    }
    if (toastTimer1) clearTimeout(toastTimer1);
    if (toastTimer2) clearTimeout(toastTimer2);

    toastEl = document.createElement('div');
    toastEl.className = 'tm-toast';
    toastEl.textContent = message;

    (document.body || document.documentElement).appendChild(toastEl);

    // 触发进入动画
    requestAnimationFrame(() => {
      toastEl.classList.add('tm-toast-show');
    });

    // 2秒后开始淡出
    toastTimer1 = setTimeout(() => {
      if (!toastEl) return;
      toastEl.classList.add('tm-toast-hide');

      // 淡出结束后移除
      toastTimer2 = setTimeout(() => {
        toastEl?.remove();
        toastEl = null;
      }, fadeMs);
    }, waitMs);
  }

  // ====== Button ======
  const btn = document.createElement('button');
  btn.id = 'tm-float-btn';
  btn.type = 'button';
  btn.textContent = '点击触发';

  btn.addEventListener('click', async () => {

    var ele = document.getElementsByClassName("text-token-text-primary w-full");
    console.log(ele.length);
    var ele_length = ele.length;
    for(var i = 0; i < ele_length-8; i++){
       ele[0].remove();
    }
    showToast("原大小:  " + (ele_length) + "      删除后:  " + ele.length, 1000, 500);
  });

  (document.body || document.documentElement).appendChild(btn);
})();