@funnycode/myclaude 0.1.89 → 0.1.91

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.89",
8
- BUILD_TIME: "2026-07-17T12:20:44.184Z",
7
+ VERSION: "0.1.91",
8
+ BUILD_TIME: "2026-07-17T20:20:49.267Z",
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.89",
117487
+ version: "0.1.91",
117488
117488
  private: false,
117489
117489
  description: "An open-source AI coding assistant in your terminal - powered by Claude",
117490
117490
  license: "MIT",
@@ -117548,6 +117548,7 @@ var init_package = __esm(() => {
117548
117548
  "@opentelemetry/semantic-conventions": "1.40.0",
117549
117549
  ajv: "8.18.0",
117550
117550
  asciichart: "1.5.25",
117551
+ "async-mutex": "^0.5.0",
117551
117552
  "auto-bind": "5.0.1",
117552
117553
  axios: "1.14.0",
117553
117554
  "bidi-js": "1.0.3",
@@ -210162,7 +210163,7 @@ function enqueueDumpRequest(agentIdOrSessionId, callback) {
210162
210163
  processQueue(agentIdOrSessionId);
210163
210164
  }
210164
210165
  }
210165
- function processQueue(agentIdOrSessionId) {
210166
+ async function processQueue(agentIdOrSessionId) {
210166
210167
  processingQueues.add(agentIdOrSessionId);
210167
210168
  const queue = dumpRequestQueue.get(agentIdOrSessionId);
210168
210169
  if (!queue || queue.length === 0) {
@@ -210171,7 +210172,7 @@ function processQueue(agentIdOrSessionId) {
210171
210172
  return;
210172
210173
  }
210173
210174
  const callback = queue.shift();
210174
- callback();
210175
+ await callback();
210175
210176
  if (queue.length > 0) {
210176
210177
  setImmediate(() => processQueue(agentIdOrSessionId));
210177
210178
  } else {
@@ -210202,14 +210203,17 @@ function addApiRequestToCache(requestData) {
210202
210203
  function getDumpPromptsPath(agentIdOrSessionId) {
210203
210204
  return join48(getClaudeConfigHomeDir(), "dump-prompts", `${agentIdOrSessionId ?? getSessionId()}.jsonl`);
210204
210205
  }
210205
- function appendToFile(filePath, entries) {
210206
+ async function appendToFile(filePath, entries) {
210206
210207
  if (entries.length === 0)
210207
210208
  return;
210208
- fs11.mkdir(dirname27(filePath), { recursive: true }).then(() => fs11.appendFile(filePath, entries.join(`
210209
+ try {
210210
+ await fs11.mkdir(dirname27(filePath), { recursive: true });
210211
+ await fs11.appendFile(filePath, entries.join(`
210209
210212
  `) + `
210210
- `)).catch((err2) => {
210213
+ `);
210214
+ } catch (err2) {
210211
210215
  logForDebugging(`dumpPrompts.appendToFile error: ${err2}`, { level: "error" });
210212
- });
210216
+ }
210213
210217
  }
210214
210218
  function initFingerprint(req) {
210215
210219
  const tools = req.tools;
@@ -210218,7 +210222,7 @@ function initFingerprint(req) {
210218
210222
  const toolNames = tools?.map((t) => t.name ?? "").join(",") ?? "";
210219
210223
  return `${req.model}|${toolNames}|${sysLen}`;
210220
210224
  }
210221
- function dumpRequest(body, ts, state, filePath) {
210225
+ async function dumpRequest(body, ts, state, filePath) {
210222
210226
  try {
210223
210227
  const req = jsonParse(body);
210224
210228
  addApiRequestToCache(req);
@@ -210256,7 +210260,7 @@ function dumpRequest(body, ts, state, filePath) {
210256
210260
  }
210257
210261
  }
210258
210262
  state.messageCountSeen = messages.length;
210259
- appendToFile(filePath, entries);
210263
+ await appendToFile(filePath, entries);
210260
210264
  } catch (err2) {
210261
210265
  logForDebugging(`dumpPrompts.dumpRequest error: ${err2}`, { level: "error" });
210262
210266
  }
@@ -210274,8 +210278,8 @@ function createDumpPromptsFetch(agentIdOrSessionId) {
210274
210278
  let timestamp;
210275
210279
  if (init2?.method === "POST" && init2.body) {
210276
210280
  timestamp = new Date().toISOString();
210277
- enqueueDumpRequest(agentIdOrSessionId, () => {
210278
- dumpRequest(init2.body, timestamp, state, filePath);
210281
+ enqueueDumpRequest(agentIdOrSessionId, async () => {
210282
+ await dumpRequest(init2.body, timestamp, state, filePath);
210279
210283
  });
210280
210284
  }
210281
210285
  const response = await globalThis.fetch(input, init2);
@@ -210289,27 +210293,50 @@ function createDumpPromptsFetch(agentIdOrSessionId) {
210289
210293
  const reader = cloned.body.getReader();
210290
210294
  const decoder = new TextDecoder;
210291
210295
  let buffer = "";
210296
+ const chunks = [];
210292
210297
  try {
210293
210298
  while (true) {
210294
210299
  const { done, value } = await reader.read();
210295
210300
  if (done)
210296
210301
  break;
210297
210302
  buffer += decoder.decode(value, { stream: true });
210303
+ const lastDoubleNewline = buffer.lastIndexOf(`
210304
+
210305
+ `);
210306
+ if (lastDoubleNewline !== -1) {
210307
+ const completeEvents = buffer.slice(0, lastDoubleNewline);
210308
+ buffer = buffer.slice(lastDoubleNewline + 2);
210309
+ for (const event of completeEvents.split(`
210310
+
210311
+ `)) {
210312
+ for (const line of event.split(`
210313
+ `)) {
210314
+ if (line.startsWith("data: ") && line !== "data: [DONE]") {
210315
+ try {
210316
+ chunks.push(jsonParse(line.slice(6)));
210317
+ } catch (err2) {
210318
+ logForDebugging(`dumpPrompts.SSE parse error: ${err2}`, { level: "error" });
210319
+ }
210320
+ }
210321
+ }
210322
+ }
210323
+ }
210298
210324
  }
210299
210325
  } finally {
210300
210326
  reader.releaseLock();
210301
210327
  }
210302
- const chunks = [];
210303
- for (const event of buffer.split(`
210328
+ if (buffer.trim()) {
210329
+ for (const event of buffer.split(`
210304
210330
 
210305
210331
  `)) {
210306
- for (const line of event.split(`
210332
+ for (const line of event.split(`
210307
210333
  `)) {
210308
- if (line.startsWith("data: ") && line !== "data: [DONE]") {
210309
- try {
210310
- chunks.push(jsonParse(line.slice(6)));
210311
- } catch (err2) {
210312
- logForDebugging(`dumpPrompts.SSE parse error: ${err2}`, { level: "error" });
210334
+ if (line.startsWith("data: ") && line !== "data: [DONE]") {
210335
+ try {
210336
+ chunks.push(jsonParse(line.slice(6)));
210337
+ } catch (err2) {
210338
+ logForDebugging(`dumpPrompts.SSE parse error: ${err2}`, { level: "error" });
210339
+ }
210313
210340
  }
210314
210341
  }
210315
210342
  }
@@ -300876,6 +300903,214 @@ var init_gracefulShutdown = __esm(() => {
300876
300903
  };
300877
300904
  });
300878
300905
 
300906
+ // node_modules/async-mutex/index.mjs
300907
+ class Semaphore {
300908
+ constructor(_value, _cancelError = E_CANCELED) {
300909
+ this._value = _value;
300910
+ this._cancelError = _cancelError;
300911
+ this._queue = [];
300912
+ this._weightedWaiters = [];
300913
+ }
300914
+ acquire(weight = 1, priority = 0) {
300915
+ if (weight <= 0)
300916
+ throw new Error(`invalid weight ${weight}: must be positive`);
300917
+ return new Promise((resolve28, reject2) => {
300918
+ const task = { resolve: resolve28, reject: reject2, weight, priority };
300919
+ const i3 = findIndexFromEnd(this._queue, (other) => priority <= other.priority);
300920
+ if (i3 === -1 && weight <= this._value) {
300921
+ this._dispatchItem(task);
300922
+ } else {
300923
+ this._queue.splice(i3 + 1, 0, task);
300924
+ }
300925
+ });
300926
+ }
300927
+ runExclusive(callback_1) {
300928
+ return __awaiter$2(this, arguments, undefined, function* (callback, weight = 1, priority = 0) {
300929
+ const [value, release] = yield this.acquire(weight, priority);
300930
+ try {
300931
+ return yield callback(value);
300932
+ } finally {
300933
+ release();
300934
+ }
300935
+ });
300936
+ }
300937
+ waitForUnlock(weight = 1, priority = 0) {
300938
+ if (weight <= 0)
300939
+ throw new Error(`invalid weight ${weight}: must be positive`);
300940
+ if (this._couldLockImmediately(weight, priority)) {
300941
+ return Promise.resolve();
300942
+ } else {
300943
+ return new Promise((resolve28) => {
300944
+ if (!this._weightedWaiters[weight - 1])
300945
+ this._weightedWaiters[weight - 1] = [];
300946
+ insertSorted(this._weightedWaiters[weight - 1], { resolve: resolve28, priority });
300947
+ });
300948
+ }
300949
+ }
300950
+ isLocked() {
300951
+ return this._value <= 0;
300952
+ }
300953
+ getValue() {
300954
+ return this._value;
300955
+ }
300956
+ setValue(value) {
300957
+ this._value = value;
300958
+ this._dispatchQueue();
300959
+ }
300960
+ release(weight = 1) {
300961
+ if (weight <= 0)
300962
+ throw new Error(`invalid weight ${weight}: must be positive`);
300963
+ this._value += weight;
300964
+ this._dispatchQueue();
300965
+ }
300966
+ cancel() {
300967
+ this._queue.forEach((entry) => entry.reject(this._cancelError));
300968
+ this._queue = [];
300969
+ }
300970
+ _dispatchQueue() {
300971
+ this._drainUnlockWaiters();
300972
+ while (this._queue.length > 0 && this._queue[0].weight <= this._value) {
300973
+ this._dispatchItem(this._queue.shift());
300974
+ this._drainUnlockWaiters();
300975
+ }
300976
+ }
300977
+ _dispatchItem(item) {
300978
+ const previousValue = this._value;
300979
+ this._value -= item.weight;
300980
+ item.resolve([previousValue, this._newReleaser(item.weight)]);
300981
+ }
300982
+ _newReleaser(weight) {
300983
+ let called = false;
300984
+ return () => {
300985
+ if (called)
300986
+ return;
300987
+ called = true;
300988
+ this.release(weight);
300989
+ };
300990
+ }
300991
+ _drainUnlockWaiters() {
300992
+ if (this._queue.length === 0) {
300993
+ for (let weight = this._value;weight > 0; weight--) {
300994
+ const waiters = this._weightedWaiters[weight - 1];
300995
+ if (!waiters)
300996
+ continue;
300997
+ waiters.forEach((waiter) => waiter.resolve());
300998
+ this._weightedWaiters[weight - 1] = [];
300999
+ }
301000
+ } else {
301001
+ const queuedPriority = this._queue[0].priority;
301002
+ for (let weight = this._value;weight > 0; weight--) {
301003
+ const waiters = this._weightedWaiters[weight - 1];
301004
+ if (!waiters)
301005
+ continue;
301006
+ const i3 = waiters.findIndex((waiter) => waiter.priority <= queuedPriority);
301007
+ (i3 === -1 ? waiters : waiters.splice(0, i3)).forEach((waiter) => waiter.resolve());
301008
+ }
301009
+ }
301010
+ }
301011
+ _couldLockImmediately(weight, priority) {
301012
+ return (this._queue.length === 0 || this._queue[0].priority < priority) && weight <= this._value;
301013
+ }
301014
+ }
301015
+ function insertSorted(a2, v2) {
301016
+ const i3 = findIndexFromEnd(a2, (other) => v2.priority <= other.priority);
301017
+ a2.splice(i3 + 1, 0, v2);
301018
+ }
301019
+ function findIndexFromEnd(a2, predicate) {
301020
+ for (let i3 = a2.length - 1;i3 >= 0; i3--) {
301021
+ if (predicate(a2[i3])) {
301022
+ return i3;
301023
+ }
301024
+ }
301025
+ return -1;
301026
+ }
301027
+
301028
+ class Mutex {
301029
+ constructor(cancelError) {
301030
+ this._semaphore = new Semaphore(1, cancelError);
301031
+ }
301032
+ acquire() {
301033
+ return __awaiter$1(this, arguments, undefined, function* (priority = 0) {
301034
+ const [, releaser] = yield this._semaphore.acquire(1, priority);
301035
+ return releaser;
301036
+ });
301037
+ }
301038
+ runExclusive(callback, priority = 0) {
301039
+ return this._semaphore.runExclusive(() => callback(), 1, priority);
301040
+ }
301041
+ isLocked() {
301042
+ return this._semaphore.isLocked();
301043
+ }
301044
+ waitForUnlock(priority = 0) {
301045
+ return this._semaphore.waitForUnlock(1, priority);
301046
+ }
301047
+ release() {
301048
+ if (this._semaphore.isLocked())
301049
+ this._semaphore.release();
301050
+ }
301051
+ cancel() {
301052
+ return this._semaphore.cancel();
301053
+ }
301054
+ }
301055
+ var E_TIMEOUT, E_ALREADY_LOCKED, E_CANCELED, __awaiter$2 = function(thisArg, _arguments, P2, generator) {
301056
+ function adopt(value) {
301057
+ return value instanceof P2 ? value : new P2(function(resolve28) {
301058
+ resolve28(value);
301059
+ });
301060
+ }
301061
+ return new (P2 || (P2 = Promise))(function(resolve28, reject2) {
301062
+ function fulfilled(value) {
301063
+ try {
301064
+ step(generator.next(value));
301065
+ } catch (e) {
301066
+ reject2(e);
301067
+ }
301068
+ }
301069
+ function rejected(value) {
301070
+ try {
301071
+ step(generator["throw"](value));
301072
+ } catch (e) {
301073
+ reject2(e);
301074
+ }
301075
+ }
301076
+ function step(result) {
301077
+ result.done ? resolve28(result.value) : adopt(result.value).then(fulfilled, rejected);
301078
+ }
301079
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
301080
+ });
301081
+ }, __awaiter$1 = function(thisArg, _arguments, P2, generator) {
301082
+ function adopt(value) {
301083
+ return value instanceof P2 ? value : new P2(function(resolve28) {
301084
+ resolve28(value);
301085
+ });
301086
+ }
301087
+ return new (P2 || (P2 = Promise))(function(resolve28, reject2) {
301088
+ function fulfilled(value) {
301089
+ try {
301090
+ step(generator.next(value));
301091
+ } catch (e) {
301092
+ reject2(e);
301093
+ }
301094
+ }
301095
+ function rejected(value) {
301096
+ try {
301097
+ step(generator["throw"](value));
301098
+ } catch (e) {
301099
+ reject2(e);
301100
+ }
301101
+ }
301102
+ function step(result) {
301103
+ result.done ? resolve28(result.value) : adopt(result.value).then(fulfilled, rejected);
301104
+ }
301105
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
301106
+ });
301107
+ };
301108
+ var init_async_mutex = __esm(() => {
301109
+ E_TIMEOUT = new Error("timeout while waiting for mutex to become available");
301110
+ E_ALREADY_LOCKED = new Error("mutex already locked");
301111
+ E_CANCELED = new Error("request for lock canceled");
301112
+ });
301113
+
300879
301114
  // src/services/api/grove.ts
300880
301115
  function memoizeWithTTL(fn, ttlMs) {
300881
301116
  let lastCachedAt = 0;
@@ -300891,12 +301126,15 @@ function memoizeWithTTL(fn, ttlMs) {
300891
301126
  const result = await memoized(...args);
300892
301127
  if (result && typeof result === "object" && "success" in result && result.success === true) {
300893
301128
  lastCachedAt = Date.now();
301129
+ } else if (result && typeof result === "object" && "success" in result && result.success === false) {
301130
+ originalClear();
301131
+ lastCachedAt = 0;
300894
301132
  }
300895
301133
  return result;
300896
301134
  } catch (error49) {
300897
301135
  originalClear();
300898
- lastCachedAt = 0;
300899
- throw error49;
301136
+ lastCachedAt = -1;
301137
+ return { success: false };
300900
301138
  }
300901
301139
  };
300902
301140
  wrapped.cache = {
@@ -300972,13 +301210,12 @@ async function isQualifiedForGrove() {
300972
301210
  return cachedEntry.grove_enabled;
300973
301211
  }
300974
301212
  async function fetchAndStoreGroveConfig(accountId) {
300975
- let releaseLock;
300976
- const lockPromise = new Promise((resolve28) => {
300977
- releaseLock = resolve28;
300978
- });
300979
- const previous = groveConfigLocks.get(accountId) ?? Promise.resolve();
300980
- groveConfigLocks.set(accountId, lockPromise);
300981
- await previous;
301213
+ let mutex = groveConfigMutexes.get(accountId);
301214
+ if (!mutex) {
301215
+ mutex = new Mutex;
301216
+ groveConfigMutexes.set(accountId, mutex);
301217
+ }
301218
+ const release = await mutex.acquire();
300982
301219
  try {
300983
301220
  const result = await getGroveNoticeConfig();
300984
301221
  if (!result.success) {
@@ -301002,10 +301239,7 @@ async function fetchAndStoreGroveConfig(accountId) {
301002
301239
  } catch (err2) {
301003
301240
  logForDebugging(`Grove: Failed to fetch and store config: ${err2}`);
301004
301241
  } finally {
301005
- releaseLock();
301006
- if (groveConfigLocks.get(accountId) === lockPromise) {
301007
- groveConfigLocks.delete(accountId);
301008
- }
301242
+ release();
301009
301243
  }
301010
301244
  }
301011
301245
  function calculateShouldShowGrove(settingsResult, configResult, showIfAlreadyViewed) {
@@ -301059,7 +301293,7 @@ An update to our Consumer Terms and Privacy Policy will take effect on October 8
301059
301293
  }
301060
301294
  }
301061
301295
  }
301062
- var groveConfigLocks, GROVE_CACHE_EXPIRATION_MS, GROVE_API_TIMEOUT_MS, getGroveSettings, getGroveNoticeConfig;
301296
+ var groveConfigMutexes, GROVE_CACHE_EXPIRATION_MS, GROVE_API_TIMEOUT_MS, getGroveSettings, getGroveNoticeConfig;
301063
301297
  var init_grove = __esm(() => {
301064
301298
  init_axios2();
301065
301299
  init_memoize();
@@ -301071,7 +301305,8 @@ var init_grove = __esm(() => {
301071
301305
  init_config();
301072
301306
  init_http2();
301073
301307
  init_log3();
301074
- groveConfigLocks = new Map;
301308
+ init_async_mutex();
301309
+ groveConfigMutexes = new Map;
301075
301310
  GROVE_CACHE_EXPIRATION_MS = 24 * 60 * 60 * 1000;
301076
301311
  GROVE_API_TIMEOUT_MS = parseInt(process.env.GROVE_API_TIMEOUT_MS ?? "3000", 10);
301077
301312
  getGroveSettings = memoizeWithTTL(async () => {
@@ -342110,17 +342345,20 @@ async function appendSessionLogImpl(sessionId, entry, url3, headers) {
342110
342345
  logForDebugging(`Session 409: adopting server lastUuid=${serverLastUuid} from header, retrying entry ${entry.uuid}`);
342111
342346
  } else {
342112
342347
  const sequentialFetch = getOrCreateSequentialFetch(sessionId);
342113
- const logs2 = await sequentialFetch(sessionId, url3, headers);
342348
+ let logs2 = null;
342349
+ try {
342350
+ logs2 = await sequentialFetch(sessionId, url3, headers);
342351
+ } catch (fetchError) {
342352
+ logError2(new Error(`Session 409: fetch failed for session ${sessionId}, entry ${entry.uuid}: ${fetchError instanceof Error ? fetchError.message : String(fetchError)}`));
342353
+ logForDiagnosticsNoPII("error", "session_persist_409_fetch_fail");
342354
+ }
342114
342355
  const adoptedUuid = findLastUuid(logs2);
342115
342356
  if (adoptedUuid) {
342116
342357
  lastUuidMap.set(sessionId, adoptedUuid);
342117
342358
  logForDebugging(`Session 409: re-fetched ${logs2.length} entries, adopting lastUuid=${adoptedUuid}, retrying entry ${entry.uuid}`);
342118
342359
  } else {
342119
- const errorData = response.data;
342120
- const errorMessage2 = errorData.error?.message || "Concurrent modification detected";
342121
- logError2(new Error(`Session persistence conflict: UUID mismatch for session ${sessionId}, entry ${entry.uuid}. ${errorMessage2}`));
342122
- logForDiagnosticsNoPII("error", "session_persist_fail_concurrent_modification");
342123
- return false;
342360
+ logForDebugging(`Session 409: could not determine server state for session ${sessionId}, entry ${entry.uuid}`);
342361
+ logForDiagnosticsNoPII("warn", "session_persist_409_no_adopted_uuid");
342124
342362
  }
342125
342363
  }
342126
342364
  logForDiagnosticsNoPII("info", "session_persist_409_adopt_server_uuid");
@@ -342137,10 +342375,11 @@ async function appendSessionLogImpl(sessionId, entry, url3, headers) {
342137
342375
  attempt
342138
342376
  });
342139
342377
  } catch (error49) {
342140
- const axiosError = error49;
342141
- logError2(new Error(`Error persisting session log: ${axiosError.message}`));
342378
+ const errorMessage2 = error49 instanceof Error ? error49.message : String(error49);
342379
+ const axiosStatus = error49 && typeof error49 === "object" && "status" in error49 ? error49.status : undefined;
342380
+ logError2(new Error(`Error persisting session log: ${errorMessage2}`));
342142
342381
  logForDiagnosticsNoPII("error", "session_persist_fail_status", {
342143
- status: axiosError.status,
342382
+ status: axiosStatus,
342144
342383
  attempt
342145
342384
  });
342146
342385
  }
@@ -348844,7 +349083,7 @@ var require_semaphore = __commonJS((exports) => {
348844
349083
  exports.Semaphore = undefined;
348845
349084
  var ral_1 = require_ral();
348846
349085
 
348847
- class Semaphore {
349086
+ class Semaphore2 {
348848
349087
  constructor(capacity = 1) {
348849
349088
  if (capacity <= 0) {
348850
349089
  throw new Error("Capacity must be greater than 0");
@@ -348901,7 +349140,7 @@ var require_semaphore = __commonJS((exports) => {
348901
349140
  }
348902
349141
  }
348903
349142
  }
348904
- exports.Semaphore = Semaphore;
349143
+ exports.Semaphore = Semaphore2;
348905
349144
  });
348906
349145
 
348907
349146
  // node_modules/vscode-jsonrpc/lib/common/messageReader.js
@@ -453615,7 +453854,11 @@ async function fetchAndStorePassesEligibility() {
453615
453854
  logForDebugging("Passes: Reusing in-flight eligibility fetch");
453616
453855
  return fetchInProgress;
453617
453856
  }
453618
- fetchInProgress = (async () => {
453857
+ let resolvePromise;
453858
+ fetchInProgress = new Promise((resolve47) => {
453859
+ resolvePromise = resolve47;
453860
+ });
453861
+ (async () => {
453619
453862
  try {
453620
453863
  const response = await fetchReferralEligibility();
453621
453864
  const cacheEntry = {
@@ -453630,11 +453873,11 @@ async function fetchAndStorePassesEligibility() {
453630
453873
  }
453631
453874
  }));
453632
453875
  logForDebugging(`Passes eligibility cached for org ${orgId}: ${response.eligible}`);
453633
- return response;
453876
+ resolvePromise(response);
453634
453877
  } catch (error49) {
453635
453878
  logForDebugging("Failed to fetch and cache passes eligibility");
453636
453879
  logError2(error49);
453637
- return null;
453880
+ resolvePromise(null);
453638
453881
  } finally {
453639
453882
  fetchInProgress = null;
453640
453883
  }
package/dist/myclaude.mjs 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.89",
8
- BUILD_TIME: "2026-07-17T12:20:44.184Z",
7
+ VERSION: "0.1.91",
8
+ BUILD_TIME: "2026-07-17T20:20:49.267Z",
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.89",
117487
+ version: "0.1.91",
117488
117488
  private: false,
117489
117489
  description: "An open-source AI coding assistant in your terminal - powered by Claude",
117490
117490
  license: "MIT",
@@ -117548,6 +117548,7 @@ var init_package = __esm(() => {
117548
117548
  "@opentelemetry/semantic-conventions": "1.40.0",
117549
117549
  ajv: "8.18.0",
117550
117550
  asciichart: "1.5.25",
117551
+ "async-mutex": "^0.5.0",
117551
117552
  "auto-bind": "5.0.1",
117552
117553
  axios: "1.14.0",
117553
117554
  "bidi-js": "1.0.3",
@@ -210162,7 +210163,7 @@ function enqueueDumpRequest(agentIdOrSessionId, callback) {
210162
210163
  processQueue(agentIdOrSessionId);
210163
210164
  }
210164
210165
  }
210165
- function processQueue(agentIdOrSessionId) {
210166
+ async function processQueue(agentIdOrSessionId) {
210166
210167
  processingQueues.add(agentIdOrSessionId);
210167
210168
  const queue = dumpRequestQueue.get(agentIdOrSessionId);
210168
210169
  if (!queue || queue.length === 0) {
@@ -210171,7 +210172,7 @@ function processQueue(agentIdOrSessionId) {
210171
210172
  return;
210172
210173
  }
210173
210174
  const callback = queue.shift();
210174
- callback();
210175
+ await callback();
210175
210176
  if (queue.length > 0) {
210176
210177
  setImmediate(() => processQueue(agentIdOrSessionId));
210177
210178
  } else {
@@ -210202,14 +210203,17 @@ function addApiRequestToCache(requestData) {
210202
210203
  function getDumpPromptsPath(agentIdOrSessionId) {
210203
210204
  return join48(getClaudeConfigHomeDir(), "dump-prompts", `${agentIdOrSessionId ?? getSessionId()}.jsonl`);
210204
210205
  }
210205
- function appendToFile(filePath, entries) {
210206
+ async function appendToFile(filePath, entries) {
210206
210207
  if (entries.length === 0)
210207
210208
  return;
210208
- fs11.mkdir(dirname27(filePath), { recursive: true }).then(() => fs11.appendFile(filePath, entries.join(`
210209
+ try {
210210
+ await fs11.mkdir(dirname27(filePath), { recursive: true });
210211
+ await fs11.appendFile(filePath, entries.join(`
210209
210212
  `) + `
210210
- `)).catch((err2) => {
210213
+ `);
210214
+ } catch (err2) {
210211
210215
  logForDebugging(`dumpPrompts.appendToFile error: ${err2}`, { level: "error" });
210212
- });
210216
+ }
210213
210217
  }
210214
210218
  function initFingerprint(req) {
210215
210219
  const tools = req.tools;
@@ -210218,7 +210222,7 @@ function initFingerprint(req) {
210218
210222
  const toolNames = tools?.map((t) => t.name ?? "").join(",") ?? "";
210219
210223
  return `${req.model}|${toolNames}|${sysLen}`;
210220
210224
  }
210221
- function dumpRequest(body, ts, state, filePath) {
210225
+ async function dumpRequest(body, ts, state, filePath) {
210222
210226
  try {
210223
210227
  const req = jsonParse(body);
210224
210228
  addApiRequestToCache(req);
@@ -210256,7 +210260,7 @@ function dumpRequest(body, ts, state, filePath) {
210256
210260
  }
210257
210261
  }
210258
210262
  state.messageCountSeen = messages.length;
210259
- appendToFile(filePath, entries);
210263
+ await appendToFile(filePath, entries);
210260
210264
  } catch (err2) {
210261
210265
  logForDebugging(`dumpPrompts.dumpRequest error: ${err2}`, { level: "error" });
210262
210266
  }
@@ -210274,8 +210278,8 @@ function createDumpPromptsFetch(agentIdOrSessionId) {
210274
210278
  let timestamp;
210275
210279
  if (init2?.method === "POST" && init2.body) {
210276
210280
  timestamp = new Date().toISOString();
210277
- enqueueDumpRequest(agentIdOrSessionId, () => {
210278
- dumpRequest(init2.body, timestamp, state, filePath);
210281
+ enqueueDumpRequest(agentIdOrSessionId, async () => {
210282
+ await dumpRequest(init2.body, timestamp, state, filePath);
210279
210283
  });
210280
210284
  }
210281
210285
  const response = await globalThis.fetch(input, init2);
@@ -210289,27 +210293,50 @@ function createDumpPromptsFetch(agentIdOrSessionId) {
210289
210293
  const reader = cloned.body.getReader();
210290
210294
  const decoder = new TextDecoder;
210291
210295
  let buffer = "";
210296
+ const chunks = [];
210292
210297
  try {
210293
210298
  while (true) {
210294
210299
  const { done, value } = await reader.read();
210295
210300
  if (done)
210296
210301
  break;
210297
210302
  buffer += decoder.decode(value, { stream: true });
210303
+ const lastDoubleNewline = buffer.lastIndexOf(`
210304
+
210305
+ `);
210306
+ if (lastDoubleNewline !== -1) {
210307
+ const completeEvents = buffer.slice(0, lastDoubleNewline);
210308
+ buffer = buffer.slice(lastDoubleNewline + 2);
210309
+ for (const event of completeEvents.split(`
210310
+
210311
+ `)) {
210312
+ for (const line of event.split(`
210313
+ `)) {
210314
+ if (line.startsWith("data: ") && line !== "data: [DONE]") {
210315
+ try {
210316
+ chunks.push(jsonParse(line.slice(6)));
210317
+ } catch (err2) {
210318
+ logForDebugging(`dumpPrompts.SSE parse error: ${err2}`, { level: "error" });
210319
+ }
210320
+ }
210321
+ }
210322
+ }
210323
+ }
210298
210324
  }
210299
210325
  } finally {
210300
210326
  reader.releaseLock();
210301
210327
  }
210302
- const chunks = [];
210303
- for (const event of buffer.split(`
210328
+ if (buffer.trim()) {
210329
+ for (const event of buffer.split(`
210304
210330
 
210305
210331
  `)) {
210306
- for (const line of event.split(`
210332
+ for (const line of event.split(`
210307
210333
  `)) {
210308
- if (line.startsWith("data: ") && line !== "data: [DONE]") {
210309
- try {
210310
- chunks.push(jsonParse(line.slice(6)));
210311
- } catch (err2) {
210312
- logForDebugging(`dumpPrompts.SSE parse error: ${err2}`, { level: "error" });
210334
+ if (line.startsWith("data: ") && line !== "data: [DONE]") {
210335
+ try {
210336
+ chunks.push(jsonParse(line.slice(6)));
210337
+ } catch (err2) {
210338
+ logForDebugging(`dumpPrompts.SSE parse error: ${err2}`, { level: "error" });
210339
+ }
210313
210340
  }
210314
210341
  }
210315
210342
  }
@@ -300876,6 +300903,214 @@ var init_gracefulShutdown = __esm(() => {
300876
300903
  };
300877
300904
  });
300878
300905
 
300906
+ // node_modules/async-mutex/index.mjs
300907
+ class Semaphore {
300908
+ constructor(_value, _cancelError = E_CANCELED) {
300909
+ this._value = _value;
300910
+ this._cancelError = _cancelError;
300911
+ this._queue = [];
300912
+ this._weightedWaiters = [];
300913
+ }
300914
+ acquire(weight = 1, priority = 0) {
300915
+ if (weight <= 0)
300916
+ throw new Error(`invalid weight ${weight}: must be positive`);
300917
+ return new Promise((resolve28, reject2) => {
300918
+ const task = { resolve: resolve28, reject: reject2, weight, priority };
300919
+ const i3 = findIndexFromEnd(this._queue, (other) => priority <= other.priority);
300920
+ if (i3 === -1 && weight <= this._value) {
300921
+ this._dispatchItem(task);
300922
+ } else {
300923
+ this._queue.splice(i3 + 1, 0, task);
300924
+ }
300925
+ });
300926
+ }
300927
+ runExclusive(callback_1) {
300928
+ return __awaiter$2(this, arguments, undefined, function* (callback, weight = 1, priority = 0) {
300929
+ const [value, release] = yield this.acquire(weight, priority);
300930
+ try {
300931
+ return yield callback(value);
300932
+ } finally {
300933
+ release();
300934
+ }
300935
+ });
300936
+ }
300937
+ waitForUnlock(weight = 1, priority = 0) {
300938
+ if (weight <= 0)
300939
+ throw new Error(`invalid weight ${weight}: must be positive`);
300940
+ if (this._couldLockImmediately(weight, priority)) {
300941
+ return Promise.resolve();
300942
+ } else {
300943
+ return new Promise((resolve28) => {
300944
+ if (!this._weightedWaiters[weight - 1])
300945
+ this._weightedWaiters[weight - 1] = [];
300946
+ insertSorted(this._weightedWaiters[weight - 1], { resolve: resolve28, priority });
300947
+ });
300948
+ }
300949
+ }
300950
+ isLocked() {
300951
+ return this._value <= 0;
300952
+ }
300953
+ getValue() {
300954
+ return this._value;
300955
+ }
300956
+ setValue(value) {
300957
+ this._value = value;
300958
+ this._dispatchQueue();
300959
+ }
300960
+ release(weight = 1) {
300961
+ if (weight <= 0)
300962
+ throw new Error(`invalid weight ${weight}: must be positive`);
300963
+ this._value += weight;
300964
+ this._dispatchQueue();
300965
+ }
300966
+ cancel() {
300967
+ this._queue.forEach((entry) => entry.reject(this._cancelError));
300968
+ this._queue = [];
300969
+ }
300970
+ _dispatchQueue() {
300971
+ this._drainUnlockWaiters();
300972
+ while (this._queue.length > 0 && this._queue[0].weight <= this._value) {
300973
+ this._dispatchItem(this._queue.shift());
300974
+ this._drainUnlockWaiters();
300975
+ }
300976
+ }
300977
+ _dispatchItem(item) {
300978
+ const previousValue = this._value;
300979
+ this._value -= item.weight;
300980
+ item.resolve([previousValue, this._newReleaser(item.weight)]);
300981
+ }
300982
+ _newReleaser(weight) {
300983
+ let called = false;
300984
+ return () => {
300985
+ if (called)
300986
+ return;
300987
+ called = true;
300988
+ this.release(weight);
300989
+ };
300990
+ }
300991
+ _drainUnlockWaiters() {
300992
+ if (this._queue.length === 0) {
300993
+ for (let weight = this._value;weight > 0; weight--) {
300994
+ const waiters = this._weightedWaiters[weight - 1];
300995
+ if (!waiters)
300996
+ continue;
300997
+ waiters.forEach((waiter) => waiter.resolve());
300998
+ this._weightedWaiters[weight - 1] = [];
300999
+ }
301000
+ } else {
301001
+ const queuedPriority = this._queue[0].priority;
301002
+ for (let weight = this._value;weight > 0; weight--) {
301003
+ const waiters = this._weightedWaiters[weight - 1];
301004
+ if (!waiters)
301005
+ continue;
301006
+ const i3 = waiters.findIndex((waiter) => waiter.priority <= queuedPriority);
301007
+ (i3 === -1 ? waiters : waiters.splice(0, i3)).forEach((waiter) => waiter.resolve());
301008
+ }
301009
+ }
301010
+ }
301011
+ _couldLockImmediately(weight, priority) {
301012
+ return (this._queue.length === 0 || this._queue[0].priority < priority) && weight <= this._value;
301013
+ }
301014
+ }
301015
+ function insertSorted(a2, v2) {
301016
+ const i3 = findIndexFromEnd(a2, (other) => v2.priority <= other.priority);
301017
+ a2.splice(i3 + 1, 0, v2);
301018
+ }
301019
+ function findIndexFromEnd(a2, predicate) {
301020
+ for (let i3 = a2.length - 1;i3 >= 0; i3--) {
301021
+ if (predicate(a2[i3])) {
301022
+ return i3;
301023
+ }
301024
+ }
301025
+ return -1;
301026
+ }
301027
+
301028
+ class Mutex {
301029
+ constructor(cancelError) {
301030
+ this._semaphore = new Semaphore(1, cancelError);
301031
+ }
301032
+ acquire() {
301033
+ return __awaiter$1(this, arguments, undefined, function* (priority = 0) {
301034
+ const [, releaser] = yield this._semaphore.acquire(1, priority);
301035
+ return releaser;
301036
+ });
301037
+ }
301038
+ runExclusive(callback, priority = 0) {
301039
+ return this._semaphore.runExclusive(() => callback(), 1, priority);
301040
+ }
301041
+ isLocked() {
301042
+ return this._semaphore.isLocked();
301043
+ }
301044
+ waitForUnlock(priority = 0) {
301045
+ return this._semaphore.waitForUnlock(1, priority);
301046
+ }
301047
+ release() {
301048
+ if (this._semaphore.isLocked())
301049
+ this._semaphore.release();
301050
+ }
301051
+ cancel() {
301052
+ return this._semaphore.cancel();
301053
+ }
301054
+ }
301055
+ var E_TIMEOUT, E_ALREADY_LOCKED, E_CANCELED, __awaiter$2 = function(thisArg, _arguments, P2, generator) {
301056
+ function adopt(value) {
301057
+ return value instanceof P2 ? value : new P2(function(resolve28) {
301058
+ resolve28(value);
301059
+ });
301060
+ }
301061
+ return new (P2 || (P2 = Promise))(function(resolve28, reject2) {
301062
+ function fulfilled(value) {
301063
+ try {
301064
+ step(generator.next(value));
301065
+ } catch (e) {
301066
+ reject2(e);
301067
+ }
301068
+ }
301069
+ function rejected(value) {
301070
+ try {
301071
+ step(generator["throw"](value));
301072
+ } catch (e) {
301073
+ reject2(e);
301074
+ }
301075
+ }
301076
+ function step(result) {
301077
+ result.done ? resolve28(result.value) : adopt(result.value).then(fulfilled, rejected);
301078
+ }
301079
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
301080
+ });
301081
+ }, __awaiter$1 = function(thisArg, _arguments, P2, generator) {
301082
+ function adopt(value) {
301083
+ return value instanceof P2 ? value : new P2(function(resolve28) {
301084
+ resolve28(value);
301085
+ });
301086
+ }
301087
+ return new (P2 || (P2 = Promise))(function(resolve28, reject2) {
301088
+ function fulfilled(value) {
301089
+ try {
301090
+ step(generator.next(value));
301091
+ } catch (e) {
301092
+ reject2(e);
301093
+ }
301094
+ }
301095
+ function rejected(value) {
301096
+ try {
301097
+ step(generator["throw"](value));
301098
+ } catch (e) {
301099
+ reject2(e);
301100
+ }
301101
+ }
301102
+ function step(result) {
301103
+ result.done ? resolve28(result.value) : adopt(result.value).then(fulfilled, rejected);
301104
+ }
301105
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
301106
+ });
301107
+ };
301108
+ var init_async_mutex = __esm(() => {
301109
+ E_TIMEOUT = new Error("timeout while waiting for mutex to become available");
301110
+ E_ALREADY_LOCKED = new Error("mutex already locked");
301111
+ E_CANCELED = new Error("request for lock canceled");
301112
+ });
301113
+
300879
301114
  // src/services/api/grove.ts
300880
301115
  function memoizeWithTTL(fn, ttlMs) {
300881
301116
  let lastCachedAt = 0;
@@ -300891,12 +301126,15 @@ function memoizeWithTTL(fn, ttlMs) {
300891
301126
  const result = await memoized(...args);
300892
301127
  if (result && typeof result === "object" && "success" in result && result.success === true) {
300893
301128
  lastCachedAt = Date.now();
301129
+ } else if (result && typeof result === "object" && "success" in result && result.success === false) {
301130
+ originalClear();
301131
+ lastCachedAt = 0;
300894
301132
  }
300895
301133
  return result;
300896
301134
  } catch (error49) {
300897
301135
  originalClear();
300898
- lastCachedAt = 0;
300899
- throw error49;
301136
+ lastCachedAt = -1;
301137
+ return { success: false };
300900
301138
  }
300901
301139
  };
300902
301140
  wrapped.cache = {
@@ -300972,13 +301210,12 @@ async function isQualifiedForGrove() {
300972
301210
  return cachedEntry.grove_enabled;
300973
301211
  }
300974
301212
  async function fetchAndStoreGroveConfig(accountId) {
300975
- let releaseLock;
300976
- const lockPromise = new Promise((resolve28) => {
300977
- releaseLock = resolve28;
300978
- });
300979
- const previous = groveConfigLocks.get(accountId) ?? Promise.resolve();
300980
- groveConfigLocks.set(accountId, lockPromise);
300981
- await previous;
301213
+ let mutex = groveConfigMutexes.get(accountId);
301214
+ if (!mutex) {
301215
+ mutex = new Mutex;
301216
+ groveConfigMutexes.set(accountId, mutex);
301217
+ }
301218
+ const release = await mutex.acquire();
300982
301219
  try {
300983
301220
  const result = await getGroveNoticeConfig();
300984
301221
  if (!result.success) {
@@ -301002,10 +301239,7 @@ async function fetchAndStoreGroveConfig(accountId) {
301002
301239
  } catch (err2) {
301003
301240
  logForDebugging(`Grove: Failed to fetch and store config: ${err2}`);
301004
301241
  } finally {
301005
- releaseLock();
301006
- if (groveConfigLocks.get(accountId) === lockPromise) {
301007
- groveConfigLocks.delete(accountId);
301008
- }
301242
+ release();
301009
301243
  }
301010
301244
  }
301011
301245
  function calculateShouldShowGrove(settingsResult, configResult, showIfAlreadyViewed) {
@@ -301059,7 +301293,7 @@ An update to our Consumer Terms and Privacy Policy will take effect on October 8
301059
301293
  }
301060
301294
  }
301061
301295
  }
301062
- var groveConfigLocks, GROVE_CACHE_EXPIRATION_MS, GROVE_API_TIMEOUT_MS, getGroveSettings, getGroveNoticeConfig;
301296
+ var groveConfigMutexes, GROVE_CACHE_EXPIRATION_MS, GROVE_API_TIMEOUT_MS, getGroveSettings, getGroveNoticeConfig;
301063
301297
  var init_grove = __esm(() => {
301064
301298
  init_axios2();
301065
301299
  init_memoize();
@@ -301071,7 +301305,8 @@ var init_grove = __esm(() => {
301071
301305
  init_config();
301072
301306
  init_http2();
301073
301307
  init_log3();
301074
- groveConfigLocks = new Map;
301308
+ init_async_mutex();
301309
+ groveConfigMutexes = new Map;
301075
301310
  GROVE_CACHE_EXPIRATION_MS = 24 * 60 * 60 * 1000;
301076
301311
  GROVE_API_TIMEOUT_MS = parseInt(process.env.GROVE_API_TIMEOUT_MS ?? "3000", 10);
301077
301312
  getGroveSettings = memoizeWithTTL(async () => {
@@ -342110,17 +342345,20 @@ async function appendSessionLogImpl(sessionId, entry, url3, headers) {
342110
342345
  logForDebugging(`Session 409: adopting server lastUuid=${serverLastUuid} from header, retrying entry ${entry.uuid}`);
342111
342346
  } else {
342112
342347
  const sequentialFetch = getOrCreateSequentialFetch(sessionId);
342113
- const logs2 = await sequentialFetch(sessionId, url3, headers);
342348
+ let logs2 = null;
342349
+ try {
342350
+ logs2 = await sequentialFetch(sessionId, url3, headers);
342351
+ } catch (fetchError) {
342352
+ logError2(new Error(`Session 409: fetch failed for session ${sessionId}, entry ${entry.uuid}: ${fetchError instanceof Error ? fetchError.message : String(fetchError)}`));
342353
+ logForDiagnosticsNoPII("error", "session_persist_409_fetch_fail");
342354
+ }
342114
342355
  const adoptedUuid = findLastUuid(logs2);
342115
342356
  if (adoptedUuid) {
342116
342357
  lastUuidMap.set(sessionId, adoptedUuid);
342117
342358
  logForDebugging(`Session 409: re-fetched ${logs2.length} entries, adopting lastUuid=${adoptedUuid}, retrying entry ${entry.uuid}`);
342118
342359
  } else {
342119
- const errorData = response.data;
342120
- const errorMessage2 = errorData.error?.message || "Concurrent modification detected";
342121
- logError2(new Error(`Session persistence conflict: UUID mismatch for session ${sessionId}, entry ${entry.uuid}. ${errorMessage2}`));
342122
- logForDiagnosticsNoPII("error", "session_persist_fail_concurrent_modification");
342123
- return false;
342360
+ logForDebugging(`Session 409: could not determine server state for session ${sessionId}, entry ${entry.uuid}`);
342361
+ logForDiagnosticsNoPII("warn", "session_persist_409_no_adopted_uuid");
342124
342362
  }
342125
342363
  }
342126
342364
  logForDiagnosticsNoPII("info", "session_persist_409_adopt_server_uuid");
@@ -342137,10 +342375,11 @@ async function appendSessionLogImpl(sessionId, entry, url3, headers) {
342137
342375
  attempt
342138
342376
  });
342139
342377
  } catch (error49) {
342140
- const axiosError = error49;
342141
- logError2(new Error(`Error persisting session log: ${axiosError.message}`));
342378
+ const errorMessage2 = error49 instanceof Error ? error49.message : String(error49);
342379
+ const axiosStatus = error49 && typeof error49 === "object" && "status" in error49 ? error49.status : undefined;
342380
+ logError2(new Error(`Error persisting session log: ${errorMessage2}`));
342142
342381
  logForDiagnosticsNoPII("error", "session_persist_fail_status", {
342143
- status: axiosError.status,
342382
+ status: axiosStatus,
342144
342383
  attempt
342145
342384
  });
342146
342385
  }
@@ -348844,7 +349083,7 @@ var require_semaphore = __commonJS((exports) => {
348844
349083
  exports.Semaphore = undefined;
348845
349084
  var ral_1 = require_ral();
348846
349085
 
348847
- class Semaphore {
349086
+ class Semaphore2 {
348848
349087
  constructor(capacity = 1) {
348849
349088
  if (capacity <= 0) {
348850
349089
  throw new Error("Capacity must be greater than 0");
@@ -348901,7 +349140,7 @@ var require_semaphore = __commonJS((exports) => {
348901
349140
  }
348902
349141
  }
348903
349142
  }
348904
- exports.Semaphore = Semaphore;
349143
+ exports.Semaphore = Semaphore2;
348905
349144
  });
348906
349145
 
348907
349146
  // node_modules/vscode-jsonrpc/lib/common/messageReader.js
@@ -453615,7 +453854,11 @@ async function fetchAndStorePassesEligibility() {
453615
453854
  logForDebugging("Passes: Reusing in-flight eligibility fetch");
453616
453855
  return fetchInProgress;
453617
453856
  }
453618
- fetchInProgress = (async () => {
453857
+ let resolvePromise;
453858
+ fetchInProgress = new Promise((resolve47) => {
453859
+ resolvePromise = resolve47;
453860
+ });
453861
+ (async () => {
453619
453862
  try {
453620
453863
  const response = await fetchReferralEligibility();
453621
453864
  const cacheEntry = {
@@ -453630,11 +453873,11 @@ async function fetchAndStorePassesEligibility() {
453630
453873
  }
453631
453874
  }));
453632
453875
  logForDebugging(`Passes eligibility cached for org ${orgId}: ${response.eligible}`);
453633
- return response;
453876
+ resolvePromise(response);
453634
453877
  } catch (error49) {
453635
453878
  logForDebugging("Failed to fetch and cache passes eligibility");
453636
453879
  logError2(error49);
453637
- return null;
453880
+ resolvePromise(null);
453638
453881
  } finally {
453639
453882
  fetchInProgress = null;
453640
453883
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@funnycode/myclaude",
3
- "version": "0.1.89",
3
+ "version": "0.1.91",
4
4
  "private": false,
5
5
  "description": "An open-source AI coding assistant in your terminal - powered by Claude",
6
6
  "license": "MIT",
@@ -64,6 +64,7 @@
64
64
  "@opentelemetry/semantic-conventions": "1.40.0",
65
65
  "ajv": "8.18.0",
66
66
  "asciichart": "1.5.25",
67
+ "async-mutex": "^0.5.0",
67
68
  "auto-bind": "5.0.1",
68
69
  "axios": "1.14.0",
69
70
  "bidi-js": "1.0.3",