@funnycode/myclaude 0.1.95 → 0.1.97

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/dist/myclaude.js CHANGED
@@ -4,8 +4,8 @@
4
4
  // MACRO - build-time constants (injected by build.ts)
5
5
  // MACRO injected by build script
6
6
  globalThis.MACRO = {
7
- VERSION: "0.1.95",
8
- BUILD_TIME: "2026-07-18T09:09:23.186Z",
7
+ VERSION: "0.1.97",
8
+ BUILD_TIME: "2026-07-18T15:18:43.301Z",
9
9
  PACKAGE_URL: "@funnycode/myclaude",
10
10
  NATIVE_PACKAGE_URL: "@funnycode/myclaude",
11
11
  VERSION_CHANGELOG: '',
@@ -117484,7 +117484,7 @@ var package_default;
117484
117484
  var init_package = __esm(() => {
117485
117485
  package_default = {
117486
117486
  name: "@funnycode/myclaude",
117487
- version: "0.1.95",
117487
+ version: "0.1.97",
117488
117488
  private: false,
117489
117489
  description: "An open-source AI coding assistant in your terminal - powered by Claude",
117490
117490
  license: "MIT",
@@ -210146,214 +210146,6 @@ var init_postSamplingHooks = __esm(() => {
210146
210146
  postSamplingHooks = [];
210147
210147
  });
210148
210148
 
210149
- // node_modules/async-mutex/index.mjs
210150
- class Semaphore {
210151
- constructor(_value, _cancelError = E_CANCELED) {
210152
- this._value = _value;
210153
- this._cancelError = _cancelError;
210154
- this._queue = [];
210155
- this._weightedWaiters = [];
210156
- }
210157
- acquire(weight = 1, priority = 0) {
210158
- if (weight <= 0)
210159
- throw new Error(`invalid weight ${weight}: must be positive`);
210160
- return new Promise((resolve25, reject2) => {
210161
- const task = { resolve: resolve25, reject: reject2, weight, priority };
210162
- const i3 = findIndexFromEnd(this._queue, (other) => priority <= other.priority);
210163
- if (i3 === -1 && weight <= this._value) {
210164
- this._dispatchItem(task);
210165
- } else {
210166
- this._queue.splice(i3 + 1, 0, task);
210167
- }
210168
- });
210169
- }
210170
- runExclusive(callback_1) {
210171
- return __awaiter$2(this, arguments, undefined, function* (callback, weight = 1, priority = 0) {
210172
- const [value, release] = yield this.acquire(weight, priority);
210173
- try {
210174
- return yield callback(value);
210175
- } finally {
210176
- release();
210177
- }
210178
- });
210179
- }
210180
- waitForUnlock(weight = 1, priority = 0) {
210181
- if (weight <= 0)
210182
- throw new Error(`invalid weight ${weight}: must be positive`);
210183
- if (this._couldLockImmediately(weight, priority)) {
210184
- return Promise.resolve();
210185
- } else {
210186
- return new Promise((resolve25) => {
210187
- if (!this._weightedWaiters[weight - 1])
210188
- this._weightedWaiters[weight - 1] = [];
210189
- insertSorted(this._weightedWaiters[weight - 1], { resolve: resolve25, priority });
210190
- });
210191
- }
210192
- }
210193
- isLocked() {
210194
- return this._value <= 0;
210195
- }
210196
- getValue() {
210197
- return this._value;
210198
- }
210199
- setValue(value) {
210200
- this._value = value;
210201
- this._dispatchQueue();
210202
- }
210203
- release(weight = 1) {
210204
- if (weight <= 0)
210205
- throw new Error(`invalid weight ${weight}: must be positive`);
210206
- this._value += weight;
210207
- this._dispatchQueue();
210208
- }
210209
- cancel() {
210210
- this._queue.forEach((entry) => entry.reject(this._cancelError));
210211
- this._queue = [];
210212
- }
210213
- _dispatchQueue() {
210214
- this._drainUnlockWaiters();
210215
- while (this._queue.length > 0 && this._queue[0].weight <= this._value) {
210216
- this._dispatchItem(this._queue.shift());
210217
- this._drainUnlockWaiters();
210218
- }
210219
- }
210220
- _dispatchItem(item) {
210221
- const previousValue = this._value;
210222
- this._value -= item.weight;
210223
- item.resolve([previousValue, this._newReleaser(item.weight)]);
210224
- }
210225
- _newReleaser(weight) {
210226
- let called = false;
210227
- return () => {
210228
- if (called)
210229
- return;
210230
- called = true;
210231
- this.release(weight);
210232
- };
210233
- }
210234
- _drainUnlockWaiters() {
210235
- if (this._queue.length === 0) {
210236
- for (let weight = this._value;weight > 0; weight--) {
210237
- const waiters = this._weightedWaiters[weight - 1];
210238
- if (!waiters)
210239
- continue;
210240
- waiters.forEach((waiter) => waiter.resolve());
210241
- this._weightedWaiters[weight - 1] = [];
210242
- }
210243
- } else {
210244
- const queuedPriority = this._queue[0].priority;
210245
- for (let weight = this._value;weight > 0; weight--) {
210246
- const waiters = this._weightedWaiters[weight - 1];
210247
- if (!waiters)
210248
- continue;
210249
- const i3 = waiters.findIndex((waiter) => waiter.priority <= queuedPriority);
210250
- (i3 === -1 ? waiters : waiters.splice(0, i3)).forEach((waiter) => waiter.resolve());
210251
- }
210252
- }
210253
- }
210254
- _couldLockImmediately(weight, priority) {
210255
- return (this._queue.length === 0 || this._queue[0].priority < priority) && weight <= this._value;
210256
- }
210257
- }
210258
- function insertSorted(a2, v2) {
210259
- const i3 = findIndexFromEnd(a2, (other) => v2.priority <= other.priority);
210260
- a2.splice(i3 + 1, 0, v2);
210261
- }
210262
- function findIndexFromEnd(a2, predicate) {
210263
- for (let i3 = a2.length - 1;i3 >= 0; i3--) {
210264
- if (predicate(a2[i3])) {
210265
- return i3;
210266
- }
210267
- }
210268
- return -1;
210269
- }
210270
-
210271
- class Mutex {
210272
- constructor(cancelError) {
210273
- this._semaphore = new Semaphore(1, cancelError);
210274
- }
210275
- acquire() {
210276
- return __awaiter$1(this, arguments, undefined, function* (priority = 0) {
210277
- const [, releaser] = yield this._semaphore.acquire(1, priority);
210278
- return releaser;
210279
- });
210280
- }
210281
- runExclusive(callback, priority = 0) {
210282
- return this._semaphore.runExclusive(() => callback(), 1, priority);
210283
- }
210284
- isLocked() {
210285
- return this._semaphore.isLocked();
210286
- }
210287
- waitForUnlock(priority = 0) {
210288
- return this._semaphore.waitForUnlock(1, priority);
210289
- }
210290
- release() {
210291
- if (this._semaphore.isLocked())
210292
- this._semaphore.release();
210293
- }
210294
- cancel() {
210295
- return this._semaphore.cancel();
210296
- }
210297
- }
210298
- var E_TIMEOUT, E_ALREADY_LOCKED, E_CANCELED, __awaiter$2 = function(thisArg, _arguments, P2, generator) {
210299
- function adopt(value) {
210300
- return value instanceof P2 ? value : new P2(function(resolve25) {
210301
- resolve25(value);
210302
- });
210303
- }
210304
- return new (P2 || (P2 = Promise))(function(resolve25, reject2) {
210305
- function fulfilled(value) {
210306
- try {
210307
- step(generator.next(value));
210308
- } catch (e) {
210309
- reject2(e);
210310
- }
210311
- }
210312
- function rejected(value) {
210313
- try {
210314
- step(generator["throw"](value));
210315
- } catch (e) {
210316
- reject2(e);
210317
- }
210318
- }
210319
- function step(result) {
210320
- result.done ? resolve25(result.value) : adopt(result.value).then(fulfilled, rejected);
210321
- }
210322
- step((generator = generator.apply(thisArg, _arguments || [])).next());
210323
- });
210324
- }, __awaiter$1 = function(thisArg, _arguments, P2, generator) {
210325
- function adopt(value) {
210326
- return value instanceof P2 ? value : new P2(function(resolve25) {
210327
- resolve25(value);
210328
- });
210329
- }
210330
- return new (P2 || (P2 = Promise))(function(resolve25, reject2) {
210331
- function fulfilled(value) {
210332
- try {
210333
- step(generator.next(value));
210334
- } catch (e) {
210335
- reject2(e);
210336
- }
210337
- }
210338
- function rejected(value) {
210339
- try {
210340
- step(generator["throw"](value));
210341
- } catch (e) {
210342
- reject2(e);
210343
- }
210344
- }
210345
- function step(result) {
210346
- result.done ? resolve25(result.value) : adopt(result.value).then(fulfilled, rejected);
210347
- }
210348
- step((generator = generator.apply(thisArg, _arguments || [])).next());
210349
- });
210350
- };
210351
- var init_async_mutex = __esm(() => {
210352
- E_TIMEOUT = new Error("timeout while waiting for mutex to become available");
210353
- E_ALREADY_LOCKED = new Error("mutex already locked");
210354
- E_CANCELED = new Error("request for lock canceled");
210355
- });
210356
-
210357
210149
  // src/services/api/dumpPrompts.ts
210358
210150
  import { createHash as createHash5 } from "crypto";
210359
210151
  import { promises as fs11 } from "fs";
@@ -210366,34 +210158,24 @@ function enqueueDumpRequest(agentIdOrSessionId, callback) {
210366
210158
  dumpRequestQueue.set(agentIdOrSessionId, []);
210367
210159
  }
210368
210160
  dumpRequestQueue.get(agentIdOrSessionId).push(callback);
210369
- processQueue(agentIdOrSessionId);
210161
+ if (!processingFlags.has(agentIdOrSessionId)) {
210162
+ processingFlags.add(agentIdOrSessionId);
210163
+ processQueue(agentIdOrSessionId);
210164
+ }
210370
210165
  }
210371
210166
  async function processQueue(agentIdOrSessionId) {
210372
- const mapRelease = await dumpRequestMapMutex.acquire();
210373
- let mutex = dumpRequestMutexes.get(agentIdOrSessionId);
210374
- if (!mutex) {
210375
- mutex = new Mutex;
210376
- dumpRequestMutexes.set(agentIdOrSessionId, mutex);
210377
- }
210378
- mapRelease();
210379
- const release = await mutex.acquire();
210380
210167
  try {
210381
- const queue = dumpRequestQueue.get(agentIdOrSessionId);
210382
- if (!queue || queue.length === 0) {
210383
- dumpRequestQueue.delete(agentIdOrSessionId);
210384
- dumpRequestMutexes.delete(agentIdOrSessionId);
210385
- return;
210386
- }
210387
- const callback = queue.shift();
210388
- await callback();
210389
- if (queue.length > 0) {
210390
- setImmediate(() => processQueue(agentIdOrSessionId));
210391
- } else {
210392
- dumpRequestQueue.delete(agentIdOrSessionId);
210393
- dumpRequestMutexes.delete(agentIdOrSessionId);
210168
+ while (true) {
210169
+ const queue = dumpRequestQueue.get(agentIdOrSessionId);
210170
+ if (!queue || queue.length === 0) {
210171
+ break;
210172
+ }
210173
+ const callback = queue.shift();
210174
+ await callback();
210394
210175
  }
210395
210176
  } finally {
210396
- release();
210177
+ dumpRequestQueue.delete(agentIdOrSessionId);
210178
+ processingFlags.delete(agentIdOrSessionId);
210397
210179
  }
210398
210180
  }
210399
210181
  function clearDumpState(agentIdOrSessionId) {
@@ -210441,10 +210223,12 @@ function initFingerprint(req) {
210441
210223
  async function dumpRequest(body, ts, state, filePath) {
210442
210224
  if (false)
210443
210225
  ;
210226
+ if (process.env.USER_TYPE !== "ant")
210227
+ return;
210444
210228
  try {
210445
210229
  const req = jsonParse(body);
210446
210230
  addApiRequestToCache(req);
210447
- if (process.env.USER_TYPE !== "ant" || process.env.DUMP_PROMPTS !== "1")
210231
+ if (process.env.DUMP_PROMPTS !== "1")
210448
210232
  return;
210449
210233
  logForDebugging("DUMP_PROMPTS is enabled. This will write full API payloads (including system prompts, user messages, and tool definitions) to the filesystem. This is intended for debugging only and should NOT be used in production.", { level: "warn" });
210450
210234
  const entries = [];
@@ -210577,35 +210361,29 @@ function createDumpPromptsFetch(agentIdOrSessionId) {
210577
210361
  jsonStringify({ type: "response", timestamp, data })
210578
210362
  ]);
210579
210363
  } catch (err2) {
210580
- try {
210581
- logForDebugging(`dumpPrompts.response handler error: ${err2}`, { level: "error" });
210582
- } catch {}
210364
+ logError2(`dumpPrompts.response handler error: ${err2}`);
210583
210365
  }
210584
210366
  })().catch((err2) => {
210585
- try {
210586
- logForDebugging(`dumpPrompts.response handler unhandled rejection: ${err2}`, { level: "error" });
210587
- } catch {}
210367
+ logError2(`dumpPrompts.response handler unhandled rejection: ${err2}`);
210588
210368
  });
210589
210369
  }
210590
210370
  return response;
210591
210371
  };
210592
210372
  }
210593
- var MAX_CACHED_REQUESTS = 5, cachedApiRequests, dumpState, dumpRequestQueue, dumpRequestMutexes, dumpRequestMapMutex;
210373
+ var MAX_CACHED_REQUESTS = 5, cachedApiRequests, dumpState, dumpRequestQueue, processingFlags;
210594
210374
  var init_dumpPrompts = __esm(() => {
210595
210375
  init_state();
210596
210376
  init_envUtils();
210597
210377
  init_slowOperations();
210598
210378
  init_debug();
210599
210379
  init_log3();
210600
- init_async_mutex();
210601
210380
  if (process.env.USER_TYPE === "ant" && process.env.DUMP_PROMPTS === "1") {
210602
210381
  logForDebugging("DUMP_PROMPTS is enabled. This will write full API payloads (including system prompts, user messages, and tool definitions) to the filesystem. This is intended for debugging only and should NOT be used in production.", { level: "warn" });
210603
210382
  }
210604
210383
  cachedApiRequests = [];
210605
210384
  dumpState = new Map;
210606
210385
  dumpRequestQueue = new Map;
210607
- dumpRequestMutexes = new Map;
210608
- dumpRequestMapMutex = new Mutex;
210386
+ processingFlags = new Set;
210609
210387
  });
210610
210388
 
210611
210389
  // src/utils/abortController.ts
@@ -301139,6 +300917,214 @@ var init_gracefulShutdown = __esm(() => {
301139
300917
  };
301140
300918
  });
