copilot-api-plus 1.2.31 → 1.2.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/main.js CHANGED
@@ -1321,6 +1321,7 @@ function modelLogger() {
1321
1321
  const accountRoutes = new Hono();
1322
1322
  let cachedDeviceCode;
1323
1323
  let cachedDeviceCodeExpiresAt = 0;
1324
+ let pollNotBefore = 0;
1324
1325
  function maskToken(token) {
1325
1326
  if (token.length <= 8) return "****";
1326
1327
  return `${token.slice(0, 4)}...${token.slice(-4)}`;
@@ -1455,6 +1456,7 @@ accountRoutes.post("/auth/start", async (c) => {
1455
1456
  const deviceCode = await getDeviceCode();
1456
1457
  cachedDeviceCode = deviceCode;
1457
1458
  cachedDeviceCodeExpiresAt = Date.now() + deviceCode.expires_in * 1e3;
1459
+ pollNotBefore = 0;
1458
1460
  return c.json(deviceCode);
1459
1461
  } catch (error) {
1460
1462
  consola.warn(`Error starting device code flow: ${rootCause(error)}`);
@@ -1462,10 +1464,53 @@ accountRoutes.post("/auth/start", async (c) => {
1462
1464
  return c.json({ error: "Failed to start device code authorization" }, 500);
1463
1465
  }
1464
1466
  });
1467
+ /** Reset all auth flow state (device code cache + rate limit). */
1468
+ function clearAuthFlowState() {
1469
+ cachedDeviceCode = void 0;
1470
+ cachedDeviceCodeExpiresAt = 0;
1471
+ pollNotBefore = 0;
1472
+ }
1473
+ /** Handle GitHub error responses during device code polling. */
1474
+ function handlePollError(json) {
1475
+ if (!("error" in json)) return void 0;
1476
+ switch (json.error) {
1477
+ case "authorization_pending":
1478
+ pollNotBefore = Date.now() + 5e3;
1479
+ return { status: "pending" };
1480
+ case "slow_down": {
1481
+ const interval = typeof json.interval === "number" ? json.interval : 10;
1482
+ pollNotBefore = Date.now() + interval * 1e3;
1483
+ consola.info(`Device code poll: GitHub says slow down, waiting ${interval}s`);
1484
+ return {
1485
+ status: "pending",
1486
+ interval
1487
+ };
1488
+ }
1489
+ case "expired_token":
1490
+ clearAuthFlowState();
1491
+ return { status: "expired" };
1492
+ case "access_denied":
1493
+ clearAuthFlowState();
1494
+ return { status: "denied" };
1495
+ default: return {
1496
+ status: "error",
1497
+ message: json.error_description || json.error
1498
+ };
1499
+ }
1500
+ }
1465
1501
  accountRoutes.post("/auth/poll", async (c) => {
1466
1502
  try {
1467
1503
  const { device_code, label, account_type } = await c.req.json();
1468
1504
  if (!device_code) return c.json({ error: "device_code is required" }, 400);
1505
+ const now = Date.now();
1506
+ if (now < pollNotBefore) {
1507
+ const waitSec = Math.ceil((pollNotBefore - now) / 1e3);
1508
+ consola.debug(`Device code poll: throttled, ${waitSec}s remaining`);
1509
+ return c.json({
1510
+ status: "pending",
1511
+ interval: waitSec
1512
+ });
1513
+ }
1469
1514
  const response = await fetch(`${GITHUB_BASE_URL}/login/oauth/access_token`, {
1470
1515
  method: "POST",
1471
1516
  headers: standardHeaders(),
@@ -1489,28 +1534,10 @@ accountRoutes.post("/auth/poll", async (c) => {
1489
1534
  consola.warn(`Device code poll: GitHub returned non-JSON: ${rawText}`);
1490
1535
  return c.json({ status: "pending" });
1491
1536
  }
1492
- if ("error" in json) switch (json.error) {
1493
- case "authorization_pending": return c.json({ status: "pending" });
1494
- case "slow_down": return c.json({
1495
- status: "pending",
1496
- interval: 10
1497
- });
1498
- case "expired_token":
1499
- cachedDeviceCode = void 0;
1500
- cachedDeviceCodeExpiresAt = 0;
1501
- return c.json({ status: "expired" });
1502
- case "access_denied":
1503
- cachedDeviceCode = void 0;
1504
- cachedDeviceCodeExpiresAt = 0;
1505
- return c.json({ status: "denied" });
1506
- default: return c.json({
1507
- status: "error",
1508
- message: json.error_description || json.error
1509
- });
1510
- }
1537
+ const errorResult = handlePollError(json);
1538
+ if (errorResult) return c.json(errorResult);
1511
1539
  if ("access_token" in json && json.access_token) {
1512
- cachedDeviceCode = void 0;
1513
- cachedDeviceCodeExpiresAt = 0;
1540
+ clearAuthFlowState();
1514
1541
  const accountLabel = label || `Account ${accountManager.accountCount + 1}`;
1515
1542
  const account = await accountManager.addAccount(json.access_token, accountLabel, account_type || "individual");
1516
1543
  return c.json({
@@ -2006,6 +2033,7 @@ async function handleMultiAccountHttpError(error, account, retryContext) {
2006
2033
  accountManager.markAccountStatus(account.id, "error", `HTTP ${error.response.status}`);
2007
2034
  return null;
2008
2035
  }
2036
+ if (error.response.status === 400) return null;
2009
2037
  accountManager.markAccountStatus(account.id, "error", `HTTP ${error.response.status}`);
2010
2038
  return null;
2011
2039
  }