acuvo-code 0.3.0 → 0.3.2
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/README.md +4 -0
- package/bin/acuvo.mjs +3256 -3201
- package/lib/device-login.mjs +57 -0
- package/package.json +1 -1
package/lib/device-login.mjs
CHANGED
|
@@ -149,3 +149,60 @@ export function openBrowser(url, { platform = process.platform, spawn } = {}) {
|
|
|
149
149
|
return false;
|
|
150
150
|
}
|
|
151
151
|
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* ── ⭐⭐⭐ ONE LOGIN FLOW, TWO DOORS ─────────────────────────────────────────
|
|
155
|
+
*
|
|
156
|
+
* Drives the whole grant: ask for a code, show it, open a browser, wait, save.
|
|
157
|
+
* Reached from `acuvo --login` AND from a bare `acuvo` that finds no
|
|
158
|
+
* credential — the second of which is what makes typing `acuvo` enough, the
|
|
159
|
+
* way typing `claude` is.
|
|
160
|
+
*
|
|
161
|
+
* ⚠️ IT LIVES HERE, NOT IN `bin/`. The first version was written inline inside
|
|
162
|
+
* the `--login` branch and was needed by a second caller within the hour. A fix
|
|
163
|
+
* that lives inside one caller is a fix for one caller — this codebase has paid
|
|
164
|
+
* for that three times today alone. Extracted before the second copy existed
|
|
165
|
+
* rather than after.
|
|
166
|
+
*
|
|
167
|
+
* ⚠️ IT THROWS RATHER THAN EXITING. `bin/` owns exit codes and phrasing; a
|
|
168
|
+
* library that calls `process.exit` cannot be tested and cannot be reused.
|
|
169
|
+
*
|
|
170
|
+
* @returns {Promise<{token: string, restricted: boolean|null, userCode: string}>}
|
|
171
|
+
*/
|
|
172
|
+
export async function runDeviceLogin({
|
|
173
|
+
gatewayUrl,
|
|
174
|
+
write = (s) => process.stderr.write(s),
|
|
175
|
+
spawn,
|
|
176
|
+
requestCode = requestDeviceCode,
|
|
177
|
+
poll = pollForKey,
|
|
178
|
+
open = openBrowser,
|
|
179
|
+
saveAccount,
|
|
180
|
+
} = {}) {
|
|
181
|
+
const start = await requestCode(gatewayUrl);
|
|
182
|
+
const url = start.verification_uri_complete || start.verification_uri;
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* ⚠️ THE URL AND CODE ARE PRINTED WHETHER OR NOT THE BROWSER OPENS. This runs
|
|
186
|
+
* over SSH, in containers, and in terminals with no desktop session, where
|
|
187
|
+
* opening a browser is impossible by definition — a flow that assumes the
|
|
188
|
+
* open worked strands every remote user.
|
|
189
|
+
*/
|
|
190
|
+
write(`\nYour code: ${start.user_code}\n\n`);
|
|
191
|
+
const opened = open(url, { spawn });
|
|
192
|
+
write(opened
|
|
193
|
+
? `Opened your browser to approve it. If nothing appeared:\n ${url}\n\n`
|
|
194
|
+
: `Open this to approve it:\n ${url}\n\n`);
|
|
195
|
+
write('Waiting for approval… (Ctrl-C to cancel)\n');
|
|
196
|
+
|
|
197
|
+
const granted = await poll(gatewayUrl, start.device_code, {
|
|
198
|
+
intervalMs: (start.interval ?? 2) * 1000,
|
|
199
|
+
expiresInMs: (start.expires_in ?? 600) * 1000,
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
const saved = saveAccount ? saveAccount(granted.api_key) : null;
|
|
203
|
+
return {
|
|
204
|
+
token: granted.api_key,
|
|
205
|
+
restricted: saved && typeof saved.restricted === 'boolean' ? saved.restricted : null,
|
|
206
|
+
userCode: start.user_code,
|
|
207
|
+
};
|
|
208
|
+
}
|