Last active
September 23, 2025 22:14
-
-
Save 23maverick23/a9c8847a609529f57f6bdd3cf53d7bba to your computer and use it in GitHub Desktop.
NS: User Script: Claude Connectors Filter
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ==UserScript== | |
| // @name Claude Connectors Filter | |
| // @namespace http://tampermonkey.net/ | |
| // @version 1.0.1 | |
| // @description Filter connectors with configurable username - NetSuite themed | |
| // @author rymoio (https://rymo.io/) | |
| // @match https://claude.ai/settings/connectors* | |
| // @icon https://www.google.com/s2/favicons?sz=64&domain=claude.ai | |
| // @require https://openuserjs.org/src/libs/sizzle/GM_config.js | |
| // @grant GM_getValue | |
| // @grant GM_setValue | |
| // @grant GM_registerMenuCommand | |
| // @downloadURL https://gist.githubusercontent.com/23maverick23/a9c8847a609529f57f6bdd3cf53d7bba/raw/claude_connectors_filter_us.js | |
| // @updateURL https://gist.githubusercontent.com/23maverick23/a9c8847a609529f57f6bdd3cf53d7bba/raw/claude_connectors_filter_us.js | |
| // ==/UserScript== | |
| (function() { | |
| 'use strict'; | |
| // NetSuite Ocean Palette & Brand Colors | |
| const COLORS = { | |
| // Ocean Palette (Primary Brand Colors) | |
| ocean180: '#13212C', // Darkest - primary text, headers | |
| ocean150: '#264759', // Dark - secondary text | |
| ocean120: '#36677D', // PRIMARY BRAND COLOR - main actions, headers | |
| ocean60: '#94BFCE', // Light - accents, highlights | |
| ocean30: '#E7F2F5', // Very light - borders, dividers | |
| ocean10: '#F5FAFC', // Lightest - subtle backgrounds | |
| // Semantic Accent Colors | |
| pine: '#86B596', // SUCCESS - positive metrics, growth | |
| rose: '#FF8675', // ERROR/NEGATIVE - warnings, declines | |
| yellow: '#E2C06B', // WARNING - highlights, action items | |
| // Base Colors | |
| white: '#FFFFFF', // Card backgrounds | |
| neutral: '#F1EFED', // Page background | |
| // Aliases for easy use | |
| primary: '#36677D', // Ocean 120 | |
| textPrimary: '#13212C', // Ocean 180 | |
| textSecondary: '#264759', // Ocean 150 | |
| border: '#E7F2F5', // Ocean 30 | |
| pageBackground: '#F1EFED', | |
| cardBackground: '#FFFFFF' | |
| }; | |
| let isFiltered = false; | |
| let configInitialized = false; | |
| // Simple fallback storage if GM_config fails | |
| function getStoredValue(key, defaultValue) { | |
| try { | |
| if (typeof GM_getValue !== 'undefined') { | |
| return GM_getValue(key, defaultValue); | |
| } | |
| } catch (e) { | |
| console.warn('GM_getValue not available, using localStorage'); | |
| } | |
| return localStorage.getItem(`connectorFilter_${key}`) || defaultValue; | |
| } | |
| function setStoredValue(key, value) { | |
| try { | |
| if (typeof GM_setValue !== 'undefined') { | |
| GM_setValue(key, value); | |
| } | |
| } catch (e) { | |
| console.warn('GM_setValue not available, using localStorage'); | |
| } | |
| localStorage.setItem(`connectorFilter_${key}`, value); | |
| } | |
| // Initialize GM_config with error handling (removed color setting) | |
| function initConfig() { | |
| try { | |
| if (typeof GM_config !== 'undefined') { | |
| GM_config.init({ | |
| 'id': 'ConnectorFilterConfig', | |
| 'title': 'Connector Filter Settings', | |
| 'fields': { | |
| 'username': { | |
| 'label': 'Username to filter by', | |
| 'type': 'text', | |
| 'default': '', | |
| 'title': 'Enter the username prefix to show (case insensitive)' | |
| } | |
| }, | |
| 'css': ` | |
| #ConnectorFilterConfig { | |
| background: ${COLORS.cardBackground} !important; | |
| font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif !important; | |
| border: 1px solid ${COLORS.border} !important; | |
| border-radius: 8px !important; | |
| } | |
| #ConnectorFilterConfig .config_header { | |
| background: ${COLORS.primary} !important; | |
| color: ${COLORS.white} !important; | |
| padding: 20px !important; | |
| font-weight: 600 !important; | |
| border-radius: 8px 8px 0 0 !important; | |
| } | |
| #ConnectorFilterConfig .section_header { | |
| background: ${COLORS.ocean10} !important; | |
| color: ${COLORS.textPrimary} !important; | |
| padding: 12px 20px !important; | |
| font-weight: 500 !important; | |
| } | |
| #ConnectorFilterConfig .field_label { | |
| color: ${COLORS.textPrimary} !important; | |
| font-weight: 500 !important; | |
| margin-bottom: 8px !important; | |
| } | |
| #ConnectorFilterConfig input[type="text"] { | |
| border: 2px solid ${COLORS.border} !important; | |
| border-radius: 6px !important; | |
| padding: 12px 16px !important; | |
| font-size: 14px !important; | |
| color: ${COLORS.textPrimary} !important; | |
| background: ${COLORS.white} !important; | |
| } | |
| #ConnectorFilterConfig input[type="text"]:focus { | |
| border-color: ${COLORS.primary} !important; | |
| outline: none !important; | |
| box-shadow: 0 0 0 3px ${COLORS.ocean30} !important; | |
| } | |
| #ConnectorFilterConfig .saveclose_buttons { | |
| background: ${COLORS.ocean10} !important; | |
| padding: 20px !important; | |
| border-radius: 0 0 8px 8px !important; | |
| } | |
| #ConnectorFilterConfig .saveclose_buttons input { | |
| background: ${COLORS.primary} !important; | |
| color: ${COLORS.white} !important; | |
| border: none !important; | |
| padding: 12px 24px !important; | |
| border-radius: 6px !important; | |
| margin-right: 12px !important; | |
| cursor: pointer !important; | |
| font-weight: 500 !important; | |
| transition: all 0.2s ease !important; | |
| } | |
| #ConnectorFilterConfig .saveclose_buttons input:hover { | |
| background: ${COLORS.ocean150} !important; | |
| transform: translateY(-1px) !important; | |
| } | |
| #ConnectorFilterConfig .saveclose_buttons input[value="Cancel"] { | |
| background: ${COLORS.neutral} !important; | |
| color: ${COLORS.textSecondary} !important; | |
| } | |
| #ConnectorFilterConfig .saveclose_buttons input[value="Cancel"]:hover { | |
| background: ${COLORS.border} !important; | |
| } | |
| ` | |
| }); | |
| GM_config.onSave = function() { | |
| console.log('Config saved via GM_config'); | |
| updateButtons(); | |
| }; | |
| configInitialized = true; | |
| console.log('GM_config initialized successfully'); | |
| } | |
| } catch (e) { | |
| console.warn('GM_config initialization failed:', e); | |
| configInitialized = false; | |
| } | |
| } | |
| function getUsername() { | |
| if (configInitialized && typeof GM_config !== 'undefined') { | |
| try { | |
| return GM_config.get('username').toLowerCase().trim(); | |
| } catch (e) { | |
| console.warn('GM_config.get failed:', e); | |
| } | |
| } | |
| return getStoredValue('username', 'rmorrissey').toLowerCase().trim(); | |
| } | |
| function openSettings() { | |
| if (configInitialized && typeof GM_config !== 'undefined') { | |
| try { | |
| GM_config.open(); | |
| return; | |
| } catch (e) { | |
| console.warn('GM_config.open failed:', e); | |
| } | |
| } | |
| // Fallback: simple prompt-based settings | |
| const currentUsername = getStoredValue('username', 'rmorrissey'); | |
| const newUsername = prompt('Enter username to filter by:', currentUsername); | |
| if (newUsername !== null && newUsername.trim()) { | |
| setStoredValue('username', newUsername.trim()); | |
| console.log('Username updated via prompt:', newUsername.trim()); | |
| updateButtons(); | |
| } | |
| } | |
| function findConnectorRows() { | |
| const flexRows = document.querySelectorAll('.flex.flex-row.gap-3.items-center'); | |
| console.log(`Found ${flexRows.length} potential connector rows`); | |
| return Array.from(flexRows); | |
| } | |
| function filterConnectors() { | |
| const username = getUsername(); | |
| console.log(`=== FILTERING CONNECTORS FOR: "${username}" ===`); | |
| const rows = findConnectorRows(); | |
| if (rows.length === 0) { | |
| console.error('No connector rows found! Make sure the page is fully loaded.'); | |
| alert('No connector rows found! Make sure the page is fully loaded.'); | |
| return; | |
| } | |
| if (!username) { | |
| console.error('No username configured!'); | |
| alert('Please configure a username first (click Settings button)'); | |
| return; | |
| } | |
| let hiddenCount = 0; | |
| let visibleCount = 0; | |
| rows.forEach((row, index) => { | |
| const allText = row.textContent.toLowerCase(); | |
| console.log(`Row ${index} text:`, row.textContent.trim()); | |
| const hasUsername = allText.includes(username); | |
| if (hasUsername) { | |
| console.log(`✅ Row ${index}: KEEPING (contains "${username}")`); | |
| row.style.display = ''; | |
| // Use subtle ocean10 background with pine border for matched rows | |
| row.style.backgroundColor = COLORS.ocean10; | |
| row.style.borderLeft = `4px solid ${COLORS.pine}`; | |
| row.style.paddingLeft = '12px'; | |
| visibleCount++; | |
| } else { | |
| console.log(`❌ Row ${index}: HIDING (no "${username}" found)`); | |
| row.style.display = 'none'; | |
| hiddenCount++; | |
| } | |
| }); | |
| console.log(`=== FILTER COMPLETE ===`); | |
| console.log(`Hidden: ${hiddenCount} rows`); | |
| console.log(`Visible: ${visibleCount} rows`); | |
| isFiltered = true; | |
| updateButtons(); | |
| } | |
| function showAllConnectors() { | |
| console.log('=== SHOWING ALL CONNECTORS ==='); | |
| const rows = findConnectorRows(); | |
| rows.forEach((row, index) => { | |
| console.log(`Showing row ${index}`); | |
| row.style.display = ''; | |
| row.style.backgroundColor = ''; | |
| row.style.borderLeft = ''; | |
| row.style.paddingLeft = ''; | |
| }); | |
| console.log(`=== SHOW ALL COMPLETE ===`); | |
| console.log(`Restored ${rows.length} rows`); | |
| isFiltered = false; | |
| updateButtons(); | |
| } | |
| function updateButtons() { | |
| const filterBtn = document.getElementById('connector-filter-btn'); | |
| const settingsBtn = document.getElementById('connector-settings-btn'); | |
| if (filterBtn) { | |
| if (isFiltered) { | |
| filterBtn.textContent = 'Show All Connectors'; | |
| filterBtn.style.background = COLORS.pine; // Success green for active state | |
| filterBtn.style.borderColor = COLORS.pine; | |
| } else { | |
| const username = getUsername(); | |
| filterBtn.textContent = username ? `Filter: ${username}` : 'Filter Connectors'; | |
| filterBtn.style.background = COLORS.primary; | |
| filterBtn.style.borderColor = COLORS.primary; | |
| } | |
| } | |
| console.log('Buttons updated'); | |
| } | |
| function createButtons() { | |
| console.log('Creating buttons...'); | |
| // Remove existing buttons if present | |
| ['connector-filter-btn', 'connector-settings-btn'].forEach(id => { | |
| const existing = document.getElementById(id); | |
| if (existing) { | |
| console.log(`Removing existing button: ${id}`); | |
| existing.remove(); | |
| } | |
| }); | |
| // Create filter button | |
| const filterButton = document.createElement('button'); | |
| filterButton.id = 'connector-filter-btn'; | |
| const username = getUsername(); | |
| filterButton.textContent = username ? `Filter: ${username}` : 'Filter Connectors'; | |
| filterButton.style.cssText = ` | |
| position: fixed; | |
| top: 20px; | |
| right: 20px; | |
| z-index: 9999; | |
| padding: 12px 20px; | |
| background: ${COLORS.primary}; | |
| color: ${COLORS.white}; | |
| border: 2px solid ${COLORS.primary}; | |
| border-radius: 8px; | |
| cursor: pointer; | |
| font-weight: 600; | |
| font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; | |
| box-shadow: 0 4px 12px rgba(54, 103, 125, 0.2); | |
| transition: all 0.2s ease; | |
| font-size: 14px; | |
| `; | |
| // Create settings button | |
| const settingsButton = document.createElement('button'); | |
| settingsButton.id = 'connector-settings-btn'; | |
| settingsButton.innerHTML = '⚙️ Settings'; | |
| settingsButton.style.cssText = ` | |
| position: fixed; | |
| top: 75px; | |
| right: 20px; | |
| z-index: 9999; | |
| padding: 10px 16px; | |
| background: ${COLORS.ocean60}; | |
| color: ${COLORS.textPrimary}; | |
| border: 2px solid ${COLORS.ocean60}; | |
| border-radius: 8px; | |
| cursor: pointer; | |
| font-weight: 500; | |
| font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; | |
| box-shadow: 0 2px 8px rgba(148, 191, 206, 0.3); | |
| transition: all 0.2s ease; | |
| font-size: 13px; | |
| `; | |
| // Add hover effects | |
| filterButton.addEventListener('mouseenter', () => { | |
| if (isFiltered) { | |
| filterButton.style.background = '#6fa085'; // Darker pine | |
| filterButton.style.borderColor = '#6fa085'; | |
| } else { | |
| filterButton.style.background = COLORS.ocean150; | |
| filterButton.style.borderColor = COLORS.ocean150; | |
| } | |
| filterButton.style.transform = 'translateY(-2px)'; | |
| filterButton.style.boxShadow = '0 6px 16px rgba(54, 103, 125, 0.3)'; | |
| }); | |
| filterButton.addEventListener('mouseleave', () => { | |
| if (isFiltered) { | |
| filterButton.style.background = COLORS.pine; | |
| filterButton.style.borderColor = COLORS.pine; | |
| } else { | |
| filterButton.style.background = COLORS.primary; | |
| filterButton.style.borderColor = COLORS.primary; | |
| } | |
| filterButton.style.transform = 'translateY(0)'; | |
| filterButton.style.boxShadow = '0 4px 12px rgba(54, 103, 125, 0.2)'; | |
| }); | |
| settingsButton.addEventListener('mouseenter', () => { | |
| settingsButton.style.background = COLORS.ocean30; | |
| settingsButton.style.borderColor = COLORS.ocean30; | |
| settingsButton.style.transform = 'translateY(-1px)'; | |
| }); | |
| settingsButton.addEventListener('mouseleave', () => { | |
| settingsButton.style.background = COLORS.ocean60; | |
| settingsButton.style.borderColor = COLORS.ocean60; | |
| settingsButton.style.transform = 'translateY(0)'; | |
| }); | |
| // Add click handlers | |
| filterButton.addEventListener('click', () => { | |
| console.log('=== FILTER BUTTON CLICKED ==='); | |
| console.log('Current state - isFiltered:', isFiltered); | |
| if (isFiltered) { | |
| showAllConnectors(); | |
| } else { | |
| filterConnectors(); | |
| } | |
| }); | |
| settingsButton.addEventListener('click', () => { | |
| console.log('=== SETTINGS BUTTON CLICKED ==='); | |
| openSettings(); | |
| }); | |
| document.body.appendChild(filterButton); | |
| document.body.appendChild(settingsButton); | |
| console.log('Both buttons added to page'); | |
| } | |
| // Register menu command as backup | |
| if (typeof GM_registerMenuCommand !== 'undefined') { | |
| GM_registerMenuCommand('Open Connector Filter Settings', openSettings); | |
| } | |
| // Initialize everything | |
| function initialize() { | |
| console.log('=== INITIALIZING CONNECTOR FILTER ==='); | |
| console.log('Document ready state:', document.readyState); | |
| initConfig(); | |
| console.log('Current username setting:', getUsername()); | |
| console.log('GM_config initialized:', configInitialized); | |
| createButtons(); | |
| } | |
| // Wait for DOM to be ready, then initialize | |
| if (document.readyState === 'loading') { | |
| document.addEventListener('DOMContentLoaded', initialize); | |
| } else { | |
| initialize(); | |
| } | |
| // Also try after delays to ensure it works | |
| setTimeout(initialize, 1000); | |
| setTimeout(initialize, 3000); | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment