Update src/ai-repo-commander.user.js

This is working for chat-gpt to update files
This commit is contained in:
rob 2025-10-07 02:18:15 +00:00
parent df4c18c3d5
commit 3a7a3b9fe6
1 changed files with 14 additions and 8 deletions

View File

@ -18,7 +18,7 @@
// ---------------------- Config ---------------------- // ---------------------- Config ----------------------
const CONFIG = { const CONFIG = {
ENABLE_API: false, // Master kill switch ENABLE_API: true, // Master kill switch
DEBUG_MODE: true, // Console logs DEBUG_MODE: true, // Console logs
DEBOUNCE_DELAY: 5000, // Bot typing protection DEBOUNCE_DELAY: 5000, // Bot typing protection
MAX_RETRIES: 2, // Retry attempts (=> up to MAX_RETRIES+1 total tries) MAX_RETRIES: 2, // Retry attempts (=> up to MAX_RETRIES+1 total tries)
@ -35,8 +35,8 @@
// ---------------------- Platform selectors ---------------------- // ---------------------- Platform selectors ----------------------
const PLATFORM_SELECTORS = { const PLATFORM_SELECTORS = {
'chat.openai.com': { messages: '[class*="message"]', input: '#prompt-textarea', content: '[class*="markdown"]' }, 'chat.openai.com': { messages: '[data-message-author-role]', input: '#prompt-textarea, textarea, [contenteditable="true"]', content: '.markdown' },
'chatgpt.com': { messages: '[class*="message"]', input: '#prompt-textarea', content: '[class*="markdown"]' }, 'chatgpt.com': { messages: '[data-message-author-role]', input: '#prompt-textarea, textarea, [contenteditable="true"]', content: '.markdown' },
'claude.ai': { messages: '.chat-message', input: '[contenteditable="true"]', content: '.content' }, 'claude.ai': { messages: '.chat-message', input: '[contenteditable="true"]', content: '.content' },
'gemini.google.com': { messages: '.message-content', input: 'textarea, [contenteditable="true"]', content: '.message-text' } 'gemini.google.com': { messages: '.message-content', input: 'textarea, [contenteditable="true"]', content: '.message-text' }
}; };
@ -145,7 +145,7 @@
// defaults // defaults
parsed.url = parsed.url || 'https://n8n.brrd.tech/webhook/ai-gitea-bridge'; parsed.url = parsed.url || 'https://n8n.brrd.tech/webhook/ai-gitea-bridge';
parsed.owner = parsed.owner || 'brrd'; parsed.owner = parsed.owner || 'rob';
// expand owner/repo shorthand // expand owner/repo shorthand
if (parsed.repo && typeof parsed.repo === 'string' && parsed.repo.includes('/')) { if (parsed.repo && typeof parsed.repo === 'string' && parsed.repo.includes('/')) {
@ -158,7 +158,7 @@
static extractCommandBlock(text) { static extractCommandBlock(text) {
// require ^%$bridge ... --- (tolerate trailing spaces and EOF) // require ^%$bridge ... --- (tolerate trailing spaces and EOF)
const m = text.match(/^\^%\$bridge[ \t]*\n([\s\S]*?)\n---[ \t]*(?:\n|$)/m); const m = text.match(/^\s*\^%\$bridge[ \t]*\n([\s\S]*?)\n---[ \t]*(?:\n|$)/m);
return m ? m[1].trimEnd() : null; return m ? m[1].trimEnd() : null;
} }
@ -350,7 +350,7 @@
} }
scanNode(node) { scanNode(node) {
if (node.querySelector && node.querySelector(this.currentPlatform.messages)) this.scanMessages(); if (node.querySelector) this.scanMessages();
} }
scanExistingMessages() { setTimeout(() => this.scanMessages(), 1000); } scanExistingMessages() { setTimeout(() => this.scanMessages(), 1000); }
@ -376,11 +376,17 @@
extractText(element) { extractText(element) {
const c = element.querySelector(this.currentPlatform.content); const c = element.querySelector(this.currentPlatform.content);
return (c ? c.textContent : element.textContent) || ''; const target = c || element;
return (target.textContent || '').trim();
} }
// Always ignore commands shown inside code/pre blocks so you can discuss examples safely // Always ignore commands shown inside code/pre blocks so you can discuss examples safely
hasBridgeInCodeBlock(element) { hasBridgeInCodeBlock(element) {
// If this is an assistant message, allow execution even when rendered as code.
// Rationale: assistant YAML often renders as <pre><code>. We still want to execute.
const isAssistant = !!element.closest?.('[data-message-author-role="assistant"]');
if (isAssistant) return false;
const nodes = element.querySelectorAll('pre, code'); const nodes = element.querySelectorAll('pre, code');
for (const el of nodes) { for (const el of nodes) {
if ((el.textContent || '').includes('^%$bridge')) return true; if ((el.textContent || '').includes('^%$bridge')) return true;
@ -402,7 +408,7 @@
if (!text) return; if (!text) return;
// Require a full ^%$bridge ... --- block to avoid false positives // Require a full ^%$bridge ... --- block to avoid false positives
const m = text.match(/^\^%\$bridge[ \t]*\n([\s\S]*?)\n---[ \t]*(?:\n|$)/m); const m = text.match(/^\s*\^%\$bridge[ \t]*\n([\s\S]*?)\n---[ \t]*(?:\n|$)/m);
if (!m) return; if (!m) return;
const wholeBlock = m[0]; const wholeBlock = m[0];