fix: add 5s delay between DigitalOcean and OpenRouter OAuth flows (#1727)

When both OAuth flows open browser tabs back-to-back, the user may
reactively close the second tab thinking it's a duplicate. Add a 5-second
pause with a message after DO OAuth completes, only when browser auth
was actually used (skipped for env var / saved token paths).

Co-authored-by: Claude <claude@anthropic.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
A 2026-02-22 11:27:14 -08:00 committed by GitHub
parent 5192912b68
commit 738ad18fee
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 15 additions and 9 deletions

View file

@ -1,6 +1,6 @@
{
"name": "@openrouter/spawn",
"version": "0.6.6",
"version": "0.6.7",
"type": "module",
"bin": {
"spawn": "cli.js"

View file

@ -416,14 +416,15 @@ async function tryDoOAuth(): Promise<string | null> {
// ─── Authentication ──────────────────────────────────────────────────────────
export async function ensureDoToken(): Promise<void> {
/** Returns true if browser OAuth was triggered (so caller can delay before next OAuth). */
export async function ensureDoToken(): Promise<boolean> {
// 1. Env var
if (process.env.DO_API_TOKEN) {
doToken = process.env.DO_API_TOKEN.trim();
if (await testDoToken()) {
logInfo("Using DigitalOcean API token from environment");
await saveTokenToConfig(doToken);
return;
return false;
}
logWarn("DO_API_TOKEN from environment is invalid");
doToken = "";
@ -439,14 +440,14 @@ export async function ensureDoToken(): Promise<void> {
doToken = refreshed;
if (await testDoToken()) {
logInfo("Using refreshed DigitalOcean token");
return;
return false;
}
}
} else {
doToken = saved;
if (await testDoToken()) {
logInfo("Using saved DigitalOcean API token");
return;
return false;
}
logWarn("Saved DigitalOcean token is invalid or expired");
// Try refresh as fallback
@ -455,7 +456,7 @@ export async function ensureDoToken(): Promise<void> {
doToken = refreshed;
if (await testDoToken()) {
logInfo("Using refreshed DigitalOcean token");
return;
return false;
}
}
}
@ -468,7 +469,7 @@ export async function ensureDoToken(): Promise<void> {
doToken = oauthToken;
if (await testDoToken()) {
logInfo("Using DigitalOcean token from OAuth");
return;
return true;
}
logWarn("OAuth token failed validation");
doToken = "";
@ -488,7 +489,7 @@ export async function ensureDoToken(): Promise<void> {
if (await testDoToken()) {
await saveTokenToConfig(doToken);
logInfo("DigitalOcean API token validated and saved");
return;
return false;
}
logError("Token is invalid");
doToken = "";

View file

@ -16,6 +16,7 @@ import {
import { resolveAgent } from "./agents";
import { runOrchestration } from "../shared/orchestrate";
import type { CloudOrchestrator } from "../shared/orchestrate";
import { logStep } from "../shared/ui";
async function main() {
const agentName = process.argv[2];
@ -33,8 +34,12 @@ async function main() {
runner: { runServer, uploadFile },
async authenticate() {
await promptSpawnName();
await ensureDoToken();
const usedBrowserAuth = await ensureDoToken();
await ensureSshKey();
if (usedBrowserAuth) {
logStep("Next step: OpenRouter authentication (opening browser in 5s)...");
await new Promise((r) => setTimeout(r, 5000));
}
},
async promptSize() {},
async createServer(name: string) {