SillyTavern Extension Data Extractor

Extract extension data from Discord posts or GitHub repos and copy as formatted JSON (Alt+Shift+E)

Size

28.9 KB

Version

1.1.2

Created

Oct 18, 2025

Updated

5 days ago

1// ==UserScript==
2// @name		SillyTavern Extension Data Extractor
3// @description		Extract extension data from Discord posts or GitHub repos and copy as formatted JSON (Alt+Shift+E)
4// @version		1.1.2
5// @match		https://*.discord.com/*
6// @match		https://github.com/*/*
7// @icon		data:image/png;base64,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
8// ==/UserScript==
9(function() {
10    'use strict';
11
12    // Utility function to show notifications
13    function showNotification(message, isError = false) {
14        const notification = document.createElement('div');
15        notification.textContent = message;
16        notification.style.cssText = `
17            position: fixed;
18            top: 20px;
19            right: 20px;
20            background: ${isError ? '#dc3545' : '#28a745'};
21            color: white;
22            padding: 15px 20px;
23            border-radius: 8px;
24            box-shadow: 0 4px 12px rgba(0,0,0,0.3);
25            z-index: 999999;
26            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
27            font-size: 14px;
28            max-width: 400px;
29            word-wrap: break-word;
30            animation: slideIn 0.3s ease-out;
31        `;
32        
33        const style = document.createElement('style');
34        style.textContent = `
35            @keyframes slideIn {
36                from { transform: translateX(400px); opacity: 0; }
37                to { transform: translateX(0); opacity: 1; }
38            }
39        `;
40        document.head.appendChild(style);
41        
42        document.body.appendChild(notification);
43        
44        setTimeout(() => {
45            notification.style.transition = 'opacity 0.3s ease-out';
46            notification.style.opacity = '0';
47            setTimeout(() => notification.remove(), 300);
48        }, 4000);
49    }
50
51    // Check if we're on a supported page
52    function isSupportedPage() {
53        const url = window.location.href;
54        const isDiscord = /https:\/\/discord\.com\/channels\/1100685673633153084\/\d+/.test(url);
55        const isGitHub = /https:\/\/github\.com\/[^\/]+\/[^\/]+/.test(url);
56        return isDiscord || isGitHub;
57    }
58
59    // Extract GitHub URL from Discord post
60    function extractGitHubUrl(postContent) {
61        const urlPattern = /https:\/\/github\.com\/[^\/\s\)]+\/[^\/\s\)]+\/?/g;
62        const matches = postContent.match(urlPattern);
63        if (matches && matches.length > 0) {
64            return matches[0].replace(/\/$/, ''); // Remove trailing slash
65        }
66        return null;
67    }
68
69    // Extract ID from GitHub URL
70    function extractIdFromUrl(url) {
71        const match = url.match(/github\.com\/[^\/]+\/([^\/\s]+)/);
72        if (match) {
73            return match[1].replace(/\/$/, '');
74        }
75        return null;
76    }
77
78    // Clean extension name
79    function cleanExtensionName(id) {
80        let name = id;
81        // Remove common prefixes/suffixes
82        name = name.replace(/^(SillyTavern-|ST-)/i, '');
83        name = name.replace(/(-Extension|-Ext|Extension|Ext)$/i, '');
84        // Add spaces before capital letters
85        name = name.replace(/([a-z])([A-Z])/g, '$1 $2');
86        // Replace hyphens and underscores with spaces
87        name = name.replace(/[-_]/g, ' ');
88        // Title case
89        name = name.split(' ').map(word => 
90            word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()
91        ).join(' ');
92        return name.trim();
93    }
94
95    // Extract Discord post content
96    async function extractDiscordPostContent() {
97        try {
98            console.log('Extracting Discord post content...');
99            
100            // Wait for content to load
101            await new Promise(resolve => setTimeout(resolve, 1000));
102            
103            // Try multiple selectors to find the initial post
104            const selectors = [
105                'article[id^="chat-messages-"]',
106                'li[id^="chat-messages-"]',
107                'div[class*="message_"]',
108                'div[class*="cozyMessage"]'
109            ];
110            
111            let postElement = null;
112            for (const selector of selectors) {
113                const elements = document.querySelectorAll(selector);
114                if (elements.length > 0) {
115                    postElement = elements[0];
116                    break;
117                }
118            }
119            
120            if (!postElement) {
121                throw new Error('Could not find Discord post element');
122            }
123            
124            const postContent = postElement.textContent || postElement.innerText;
125            console.log('Extracted post content:', postContent.substring(0, 200));
126            
127            const githubUrl = extractGitHubUrl(postContent);
128            if (!githubUrl) {
129                throw new Error('No GitHub URL found in post');
130            }
131            
132            console.log('Found GitHub URL:', githubUrl);
133            
134            const id = extractIdFromUrl(githubUrl);
135            if (!id) {
136                throw new Error('Could not extract ID from GitHub URL');
137            }
138            
139            // Use AI to generate name and description
140            const namePrompt = `Convert this repository ID to a clean extension name: "${id}". Remove prefixes like "SillyTavern-", "ST-" and suffixes like "-Extension", "Extension", "Ext". Add spaces and use title case. Return ONLY the clean name, nothing else.`;
141            
142            const descriptionPrompt = `Summarize this SillyTavern extension post in 1-2 concise sentences. Use plain text only - NO markdown formatting, NO asterisks, NO special characters, NO newlines. If there are warnings about WIP status, dependencies, requirements, or compatibility issues, prepend them as "Warning: [concise warning]. " Here is the post content:\n\n${postContent.substring(0, 2000)}`;
143            
144            console.log('Calling AI for name and description...');
145            const [name, description] = await Promise.all([
146                RM.aiCall(namePrompt),
147                RM.aiCall(descriptionPrompt)
148            ]);
149            
150            console.log('AI generated name:', name);
151            console.log('AI generated description:', description);
152            
153            return {
154                id,
155                type: 'extension',
156                name: name.trim(),
157                description: description.trim().replace(/\n/g, ' ').replace(/\s+/g, ' '),
158                url: githubUrl
159            };
160            
161        } catch (error) {
162            console.error('Error extracting Discord post:', error);
163            throw error;
164        }
165    }
166
167    // Extract GitHub repository data
168    async function extractGitHubRepoData() {
169        try {
170            console.log('Extracting GitHub repository data...');
171            
172            const url = window.location.href.replace(/\/$/, '');
173            const id = extractIdFromUrl(url);
174            
175            if (!id) {
176                throw new Error('Could not extract repository ID from URL');
177            }
178            
179            // Try to get About section
180            let description = '';
181            const aboutSelectors = [
182                'p[class*="About"]',
183                'p.f4.my-3',
184                '[data-pjax="#repo-content-pjax-container"] p'
185            ];
186            
187            let aboutElement = null;
188            for (const selector of aboutSelectors) {
189                aboutElement = document.querySelector(selector);
190                if (aboutElement && aboutElement.textContent.trim()) {
191                    description = aboutElement.textContent.trim();
192                    console.log('Found About section:', description);
193                    break;
194                }
195            }
196            
197            // If no About section, try to get README
198            if (!description) {
199                console.log('No About section found, looking for README...');
200                const readmeSelectors = [
201                    'article[class*="markdown"]',
202                    'div[class*="markdown-body"]',
203                    '#readme'
204                ];
205                
206                let readmeElement = null;
207                for (const selector of readmeSelectors) {
208                    readmeElement = document.querySelector(selector);
209                    if (readmeElement) {
210                        const readmeText = readmeElement.textContent || readmeElement.innerText;
211                        console.log('Found README, length:', readmeText.length);
212                        
213                        // Use AI to summarize README
214                        const descriptionPrompt = `Summarize this SillyTavern extension README in 1-2 concise sentences. Use plain text only - NO markdown formatting, NO asterisks, NO special characters, NO newlines. If there are warnings about WIP status, dependencies, requirements, or compatibility issues, prepend them as "Warning: [concise warning]. " Here is the README:\n\n${readmeText.substring(0, 2000)}`;
215                        
216                        description = await RM.aiCall(descriptionPrompt);
217                        console.log('AI generated description from README:', description);
218                        break;
219                    }
220                }
221            }
222            
223            if (!description) {
224                throw new Error('Could not find repository description or README');
225            }
226            
227            // Generate clean name
228            const namePrompt = `Convert this repository ID to a clean extension name: "${id}". Remove prefixes like "SillyTavern-", "ST-" and suffixes like "-Extension", "Extension", "Ext". Add spaces and use title case. Return ONLY the clean name, nothing else.`;
229            const name = await RM.aiCall(namePrompt);
230            
231            console.log('AI generated name:', name);
232            
233            return {
234                id,
235                type: 'extension',
236                name: name.trim(),
237                description: description.trim().replace(/\n/g, ' ').replace(/\s+/g, ' '),
238                url
239            };
240            
241        } catch (error) {
242            console.error('Error extracting GitHub repo:', error);
243            throw error;
244        }
245    }
246
247    // Format data as JSON
248    function formatAsJson(data) {
249        const json = {
250            id: data.id,
251            type: data.type,
252            name: data.name,
253            description: data.description,
254            url: data.url
255        };
256        
257        // Manually format with 8 spaces for fields and trailing comma
258        const lines = [
259            '{',
260            `    "id": "${json.id}",`,
261            `    "type": "${json.type}",`,
262            `    "name": "${json.name}",`,
263            `    "description": "${json.description}",`,
264            `    "url": "${json.url}"`,
265            '},'
266        ];
267        
268        return lines.join('\n');
269    }
270
271    // Copy to clipboard
272    async function copyToClipboard(text) {
273        try {
274            if (navigator.clipboard && navigator.clipboard.writeText) {
275                await navigator.clipboard.writeText(text);
276            } else {
277                // Fallback for browsers without clipboard API
278                const textarea = document.createElement('textarea');
279                textarea.value = text;
280                textarea.style.position = 'fixed';
281                textarea.style.opacity = '0';
282                document.body.appendChild(textarea);
283                textarea.select();
284                document.execCommand('copy');
285                document.body.removeChild(textarea);
286            }
287        } catch (error) {
288            console.error('Clipboard error:', error);
289            throw new Error('Failed to copy to clipboard. Please check browser permissions.');
290        }
291    }
292
293    // Main extraction function
294    async function extractAndCopy() {
295        try {
296            console.log('Starting extraction...');
297            
298            // Show processing notification
299            showNotification('Processing... Please wait while AI extracts the data.');
300            
301            const url = window.location.href;
302            let data;
303            
304            if (/https:\/\/discord\.com\/channels\/1100685673633153084/.test(url)) {
305                console.log('Detected Discord page');
306                data = await extractDiscordPostContent();
307            } else if (/https:\/\/github\.com\/[^\/]+\/[^\/]+/.test(url)) {
308                console.log('Detected GitHub page');
309                data = await extractGitHubRepoData();
310            } else {
311                throw new Error('Unsupported page. This extension only works on Discord posts and GitHub repositories.');
312            }
313            
314            const formattedJson = formatAsJson(data);
315            console.log('Formatted JSON:', formattedJson);
316            
317            await copyToClipboard(formattedJson);
318            
319            showNotification(`Data about ${data.id} successfully JSON formatted and copied to clipboard`);
320            
321        } catch (error) {
322            console.error('Extraction error:', error);
323            showNotification(`Error: ${error.message}`, true);
324        }
325    }
326
327    // Initialize
328    function init() {
329        console.log('SillyTavern Extension Data Extractor loaded');
330        
331        if (!isSupportedPage()) {
332            console.log('Not on a supported page');
333            return;
334        }
335        
336        // Show activation notification
337        setTimeout(() => {
338            showNotification('Extension active! Press Alt+Shift+E to extract data');
339        }, 1000);
340        
341        // Add keyboard shortcut listener
342        document.addEventListener('keydown', (event) => {
343            // Alt+Shift+E
344            if (event.altKey && event.shiftKey && event.key.toLowerCase() === 'e') {
345                event.preventDefault();
346                console.log('Keyboard shortcut triggered');
347                extractAndCopy();
348            }
349        });
350        
351        console.log('Keyboard shortcut registered: Alt+Shift+E');
352    }
353
354    // Wait for page to load
355    if (document.readyState === 'loading') {
356        document.addEventListener('DOMContentLoaded', init);
357    } else {
358        init();
359    }
360
361})();
SillyTavern Extension Data Extractor | Robomonkey