| 93 | } |
| 94 | |
| 95 | async function pollForApiKey(apiUrl: string, sessionId: string, verifier: string): Promise<string> { |
| 96 | const deadline = Date.now() + POLL_TIMEOUT_MS; |
| 97 | |
| 98 | while (Date.now() < deadline) { |
| 99 | const res = await fetch(`${apiUrl}/cli-sessions/${sessionId}`, { |
| 100 | method: "GET", |
| 101 | headers: { "X-Cli-Verifier": verifier }, |
| 102 | }); |
| 103 | |
| 104 | if (res.ok) { |
| 105 | const body = (await res.json()) as |
| 106 | | { status: "pending" } |
| 107 | | { status: "completed"; apiKey: string }; |
| 108 | if (body.status === "completed") return body.apiKey; |
| 109 | } else if (res.status === 404) { |
| 110 | throw new Error("CLI session not found. Please rerun the command."); |
| 111 | } else if (res.status >= 400 && res.status < 500) { |
| 112 | const body = await res.text(); |
| 113 | throw new Error(`CLI authentication failed: ${body || `HTTP ${res.status}`}`); |
| 114 | } |
| 115 | // 5xx: transient — keep polling. |
| 116 | |
| 117 | await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS)); |
| 118 | } |
| 119 | |
| 120 | throw new Error("Timed out waiting for browser confirmation"); |
| 121 | } |