301141
300919
 
300920
+ // node_modules/async-mutex/index.mjs
300921
+ class Semaphore {
300922
+ constructor(_value, _cancelError = E_CANCELED) {
300923
+ this._value = _value;
300924
+ this._cancelError = _cancelError;
300925
+ this._queue = [];
300926
+ this._weightedWaiters = [];
300927
+ }
300928
+ acquire(weight = 1, priority = 0) {
300929
+ if (weight <= 0)
300930
+ throw new Error(`invalid weight ${weight}: must be positive`);
300931
+ return new Promise((resolve28, reject2) => {
300932
+ const task = { resolve: resolve28, reject: reject2, weight, priority };
300933
+ const i3 = findIndexFromEnd(this._queue, (other) => priority <= other.priority);
300934
+ if (i3 === -1 && weight <= this._value) {
300935
+ this._dispatchItem(task);
300936
+ } else {
300937
+ this._queue.splice(i3 + 1, 0, task);
300938
+ }
300939
+ });
300940
+ }
300941
+ runExclusive(callback_1) {
300942
+ return __awaiter$2(this, arguments, undefined, function* (callback, weight = 1, priority = 0) {
300943
+ const [value, release] = yield this.acquire(weight, priority);
300944
+ try {
300945
+ return yield callback(value);
300946
+ } finally {
300947
+ release();
300948
+ }
300949
+ });
300950
+ }
300951
+ waitForUnlock(weight = 1, priority = 0) {
300952
+ if (weight <= 0)
300953
+ throw new Error(`invalid weight ${weight}: must be positive`);
300954
+ if (this._couldLockImmediately(weight, priority)) {
300955
+ return Promise.resolve();
300956
+ } else {
300957
+ return new Promise((resolve28) => {
300958
+ if (!this._weightedWaiters[weight - 1])
300959
+ this._weightedWaiters[weight - 1] = [];
300960
+ insertSorted(this._weightedWaiters[weight - 1], { resolve: resolve28, priority });
300961
+ });
300962
+ }
300963
+ }
300964
+ isLocked() {
300965
+ return this._value <= 0;
300966
+ }
300967
+ getValue() {
300968
+ return this._value;
300969
+ }
300970
+ setValue(value) {
300971
+ this._value = value;
300972
+ this._dispatchQueue();
300973
+ }
300974
+ release(weight = 1) {
300975
+ if (weight <= 0)
300976
+ throw new Error(`invalid weight ${weight}: must be positive`);
300977
+ this._value += weight;
300978
+ this._dispatchQueue();
300979
+ }
300980
+ cancel() {
300981
+ this._queue.forEach((entry) => entry.reject(this._cancelError));
300982
+ this._queue = [];
300983
+ }
300984
+ _dispatchQueue() {
300985
+ this._drainUnlockWaiters();
300986
+ while (this._queue.length > 0 && this._queue[0].weight <= this._value) {
300987
+ this._dispatchItem(this._queue.shift());
300988
+ this._drainUnlockWaiters();
300989
+ }
300990
+ }
300991
+ _dispatchItem(item) {
300992
+ const previousValue = this._value;
300993
+ this._value -= item.weight;
300994
+ item.resolve([previousValue, this._newReleaser(item.weight)]);
300995
+ }
300996
+ _newReleaser(weight) {
300997
+ let called = false;
300998
+ return () => {
300999
+ if (called)
301000
+ return;
301001
+ called = true;
301002
+ this.release(weight);
301003
+ };
301004
+ }
301005
+ _drainUnlockWaiters() {
301006
+ if (this._queue.length === 0) {
301007
+ for (let weight = this._value;weight > 0; weight--) {
301008
+ const waiters = this._weightedWaiters[weight - 1];
301009
+ if (!waiters)
301010
+ continue;
301011
+ waiters.forEach((waiter) => waiter.resolve());
301012
+ this._weightedWaiters[weight - 1] = [];
301013
+ }
301014
+ } else {
301015
+ const queuedPriority = this._queue[0].priority;
301016
+ for (let weight = this._value;weight > 0; weight--) {
301017
+ const waiters = this._weightedWaiters[weight - 1];
301018
+ if (!waiters)
301019
+ continue;
301020
+ const i3 = waiters.findIndex((waiter) => waiter.priority <= queuedPriority);
301021
+ (i3 === -1 ? waiters : waiters.splice(0, i3)).forEach((waiter) => waiter.resolve());
301022
+ }
301023
+ }
301024
+ }
301025
+ _couldLockImmediately(weight, priority) {
301026
+ return (this._queue.length === 0 || this._queue[0].priority < priority) && weight <= this._value;
301027
+ }
301028
+ }
301029
+ function insertSorted(a2, v2) {
301030
+ const i3 = findIndexFromEnd(a2, (other) => v2.priority <= other.priority);
301031
+ a2.splice(i3 + 1, 0, v2);
301032
+ }
301033
+ function findIndexFromEnd(a2, predicate) {
301034
+ for (let i3 = a2.length - 1;i3 >= 0; i3--) {
301035
+ if (predicate(a2[i3])) {
301036
+ return i3;
301037
+ }
301038
+ }
301039
+ return -1;
301040
+ }
301041
+
301042
+ class Mutex {
301043
+ constructor(cancelError) {
301044
+ this._semaphore = new Semaphore(1, cancelError);
301045
+ }
301046
+ acquire() {
301047
+ return __awaiter$1(this, arguments, undefined, function* (priority = 0) {
301048
+ const [, releaser] = yield this._semaphore.acquire(1, priority);
301049
+ return releaser;
301050
+ });
301051
+ }
301052
+ runExclusive(callback, priority = 0) {
301053
+ return this._semaphore.runExclusive(() => callback(), 1, priority);
301054
+ }
301055
+ isLocked() {
301056
+ return this._semaphore.isLocked();
301057
+ }
301058
+ waitForUnlock(priority = 0) {
301059
+ return this._semaphore.waitForUnlock(1, priority);
301060
+ }
301061
+ release() {
301062
+ if (this._semaphore.isLocked())
301063
+ this._semaphore.release();
301064
+ }
301065
+ cancel() {
301066
+ return this._semaphore.cancel();
301067
+ }
301068
+ }
301069
+ var E_TIMEOUT, E_ALREADY_LOCKED, E_CANCELED, __awaiter$2 = function(thisArg, _arguments, P2, generator) {
301070
+ function adopt(value) {
301071
+ return value instanceof P2 ? value : new P2(function(resolve28) {
301072
+ resolve28(value);
301073
+ });
301074
+ }
301075
+ return new (P2 || (P2 = Promise))(function(resolve28, reject2) {
301076
+ function fulfilled(value) {
301077
+ try {
301078
+ step(generator.next(value));
301079
+ } catch (e) {
301080
+ reject2(e);
301081
+ }
301082
+ }
301083
+ function rejected(value) {
301084
+ try {
301085
+ step(generator["throw"](value));
301086
+ } catch (e) {
301087
+ reject2(e);
301088
+ }
301089
+ }
301090
+ function step(result) {
301091
+ result.done ? resolve28(result.value) : adopt(result.value).then(fulfilled, rejected);
301092
+ }
301093
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
301094
+ });
301095
+ }, __awaiter$1 = function(thisArg, _arguments, P2, generator) {
301096
+ function adopt(value) {
301097
+ return value instanceof P2 ? value : new P2(function(resolve28) {
301098
+ resolve28(value);
301099
+ });
301100
+ }
301101
+ return new (P2 || (P2 = Promise))(function(resolve28, reject2) {
301102
+ function fulfilled(value) {
301103
+ try {
301104
+ step(generator.next(value));
301105
+ } catch (e) {
301106
+ reject2(e);
301107
+ }
301108
+ }
301109
+ function rejected(value) {
301110
+ try {
301111
+ step(generator["throw"](value));
301112
+ } catch (e) {
301113
+ reject2(e);
301114
+ }
301115
+ }
301116
+ function step(result) {
301117
+ result.done ? resolve28(result.value) : adopt(result.value).then(fulfilled, rejected);
301118
+ }
301119
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
301120
+ });
301121
+ };
301122
+ var init_async_mutex = __esm(() => {
301123
+ E_TIMEOUT = new Error("timeout while waiting for mutex to become available");
301124
+ E_ALREADY_LOCKED = new Error("mutex already locked");
301125
+ E_CANCELED = new Error("request for lock canceled");
301126
+ });
301127
+
301142
301128
  // src/services/api/grove.ts
