您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Ctrl+& fixes grammar using Github API
// ==UserScript== // @name Simple Grammar Fix // @namespace http://tampermonkey.net/ // @version 1.0 // @description Ctrl+& fixes grammar using Github API // @match *://*/* // @license WTFPL // @icon https://www.iconsdb.com/icons/preview/royal-blue/edit-12-xxl.png // @author moony // @grant GM_xmlhttpRequest // @grant GM_registerMenuCommand // @grant GM_setValue // @grant GM_getValue // @connect models.github.ai // ==/UserScript== (function() { const MODEL = "openai/gpt-4.1"; // gpt-4o, o4-mini, gpt-4.1, Mistral-Large-2411 from https://github.com/marketplace?type=models const SYSTEM_PROMPT = "Fix grammar only. Return compact corrected text."; GM_registerMenuCommand("🗝️ Set API Key", () => GM_setValue("GITHUB_TOKEN", prompt("Enter your GitHub API key:") || GM_getValue("GITHUB_TOKEN")) ); document.addEventListener('keydown', e => { if (!(e.ctrlKey && e.key === '&')) return; e.preventDefault(); const token = GM_getValue("GITHUB_TOKEN"); if (!token) return alert("API key not set. Use Tampermonkey menu → 🗝️ Set API Key"); const sel = window.getSelection(); const txt = sel.toString().trim(); if (!txt) return; const el = document.activeElement; const isInput = el.tagName === 'TEXTAREA' || el.tagName === 'INPUT'; GM_xmlhttpRequest({ method: "POST", url: "https://models.github.ai/inference/chat/completions", headers: {"Content-Type": "application/json", "Authorization": `Bearer ${token}`}, data: JSON.stringify({ messages: [{role: "system", content: SYSTEM_PROMPT}, {role: "user", content: txt}], model: MODEL, temperature: 0.7 }), onload: r => { if (r.status !== 200) return console.error("Error:", r.responseText); const fixed = JSON.parse(r.responseText).choices[0].message.content; if (isInput) { const [start, end] = [el.selectionStart, el.selectionEnd]; el.value = el.value.substring(0, start) + fixed + el.value.substring(end); el.selectionStart = start; el.selectionEnd = start + fixed.length; } else if (sel.rangeCount) { const rng = sel.getRangeAt(0); rng.deleteContents(); rng.insertNode(document.createTextNode(fixed)); } }, onerror: e => console.error("Request failed:", e) }); }); })();