@funnycode/myclaude 0.1.120 → 0.1.121

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.120",
8
- BUILD_TIME: "2026-07-22T22:27:16.931Z",
7
+ VERSION: "0.1.121",
8
+ BUILD_TIME: "2026-07-23T00:30:43.487Z",
9
9
  PACKAGE_URL: "@funnycode/myclaude",
10
10
  NATIVE_PACKAGE_URL: "@funnycode/myclaude",
11
11
  VERSION_CHANGELOG: '',
@@ -117790,7 +117790,7 @@ var package_default;
117790
117790
  var init_package = __esm(() => {
117791
117791
  package_default = {
117792
117792
  name: "@funnycode/myclaude",
117793
- version: "0.1.120",
117793
+ version: "0.1.121",
117794
117794
  private: false,
117795
117795
  description: "An open-source AI coding assistant in your terminal - powered by Claude",
117796
117796
  license: "MIT",
@@ -210421,6 +210421,214 @@ var init_postSamplingHooks = __esm(() => {
210421
210421
  postSamplingHooks = [];
210422
210422
  });
210423
210423
 
210424
+ // node_modules/async-mutex/index.mjs
210425
+ class Semaphore {
210426
+ constructor(_value, _cancelError = E_CANCELED) {
210427
+ this._value = _value;
210428
+ this._cancelError = _cancelError;
210429
+ this._queue = [];
210430
+ this._weightedWaiters = [];
210431
+ }
210432
+ acquire(weight = 1, priority = 0) {
210433
+ if (weight <= 0)
210434
+ throw new Error(`invalid weight ${weight}: must be positive`);
210435
+ return new Promise((resolve25, reject2) => {
210436
+ const task = { resolve: resolve25, reject: reject2, weight, priority };
210437
+ const i3 = findIndexFromEnd(this._queue, (other) => priority <= other.priority);
210438
+ if (i3 === -1 && weight <= this._value) {
210439
+ this._dispatchItem(task);
210440
+ } else {
210441
+ this._queue.splice(i3 + 1, 0, task);
210442
+ }
210443
+ });
210444
+ }
210445
+ runExclusive(callback_1) {
210446
+ return __awaiter$2(this, arguments, undefined, function* (callback, weight = 1, priority = 0) {
210447
+ const [value, release] = yield this.acquire(weight, priority);
210448
+ try {
210449
+ return yield callback(value);
210450
+ } finally {
210451
+ release();
210452
+ }
210453
+ });
210454
+ }
210455
+ waitForUnlock(weight = 1, priority = 0) {
210456
+ if (weight <= 0)
210457
+ throw new Error(`invalid weight ${weight}: must be positive`);
210458
+ if (this._couldLockImmediately(weight, priority)) {
210459
+ return Promise.resolve();
210460
+ } else {
210461
+ return new Promise((resolve25) => {
210462
+ if (!this._weightedWaiters[weight - 1])
210463
+ this._weightedWaiters[weight - 1] = [];
210464
+ insertSorted(this._weightedWaiters[weight - 1], { resolve: resolve25, priority });
210465
+ });
210466
+ }
210467
+ }
210468
+ isLocked() {
210469
+ return this._value <= 0;
210470
+ }
210471
+ getValue() {
210472
+ return this._value;
210473
+ }
210474
+ setValue(value) {
210475
+ this._value = value;
210476
+ this._dispatchQueue();
210477
+ }
210478
+ release(weight = 1) {
210479
+ if (weight <= 0)
210480
+ throw new Error(`invalid weight ${weight}: must be positive`);
210481
+ this._value += weight;
210482
+ this._dispatchQueue();
210483
+ }
210484
+ cancel() {
210485
+ this._queue.forEach((entry) => entry.reject(this._cancelError));
210486
+ this._queue = [];
210487
+ }
210488
+ _dispatchQueue() {
210489
+ this._drainUnlockWaiters();
210490
+ while (this._queue.length > 0 && this._queue[0].weight <= this._value) {
210491
+ this._dispatchItem(this._queue.shift());
210492
+ this._drainUnlockWaiters();
210493
+ }
210494
+ }
210495
+ _dispatchItem(item) {
210496
+ const previousValue = this._value;
210497
+ this._value -= item.weight;
210498
+ item.resolve([previousValue, this._newReleaser(item.weight)]);
210499
+ }
210500
+ _newReleaser(weight) {
210501
+ let called = false;
210502
+ return () => {
210503
+ if (called)
210504
+ return;
210505
+ called = true;
210506
+ this.release(weight);
210507
+ };
210508
+ }
210509
+ _drainUnlockWaiters() {
210510
+ if (this._queue.length === 0) {
210511
+ for (let weight = this._value;weight > 0; weight--) {
210512
+ const waiters = this._weightedWaiters[weight - 1];
210513
+ if (!waiters)
210514
+ continue;
210515
+ waiters.forEach((waiter) => waiter.resolve());
210516
+ this._weightedWaiters[weight - 1] = [];
210517
+ }
210518
+ } else {
210519
+ const queuedPriority = this._queue[0].priority;
210520
+ for (let weight = this._value;weight > 0; weight--) {
210521
+ const waiters = this._weightedWaiters[weight - 1];
210522
+ if (!waiters)
210523
+ continue;
210524
+ const i3 = waiters.findIndex((waiter) => waiter.priority <= queuedPriority);
210525
+ (i3 === -1 ? waiters : waiters.splice(0, i3)).forEach((waiter) => waiter.resolve());
210526
+ }
210527
+ }
210528
+ }
210529
+ _couldLockImmediately(weight, priority) {
210530
+ return (this._queue.length === 0 || this._queue[0].priority < priority) && weight <= this._value;
210531
+ }
210532
+ }
210533
+ function insertSorted(a2, v2) {
210534
+ const i3 = findIndexFromEnd(a2, (other) => v2.priority <= other.priority);
210535
+ a2.splice(i3 + 1, 0, v2);
210536
+ }
210537
+ function findIndexFromEnd(a2, predicate) {
210538
+ for (let i3 = a2.length - 1;i3 >= 0; i3--) {
210539
+ if (predicate(a2[i3])) {
210540
+ return i3;
210541
+ }
210542
+ }
210543
+ return -1;
210544
+ }
210545
+
210546
+ class Mutex {
210547
+ constructor(cancelError) {
210548
+ this._semaphore = new Semaphore(1, cancelError);
210549
+ }
210550
+ acquire() {
210551
+ return __awaiter$1(this, arguments, undefined, function* (priority = 0) {
210552
+ const [, releaser] = yield this._semaphore.acquire(1, priority);
210553
+ return releaser;
210554
+ });
210555
+ }
210556
+ runExclusive(callback, priority = 0) {
210557
+ return this._semaphore.runExclusive(() => callback(), 1, priority);
210558
+ }
210559
+ isLocked() {
210560
+ return this._semaphore.isLocked();
210561
+ }
210562
+ waitForUnlock(priority = 0) {
210563
+ return this._semaphore.waitForUnlock(1, priority);
210564
+ }
210565
+ release() {
210566
+ if (this._semaphore.isLocked())
210567
+ this._semaphore.release();
210568
+ }
210569
+ cancel() {
210570
+ return this._semaphore.cancel();
210571
+ }
210572
+ }
210573
+ var E_TIMEOUT, E_ALREADY_LOCKED, E_CANCELED, __awaiter$2 = function(thisArg, _arguments, P2, generator) {
210574
+ function adopt(value) {
210575
+ return value instanceof P2 ? value : new P2(function(resolve25) {
210576
+ resolve25(value);
210577
+ });
210578
+ }
210579
+ return new (P2 || (P2 = Promise))(function(resolve25, reject2) {
210580
+ function fulfilled(value) {
210581
+ try {
210582
+ step(generator.next(value));
210583
+ } catch (e) {
210584
+ reject2(e);
210585
+ }
210586
+ }
210587
+ function rejected(value) {
210588
+ try {
210589
+ step(generator["throw"](value));
210590
+ } catch (e) {
210591
+ reject2(e);
210592
+ }
210593
+ }
210594
+ function step(result) {
210595
+ result.done ? resolve25(result.value) : adopt(result.value).then(fulfilled, rejected);
210596
+ }
210597
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
210598
+ });
210599
+ }, __awaiter$1 = function(thisArg, _arguments, P2, generator) {
210600
+ function adopt(value) {
210601
+ return value instanceof P2 ? value : new P2(function(resolve25) {
210602
+ resolve25(value);
210603
+ });
210604
+ }
210605
+ return new (P2 || (P2 = Promise))(function(resolve25, reject2) {
210606
+ function fulfilled(value) {
210607
+ try {
210608
+ step(generator.next(value));
210609
+ } catch (e) {
210610
+ reject2(e);
210611
+ }
210612
+ }
210613
+ function rejected(value) {
210614
+ try {
210615
+ step(generator["throw"](value));
210616
+ } catch (e) {
210617
+ reject2(e);
210618
+ }
210619
+ }
210620
+ function step(result) {
210621
+ result.done ? resolve25(result.value) : adopt(result.value).then(fulfilled, rejected);
210622
+ }
210623
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
210624
+ });
210625
+ };
210626
+ var init_async_mutex = __esm(() => {
210627
+ E_TIMEOUT = new Error("timeout while waiting for mutex to become available");
210628
+ E_ALREADY_LOCKED = new Error("mutex already locked");
210629
+ E_CANCELED = new Error("request for lock canceled");
210630
+ });
210631
+
210424
210632
  // src/services/api/dumpPrompts.ts
210425
210633
  import { createHash as createHash5 } from "crypto";
210426
210634
  import { promises as fs11 } from "fs";
@@ -210450,28 +210658,34 @@ function enqueueDumpRequest(agentIdOrSessionId, callback) {
210450
210658
  dumpRequestQueue.set(agentIdOrSessionId, []);
210451
210659
  }
210452
210660
  dumpRequestQueue.get(agentIdOrSessionId).push(callback);
210453
- if (!processingPromises.has(agentIdOrSessionId)) {
210454
- const promise2 = (async () => {
210455
- while (true) {
210456
- const queue = dumpRequestQueue.get(agentIdOrSessionId);
210457
- if (!queue || queue.length === 0) {
210458
- break;
210459
- }
210460
- const cb = queue.shift();
210461
- try {
210462
- await cb();
210463
- } catch (err2) {
210464
- logForDebugging(`dumpPrompts.processQueue: callback threw: ${err2}`, { level: "error" });
210661
+ const mutex = enqueueMutexes.get(agentIdOrSessionId) ?? new Mutex;
210662
+ enqueueMutexes.set(agentIdOrSessionId, mutex);
210663
+ mutex.runExclusive(async () => {
210664
+ if (!processingPromises.has(agentIdOrSessionId)) {
210665
+ const promise2 = (async () => {
210666
+ while (true) {
210667
+ const queue = dumpRequestQueue.get(agentIdOrSessionId);
210668
+ if (!queue || queue.length === 0) {
210669
+ break;
210670
+ }
210671
+ const cb = queue.shift();
210672
+ try {
210673
+ await cb();
210674
+ } catch (err2) {
210675
+ logForDebugging(`dumpPrompts.processQueue: callback threw: ${err2}`, { level: "error" });
210676
+ }
210465
210677
  }
210466
- }
210467
- })().catch((err2) => {
210468
- logError2(`processQueue: failed for ${agentIdOrSessionId}`, err2);
210469
- dumpRequestQueue.delete(agentIdOrSessionId);
210470
- }).finally(() => {
210471
- processingPromises.delete(agentIdOrSessionId);
210472
- });
210473
- processingPromises.set(agentIdOrSessionId, promise2);
210474
- }
210678
+ })().catch((err2) => {
210679
+ logError2(`processQueue: failed for ${agentIdOrSessionId}`, err2);
210680
+ dumpRequestQueue.delete(agentIdOrSessionId);
210681
+ }).finally(() => {
210682
+ processingPromises.delete(agentIdOrSessionId);
210683
+ });
210684
+ processingPromises.set(agentIdOrSessionId, promise2);
210685
+ }
210686
+ }).catch((err2) => {
210687
+ logError2(`enqueueDumpRequest: mutex acquisition failed for ${agentIdOrSessionId}`, err2);
210688
+ });
210475
210689
  }
210476
210690
  function clearDumpState(agentIdOrSessionId) {
210477
210691
  dumpState.delete(agentIdOrSessionId);
@@ -210667,13 +210881,14 @@ function createDumpPromptsFetch(agentIdOrSessionId) {
210667
210881
  return response;
210668
210882
  };
210669
210883
  }
210670
- var MAX_CACHED_REQUESTS = 5, cachedApiRequests, dumpState, dumpRequestQueue, processingPromises;
210884
+ var MAX_CACHED_REQUESTS = 5, cachedApiRequests, dumpState, dumpRequestQueue, processingPromises, enqueueMutexes;
210671
210885
  var init_dumpPrompts = __esm(() => {
210672
210886
  init_state();
210673
210887
  init_envUtils();
210674
210888
  init_slowOperations();
210675
210889
  init_debug();
210676
210890
  init_log3();
210891
+ init_async_mutex();
210677
210892
  if (process.env.USER_TYPE === "ant" && process.env.DUMP_PROMPTS === "1") {
210678
210893
  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" });
210679
210894
  }
@@ -210681,6 +210896,7 @@ var init_dumpPrompts = __esm(() => {
210681
210896
  dumpState = new Map;
210682
210897
  dumpRequestQueue = new Map;
210683
210898
  processingPromises = new Map;
210899
+ enqueueMutexes = new Map;
210684
210900
  });
210685
210901
 
210686
210902
  // src/utils/abortController.ts
@@ -301374,214 +301590,6 @@ var init_gracefulShutdown = __esm(() => {
301374
301590
  };
301375
301591
  });
301376
301592
 
301377
- // node_modules/async-mutex/index.mjs
301378
- class Semaphore {
301379
- constructor(_value, _cancelError = E_CANCELED) {
301380
- this._value = _value;
301381
- this._cancelError = _cancelError;
301382
- this._queue = [];
301383
- this._weightedWaiters = [];
301384
- }
301385
- acquire(weight = 1, priority = 0) {
301386
- if (weight <= 0)
301387
- throw new Error(`invalid weight ${weight}: must be positive`);
301388
- return new Promise((resolve28, reject2) => {
301389
- const task = { resolve: resolve28, reject: reject2, weight, priority };
301390
- const i3 = findIndexFromEnd(this._queue, (other) => priority <= other.priority);
301391
- if (i3 === -1 && weight <= this._value) {
301392
- this._dispatchItem(task);
301393
- } else {
301394
- this._queue.splice(i3 + 1, 0, task);
301395
- }
301396
- });
301397
- }
301398
- runExclusive(callback_1) {
301399
- return __awaiter$2(this, arguments, undefined, function* (callback, weight = 1, priority = 0) {
301400
- const [value, release] = yield this.acquire(weight, priority);
301401
- try {
301402
- return yield callback(value);
301403
- } finally {
301404
- release();
301405
- }
301406
- });
301407
- }
301408
- waitForUnlock(weight = 1, priority = 0) {
301409
- if (weight <= 0)
301410
- throw new Error(`invalid weight ${weight}: must be positive`);
301411
- if (this._couldLockImmediately(weight, priority)) {
301412
- return Promise.resolve();
301413
- } else {
301414
- return new Promise((resolve28) => {
301415
- if (!this._weightedWaiters[weight - 1])
301416
- this._weightedWaiters[weight - 1] = [];
301417
- insertSorted(this._weightedWaiters[weight - 1], { resolve: resolve28, priority });
301418
- });
301419
- }
301420
- }
301421
- isLocked() {
301422
- return this._value <= 0;
301423
- }
301424
- getValue() {
301425
- return this._value;
301426
- }
301427
- setValue(value) {
301428
- this._value = value;
301429
- this._dispatchQueue();
301430
- }
301431
- release(weight = 1) {
301432
- if (weight <= 0)
301433
- throw new Error(`invalid weight ${weight}: must be positive`);
301434
- this._value += weight;
301435
- this._dispatchQueue();
301436
- }
301437
- cancel() {
301438
- this._queue.forEach((entry) => entry.reject(this._cancelError));
301439
- this._queue = [];
301440
- }
301441
- _dispatchQueue() {
301442
- this._drainUnlockWaiters();
301443
- while (this._queue.length > 0 && this._queue[0].weight <= this._value) {
301444
- this._dispatchItem(this._queue.shift());
301445
- this._drainUnlockWaiters();
301446
- }
301447
- }
301448
- _dispatchItem(item) {
301449
- const previousValue = this._value;
301450
- this._value -= item.weight;
301451
- item.resolve([previousValue, this._newReleaser(item.weight)]);
301452
- }
301453
- _newReleaser(weight) {
301454
- let called = false;
301455
- return () => {
301456
- if (called)
301457
- return;
301458
- called = true;
301459
- this.release(weight);
301460
- };
301461
- }
301462
- _drainUnlockWaiters() {
301463
- if (this._queue.length === 0) {
301464
- for (let weight = this._value;weight > 0; weight--) {
301465
- const waiters = this._weightedWaiters[weight - 1];
301466
- if (!waiters)
301467
- continue;
301468
- waiters.forEach((waiter) => waiter.resolve());
301469
- this._weightedWaiters[weight - 1] = [];
301470
- }
301471
- } else {
301472
- const queuedPriority = this._queue[0].priority;
301473
- for (let weight = this._value;weight > 0; weight--) {
301474
- const waiters = this._weightedWaiters[weight - 1];
301475
- if (!waiters)
301476
- continue;
301477
- const i3 = waiters.findIndex((waiter) => waiter.priority <= queuedPriority);
301478
- (i3 === -1 ? waiters : waiters.splice(0, i3)).forEach((waiter) => waiter.resolve());
301479
- }
301480
- }
301481
- }
301482
- _couldLockImmediately(weight, priority) {
301483
- return (this._queue.length === 0 || this._queue[0].priority < priority) && weight <= this._value;
301484
- }
301485
- }
301486
- function insertSorted(a2, v2) {
301487
- const i3 = findIndexFromEnd(a2, (other) => v2.priority <= other.priority);
301488
- a2.splice(i3 + 1, 0, v2);
301489
- }
301490
- function findIndexFromEnd(a2, predicate) {
301491
- for (let i3 = a2.length - 1;i3 >= 0; i3--) {
301492
- if (predicate(a2[i3])) {
301493
- return i3;
301494
- }
301495
- }
301496
- return -1;
301497
- }
301498
-
301499
- class Mutex {
301500
- constructor(cancelError) {
301501
- this._semaphore = new Semaphore(1, cancelError);
301502
- }
301503
- acquire() {
301504
- return __awaiter$1(this, arguments, undefined, function* (priority = 0) {
301505
- const [, releaser] = yield this._semaphore.acquire(1, priority);
301506
- return releaser;
301507
- });
301508
- }
301509
- runExclusive(callback, priority = 0) {
301510
- return this._semaphore.runExclusive(() => callback(), 1, priority);
301511
- }
301512
- isLocked() {
301513
- return this._semaphore.isLocked();
301514
- }
301515
- waitForUnlock(priority = 0) {
301516
- return this._semaphore.waitForUnlock(1, priority);
301517
- }
301518
- release() {
301519
- if (this._semaphore.isLocked())
301520
- this._semaphore.release();
301521
- }
301522
- cancel() {
301523
- return this._semaphore.cancel();
301524
- }
301525
- }
301526
- var E_TIMEOUT, E_ALREADY_LOCKED, E_CANCELED, __awaiter$2 = function(thisArg, _arguments, P2, generator) {
301527
- function adopt(value) {
301528
- return value instanceof P2 ? value : new P2(function(resolve28) {
301529
- resolve28(value);
301530
- });
301531
- }
301532
- return new (P2 || (P2 = Promise))(function(resolve28, reject2) {
301533
- function fulfilled(value) {
301534
- try {
301535
- step(generator.next(value));
301536
- } catch (e) {
301537
- reject2(e);
301538
- }
301539
- }
301540
- function rejected(value) {
301541
- try {
301542
- step(generator["throw"](value));
301543
- } catch (e) {
301544
- reject2(e);
301545
- }
301546
- }
301547
- function step(result) {
301548
- result.done ? resolve28(result.value) : adopt(result.value).then(fulfilled, rejected);
301549
- }
301550
- step((generator = generator.apply(thisArg, _arguments || [])).next());
301551
- });
301552
- }, __awaiter$1 = function(thisArg, _arguments, P2, generator) {
301553
- function adopt(value) {
301554
- return value instanceof P2 ? value : new P2(function(resolve28) {
301555
- resolve28(value);
301556
- });
301557
- }
301558
- return new (P2 || (P2 = Promise))(function(resolve28, reject2) {
301559
- function fulfilled(value) {
301560
- try {
301561
- step(generator.next(value));
301562
- } catch (e) {
301563
- reject2(e);
301564
- }
301565
- }
301566
- function rejected(value) {
301567
- try {
301568
- step(generator["throw"](value));
301569
- } catch (e) {
301570
- reject2(e);
301571
- }
301572
- }
301573
- function step(result) {
301574
- result.done ? resolve28(result.value) : adopt(result.value).then(fulfilled, rejected);
301575
- }
301576
- step((generator = generator.apply(thisArg, _arguments || [])).next());
301577
- });
301578
- };
301579
- var init_async_mutex = __esm(() => {
301580
- E_TIMEOUT = new Error("timeout while waiting for mutex to become available");
301581
- E_ALREADY_LOCKED = new Error("mutex already locked");
301582
- E_CANCELED = new Error("request for lock canceled");
301583
- });
301584
-
301585
301593
  // src/services/api/grove.ts
301586
301594
  function memoizeWithTTL(fn, ttlMs) {
301587
301595
  let lastCachedAt = 0;
@@ -301619,7 +301627,7 @@ function memoizeWithTTL(fn, ttlMs) {
301619
301627
  try {
301620
301628
  const freshResult = await Promise.race([fn(...args), timeoutPromise]);
301621
301629
  if (freshResult && typeof freshResult === "object" && "success" in freshResult && freshResult.success === true) {
301622
- originalClear();
301630
+ memoized.cache.delete(args[0]);
301623
301631
  memoized.cache.set(args[0], freshResult);
301624
301632
  lastCachedAt = Date.now();
301625
301633
  return freshResult;
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.120",
8
- BUILD_TIME: "2026-07-22T22:27:16.931Z",
7
+ VERSION: "0.1.121",
8
+ BUILD_TIME: "2026-07-23T00:30:43.487Z",
9
9
  PACKAGE_URL: "@funnycode/myclaude",
10
10
  NATIVE_PACKAGE_URL: "@funnycode/myclaude",
11
11
  VERSION_CHANGELOG: '',
@@ -117790,7 +117790,7 @@ var package_default;
117790
117790
  var init_package = __esm(() => {
117791
117791
  package_default = {
117792
117792
  name: "@funnycode/myclaude",
117793
- version: "0.1.120",
117793
+ version: "0.1.121",
117794
117794
  private: false,
117795
117795
  description: "An open-source AI coding assistant in your terminal - powered by Claude",
117796
117796
  license: "MIT",
@@ -210421,6 +210421,214 @@ var init_postSamplingHooks = __esm(() => {
210421
210421
  postSamplingHooks = [];
210422
210422
  });
210423
210423
 
210424
+ // node_modules/async-mutex/index.mjs
210425
+ class Semaphore {
210426
+ constructor(_value, _cancelError = E_CANCELED) {
210427
+ this._value = _value;
210428
+ this._cancelError = _cancelError;
210429
+ this._queue = [];
210430
+ this._weightedWaiters = [];
210431
+ }
210432
+ acquire(weight = 1, priority = 0) {
210433
+ if (weight <= 0)
210434
+ throw new Error(`invalid weight ${weight}: must be positive`);
210435
+ return new Promise((resolve25, reject2) => {
210436
+ const task = { resolve: resolve25, reject: reject2, weight, priority };
210437
+ const i3 = findIndexFromEnd(this._queue, (other) => priority <= other.priority);
210438
+ if (i3 === -1 && weight <= this._value) {
210439
+ this._dispatchItem(task);
210440
+ } else {
210441
+ this._queue.splice(i3 + 1, 0, task);
210442
+ }
210443
+ });
210444
+ }
210445
+ runExclusive(callback_1) {
210446
+ return __awaiter$2(this, arguments, undefined, function* (callback, weight = 1, priority = 0) {
210447
+ const [value, release] = yield this.acquire(weight, priority);
210448
+ try {
210449
+ return yield callback(value);
210450
+ } finally {
210451
+ release();
210452
+ }
210453
+ });
210454
+ }
210455
+ waitForUnlock(weight = 1, priority = 0) {
210456
+ if (weight <= 0)
210457
+ throw new Error(`invalid weight ${weight}: must be positive`);
210458
+ if (this._couldLockImmediately(weight, priority)) {
210459
+ return Promise.resolve();
210460
+ } else {
210461
+ return new Promise((resolve25) => {
210462
+ if (!this._weightedWaiters[weight - 1])
210463
+ this._weightedWaiters[weight - 1] = [];
210464
+ insertSorted(this._weightedWaiters[weight - 1], { resolve: resolve25, priority });
210465
+ });
210466
+ }
210467
+ }
210468
+ isLocked() {
210469
+ return this._value <= 0;
210470
+ }
210471
+ getValue() {
210472
+ return this._value;
210473
+ }
210474
+ setValue(value) {
210475
+ this._value = value;
210476
+ this._dispatchQueue();
210477
+ }
210478
+ release(weight = 1) {
210479
+ if (weight <= 0)
210480
+ throw new Error(`invalid weight ${weight}: must be positive`);
210481
+ this._value += weight;
210482
+ this._dispatchQueue();
210483
+ }
210484
+ cancel() {
210485
+ this._queue.forEach((entry) => entry.reject(this._cancelError));
210486
+ this._queue = [];
210487
+ }
210488
+ _dispatchQueue() {
210489
+ this._drainUnlockWaiters();
210490
+ while (this._queue.length > 0 && this._queue[0].weight <= this._value) {
210491
+ this._dispatchItem(this._queue.shift());
210492
+ this._drainUnlockWaiters();
210493
+ }
210494
+ }
210495
+ _dispatchItem(item) {
210496
+ const previousValue = this._value;
210497
+ this._value -= item.weight;
210498
+ item.resolve([previousValue, this._newReleaser(item.weight)]);
210499
+ }
210500
+ _newReleaser(weight) {
210501
+ let called = false;
210502
+ return () => {
210503
+ if (called)
210504
+ return;
210505
+ called = true;
210506
+ this.release(weight);
210507
+ };
210508
+ }
210509
+ _drainUnlockWaiters() {
210510
+ if (this._queue.length === 0) {
210511
+ for (let weight = this._value;weight > 0; weight--) {
210512
+ const waiters = this._weightedWaiters[weight - 1];
210513
+ if (!waiters)
210514
+ continue;
210515
+ waiters.forEach((waiter) => waiter.resolve());
210516
+ this._weightedWaiters[weight - 1] = [];
210517
+ }
210518
+ } else {
210519
+ const queuedPriority = this._queue[0].priority;
210520
+ for (let weight = this._value;weight > 0; weight--) {
210521
+ const waiters = this._weightedWaiters[weight - 1];
210522
+ if (!waiters)
210523
+ continue;
210524
+ const i3 = waiters.findIndex((waiter) => waiter.priority <= queuedPriority);
210525
+ (i3 === -1 ? waiters : waiters.splice(0, i3)).forEach((waiter) => waiter.resolve());
210526
+ }
210527
+ }
210528
+ }
210529
+ _couldLockImmediately(weight, priority) {
210530
+ return (this._queue.length === 0 || this._queue[0].priority < priority) && weight <= this._value;
210531
+ }
210532
+ }
210533
+ function insertSorted(a2, v2) {
210534
+ const i3 = findIndexFromEnd(a2, (other) => v2.priority <= other.priority);
210535
+ a2.splice(i3 + 1, 0, v2);
210536
+ }
210537
+ function findIndexFromEnd(a2, predicate) {
210538
+ for (let i3 = a2.length - 1;i3 >= 0; i3--) {
210539
+ if (predicate(a2[i3])) {
210540
+ return i3;
210541
+ }
210542
+ }
210543
+ return -1;
210544
+ }
210545
+
210546
+ class Mutex {
210547
+ constructor(cancelError) {
210548
+ this._semaphore = new Semaphore(1, cancelError);
210549
+ }
210550
+ acquire() {
210551
+ return __awaiter$1(this, arguments, undefined, function* (priority = 0) {
210552
+ const [, releaser] = yield this._semaphore.acquire(1, priority);
210553
+ return releaser;
210554
+ });
210555
+ }
210556
+ runExclusive(callback, priority = 0) {
210557
+ return this._semaphore.runExclusive(() => callback(), 1, priority);
210558
+ }
210559
+ isLocked() {
210560
+ return this._semaphore.isLocked();
210561
+ }
210562
+ waitForUnlock(priority = 0) {
210563
+ return this._semaphore.waitForUnlock(1, priority);
210564
+ }
210565
+ release() {
210566
+ if (this._semaphore.isLocked())
210567
+ this._semaphore.release();
210568
+ }
210569
+ cancel() {
210570
+ return this._semaphore.cancel();
210571
+ }
210572
+ }
210573
+ var E_TIMEOUT, E_ALREADY_LOCKED, E_CANCELED, __awaiter$2 = function(thisArg, _arguments, P2, generator) {
210574
+ function adopt(value) {
210575
+ return value instanceof P2 ? value : new P2(function(resolve25) {
210576
+ resolve25(value);
210577
+ });
210578
+ }
210579
+ return new (P2 || (P2 = Promise))(function(resolve25, reject2) {
210580
+ function fulfilled(value) {
210581
+ try {
210582
+ step(generator.next(value));
210583
+ } catch (e) {
210584
+ reject2(e);
210585
+ }
210586
+ }
210587
+ function rejected(value) {
210588
+ try {
210589
+ step(generator["throw"](value));
210590
+ } catch (e) {
210591
+ reject2(e);
210592
+ }
210593
+ }
210594
+ function step(result) {
210595
+ result.done ? resolve25(result.value) : adopt(result.value).then(fulfilled, rejected);
210596
+ }
210597
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
210598
+ });
210599
+ }, __awaiter$1 = function(thisArg, _arguments, P2, generator) {
210600
+ function adopt(value) {
210601
+ return value instanceof P2 ? value : new P2(function(resolve25) {
210602
+ resolve25(value);
210603
+ });
210604
+ }
210605
+ return new (P2 || (P2 = Promise))(function(resolve25, reject2) {
210606
+ function fulfilled(value) {
210607
+ try {
210608
+ step(generator.next(value));
210609
+ } catch (e) {
210610
+ reject2(e);
210611
+ }
210612
+ }
210613
+ function rejected(value) {
210614
+ try {
210615
+ step(generator["throw"](value));
210616
+ } catch (e) {
210617
+ reject2(e);
210618
+ }
210619
+ }
210620
+ function step(result) {
210621
+ result.done ? resolve25(result.value) : adopt(result.value).then(fulfilled, rejected);
210622
+ }
210623
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
210624
+ });
210625
+ };
210626
+ var init_async_mutex = __esm(() => {
210627
+ E_TIMEOUT = new Error("timeout while waiting for mutex to become available");
210628
+ E_ALREADY_LOCKED = new Error("mutex already locked");
210629
+ E_CANCELED = new Error("request for lock canceled");
210630
+ });
210631
+
210424
210632
  // src/services/api/dumpPrompts.ts
210425
210633
  import { createHash as createHash5 } from "crypto";
210426
210634
  import { promises as fs11 } from "fs";
@@ -210450,28 +210658,34 @@ function enqueueDumpRequest(agentIdOrSessionId, callback) {
210450
210658
  dumpRequestQueue.set(agentIdOrSessionId, []);
210451
210659
  }
210452
210660
  dumpRequestQueue.get(agentIdOrSessionId).push(callback);
210453
- if (!processingPromises.has(agentIdOrSessionId)) {
210454
- const promise2 = (async () => {
210455
- while (true) {
210456
- const queue = dumpRequestQueue.get(agentIdOrSessionId);
210457
- if (!queue || queue.length === 0) {
210458
- break;
210459
- }
210460
- const cb = queue.shift();
210461
- try {
210462
- await cb();
210463
- } catch (err2) {
210464
- logForDebugging(`dumpPrompts.processQueue: callback threw: ${err2}`, { level: "error" });
210661
+ const mutex = enqueueMutexes.get(agentIdOrSessionId) ?? new Mutex;
210662
+ enqueueMutexes.set(agentIdOrSessionId, mutex);
210663
+ mutex.runExclusive(async () => {
210664
+ if (!processingPromises.has(agentIdOrSessionId)) {
210665
+ const promise2 = (async () => {
210666
+ while (true) {
210667
+ const queue = dumpRequestQueue.get(agentIdOrSessionId);
210668
+ if (!queue || queue.length === 0) {
210669
+ break;
210670
+ }
210671
+ const cb = queue.shift();
210672
+ try {
210673
+ await cb();
210674
+ } catch (err2) {
210675
+ logForDebugging(`dumpPrompts.processQueue: callback threw: ${err2}`, { level: "error" });
210676
+ }
210465
210677
  }
210466
- }
210467
- })().catch((err2) => {
210468
- logError2(`processQueue: failed for ${agentIdOrSessionId}`, err2);
210469
- dumpRequestQueue.delete(agentIdOrSessionId);
210470
- }).finally(() => {
210471
- processingPromises.delete(agentIdOrSessionId);
210472
- });
210473
- processingPromises.set(agentIdOrSessionId, promise2);
210474
- }
210678
+ })().catch((err2) => {
210679
+ logError2(`processQueue: failed for ${agentIdOrSessionId}`, err2);
210680
+ dumpRequestQueue.delete(agentIdOrSessionId);
210681
+ }).finally(() => {
210682
+ processingPromises.delete(agentIdOrSessionId);
210683
+ });
210684
+ processingPromises.set(agentIdOrSessionId, promise2);
210685
+ }
210686
+ }).catch((err2) => {
210687
+ logError2(`enqueueDumpRequest: mutex acquisition failed for ${agentIdOrSessionId}`, err2);
210688
+ });
210475
210689
  }
210476
210690
  function clearDumpState(agentIdOrSessionId) {
210477
210691
  dumpState.delete(agentIdOrSessionId);
@@ -210667,13 +210881,14 @@ function createDumpPromptsFetch(agentIdOrSessionId) {
210667
210881
  return response;
210668
210882
  };
210669
210883
  }
210670
- var MAX_CACHED_REQUESTS = 5, cachedApiRequests, dumpState, dumpRequestQueue, processingPromises;
210884
+ var MAX_CACHED_REQUESTS = 5, cachedApiRequests, dumpState, dumpRequestQueue, processingPromises, enqueueMutexes;
210671
210885
  var init_dumpPrompts = __esm(() => {
210672
210886
  init_state();
210673
210887
  init_envUtils();
210674
210888
  init_slowOperations();
210675
210889
  init_debug();
210676
210890
  init_log3();
210891
+ init_async_mutex();
210677
210892
  if (process.env.USER_TYPE === "ant" && process.env.DUMP_PROMPTS === "1") {
210678
210893
  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" });
210679
210894
  }
@@ -210681,6 +210896,7 @@ var init_dumpPrompts = __esm(() => {
210681
210896
  dumpState = new Map;
210682
210897
  dumpRequestQueue = new Map;
210683
210898
  processingPromises = new Map;
210899
+ enqueueMutexes = new Map;
210684
210900
  });
210685
210901
 
210686
210902
  // src/utils/abortController.ts
@@ -301374,214 +301590,6 @@ var init_gracefulShutdown = __esm(() => {
301374
301590
  };
301375
301591
  });
301376
301592
 
301377
- // node_modules/async-mutex/index.mjs
301378
- class Semaphore {
301379
- constructor(_value, _cancelError = E_CANCELED) {
301380
- this._value = _value;
301381
- this._cancelError = _cancelError;
301382
- this._queue = [];
301383
- this._weightedWaiters = [];
301384
- }
301385
- acquire(weight = 1, priority = 0) {
301386
- if (weight <= 0)
301387
- throw new Error(`invalid weight ${weight}: must be positive`);
301388
- return new Promise((resolve28, reject2) => {
301389
- const task = { resolve: resolve28, reject: reject2, weight, priority };
301390
- const i3 = findIndexFromEnd(this._queue, (other) => priority <= other.priority);
301391
- if (i3 === -1 && weight <= this._value) {
301392
- this._dispatchItem(task);
301393
- } else {
301394
- this._queue.splice(i3 + 1, 0, task);
301395
- }
301396
- });
301397
- }
301398
- runExclusive(callback_1) {
301399
- return __awaiter$2(this, arguments, undefined, function* (callback, weight = 1, priority = 0) {
301400
- const [value, release] = yield this.acquire(weight, priority);
301401
- try {
301402
- return yield callback(value);
301403
- } finally {
301404
- release();
301405
- }
301406
- });
301407
- }
301408
- waitForUnlock(weight = 1, priority = 0) {
301409
- if (weight <= 0)
301410
- throw new Error(`invalid weight ${weight}: must be positive`);
301411
- if (this._couldLockImmediately(weight, priority)) {
301412
- return Promise.resolve();
301413
- } else {
301414
- return new Promise((resolve28) => {
301415
- if (!this._weightedWaiters[weight - 1])
301416
- this._weightedWaiters[weight - 1] = [];
301417
- insertSorted(this._weightedWaiters[weight - 1], { resolve: resolve28, priority });
301418
- });
301419
- }
301420
- }
301421
- isLocked() {
301422
- return this._value <= 0;
301423
- }
301424
- getValue() {
301425
- return this._value;
301426
- }
301427
- setValue(value) {
301428
- this._value = value;
301429
- this._dispatchQueue();
301430
- }
301431
- release(weight = 1) {
301432
- if (weight <= 0)
301433
- throw new Error(`invalid weight ${weight}: must be positive`);
301434
- this._value += weight;
301435
- this._dispatchQueue();
301436
- }
301437
- cancel() {
301438
- this._queue.forEach((entry) => entry.reject(this._cancelError));
301439
- this._queue = [];
301440
- }
301441
- _dispatchQueue() {
301442
- this._drainUnlockWaiters();
301443
- while (this._queue.length > 0 && this._queue[0].weight <= this._value) {
301444
- this._dispatchItem(this._queue.shift());
301445
- this._drainUnlockWaiters();
301446
- }
301447
- }
301448
- _dispatchItem(item) {
301449
- const previousValue = this._value;
301450
- this._value -= item.weight;
301451
- item.resolve([previousValue, this._newReleaser(item.weight)]);
301452
- }
301453
- _newReleaser(weight) {
301454
- let called = false;
301455
- return () => {
301456
- if (called)
301457
- return;
301458
- called = true;
301459
- this.release(weight);
301460
- };
301461
- }
301462
- _drainUnlockWaiters() {
301463
- if (this._queue.length === 0) {
301464
- for (let weight = this._value;weight > 0; weight--) {
301465
- const waiters = this._weightedWaiters[weight - 1];
301466
- if (!waiters)
301467
- continue;
301468
- waiters.forEach((waiter) => waiter.resolve());
301469
- this._weightedWaiters[weight - 1] = [];
301470
- }
301471
- } else {
301472
- const queuedPriority = this._queue[0].priority;
301473
- for (let weight = this._value;weight > 0; weight--) {
301474
- const waiters = this._weightedWaiters[weight - 1];
301475
- if (!waiters)
301476
- continue;
301477
- const i3 = waiters.findIndex((waiter) => waiter.priority <= queuedPriority);
301478
- (i3 === -1 ? waiters : waiters.splice(0, i3)).forEach((waiter) => waiter.resolve());
301479
- }
301480
- }
301481
- }
301482
- _couldLockImmediately(weight, priority) {
301483
- return (this._queue.length === 0 || this._queue[0].priority < priority) && weight <= this._value;
301484
- }
301485
- }
301486
- function insertSorted(a2, v2) {
301487
- const i3 = findIndexFromEnd(a2, (other) => v2.priority <= other.priority);
301488
- a2.splice(i3 + 1, 0, v2);
301489
- }
301490
- function findIndexFromEnd(a2, predicate) {
301491
- for (let i3 = a2.length - 1;i3 >= 0; i3--) {
301492
- if (predicate(a2[i3])) {
301493
- return i3;
301494
- }
301495
- }
301496
- return -1;
301497
- }
301498
-
301499
- class Mutex {
301500
- constructor(cancelError) {
301501
- this._semaphore = new Semaphore(1, cancelError);
301502
- }
301503
- acquire() {
301504
- return __awaiter$1(this, arguments, undefined, function* (priority = 0) {
301505
- const [, releaser] = yield this._semaphore.acquire(1, priority);
301506
- return releaser;
301507
- });
301508
- }
301509
- runExclusive(callback, priority = 0) {
301510
- return this._semaphore.runExclusive(() => callback(), 1, priority);
301511
- }
301512
- isLocked() {
301513
- return this._semaphore.isLocked();
301514
- }
301515
- waitForUnlock(priority = 0) {
301516
- return this._semaphore.waitForUnlock(1, priority);
301517
- }
301518
- release() {
301519
- if (this._semaphore.isLocked())
301520
- this._semaphore.release();
301521
- }
301522
- cancel() {
301523
- return this._semaphore.cancel();
301524
- }
301525
- }
301526
- var E_TIMEOUT, E_ALREADY_LOCKED, E_CANCELED, __awaiter$2 = function(thisArg, _arguments, P2, generator) {
301527
- function adopt(value) {
301528
- return value instanceof P2 ? value : new P2(function(resolve28) {
301529
- resolve28(value);
301530
- });
301531
- }
301532
- return new (P2 || (P2 = Promise))(function(resolve28, reject2) {
301533
- function fulfilled(value) {
301534
- try {
301535
- step(generator.next(value));
301536
- } catch (e) {
301537
- reject2(e);
301538
- }
301539
- }
301540
- function rejected(value) {
301541
- try {
301542
- step(generator["throw"](value));
301543
- } catch (e) {
301544
- reject2(e);
301545
- }
301546
- }
301547
- function step(result) {
301548
- result.done ? resolve28(result.value) : adopt(result.value).then(fulfilled, rejected);
301549
- }
301550
- step((generator = generator.apply(thisArg, _arguments || [])).next());
301551
- });
301552
- }, __awaiter$1 = function(thisArg, _arguments, P2, generator) {
301553
- function adopt(value) {
301554
- return value instanceof P2 ? value : new P2(function(resolve28) {
301555
- resolve28(value);
301556
- });
301557
- }
301558
- return new (P2 || (P2 = Promise))(function(resolve28, reject2) {
301559
- function fulfilled(value) {
301560
- try {
301561
- step(generator.next(value));
301562
- } catch (e) {
301563
- reject2(e);
301564
- }
301565
- }
301566
- function rejected(value) {
301567
- try {
301568
- step(generator["throw"](value));
301569
- } catch (e) {
301570
- reject2(e);
301571
- }
301572
- }
301573
- function step(result) {
301574
- result.done ? resolve28(result.value) : adopt(result.value).then(fulfilled, rejected);
301575
- }
301576
- step((generator = generator.apply(thisArg, _arguments || [])).next());
301577
- });
301578
- };
301579
- var init_async_mutex = __esm(() => {
301580
- E_TIMEOUT = new Error("timeout while waiting for mutex to become available");
301581
- E_ALREADY_LOCKED = new Error("mutex already locked");
301582
- E_CANCELED = new Error("request for lock canceled");
301583
- });
301584
-
301585
301593
  // src/services/api/grove.ts
301586
301594
  function memoizeWithTTL(fn, ttlMs) {
301587
301595
  let lastCachedAt = 0;
@@ -301619,7 +301627,7 @@ function memoizeWithTTL(fn, ttlMs) {
301619
301627
  try {
301620
301628
  const freshResult = await Promise.race([fn(...args), timeoutPromise]);
301621
301629
  if (freshResult && typeof freshResult === "object" && "success" in freshResult && freshResult.success === true) {
301622
- originalClear();
301630
+ memoized.cache.delete(args[0]);
301623
301631
  memoized.cache.set(args[0], freshResult);
301624
301632
  lastCachedAt = Date.now();
301625
301633
  return freshResult;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@funnycode/myclaude",
3
- "version": "0.1.120",
3
+ "version": "0.1.121",
4
4
  "private": false,
5
5
  "description": "An open-source AI coding assistant in your terminal - powered by Claude",
6
6
  "license": "MIT",