Greasy Fork镜像 还支持 简体中文。

Copilot Continue

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

  1. // ==UserScript==
  2. // @name Copilot Continue
  3. // @namespace https://snomiao.com
  4. // @match *://*/*
  5. // @grant none
  6. // @version 1.2.9
  7. // @author snomiao
  8. // @description Auto-clicks the "Continue" button when GitHub Copilot gets stuck
  9. // @homepage https://github.com/snomiao/copilot-continue.user.js
  10. // @supportURL https://github.com/snomiao/copilot-continue.user.js/issues
  11. // @license MIT
  12. // @compatible chrome
  13. // @compatible firefox
  14. // @compatible edge
  15. // @compatible opera
  16. // ==/UserScript==
  17.  
  18. /*
  19. * Copilot Continue - A userscript to automatically continue GitHub Copilot
  20. *
  21. * This script automatically clicks the "Continue" button when GitHub Copilot
  22. * shows interruption messages like:
  23. * - "Copilot has been working on this problem for a while"
  24. * - "Run command in the terminal"
  25. * - "Allow task run?"
  26. *
  27. * The script runs in VS Code web environments and checks for interruptions every second.
  28. *
  29. * Notes for Copilot: dont forget to bump version number in the header when you modify this script.
  30. */
  31.  
  32. const actionMatchers = {
  33. cilckContinue: [
  34. /^Copilot has been working on this problem for a while/,
  35. /^Run command in terminal/,
  36. /^Run command `.*`\?/,
  37. /^Run command in background terminal/,
  38. /^Continue to iterate\?/,
  39. /^Allow task run\?/,
  40. /^Allow test run\?/,
  41. ],
  42. clickGrant: [
  43. /^To get more relevant Copilot Chat results, we need permission to read the contents of your repository on GitHub./,
  44. ],
  45. clickTryAgain: [
  46. /^The model unexpectedly did not return a response, which may indicate a service issue. Please report a bug./,
  47. /^Sorry, your request failed. Please try again./,
  48. /^Sorry, no response was returned./
  49. ],
  50. clickRetryIcon: [/^Language model unavailable/, /^Copilot setup failed/],
  51. };
  52.  
  53. const actions = {
  54. default: () =>
  55. console.warn("No action matched. Please check the action matchers."),
  56. refresh: () => (location.reload()),
  57. clickRetryIcon: () => $$('a[aria-label="Retry"]').findLast(Boolean)?.click(),
  58. cilckContinue: () =>
  59. $$("a.monaco-button").findLast(textContentEq("Continue"))?.click(),
  60. clickGrant: () =>
  61. $$("a.monaco-button").findLast(textContentEq("Grant"))?.click(),
  62. clickTryAgain: (
  63. (tryAgainCount = 0) =>
  64. () => {
  65. if (tryAgainCount >= 3) return (location.reload());
  66. const btn = $$("a.monaco-button").findLast(textContentEq("Try Again"));
  67. if (!btn) return;
  68. btn.click();
  69. tryAgainCount++;
  70. }
  71. )(),
  72. };
  73. function textContentEq(content) {
  74. return (e) => e.textContent === content;
  75. }
  76. const enable = !!document.querySelector("meta#vscode-workbench-auth-session");
  77.  
  78. // Prevent double execution if loaded both as userscript and extension
  79. if (enable && !globalThis.copilotContinueLoaded) {
  80. main();
  81. globalThis.copilotContinueLoaded = true;
  82. }
  83.  
  84. function main() {
  85. const clear = useInterval(() => loop(), 1e3);
  86. return () => clear();
  87. }
  88. function loop() {
  89. const text = $$("div.rendered-markdown")
  90. .map((e) => e.innerText)
  91. .flatMap((e) => (e ? [e] : [])) // empty filter
  92. .map((e) => e.replace(/\s+/g, " "));
  93.  
  94. for (const [action, matchers] of Object.entries(actionMatchers)) {
  95. if (text.some((s) => matchers.some((m) => s.match(m)))) {
  96. (actions[action] || actions.default)?.();
  97. return;
  98. }
  99. }
  100. }
  101.  
  102. function $$(sel) {
  103. return [...document.querySelectorAll(sel)];
  104. }
  105.  
  106. function useInterval(...args) {
  107. const id = setInterval(...args);
  108. return () => clearInterval(id);
  109. }

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址