301143
301129
  function memoizeWithTTL(fn, ttlMs) {
301144
301130
  let lastCachedAt = 0;
@@ -301154,14 +301140,9 @@ function memoizeWithTTL(fn, ttlMs) {
301154
301140
  const result = await memoized(...args);
301155
301141
  if (result && typeof result === "object" && "success" in result && result.success === true) {
301156
301142
  lastCachedAt = Date.now();
301157
- } else if (result && typeof result === "object" && "success" in result && result.success === false) {
301158
- originalClear();
301159
- lastCachedAt = 0;
301160
- }
301143
+ } else if (result && typeof result === "object" && "success" in result && result.success === false) {}
301161
301144
  return result;
301162
301145
  } catch (error49) {
301163
- originalClear();
301164
- lastCachedAt = -1;
301165
301146
  return { success: false };
301166
301147
  }
301167
301148
  };
@@ -301225,13 +301206,21 @@ async function isQualifiedForGrove() {
301225
301206
  const cachedEntry = globalConfig2.groveConfigCache?.[accountId];
301226
301207
  const now2 = Date.now();
301227
301208
  if (!cachedEntry) {
301228
- logForDebugging("Grove: No cache, fetching config in background (dialog skipped this session)");
301229
- fetchAndStoreGroveConfig(accountId);
301209
+ logForDebugging("Grove: No cache, fetching config synchronously");
301210
+ await fetchAndStoreGroveConfig(accountId);
301211
+ const updatedConfig = getGlobalConfig().groveConfigCache?.[accountId];
301212
+ if (updatedConfig) {
301213
+ return updatedConfig.grove_enabled;
301214
+ }
301230
301215
  return false;
301231
301216
  }
301232
301217
  if (now2 - cachedEntry.timestamp > GROVE_CACHE_EXPIRATION_MS) {
301233
- logForDebugging("Grove: Cache stale, returning cached data and refreshing in background");
301234
- fetchAndStoreGroveConfig(accountId);
301218
+ logForDebugging("Grove: Cache stale, refreshing config");
301219
+ await fetchAndStoreGroveConfig(accountId);
301220
+ const updatedConfig = getGlobalConfig().groveConfigCache?.[accountId];
301221
+ if (updatedConfig) {
301222
+ return updatedConfig.grove_enabled;
301223
+ }
301235
301224
  return cachedEntry.grove_enabled;
301236
301225
  }
301237
301226
  logForDebugging("Grove: Using fresh cached config");
@@ -301247,27 +301236,41 @@ async function fetchAndStoreGroveConfig(accountId) {
301247
301236
  mapRelease();
301248
301237
  const release = await mutex.acquire();
301249
301238
  try {
301250
- const result = await getGroveNoticeConfig();
301251
- if (!result.success) {
301252
- return;
301253
- }
301254
- const groveEnabled = result.data.grove_enabled;
301255
- const cachedEntry = getGlobalConfig().groveConfigCache?.[accountId];
301256
- if (cachedEntry?.grove_enabled === groveEnabled && Date.now() - cachedEntry.timestamp <= GROVE_CACHE_EXPIRATION_MS) {
301257
- return;
301258
- }
301259
- saveGlobalConfig((current) => ({
301260
- ...current,
301261
- groveConfigCache: {
301262
- ...current.groveConfigCache,
301263
- [accountId]: {
301264
- grove_enabled: groveEnabled,
301265
- timestamp: Date.now()
301239
+ let lastError;
301240
+ for (let attempt = 0;attempt < 3; attempt++) {
301241
+ try {
301242
+ const result = await getGroveNoticeConfig();
301243
+ if (!result.success) {
301244
+ if (attempt < 2) {
301245
+ await new Promise((resolve28) => setTimeout(resolve28, 500));
301246
+ continue;
301247
+ }
301248
+ return;
301249
+ }
301250
+ const groveEnabled = result.data.grove_enabled;
301251
+ const cachedEntry = getGlobalConfig().groveConfigCache?.[accountId];
301252
+ if (cachedEntry?.grove_enabled === groveEnabled && Date.now() - cachedEntry.timestamp <= GROVE_CACHE_EXPIRATION_MS) {
301253
+ return;
301254
+ }
301255
+ saveGlobalConfig((current) => ({
301256
+ ...current,
301257
+ groveConfigCache: {
301258
+ ...current.groveConfigCache,
301259
+ [accountId]: {
301260
+ grove_enabled: groveEnabled,
301261
+ timestamp: Date.now()
301262
+ }
301263
+ }
301264
+ }));
301265
+ return;
301266
+ } catch (err2) {
301267
+ lastError = err2 instanceof Error ? err2 : new Error(String(err2));
301268
+ if (attempt < 2) {
301269
+ await new Promise((resolve28) => setTimeout(resolve28, 500));
301266
301270
  }
301267
301271
  }
301268
- }));
301269
- } catch (err2) {
301270
- logForDebugging(`Grove: Failed to fetch and store config: ${err2}`);
301272
+ }
301273
+ logForDebugging(`Grove: Failed to fetch and store config after 3 attempts: ${lastError}`);
301271
301274
  } finally {
301272
301275
  release();
301273
301276
  }
@@ -301360,7 +301363,6 @@ var init_grove = __esm(() => {
301360
301363
  return { success: true, data: response.data };
301361
301364
  } catch (err2) {
301362
301365
  logError2(err2);
301363
- getGroveSettings.cache.clear?.();
301364
301366
  return { success: false };
301365
301367
  }
301366
301368
  }, GROVE_CACHE_EXPIRATION_MS);
@@ -301402,7 +301404,6 @@ var init_grove = __esm(() => {
301402
301404
  if (axios_default.isAxiosError(err2) && err2.code === "ECONNABORTED") {
301403
301405
  logForDebugging(`Grove: API request timed out after ${GROVE_API_TIMEOUT_MS}ms. This may cause the Grove dialog to be suppressed for users with slow connections.`);
301404
301406
  }
301405
- getGroveNoticeConfig.cache.clear?.();
301406
301407
  return { success: false };
301407
301408
  }
301408
301409
  }, GROVE_CACHE_EXPIRATION_MS);
@@ -342446,7 +342447,9 @@ async function getSessionLogs(sessionId, url3) {
342446
342447
  return null;
342447
342448
  }
342448
342449
  const headers = { Authorization: `Bearer ${sessionToken}` };
342449
- const logs2 = await fetchSessionLogsFromUrl(sessionId, url3, headers);
342450
+ const sequential2 = getOrCreateSequential(sessionId);
342451
+ const result = await sequential2(sessionId, url3, headers, true);
342452
+ const logs2 = result;
342450
342453
  if (logs2 && logs2.length > 0) {
342451
342454
  const lastEntry = logs2.at(-1);
342452
342455
  if (lastEntry && "uuid" in lastEntry && lastEntry.uuid) {
@@ -453788,17 +453791,36 @@ var init_FeedColumn = __esm(() => {
453788
453791
  // src/services/api/referral.ts
453789
453792
  async function fetchReferralEligibility(campaign = "claude_code_guest_pass") {
453790
453793
  const { accessToken, orgUUID } = await prepareApiRequest();
453794
+ const existingPromise = fetchInProgressMap.get(orgUUID);
453795
+ if (existingPromise) {
453796
+ logForDebugging(`Passes: Reusing in-flight eligibility fetch for org ${orgUUID}`);
453797
+ return existingPromise;
453798
+ }
453791
453799
  const headers = {
453792
453800
  ...getOAuthHeaders(accessToken),
453793
453801
  "x-organization-uuid": orgUUID
453794
453802
  };
453795
453803
  const url3 = `${getOauthConfig().BASE_API_URL}/api/oauth/organizations/${orgUUID}/referral/eligibility`;
453796
- const response = await axios_default.get(url3, {
453797
- headers,
453798
- params: { campaign },
453799
- timeout: 5000
453804
+ let resolvePromise;
453805
+ const promise3 = new Promise((resolve47) => {
453806
+ resolvePromise = resolve47;
453800
453807
  });
453801
- return response.data;
453808
+ fetchInProgressMap.set(orgUUID, promise3);
453809
+ (async () => {
453810
+ try {
453811
+ const response = await axios_default.get(url3, {
453812
+ headers,
453813
+ params: { campaign },
453814
+ timeout: 5000
453815
+ });
453816
+ resolvePromise(response.data);
453817
+ } catch (error49) {
453818
+ logError2(error49);
453819
+ fetchInProgressMap.delete(orgUUID);
453820
+ throw error49;
453821
+ }
453822
+ })();
453823
+ return promise3;
453802
453824
  }
453803
453825
  async function fetchReferralRedemptions(campaign = "claude_code_guest_pass") {
453804
453826
  const { accessToken, orgUUID } = await prepareApiRequest();
@@ -453878,41 +453900,26 @@ async function fetchAndStorePassesEligibility() {
453878
453900
  if (!orgId) {
453879
453901
  return null;
453880
453902
  }
453881
- const existingPromise = fetchInProgressMap.get(orgId);
453882
- if (existingPromise) {
453883
- logForDebugging(`Passes: Reusing in-flight eligibility fetch for org ${orgId}`);
453884
- return existingPromise;
453903
+ try {
453904
+ const response = await fetchReferralEligibility();
453905
+ const cacheEntry = {
453906
+ ...response,
453907
+ timestamp: Date.now()
453908
+ };
453909
+ saveGlobalConfig((current) => ({
453910
+ ...current,
453911
+ passesEligibilityCache: {
453912
+ ...current.passesEligibilityCache,
453913
+ [orgId]: cacheEntry
453914
+ }
453915
+ }));
453916
+ logForDebugging(`Passes eligibility cached for org ${orgId}: ${response.eligible}`);
453917
+ return response;
453918
+ } catch (error49) {
453919
+ logForDebugging("Failed to fetch and cache passes eligibility");
453920
+ logError2(error49);
453921
+ return null;
453885
453922
  }
453886
- let resolvePromise;
453887
- const promise3 = new Promise((resolve47) => {
453888
- resolvePromise = resolve47;
453889
- });
453890
- fetchInProgressMap.set(orgId, promise3);
453891
- (async () => {
453892
- try {
453893
- const response = await fetchReferralEligibility();
453894
- const cacheEntry = {
453895
- ...response,
453896
- timestamp: Date.now()
453897
- };
453898
- saveGlobalConfig((current) => ({
453899
- ...current,
453900
- passesEligibilityCache: {
453901
- ...current.passesEligibilityCache,
453902
- [orgId]: cacheEntry
453903
- }
453904
- }));
453905
- logForDebugging(`Passes eligibility cached for org ${orgId}: ${response.eligible}`);
453906
- resolvePromise(response);
453907
- } catch (error49) {
453908
- logForDebugging("Failed to fetch and cache passes eligibility");
453909
- logError2(error49);
453910
- resolvePromise(null);
453911
- } finally {
453912
- fetchInProgressMap.delete(orgId);
453913
- }
453914
- })();
453915
- return promise3;
453916
453923
  }
453917
453924
  async function getCachedOrFetchPassesEligibility() {
453918
453925
  if (!shouldCheckForPasses()) {