gramatr 0.3.62 → 0.3.63

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.
Files changed (2) hide show
  1. package/bin/gmtr-login.ts +20 -4
  2. package/package.json +1 -1
package/bin/gmtr-login.ts CHANGED
@@ -365,10 +365,26 @@ async function loginBrowser(): Promise<void> {
365
365
  console.log(' Sign in with Google or GitHub, approve the device, then return here.\n');
366
366
  console.log(' Waiting for authorization...');
367
367
 
368
- const accessToken = await Promise.race([
369
- pollDeviceAuthorization(device.device_code),
370
- new Promise<string>((_, reject) => setTimeout(() => reject(new Error('Device login timed out')), device.expires_in * 1000)),
371
- ]);
368
+ // v0.3.63 hotfix: must clear the timeout after the race resolves,
369
+ // otherwise the orphan setTimeout keeps the Node event loop alive
370
+ // until expires_in elapses (typically 600s). Symptom: success path
371
+ // prints "Authenticated successfully" and then hangs until Ctrl+C.
372
+ let timeoutHandle: ReturnType<typeof setTimeout> | undefined;
373
+ const timeoutPromise = new Promise<string>((_, reject) => {
374
+ timeoutHandle = setTimeout(
375
+ () => reject(new Error('Device login timed out')),
376
+ device.expires_in * 1000,
377
+ );
378
+ });
379
+ let accessToken: string;
380
+ try {
381
+ accessToken = await Promise.race([
382
+ pollDeviceAuthorization(device.device_code),
383
+ timeoutPromise,
384
+ ]);
385
+ } finally {
386
+ if (timeoutHandle) clearTimeout(timeoutHandle);
387
+ }
372
388
 
373
389
  const config = readConfig();
374
390
  config.token = accessToken;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gramatr",
3
- "version": "0.3.62",
3
+ "version": "0.3.63",
4
4
  "description": "grāmatr — context engineering layer for AI coding agents. Every prompt gets a pre-computed intelligence packet: decision routing, capability audit, behavioral directives, memory pre-load, and ISC scaffolds. Continuity across sessions for Claude Code, Codex, and Gemini CLI.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "type": "module",