Grok Feature Flags

Toggle feature flags on grok.com to test out new features

2025-05-16 يوللانغان نەشرى. ئەڭ يېڭى نەشرىنى كۆرۈش.

// ==UserScript==
// @name         Grok Feature Flags
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Toggle feature flags on grok.com to test out new features
// @author       Blankspeaker
// @match        https://grok.com/*
// @grant        none
// @license      GNU GPLv3
// ==/UserScript==

(function() {
    'use strict';

    try {
        // Default flags to initialize if local_feature_flags is missing or empty
        const defaultFlags = {
            "show_favorite_button": false, "SHOW_FAVORITE_BUTTON": false,
            "show_followups": false, "SHOW_FOLLOWUPS": false,
            "store_long_pastes_as_files": false, "STORE_LONG_PASTES_AS_FILES": false,
            "show_sports_cards": false, "SHOW_SPORTS_CARDS": false,
            "show_finance_cards": false, "SHOW_FINANCE_CARDS": false,
            "show_places_cards": false, "SHOW_PLACES_CARDS": false,
            "show_images_cards": false, "SHOW_IMAGES_CARDS": false,
            "enable_brave_completions": false, "ENABLE_BRAVE_COMPLETIONS": false,
            "suggestions_use_cache": false, "SUGGESTIONS_USE_CACHE": false,
            "show_create_report_button_on_attachments": false, "SHOW_CREATE_REPORT_BUTTON_ON_ATTACHMENTS": false,
            "enable_report_loading_screen": false, "ENABLE_REPORT_LOADING_SCREEN": false,
            "show_artifacts_share_button": false, "SHOW_ARTIFACTS_SHARE_BUTTON": false,
            "show_artifacts_inline_button": false, "SHOW_ARTIFACTS_INLINE_BUTTON": false,
            "disable_python_artifacts": false, "DISABLE_PYTHON_ARTIFACTS": false,
            "enable_code_execution": false, "ENABLE_CODE_EXECUTION": false,
            "enable_latex_preview": false, "ENABLE_LATEX_PREVIEW": false,
            "show_response_load_timer": false, "SHOW_RESPONSE_LOAD_TIMER": false,
            "thinking_auto_open": false, "THINKING_AUTO_OPEN": false,
            "enable_anon_cloning": false, "ENABLE_ANON_CLONING": false,
            "enable_anon_users": false, "ENABLE_ANON_USERS": false,
            "show_grok_2": false, "SHOW_GROK_2": false,
            "hide_subscription_flows_from_premium_plus_users": false, "HIDE_SUBSCRIPTION_FLOWS_FROM_PREMIUM_PLUS_USERS": false,
            "show_anon_help_link": false, "SHOW_ANON_HELP_LINK": false,
            "enable_auto_stream_retry": false, "ENABLE_AUTO_STREAM_RETRY": false,
            "enable_browser_notifications": false, "ENABLE_BROWSER_NOTIFICATIONS": false,
            "enable_conversation_tabs": false, "ENABLE_CONVERSATION_TABS": false,
            "show_artifacts_ask_grok_button": false, "SHOW_ARTIFACTS_ASK_GROK_BUTTON": false,
            "show_artifacts_explain_button": false, "SHOW_ARTIFACTS_EXPLAIN_BUTTON": false,
            "enable_artifacts_editing": false, "ENABLE_ARTIFACTS_EDITING": false,
            "show_x_badge": false, "SHOW_X_BADGE": false,
            "show_open_in_app_dialog": false, "SHOW_OPEN_IN_APP_DIALOG": false,
            "show_open_in_app_dialog_every_time": false, "SHOW_OPEN_IN_APP_DIALOG_EVERY_TIME": false,
            "show_open_in_app_dialog_download_default": false, "SHOW_OPEN_IN_APP_DIALOG_DOWNLOAD_DEFAULT": false,
            "enable_grok_analyze_url": false, "ENABLE_GROK_ANALYZE_URL": false,
            "show_deeper_search": false, "SHOW_DEEPER_SEARCH": false,
            "enable_memory_toggle": false, "ENABLE_MEMORY_TOGGLE": false,
            "toggle_search_only": false, "TOGGLE_SEARCH_ONLY": false,
            "show_memory_summary": false, "SHOW_MEMORY_SUMMARY": false,
            "open_memory_in_new_tab": false, "OPEN_MEMORY_IN_NEW_TAB": false,
            "show_orb_icon_memory": false, "SHOW_ORB_ICON_MEMORY": false,
            "show_search_deeper": false, "SHOW_SEARCH_DEEPER": false,
            "enable_add_text_content": false, "ENABLE_ADD_TEXT_CONTENT": false,
            "enable_google_drive": false, "ENABLE_GOOGLE_DRIVE": false,
            "enable_microsoft_onedrive": false, "ENABLE_MICROSOFT_ONEDRIVE": false,
            "enable_csv_rendering": false, "ENABLE_CSV_RENDERING": false,
            "enable_in_app_reporting": false, "ENABLE_IN_APP_REPORTING": false,
            "show_artifact_to_workspace_button": false, "SHOW_ARTIFACT_TO_WORKSPACE_BUTTON": false,
            "workspace_agent": false, "WORKSPACE_AGENT": false,
            "show_youtube_embeds": false, "SHOW_YOUTUBE_EMBEDS": false,
            "show_reddit_embeds": false, "SHOW_REDDIT_EMBEDS": false,
            "only_use_single_youtube": false, "ONLY_USE_SINGLE_YOUTUBE": false,
            "show_x_inline": false, "SHOW_X_INLINE": false,
            "enable_think_harder": false, "ENABLE_THINK_HARDER": false,
            "enable_conversation_starters": false, "ENABLE_CONVERSATION_STARTERS": false,
            "enable_expanded_upsell_banners": false, "ENABLE_EXPANDED_UPSELL_BANNERS": false,
            "use_dynamic_suggested_mode_text": false, "USE_DYNAMIC_SUGGESTED_MODE_TEXT": false,
            "show_model_config_override": false, "SHOW_MODEL_CONFIG_OVERRIDE": false,
            "enable_grok_tasks": false, "ENABLE_GROK_TASKS": false
        };

        // Read current flags from localStorage, initialize with defaults if empty
        let rawFlags = localStorage.getItem("local_feature_flags");
        console.log("Raw local_feature_flags:", rawFlags);
        let currentFlags = rawFlags ? JSON.parse(rawFlags) : {};
        if (Object.keys(currentFlags).length === 0) {
            console.log("No flags found in localStorage. Initializing with default flags.");
            currentFlags = { ...defaultFlags };
            localStorage.setItem("local_feature_flags", JSON.stringify(currentFlags));
        }

        // Group flags by uppercase name to avoid duplicate display
        let flagGroups = {};
        Object.keys(currentFlags).forEach(flag => {
            const normalized = flag.toUpperCase();
            if (!flagGroups[normalized]) {
                flagGroups[normalized] = [];
            }
            flagGroups[normalized].push(flag);
        });
        let displayFlags = Object.keys(flagGroups);

        // Log the number of unique and total flags
        console.log("Total flags:", Object.keys(currentFlags).length, "Unique flags (after normalization):", displayFlags.length);

        // Create UI element for flag picker
        let ui = document.createElement("div");
        ui.id = "feature-flags-ui";
        ui.style.display = "none"; // Initially hidden
        ui.innerHTML = `
            <div class="title-bar">
                <span>Feature Flags</span>
                <button id="minimize-btn">_</button>
                <button id="close-btn">X</button>
            </div>
            <div class="content">
                <div class="flag-list">
                    ${displayFlags.length > 0 ? displayFlags.map(normalizedFlag => {
                        // Use the first original key for checkbox state
                        const originalKeys = flagGroups[normalizedFlag];
                        const primaryKey = originalKeys[0];
                        return `
                            <label>
                                <input type="checkbox" data-flag="${normalizedFlag}" ${typeof currentFlags[primaryKey] === 'boolean' && currentFlags[primaryKey] ? 'checked' : ''}>
                                ${normalizedFlag}
                            </label>
                        `;
                    }).join("") : '<p>No feature flags available.</p>'}
                </div>
                <button id="save-btn">Save</button>
            </div>
        `;

        // Append UI to body
        document.body.appendChild(ui);

        // Load saved UI state
        let uiState = JSON.parse(localStorage.getItem("feature_flags_ui_state") || "{}");
        if (uiState.left && uiState.top) {
            ui.style.left = uiState.left + "px";
            ui.style.top = uiState.top + "px";
        }
        if (uiState.minimized) {
            ui.classList.add("minimized");
        }
        if (uiState.visible) {
            ui.style.display = "block";
        }

        // Add CSS for styling, dragging, and fixed save button
        let style = document.createElement("style");
        style.textContent = `
        #feature-flags-ui {
            position: absolute;
            top: 10px;
            left: 10px;
            width: 400px; /* Wider UI to prevent text wrapping */
            background: #333333; /* Dark gray background */
            color: #ffffff; /* White text */
            border: 1px solid #555555;
            box-shadow: 2px 2px 5px rgba(0,0,0,0.5);
            font-family: Arial, sans-serif;
            z-index: 10000; /* Ensure UI is above other elements */
        }

        #feature-flags-ui .title-bar {
            background: #555555; /* Slightly lighter gray for title bar */
            color: #ffffff;
            padding: 5px;
            cursor: move;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        #feature-flags-ui .title-bar span {
            flex-grow: 1;
        }

        #feature-flags-ui .content {
            padding: 10px;
            display: flex;
            flex-direction: column;
            max-height: 400px;
        }

        #feature-flags-ui .flag-list {
            flex: 1;
            overflow-y: auto;
            padding-bottom: 10px;
        }

        #feature-flags-ui.minimized .content {
            display: none;
        }

        #feature-flags-ui label {
            display: flex; /* Keep checkbox and text inline */
            align-items: center;
            margin-bottom: 5px;
            color: #ffffff; /* White text for labels */
        }

        #feature-flags-ui label input {
            margin-right: 8px; /* Space between checkbox and text */
        }

        #feature-flags-ui button {
            color: #ffffff;
            background: #555555;
            border: 1px solid #777777;
        }

        #feature-flags-ui #save-btn {
            position: sticky;
            bottom: 0;
            margin-top: 10px;
            padding: 5px;
            width: 100%;
            box-sizing: border-box;
        }

        #feature-flags-ui p {
            color: #ffffff;
            margin: 0;
        }
        `;
        document.head.appendChild(style);

        // Add menu item for Feature Flags
        const manageSubscriptionItem = document.querySelector('div[role="menuitem"] svg path[d="M21 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h6"]');
        if (manageSubscriptionItem) {
            const menuItem = document.createElement("div");
            menuItem.setAttribute("role", "menuitem");
            menuItem.className = "relative flex select-none items-center cursor-pointer px-3 py-2 rounded-xl text-sm outline-none focus:bg-button-ghost-hover";
            menuItem.setAttribute("tabindex", "-1");
            menuItem.setAttribute("data-orientation", "vertical");
            menuItem.setAttribute("data-radix-collection-item", "");
            menuItem.innerHTML = `
                <svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" class="stroke-[2] text-neutral-400 mr-2" stroke-width="2">
                    <path d="M10 4V4C8.13623 4 7.20435 4 6.46927 4.30448C5.48915 4.71046 4.71046 5.48915 4.30448 6.46927C4 7.20435 4 8.13623 4 10V13.6C4 15.8402 4 16.9603 4.43597 17.816C4.81947 18.5686 5.43139 19.1805 6.18404 19.564C7.03968 20 8.15979 20 10.4 20H14C15.8638 20 16.7956 20 17.5307 19.6955C18.5108 19.2895 19.2895 18.5108 19.6955 17.5307C20 16.7956 20 15.8638 20 14V14" stroke="currentColor" stroke-linecap="square"></path>
                    <path d="M12.4393 14.5607L19.5 7.5C20.3284 6.67157 20.3284 5.32843 19.5 4.5C18.6716 3.67157 17.3284 3.67157 16.5 4.5L9.43934 11.5607C9.15804 11.842 9 12.2235 9 12.6213V15H11.3787C11.7765 15 12.158 14.842 12.4393 14.5607Z" stroke="currentColor" stroke-linecap="square"></path>
                </svg>
                Feature Flags
            `;
            manageSubscriptionItem.parentElement.insertAdjacentElement("afterend", menuItem);

            // Toggle flag picker visibility on menu item click
            menuItem.addEventListener("click", () => {
                ui.style.display = ui.style.display === "none" ? "block" : "none";
                uiState.visible = ui.style.display === "block";
                localStorage.setItem("feature_flags_ui_state", JSON.stringify(uiState));
            });
        } else {
            console.warn("Manage Subscription menu item not found. Flag picker will be shown by default.");
            ui.style.display = "block"; // Fallback to visible if menu item not found
        }

        // Make UI draggable and save position
        let titleBar = ui.querySelector(".title-bar");
        let isDragging = false;
        let offsetX, offsetY;

        titleBar.addEventListener("mousedown", (e) => {
            isDragging = true;
            offsetX = e.clientX - ui.offsetLeft;
            offsetY = e.clientY - ui.offsetTop;
        });

        document.addEventListener("mousemove", (e) => {
            if (isDragging) {
                ui.style.left = (e.clientX - offsetX) + "px";
                ui.style.top = (e.clientY - offsetY) + "px";
                // Update saved position
                uiState.left = e.clientX - offsetX;
                uiState.top = e.clientY - offsetY;
                localStorage.setItem("feature_flags_ui_state", JSON.stringify(uiState));
            }
        });

        document.addEventListener("mouseup", () => {
            isDragging = false;
        });

        // Minimize button and save state
        ui.querySelector("#minimize-btn").addEventListener("click", () => {
            ui.classList.toggle("minimized");
            uiState.minimized = ui.classList.contains("minimized");
            localStorage.setItem("feature_flags_ui_state", JSON.stringify(uiState));
        });

        // Close button
        ui.querySelector("#close-btn").addEventListener("click", () => {
            ui.style.display = "none";
            uiState.visible = false;
            localStorage.setItem("feature_flags_ui_state", JSON.stringify(uiState));
        });

        // Save button with auto-refresh
        ui.querySelector("#save-btn").addEventListener("click", () => {
            let modifiedFlags = { ...currentFlags };
            displayFlags.forEach(normalizedFlag => {
                let checkbox = ui.querySelector(`input[data-flag="${normalizedFlag}"]`);
                if (checkbox) {
                    // Update all original keys for this normalized flag
                    flagGroups[normalizedFlag].forEach(originalKey => {
                        modifiedFlags[originalKey] = checkbox.checked;
                    });
                }
            });
            localStorage.setItem("local_feature_flags", JSON.stringify(modifiedFlags));
            console.log("Flags saved. Reloading page...");
            location.reload(); // Auto-refresh the page
        });

        console.log("Grok Feature Flags Toggler loaded successfully with", displayFlags.length, "unique flags.");
    } catch (error) {
        console.error("Error in Grok Feature Flags Toggler:", error);
    }
})();