🎉 欢迎访问GreasyFork.Org 镜像站!本镜像站由公众号【爱吃馍】搭建,用于分享脚本。联系邮箱📮

Greasy fork 爱吃馍镜像

Copilot Continue

Auto-clicks the "Continue" button when GitHub Copilot gets stuck

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

You will need to install an extension such as Tampermonkey to install this script.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

🚀 安装遇到问题?关注公众号获取帮助

公众号二维码

扫码关注【爱吃馍】

回复【脚本】获取最新教程和防失联地址

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

🚀 安装遇到问题?关注公众号获取帮助

公众号二维码

扫码关注【爱吃馍】

回复【脚本】获取最新教程和防失联地址

// ==UserScript==
// @name        Copilot Continue
// @namespace   https://snomiao.com
// @match       *://*/*
// @grant       none
// @version     1.2.10
// @author      snomiao
// @description Auto-clicks the "Continue" button when GitHub Copilot gets stuck
// @homepage    https://github.com/snomiao/copilot-continue.user.js
// @supportURL  https://github.com/snomiao/copilot-continue.user.js/issues
// @license     MIT
// @compatible  chrome
// @compatible  firefox
// @compatible  edge
// @compatible  opera
// ==/UserScript==

/*
 * Copilot Continue - A userscript to automatically continue GitHub Copilot
 *
 * This script automatically clicks the "Continue" button when GitHub Copilot
 * shows interruption messages like:
 * - "Copilot has been working on this problem for a while"
 * - "Run command in the terminal"
 * - "Allow task run?"
 *
 * The script runs in VS Code web environments and checks for interruptions every second.
 *
 * Notes for Copilot: dont forget to bump version number in the header when you modify this script.
 */

const actionMatchers = {
  clickContinue: [
    /^Copilot has been working on this problem for a while/,
    /^Run command in terminal/,
    /^Run command `.*`\?/,
    /^Run command in background terminal/,
    /^Continue to iterate\?/,
    /^Allow task run\?/,
    /^Allow test run\?/,
  ],
  clickAllow: [
    /^Run .*? command\?/,
  ],
  clickGrant: [
    /^To get more relevant Copilot Chat results, we need permission to read the contents of your repository on GitHub./,
  ],
  clickTryAgain: [
    /^The model unexpectedly did not return a response, which may indicate a service issue. Please report a bug./,
    /^Sorry, your request failed. Please try again./,
    /^Sorry, no response was returned./
  ],
  clickRetryIcon: [/^Language model unavailable/, /^Copilot setup failed/],
};

const actions = {
  default: () =>
    console.warn("No action matched. Please check the action matchers."),
  refresh: () => (location.reload()),
  clickRetryIcon: () => $$('a[aria-label="Retry"]').findLast(Boolean)?.click(),
  clickContinue: () =>
    $$("a.monaco-button").findLast(textEq("Continue"))?.click(),
  clickAllow: () =>
    $$("a.monaco-button").findLast(textEq("Allow"))?.click(),
  clickGrant: () =>
    $$("a.monaco-button").findLast(textEq("Grant"))?.click(),
  clickTryAgain: (
    (tryAgainCount = 0) =>
      () => {
        if (tryAgainCount >= 3) return (location.reload());
        const btn = $$("a.monaco-button").findLast(textEq("Try Again"));
        if (!btn) return;
        btn.click();
        tryAgainCount++;
      }
  )(),
};

function textEq(content) {
  return (e) => e.textContent === content;
}
const enable = !!document.querySelector("meta#vscode-workbench-auth-session");

// Prevent double execution if loaded both as userscript and extension
if (enable && !globalThis.copilotContinueLoaded) {
  main();
  globalThis.copilotContinueLoaded = true;
}

function main() {
  const clear = useInterval(() => loop(), 1e3);
  return () => clear();
}
function loop() {
  const text = $$("div.rendered-markdown")
    .map((e) => e.innerText)
    .flatMap((e) => (e ? [e] : [])) // empty filter
    .map((e) => e.replace(/\s+/g, " "))
    .map((e) => e.trim())

  Object.entries(actionMatchers).find(([action, matchers]) => {
    if (text.some((s) => matchers.some((m) => s.match(m)))) {
      (actions[action] || actions.default)?.();
      return true;
    }
  });
}

function $$(sel) {
  return [...document.querySelectorAll(sel)];
}

function useInterval(...args) {
  const id = setInterval(...args);
  return () => clearInterval(id);
}