repowise 0.1.65 → 0.1.67

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.
@@ -228,16 +228,23 @@ async function storeCredentials(credentials) {
228
228
  await writeFile3(CREDENTIALS_PATH, JSON.stringify(credentials, null, 2));
229
229
  await chmod3(CREDENTIALS_PATH, 384);
230
230
  }
231
- async function getValidCredentials() {
231
+ async function getValidCredentials(options) {
232
232
  const creds = await getStoredCredentials();
233
233
  if (!creds)
234
234
  return null;
235
- if (Date.now() > creds.expiresAt - 5 * 60 * 1e3) {
235
+ const now = Date.now();
236
+ const needsRefresh = options?.forceRefresh || now > creds.expiresAt - 5 * 60 * 1e3;
237
+ if (needsRefresh) {
236
238
  try {
237
239
  const refreshed = await refreshTokens(creds.refreshToken, creds);
238
240
  await storeCredentials(refreshed);
239
241
  return refreshed;
240
- } catch {
242
+ } catch (err) {
243
+ const message = err instanceof Error ? err.message : String(err);
244
+ console.warn(`Token refresh failed: ${message}`);
245
+ if (now < creds.expiresAt) {
246
+ return creds;
247
+ }
241
248
  return null;
242
249
  }
243
250
  }
@@ -269,24 +276,40 @@ var PollClient = class {
269
276
  if (options?.includeActiveRepos) {
270
277
  params.set("includeActiveRepos", "true");
271
278
  }
279
+ const url = `${this.apiUrl}/v1/listeners/poll?${params.toString()}`;
280
+ const result = await this.fetchWithAuth(url, credentials.accessToken);
281
+ if (result.status === 401 || result.status === 403) {
282
+ const refreshed = await getValidCredentials({ forceRefresh: true });
283
+ if (!refreshed) {
284
+ throw new AuthError("Session expired. Run `repowise login` again.");
285
+ }
286
+ const retry = await this.fetchWithAuth(url, refreshed.accessToken);
287
+ if (retry.status === 401 || retry.status === 403) {
288
+ throw new AuthError("Session expired. Run `repowise login` again.");
289
+ }
290
+ if (!retry.ok) {
291
+ throw new Error(`Poll request failed: ${retry.status}`);
292
+ }
293
+ const json2 = await retry.json();
294
+ return json2.data;
295
+ }
296
+ if (!result.ok) {
297
+ throw new Error(`Poll request failed: ${result.status}`);
298
+ }
299
+ const json = await result.json();
300
+ return json.data;
301
+ }
302
+ async fetchWithAuth(url, accessToken) {
272
303
  const controller = new AbortController();
273
304
  const timeoutId = setTimeout(() => controller.abort(), POLL_TIMEOUT_MS);
274
305
  try {
275
- const response = await fetch(`${this.apiUrl}/v1/listeners/poll?${params.toString()}`, {
306
+ return await fetch(url, {
276
307
  headers: {
277
- Authorization: `Bearer ${credentials.accessToken}`,
308
+ Authorization: `Bearer ${accessToken}`,
278
309
  "Content-Type": "application/json"
279
310
  },
280
311
  signal: controller.signal
281
312
  });
282
- if (response.status === 401 || response.status === 403) {
283
- throw new AuthError("Session expired. Run `repowise login` again.");
284
- }
285
- if (!response.ok) {
286
- throw new Error(`Poll request failed: ${response.status}`);
287
- }
288
- const json = await response.json();
289
- return json.data;
290
313
  } finally {
291
314
  clearTimeout(timeoutId);
292
315
  }
@@ -757,7 +780,22 @@ async function startListener(options) {
757
780
  }
758
781
  }
759
782
  if (anyAuthError) {
760
- console.error("Session expired. Sending notification email and waiting for re-authentication...");
783
+ let recovered = false;
784
+ for (let attempt = 1; attempt <= 3; attempt++) {
785
+ console.warn(`Auth error \u2014 retrying credentials (attempt ${attempt}/3)...`);
786
+ await sleep(5e3);
787
+ if (!running)
788
+ break;
789
+ const fresh = await getValidCredentials({ forceRefresh: true });
790
+ if (fresh) {
791
+ console.log("Credentials recovered \u2014 resuming listener");
792
+ recovered = true;
793
+ break;
794
+ }
795
+ }
796
+ if (recovered)
797
+ continue;
798
+ console.error("Session expired after 3 retries. Sending notification email and waiting for re-authentication...");
761
799
  const creds = await getStoredCredentials();
762
800
  const email = creds?.idToken ? decodeEmailFromIdToken(creds.idToken) : null;
763
801
  if (email && authErrorGroup) {
@@ -774,7 +812,7 @@ async function startListener(options) {
774
812
  await sleep(5 * 60 * 1e3);
775
813
  if (!running)
776
814
  break;
777
- const fresh = await getValidCredentials();
815
+ const fresh = await getValidCredentials({ forceRefresh: true });
778
816
  if (fresh) {
779
817
  console.log("Re-authenticated \u2014 resuming listener");
780
818
  break;
@@ -806,8 +844,7 @@ function isStagingMode() {
806
844
  var PRODUCTION = {
807
845
  apiUrl: "https://api.repowise.ai",
808
846
  cognitoDomain: "auth-repowise",
809
- cognitoClientId: "",
810
- // TODO: set after production Cognito deploy
847
+ cognitoClientId: "50so1fkmjbqt1ufnsmbhsjbtst",
811
848
  cognitoRegion: "us-east-1",
812
849
  customDomain: false
813
850
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "repowise",
3
- "version": "0.1.65",
3
+ "version": "0.1.67",
4
4
  "type": "module",
5
5
  "description": "AI-optimized codebase context generator",
6
6
  "bin": {