Gemini Workspace Auto-Pro

Auto-selects Gemini Pro in chats (if available)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Gemini Workspace Auto-Pro
// @namespace    http://tampermonkey.net/
// @version      1.2
// @description  Auto-selects Gemini Pro in chats (if available)
// @author       Gemini & You
// @match        https://gemini.google.com/*
// @grant        none
// @run-at       document-idle
// @noframes
// ==/UserScript==

(function() {
    'use strict';

    const LOG_PREFIX = "[Gemini3-AutoPro]";

    // --- CONFIGURATION ---
    const PRO_SELECTOR = 'button[data-test-id="bard-mode-option-pro"]';
    const ENEMY_LABELS = ["Fast", "Flash"];
    
    // How long to fight the server after a navigation event (in seconds)
    const WATCHDOG_DURATION_SEC = 30; 

    // --- STATE MANAGEMENT ---
    let lastUrl = location.href;
    let watchdogTimer = 0;
    let isWatchdogActive = true; // Start active on load

    function log(...args) {
        console.log(LOG_PREFIX, ...args);
    }

    function waitFor(selector, timeout = 2000) {
        return new Promise(resolve => {
            if (document.querySelector(selector)) return resolve(document.querySelector(selector));
            const observer = new MutationObserver((mutations, obs) => {
                if (document.querySelector(selector)) {
                    obs.disconnect();
                    resolve(document.querySelector(selector));
                }
            });
            observer.observe(document.body, { childList: true, subtree: true });
            setTimeout(() => { observer.disconnect(); resolve(null); }, timeout);
        });
    }

    async function runEnforcer() {
        // 1. Check for Navigation (User clicked a Gem or changed chat)
        if (location.href !== lastUrl) {
            log("🚀 Navigation detected! Waking up watchdog.");
            lastUrl = location.href;
            isWatchdogActive = true;
            watchdogTimer = 0; // Reset the 30s timer
        }

        // 2. If Watchdog is asleep, do nothing
        if (!isWatchdogActive) return;

        // 3. Increment Timer
        watchdogTimer++;
        if (watchdogTimer > WATCHDOG_DURATION_SEC) {
            log("💤 No activity for 30s. Watchdog going to sleep.");
            isWatchdogActive = false;
            return;
        }

        // 4. THE ENFORCER LOGIC
        // Look for the "Fast" button
        const buttons = Array.from(document.querySelectorAll('button, div[role="button"]'));
        const trigger = buttons.find(b => {
            const text = b.innerText || "";
            return ENEMY_LABELS.some(label => text.includes(label)) && b.offsetParent !== null;
        });

        if (!trigger) return; // Fast button not visible, we are safe.

        // Fast found! Open menu.
        let proOption = document.querySelector(PRO_SELECTOR);
        if (!proOption) {
            // Only log this occasionally to avoid spamming console during the animation
            if (watchdogTimer % 2 === 0) log(`⚔️ Detected 'Fast' mode. Opening menu...`);
            trigger.click();
            proOption = await waitFor(PRO_SELECTOR, 1500);
        }

        if (proOption) {
            log("🎯 Found Pro option. Switching...");
            proOption.click();
            // We do NOT stop the watchdog here. We keep watching for the remainder of the 30s
            // in case the server tries to revert it (hydration).
        } else {
            // Close menu if failed
            trigger.click(); 
        }
    }

    // Run forever, checking every 1 second
    log("Gemini Workspace Auto-Pro v1.2 (SPA-Aware) active.");
    setInterval(runEnforcer, 1000);

})();