@prestyj/core 5.25.0 → 5.25.1

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/index.cjs CHANGED
@@ -48,6 +48,7 @@ __export(index_exports, {
48
48
  clearLocalDiscoveryCache: () => clearLocalDiscoveryCache,
49
49
  clearRuntimeModels: () => clearRuntimeModels,
50
50
  closeLogger: () => closeLogger,
51
+ compareClaudeCodeVersions: () => compareClaudeCodeVersions,
51
52
  createAutoUpdater: () => createAutoUpdater,
52
53
  decodeOggOpus: () => decodeOggOpus,
53
54
  discoverLocalModels: () => discoverLocalModels,
@@ -101,6 +102,7 @@ __export(index_exports, {
101
102
  probeEndpoint: () => probeEndpoint,
102
103
  providerStorageKeys: () => providerStorageKeys,
103
104
  readStoredBaseUrlSync: () => readStoredBaseUrlSync,
105
+ recordRequiredClaudeCodeVersion: () => recordRequiredClaudeCodeVersion,
104
106
  refreshAnthropicToken: () => refreshAnthropicToken,
105
107
  refreshGeminiToken: () => refreshGeminiToken,
106
108
  refreshKimiToken: () => refreshKimiToken,
@@ -365,7 +367,7 @@ async function refreshKimiToken(refreshToken) {
365
367
 
366
368
  // src/auth-storage.ts
367
369
  var import_promises4 = __toESM(require("fs/promises"), 1);
368
- var import_node_fs3 = require("fs");
370
+ var import_node_fs4 = require("fs");
369
371
  var import_node_crypto6 = __toESM(require("crypto"), 1);
370
372
 
371
373
  // src/oauth/anthropic.ts
@@ -391,6 +393,7 @@ async function generatePKCE() {
391
393
 
392
394
  // src/claude-code-version.ts
393
395
  var import_promises = __toESM(require("fs/promises"), 1);
396
+ var import_node_fs3 = require("fs");
394
397
  var import_node_path4 = __toESM(require("path"), 1);
395
398
 
396
399
  // src/logger.ts
@@ -518,19 +521,41 @@ function closeLogger(opts) {
518
521
 
519
522
  // src/claude-code-version.ts
520
523
  var NPM_LATEST_URL = "https://registry.npmjs.org/@anthropic-ai/claude-code/latest";
521
- var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
524
+ var CACHE_FRESH_MS = 60 * 60 * 1e3;
525
+ var CACHE_HARD_MS = 24 * 60 * 60 * 1e3;
522
526
  var FETCH_TIMEOUT_MS = 3e3;
523
- var FALLBACK_VERSION = "2.1.88";
527
+ var FALLBACK_VERSION = "2.1.280";
524
528
  var memoryCache = null;
525
529
  var inflight = null;
530
+ var backgroundRefresh = null;
531
+ var versionFloor = null;
526
532
  function cachePath() {
527
533
  return import_node_path4.default.join(getAppPaths().agentDir, "claude-code-version.json");
528
534
  }
535
+ function compareClaudeCodeVersions(a, b) {
536
+ const parse = (v) => v.split(".").map((part) => Number.parseInt(part, 10)).map((n) => Number.isFinite(n) ? n : 0);
537
+ const left = parse(a);
538
+ const right = parse(b);
539
+ for (let i = 0; i < Math.max(left.length, right.length); i += 1) {
540
+ const diff = (left[i] ?? 0) - (right[i] ?? 0);
541
+ if (diff !== 0) return diff;
542
+ }
543
+ return 0;
544
+ }
545
+ function applyFloor(version) {
546
+ if (!versionFloor) return version;
547
+ return compareClaudeCodeVersions(versionFloor, version) > 0 ? versionFloor : version;
548
+ }
529
549
  async function readDiskCache() {
530
550
  try {
531
551
  const raw = await import_promises.default.readFile(cachePath(), "utf-8");
532
552
  const parsed = JSON.parse(raw);
533
553
  if (typeof parsed.version === "string" && typeof parsed.fetchedAt === "number") {
554
+ if (typeof parsed.minVersion === "string") {
555
+ if (!versionFloor || compareClaudeCodeVersions(parsed.minVersion, versionFloor) > 0) {
556
+ versionFloor = parsed.minVersion;
557
+ }
558
+ }
534
559
  return parsed;
535
560
  }
536
561
  return null;
@@ -541,7 +566,11 @@ async function readDiskCache() {
541
566
  async function writeDiskCache(data) {
542
567
  try {
543
568
  await import_promises.default.mkdir(getAppPaths().agentDir, { recursive: true, mode: 448 });
544
- await import_promises.default.writeFile(cachePath(), JSON.stringify(data), { mode: 384 });
569
+ await import_promises.default.writeFile(
570
+ cachePath(),
571
+ JSON.stringify({ ...data, ...versionFloor ? { minVersion: versionFloor } : {} }),
572
+ { mode: 384 }
573
+ );
545
574
  } catch (err) {
546
575
  log(
547
576
  "WARN",
@@ -567,6 +596,19 @@ async function fetchLatest() {
567
596
  clearTimeout(timer);
568
597
  }
569
598
  }
599
+ function refreshInBackground() {
600
+ if (backgroundRefresh) return;
601
+ backgroundRefresh = (async () => {
602
+ const fetched = await fetchLatest();
603
+ if (fetched) {
604
+ await writeDiskCache({ version: fetched, fetchedAt: Date.now() });
605
+ memoryCache = { version: applyFloor(fetched), expiresAt: Date.now() + CACHE_FRESH_MS };
606
+ }
607
+ })().catch(() => {
608
+ }).finally(() => {
609
+ backgroundRefresh = null;
610
+ });
611
+ }
570
612
  async function getClaudeCodeVersion() {
571
613
  if (memoryCache && Date.now() < memoryCache.expiresAt) {
572
614
  return memoryCache.version;
@@ -574,18 +616,26 @@ async function getClaudeCodeVersion() {
574
616
  if (inflight) return inflight;
575
617
  inflight = (async () => {
576
618
  const disk = await readDiskCache();
577
- const diskFresh = disk && Date.now() - disk.fetchedAt < CACHE_TTL_MS;
578
- if (disk && diskFresh) {
579
- memoryCache = { version: disk.version, expiresAt: Date.now() + CACHE_TTL_MS };
580
- return disk.version;
619
+ const age = disk ? Date.now() - disk.fetchedAt : Infinity;
620
+ if (disk && age < CACHE_FRESH_MS) {
621
+ const version = applyFloor(disk.version);
622
+ memoryCache = { version, expiresAt: Date.now() + CACHE_FRESH_MS };
623
+ return version;
624
+ }
625
+ if (disk && age < CACHE_HARD_MS) {
626
+ const version = applyFloor(disk.version);
627
+ memoryCache = { version, expiresAt: Date.now() + 5 * 60 * 1e3 };
628
+ refreshInBackground();
629
+ return version;
581
630
  }
582
631
  const fetched = await fetchLatest();
583
632
  if (fetched) {
584
633
  await writeDiskCache({ version: fetched, fetchedAt: Date.now() });
585
- memoryCache = { version: fetched, expiresAt: Date.now() + CACHE_TTL_MS };
586
- return fetched;
634
+ const version = applyFloor(fetched);
635
+ memoryCache = { version, expiresAt: Date.now() + CACHE_FRESH_MS };
636
+ return version;
587
637
  }
588
- const resolved = disk?.version ?? FALLBACK_VERSION;
638
+ const resolved = applyFloor(disk?.version ?? FALLBACK_VERSION);
589
639
  memoryCache = { version: resolved, expiresAt: Date.now() + 5 * 60 * 1e3 };
590
640
  log(
591
641
  "WARN",
@@ -600,6 +650,44 @@ async function getClaudeCodeVersion() {
600
650
  inflight = null;
601
651
  }
602
652
  }
653
+ var REQUIRED_VERSION_PATTERN = /version\s+(\d+(?:\.\d+)+)\s+or\s+newer\s+is\s+required/i;
654
+ function recordRequiredClaudeCodeVersion(message) {
655
+ const required = REQUIRED_VERSION_PATTERN.exec(message ?? "")?.[1];
656
+ if (!required) return null;
657
+ if (versionFloor && compareClaudeCodeVersions(required, versionFloor) <= 0) return versionFloor;
658
+ versionFloor = required;
659
+ memoryCache = null;
660
+ log(
661
+ "WARN",
662
+ "claude-code-version",
663
+ `Provider requires Claude Code >= ${required}; pinning User-Agent floor`
664
+ );
665
+ try {
666
+ const dir = getAppPaths().agentDir;
667
+ (0, import_node_fs3.mkdirSync)(dir, { recursive: true, mode: 448 });
668
+ let existing = {};
669
+ try {
670
+ existing = JSON.parse((0, import_node_fs3.readFileSync)(cachePath(), "utf-8"));
671
+ } catch {
672
+ }
673
+ (0, import_node_fs3.writeFileSync)(
674
+ cachePath(),
675
+ JSON.stringify({
676
+ version: existing.version ?? required,
677
+ fetchedAt: existing.fetchedAt ?? 0,
678
+ minVersion: required
679
+ }),
680
+ { mode: 384 }
681
+ );
682
+ } catch (err) {
683
+ log(
684
+ "WARN",
685
+ "claude-code-version",
686
+ `Failed to persist required version: ${err instanceof Error ? err.message : String(err)}`
687
+ );
688
+ }
689
+ return required;
690
+ }
603
691
  async function getClaudeCliUserAgent() {
604
692
  const version = await getClaudeCodeVersion();
605
693
  return `claude-cli/${version} (external, cli)`;
@@ -1587,7 +1675,7 @@ function activeBaseUrlEntry(data, provider) {
1587
1675
  }
1588
1676
  function readStoredBaseUrlSync(authFile, provider) {
1589
1677
  try {
1590
- const data = JSON.parse((0, import_node_fs3.readFileSync)(authFile, "utf-8"));
1678
+ const data = JSON.parse((0, import_node_fs4.readFileSync)(authFile, "utf-8"));
1591
1679
  return activeBaseUrlEntry(data, provider)?.baseUrl;
1592
1680
  } catch {
1593
1681
  return void 0;
@@ -2870,7 +2958,7 @@ var FALLBACK_CONTEXT_WINDOW = 4096;
2870
2958
  var LOCAL_API_KEY_PLACEHOLDER = "local";
2871
2959
  var DEFAULT_PROBE_TIMEOUT_MS = 1200;
2872
2960
  var ENRICH_CONCURRENCY = 6;
2873
- var CACHE_TTL_MS2 = 3e4;
2961
+ var CACHE_TTL_MS = 3e4;
2874
2962
  var NON_CHAT_ID_PATTERN = /(?:^|[-_/])(?:embed|embedding|rerank|reranker|bge|nomic-embed)/i;
2875
2963
  var LOCAL_ID_PREFIX = "local/";
2876
2964
  function formatLocalModelId(endpointId, rawId) {
@@ -3111,7 +3199,7 @@ function cacheKey(endpoints) {
3111
3199
  }
3112
3200
  async function discoverLocalModels(endpoints = DEFAULT_LOCAL_ENDPOINTS, options = {}) {
3113
3201
  const key = cacheKey(endpoints);
3114
- if (!options.force && cache && cache.key === key && Date.now() - cache.at < CACHE_TTL_MS2) {
3202
+ if (!options.force && cache && cache.key === key && Date.now() - cache.at < CACHE_TTL_MS) {
3115
3203
  return cache.result;
3116
3204
  }
3117
3205
  const probes = await Promise.all(endpoints.map((endpoint) => probeEndpoint(endpoint, options)));
@@ -3684,7 +3772,7 @@ async function transcribeVoice(fileUrl) {
3684
3772
 
3685
3773
  // src/auto-update.ts
3686
3774
  var import_node_child_process2 = require("child_process");
3687
- var import_node_fs4 = __toESM(require("fs"), 1);
3775
+ var import_node_fs5 = __toESM(require("fs"), 1);
3688
3776
  var import_node_path5 = __toESM(require("path"), 1);
3689
3777
  var CHECK_INTERVAL_MS = 60 * 60 * 1e3;
3690
3778
  var FETCH_TIMEOUT_MS2 = 1e4;
@@ -3718,7 +3806,7 @@ function createAutoUpdater(config) {
3718
3806
  }
3719
3807
  function readState() {
3720
3808
  try {
3721
- const raw = import_node_fs4.default.readFileSync(stateFilePath(), "utf-8");
3809
+ const raw = import_node_fs5.default.readFileSync(stateFilePath(), "utf-8");
3722
3810
  return JSON.parse(raw);
3723
3811
  } catch {
3724
3812
  return null;
@@ -3727,8 +3815,8 @@ function createAutoUpdater(config) {
3727
3815
  function writeState(state) {
3728
3816
  try {
3729
3817
  const filePath = stateFilePath();
3730
- import_node_fs4.default.mkdirSync(import_node_path5.default.dirname(filePath), { recursive: true, mode: 448 });
3731
- import_node_fs4.default.writeFileSync(filePath, JSON.stringify(state));
3818
+ import_node_fs5.default.mkdirSync(import_node_path5.default.dirname(filePath), { recursive: true, mode: 448 });
3819
+ import_node_fs5.default.writeFileSync(filePath, JSON.stringify(state));
3732
3820
  } catch {
3733
3821
  }
3734
3822
  }
@@ -3870,6 +3958,7 @@ function createAutoUpdater(config) {
3870
3958
  clearLocalDiscoveryCache,
3871
3959
  clearRuntimeModels,
3872
3960
  closeLogger,
3961
+ compareClaudeCodeVersions,
3873
3962
  createAutoUpdater,
3874
3963
  decodeOggOpus,
3875
3964
  discoverLocalModels,
@@ -3923,6 +4012,7 @@ function createAutoUpdater(config) {
3923
4012
  probeEndpoint,
3924
4013
  providerStorageKeys,
3925
4014
  readStoredBaseUrlSync,
4015
+ recordRequiredClaudeCodeVersion,
3926
4016
  refreshAnthropicToken,
3927
4017
  refreshGeminiToken,
3928
4018
  refreshKimiToken,