token-goat 2.9.28 → 2.9.30

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.
Files changed (134) hide show
  1. package/README.md +36 -40
  2. package/SECURITY.md +28 -10
  3. package/THIRD_PARTY_NOTICES.md +40 -3
  4. package/dist/native/linux-arm64/tg-hook +0 -0
  5. package/dist/native/linux-x64/tg-hook +0 -0
  6. package/dist/ort-wasm-simd-threaded.mjs +59 -0
  7. package/dist/token-goat-chunk-3CHUNJ2O.mjs +53 -0
  8. package/dist/token-goat-chunk-3Z5S4KGM.mjs +918 -0
  9. package/dist/token-goat-chunk-4FVIAHSI.mjs +211 -0
  10. package/dist/{token-goat-chunk-66LODAUT.mjs → token-goat-chunk-4JJS54TR.mjs} +4 -3
  11. package/dist/token-goat-chunk-4LCCNRTG.mjs +313 -0
  12. package/dist/token-goat-chunk-54K3EUV3.mjs +35 -0
  13. package/dist/token-goat-chunk-56EIMS3E.mjs +159 -0
  14. package/dist/token-goat-chunk-5BCIJXMO.mjs +609 -0
  15. package/dist/token-goat-chunk-5KDMCMF2.mjs +362 -0
  16. package/dist/token-goat-chunk-5RG5SBL6.mjs +221 -0
  17. package/dist/{token-goat-chunk-RRNZMM3A.mjs → token-goat-chunk-5Y6ZYL6U.mjs} +21 -2
  18. package/dist/{token-goat-chunk-NILVK7XM.mjs → token-goat-chunk-64FBPDTK.mjs} +12 -6
  19. package/dist/{token-goat-chunk-LEG3JNJ6.mjs → token-goat-chunk-664RTTUV.mjs} +31 -15
  20. package/dist/token-goat-chunk-67TQJ76B.mjs +57 -0
  21. package/dist/token-goat-chunk-6QMAS7AB.mjs +42 -0
  22. package/dist/token-goat-chunk-7BXSNBY5.mjs +253 -0
  23. package/dist/{token-goat-chunk-F7QZRIWM.mjs → token-goat-chunk-7F2UBPD3.mjs} +42 -35
  24. package/dist/{token-goat-chunk-CC2PYJM7.mjs → token-goat-chunk-7IN2MKDS.mjs} +718 -595
  25. package/dist/token-goat-chunk-7NADEDKJ.mjs +124 -0
  26. package/dist/{token-goat-chunk-6SGLIPQB.mjs → token-goat-chunk-A3CK6N5Z.mjs} +621 -72
  27. package/dist/{token-goat-chunk-HXNAC4ZF.mjs → token-goat-chunk-AFLYLHDH.mjs} +48 -33
  28. package/dist/token-goat-chunk-AM5V6GSX.mjs +367 -0
  29. package/dist/{token-goat-chunk-I7CB3X4K.mjs → token-goat-chunk-APGZXSPS.mjs} +44 -148
  30. package/dist/{token-goat-chunk-BJBRGPBX.mjs → token-goat-chunk-ARDNEC2U.mjs} +11 -7
  31. package/dist/token-goat-chunk-ATCPY7EQ.mjs +134 -0
  32. package/dist/token-goat-chunk-B2RZZCSS.mjs +354 -0
  33. package/dist/{token-goat-chunk-QM76S6YS.mjs → token-goat-chunk-B45VMIIH.mjs} +6 -5
  34. package/dist/token-goat-chunk-BPGCUMR7.mjs +30 -0
  35. package/dist/{token-goat-chunk-GGLEE35R.mjs → token-goat-chunk-C63JQV5K.mjs} +49 -10
  36. package/dist/{token-goat-chunk-RJH64KQH.mjs → token-goat-chunk-COBQGL5S.mjs} +2661 -2440
  37. package/dist/token-goat-chunk-COTXZHTS.mjs +39 -0
  38. package/dist/token-goat-chunk-CYCEYAEO.mjs +265 -0
  39. package/dist/token-goat-chunk-CZ3LUXYZ.mjs +4115 -0
  40. package/dist/token-goat-chunk-DZX2YDPT.mjs +15 -0
  41. package/dist/token-goat-chunk-E3OQX2XT.mjs +824 -0
  42. package/dist/token-goat-chunk-EFHMMIGP.mjs +68 -0
  43. package/dist/token-goat-chunk-ETBHVDB6.mjs +328 -0
  44. package/dist/token-goat-chunk-EVMZJ27Z.mjs +147 -0
  45. package/dist/token-goat-chunk-EXKGNHEG.mjs +2096 -0
  46. package/dist/{token-goat-chunk-6Z5ULNE5.mjs → token-goat-chunk-FBNQNSJK.mjs} +2490 -4957
  47. package/dist/{token-goat-chunk-NMTKNYGF.mjs → token-goat-chunk-FNFBKLRD.mjs} +74 -9
  48. package/dist/{token-goat-chunk-XI2VFAV6.mjs → token-goat-chunk-FZ3NEW5O.mjs} +33 -19
  49. package/dist/token-goat-chunk-G5PJ7AGM.mjs +36 -0
  50. package/dist/{token-goat-chunk-VE27HPIF.mjs → token-goat-chunk-GFBSN7BD.mjs} +30 -398
  51. package/dist/{token-goat-chunk-L45ZQRT7.mjs → token-goat-chunk-GOLEOXZP.mjs} +780 -786
  52. package/dist/token-goat-chunk-H2K3QP6H.mjs +24 -0
  53. package/dist/token-goat-chunk-H2PHHGM5.mjs +188 -0
  54. package/dist/token-goat-chunk-HAVAOB3S.mjs +87 -0
  55. package/dist/token-goat-chunk-HG45AF2B.mjs +2228 -0
  56. package/dist/{token-goat-chunk-CBMY2FGI.mjs → token-goat-chunk-HOJLCGDP.mjs} +17113 -15554
  57. package/dist/{token-goat-chunk-HUDC5GS5.mjs → token-goat-chunk-HYBFA5X3.mjs} +120 -19
  58. package/dist/token-goat-chunk-IVALLT3S.mjs +48 -0
  59. package/dist/token-goat-chunk-IVE6U7KV.mjs +53 -0
  60. package/dist/{token-goat-chunk-UBUKHVYW.mjs → token-goat-chunk-IVKIZWAB.mjs} +3 -3
  61. package/dist/{token-goat-chunk-4JMWPWCS.mjs → token-goat-chunk-JB6QN6VF.mjs} +6 -4
  62. package/dist/{token-goat-chunk-Q4S3UQGO.mjs → token-goat-chunk-JDHE26RP.mjs} +10 -3
  63. package/dist/{token-goat-chunk-7R2XYKC5.mjs → token-goat-chunk-JDU3EXSU.mjs} +14 -10
  64. package/dist/token-goat-chunk-JDWCRD6M.mjs +253 -0
  65. package/dist/{token-goat-chunk-XBESNWEX.mjs → token-goat-chunk-JN4XMLSD.mjs} +7 -4
  66. package/dist/token-goat-chunk-JTQQGXZH.mjs +733 -0
  67. package/dist/token-goat-chunk-KKUFXAPD.mjs +25 -0
  68. package/dist/token-goat-chunk-KQNZDCBD.mjs +47 -0
  69. package/dist/{token-goat-chunk-4RN64ZND.mjs → token-goat-chunk-KWPNJBDH.mjs} +28 -3
  70. package/dist/token-goat-chunk-LOBGHXPB.mjs +242 -0
  71. package/dist/token-goat-chunk-MKPF4CL5.mjs +37 -0
  72. package/dist/token-goat-chunk-MNWKPRAL.mjs +13 -0
  73. package/dist/{token-goat-chunk-YWSP6IU7.mjs → token-goat-chunk-N2NMER56.mjs} +25 -15
  74. package/dist/token-goat-chunk-NYKZLXMK.mjs +218 -0
  75. package/dist/token-goat-chunk-OJBNYTJP.mjs +3087 -0
  76. package/dist/token-goat-chunk-P4QMM4WK.mjs +295 -0
  77. package/dist/token-goat-chunk-PD5VKH46.mjs +184 -0
  78. package/dist/token-goat-chunk-PEPTHRFF.mjs +129 -0
  79. package/dist/{token-goat-chunk-VWZKZPSR.mjs → token-goat-chunk-PU7V3FD6.mjs} +8752 -11098
  80. package/dist/token-goat-chunk-PY533T7F.mjs +46 -0
  81. package/dist/token-goat-chunk-Q5VTGRH7.mjs +761 -0
  82. package/dist/{token-goat-chunk-IHKZ3QNA.mjs → token-goat-chunk-QCLDAQTS.mjs} +33 -19
  83. package/dist/{token-goat-chunk-LKSXAMJB.mjs → token-goat-chunk-QSBRTGM2.mjs} +9 -2
  84. package/dist/{token-goat-chunk-4STDIGYC.mjs → token-goat-chunk-RC35RBUL.mjs} +7 -5
  85. package/dist/{token-goat-chunk-D5ICEPSB.mjs → token-goat-chunk-RHXKCZX3.mjs} +887 -507
  86. package/dist/{token-goat-chunk-RSS3TLXU.mjs → token-goat-chunk-RZRTDST7.mjs} +17 -7
  87. package/dist/{token-goat-chunk-MAMQPC43.mjs → token-goat-chunk-SJHWVNDQ.mjs} +15 -21
  88. package/dist/token-goat-chunk-SMVRN2HU.mjs +188 -0
  89. package/dist/{token-goat-chunk-EL7M26WP.mjs → token-goat-chunk-SQSSNQPE.mjs} +2100 -1442
  90. package/dist/{token-goat-chunk-OZRSREKR.mjs → token-goat-chunk-T4FK7VOV.mjs} +3 -3
  91. package/dist/token-goat-chunk-U4N3BN2W.mjs +92 -0
  92. package/dist/token-goat-chunk-UA5V6P3P.mjs +122 -0
  93. package/dist/{token-goat-chunk-XKY4VKJ4.mjs → token-goat-chunk-UQ5UK2T7.mjs} +15 -4
  94. package/dist/token-goat-chunk-USILZ3T3.mjs +53 -0
  95. package/dist/token-goat-chunk-VES7EL7O.mjs +205 -0
  96. package/dist/{token-goat-chunk-M56BWPBN.mjs → token-goat-chunk-VL3YIFHZ.mjs} +550 -49
  97. package/dist/{token-goat-chunk-IZXKVT4A.mjs → token-goat-chunk-VPBBTSJR.mjs} +362 -128
  98. package/dist/{token-goat-chunk-F2ARFHLJ.mjs → token-goat-chunk-W3QCJS6G.mjs} +10 -2
  99. package/dist/{token-goat-chunk-FSTWAOW6.mjs → token-goat-chunk-WY3L4DVT.mjs} +11 -5
  100. package/dist/{token-goat-chunk-OSUFN2FV.mjs → token-goat-chunk-XB5KKOCG.mjs} +5 -25
  101. package/dist/token-goat-chunk-XKI4SEMX.mjs +66 -0
  102. package/dist/token-goat-chunk-XU4P6Z24.mjs +133 -0
  103. package/dist/{token-goat-chunk-6CCQDAYY.mjs → token-goat-chunk-Y776AENC.mjs} +138 -33
  104. package/dist/token-goat-chunk-YARZFCZS.mjs +359 -0
  105. package/dist/{token-goat-chunk-EEIDFMEM.mjs → token-goat-chunk-YZAAZU2S.mjs} +12 -3
  106. package/dist/{token-goat-chunk-E3K3BTEQ.mjs → token-goat-chunk-Z44YO3QZ.mjs} +12 -6
  107. package/dist/token-goat-chunk-Z57YODA2.mjs +35 -0
  108. package/dist/{token-goat-chunk-DA43OE7L.mjs → token-goat-chunk-ZCDTCVIS.mjs} +49 -30
  109. package/dist/token-goat-chunk-ZEJVMUQH.mjs +48 -0
  110. package/dist/{token-goat-chunk-BGHSSJUA.mjs → token-goat-chunk-ZFOBKUWH.mjs} +1 -1
  111. package/dist/token-goat-chunk-ZMBL6UVV.mjs +110 -0
  112. package/dist/{token-goat-chunk-SJEKA7Y2.mjs → token-goat-chunk-ZQSJMO2R.mjs} +381 -201
  113. package/dist/token-goat-hook-client.cjs +539 -0
  114. package/dist/token-goat-hook-client.mjs +26 -0
  115. package/dist/token-goat-hook.mjs +48 -28
  116. package/dist/token-goat.core.mjs +10 -45
  117. package/docs/C4_RUNTIME_ARCHITECTURE.md +3 -3
  118. package/docs/cli.md +82 -47
  119. package/docs/install.md +58 -23
  120. package/docs/security.md +7 -7
  121. package/package.json +17 -7
  122. package/scripts/verify-native-dist.mjs +386 -0
  123. package/dist/token-goat-chunk-4JJBFT7V.mjs +0 -20
  124. package/dist/token-goat-chunk-5NNYIUGV.mjs +0 -143
  125. package/dist/token-goat-chunk-6DQNNFJ6.mjs +0 -294
  126. package/dist/token-goat-chunk-7MAFDRVR.mjs +0 -47
  127. package/dist/token-goat-chunk-BCN2YQC6.mjs +0 -32
  128. package/dist/token-goat-chunk-D7GHQKQD.mjs +0 -30
  129. package/dist/token-goat-chunk-GMOUBOX4.mjs +0 -386
  130. package/dist/token-goat-chunk-IFORDBGC.mjs +0 -192
  131. package/dist/token-goat-chunk-JXK2HQXS.mjs +0 -318
  132. package/dist/token-goat-chunk-L7SDVGBT.mjs +0 -430
  133. package/dist/token-goat-chunk-MMLMALWK.mjs +0 -1381
  134. package/dist/token-goat-chunk-MVSWBNMD.mjs +0 -1985
@@ -3,7 +3,13 @@ const require = __cjsRequire(import.meta.url);
3
3
  import {
4
4
  queryCsv,
5
5
  quoteCsvCell
6
- } from "./token-goat-chunk-YWSP6IU7.mjs";
6
+ } from "./token-goat-chunk-N2NMER56.mjs";
7
+ import {
8
+ redactSecrets
9
+ } from "./token-goat-chunk-4FVIAHSI.mjs";
10
+ import {
11
+ loadConfig
12
+ } from "./token-goat-chunk-7IN2MKDS.mjs";
7
13
  import {
8
14
  NotAnOfficeDocumentError,
9
15
  assertOoxmlWithinDeadline,
@@ -12,13 +18,13 @@ import {
12
18
  ooxmlWorkDeadline,
13
19
  parseOoxmlPart,
14
20
  readOoxmlZip
15
- } from "./token-goat-chunk-UBUKHVYW.mjs";
16
- import {
17
- displaySafeText
18
- } from "./token-goat-chunk-NMTKNYGF.mjs";
21
+ } from "./token-goat-chunk-IVKIZWAB.mjs";
19
22
  import {
20
23
  DocumentRefusedError
21
24
  } from "./token-goat-chunk-Y4AFKTHK.mjs";
25
+ import {
26
+ displaySafeText
27
+ } from "./token-goat-chunk-FNFBKLRD.mjs";
22
28
  import {
23
29
  init_define_import_meta_env
24
30
  } from "./token-goat-chunk-A37V4PBF.mjs";
@@ -562,14 +568,18 @@ async function xlsxColumns(filePath, sheetName, sampleLimit = 100) {
562
568
  columns: colSummaries
563
569
  };
564
570
  }
565
- function formatXlsxColumns(result) {
571
+ function formatXlsxColumns(result, config = loadConfig()) {
566
572
  if (result.columns.length === 0) return `Sheet "${displaySafeText(result.sheetName)}" is empty`;
573
+ const clip = (v) => {
574
+ const safe = redactSecrets(v, config).text;
575
+ return safe.length > 30 ? safe.slice(0, 27) + "..." : safe;
576
+ };
567
577
  const lines = [
568
578
  `Sheet: ${displaySafeText(result.sheetName)} (${result.totalSheetRows} data rows, ${result.columns.length} columns; sampled first ${result.sampleRows} rows)`
569
579
  ];
570
580
  for (const c of result.columns) {
571
581
  const pct = result.sampleRows > 0 ? Math.round(c.nonEmptyRows / c.sampleRows * 100) : 0;
572
- const samples = c.sampleValues.length > 0 ? ` (e.g. ${c.sampleValues.map((v) => JSON.stringify(v.length > 30 ? v.slice(0, 27) + "..." : v)).join(", ")})` : " (all empty)";
582
+ const samples = c.sampleValues.length > 0 ? ` (e.g. ${c.sampleValues.map((v) => JSON.stringify(clip(v))).join(", ")})` : " (all empty)";
573
583
  lines.push(` ${c.letter.padEnd(4)} ${displaySafeText(c.name).padEnd(25)} ${c.nonEmptyRows}/${c.sampleRows} (${pct}%)${samples}`);
574
584
  }
575
585
  return lines.join("\n");
@@ -2,24 +2,17 @@ import { createRequire as __cjsRequire } from 'node:module';
2
2
  const require = __cjsRequire(import.meta.url);
3
3
  import {
4
4
  estimateTokensFromLength
5
- } from "./token-goat-chunk-4JMWPWCS.mjs";
5
+ } from "./token-goat-chunk-JB6QN6VF.mjs";
6
+ import {
7
+ matchRestOfLine
8
+ } from "./token-goat-chunk-EVMZJ27Z.mjs";
6
9
  import {
7
10
  displaySafeText
8
- } from "./token-goat-chunk-NMTKNYGF.mjs";
11
+ } from "./token-goat-chunk-FNFBKLRD.mjs";
9
12
  import {
10
13
  init_define_import_meta_env
11
14
  } from "./token-goat-chunk-A37V4PBF.mjs";
12
15
 
13
- // src/claude_config_dir.ts
14
- init_define_import_meta_env();
15
- import * as os from "node:os";
16
- import * as path from "node:path";
17
- function claudeConfigDir(homeDir = os.homedir()) {
18
- const override = process.env["CLAUDE_CONFIG_DIR"];
19
- if (override !== void 0 && override !== "") return override;
20
- return path.join(homeDir, ".claude");
21
- }
22
-
23
16
  // src/resident_context.ts
24
17
  init_define_import_meta_env();
25
18
  import * as fs from "node:fs";
@@ -59,14 +52,16 @@ function messageText(message) {
59
52
  return out;
60
53
  }
61
54
  function skillNameFromBody(text) {
62
- const dir = /^Base directory for this skill:\s*(.+?)\s*$/m.exec(text);
63
- if (dir?.[1] !== void 0) {
64
- const segments = dir[1].split(/[\\/]/).filter((s) => s.length > 0);
55
+ const dirAt = /^Base directory for this skill:/m.exec(text);
56
+ const dir = dirAt === null ? null : matchRestOfLine(text, dirAt.index + dirAt[0].length, 0);
57
+ if (dir !== null) {
58
+ const segments = dir.split(/[\\/]/).filter((s) => s.length > 0);
65
59
  const last = segments[segments.length - 1];
66
60
  if (last !== void 0 && last.length > 0) return last;
67
61
  }
68
- const heading = /^#\s+(.+?)\s*$/m.exec(text);
69
- if (heading?.[1] !== void 0 && heading[1].length > 0) return heading[1];
62
+ const hashAt = /^#(?=\s)/m.exec(text);
63
+ const heading = hashAt === null ? null : matchRestOfLine(text, hashAt.index + 1, 1);
64
+ if (heading !== null && heading.length > 0) return heading;
70
65
  return null;
71
66
  }
72
67
  function readTaskList(attachment, bytes) {
@@ -111,9 +106,9 @@ function collectInvokedSkills(acc, record) {
111
106
  function skillName(skill) {
112
107
  const name = skill["name"];
113
108
  if (typeof name === "string" && name.trim() !== "") return name.trim();
114
- const path2 = skill["path"];
115
- if (typeof path2 !== "string") return null;
116
- const segments = path2.split(/[\\/]/).filter((part) => part !== "");
109
+ const path = skill["path"];
110
+ if (typeof path !== "string") return null;
111
+ const segments = path.split(/[\\/]/).filter((part) => part !== "");
117
112
  const last = segments[segments.length - 1];
118
113
  return last === void 0 || last === "" ? null : last;
119
114
  }
@@ -225,7 +220,6 @@ function accumulateResidentLines(lines) {
225
220
  }
226
221
 
227
222
  export {
228
- claudeConfigDir,
229
223
  createResidentContextStats,
230
224
  accumulateResidentLine,
231
225
  summarizeResidentContext,
@@ -0,0 +1,188 @@
1
+ import { createRequire as __cjsRequire } from 'node:module';
2
+ const require = __cjsRequire(import.meta.url);
3
+ import {
4
+ LOCK_WAIT_MS_HARDENED,
5
+ atomicWriteText,
6
+ ensureDirSync,
7
+ withFileLock
8
+ } from "./token-goat-chunk-GOLEOXZP.mjs";
9
+ import {
10
+ dataDir
11
+ } from "./token-goat-chunk-VES7EL7O.mjs";
12
+ import {
13
+ init_define_import_meta_env
14
+ } from "./token-goat-chunk-A37V4PBF.mjs";
15
+
16
+ // src/model_download_gate.ts
17
+ init_define_import_meta_env();
18
+ import { AsyncLocalStorage } from "node:async_hooks";
19
+ import * as fs from "node:fs";
20
+ import * as path from "node:path";
21
+ var MODEL_DOWNLOAD_HOST = "huggingface.co";
22
+ var RUNTIME_DOWNLOAD_HOST = "registry.npmjs.org";
23
+ var FIRST_HOLD_MS = 10 * 60 * 1e3;
24
+ var MAX_HOLD_MS = 60 * 60 * 1e3;
25
+ var CONSECUTIVE_WINDOW_MS = 24 * 60 * 60 * 1e3;
26
+ var CLOCK_SKEW_MS = 60 * 1e3;
27
+ var DownloadFailedError = class extends Error {
28
+ failedAt;
29
+ url;
30
+ constructor(message, url, failedAt, cause) {
31
+ super(message, cause === void 0 ? void 0 : { cause });
32
+ this.name = "DownloadFailedError";
33
+ this.url = url;
34
+ this.failedAt = failedAt;
35
+ }
36
+ };
37
+ var DownloadCooldownError = class extends Error {
38
+ failedAt;
39
+ retryAt;
40
+ lastMessage;
41
+ url;
42
+ constructor(url, cooldown, now = Date.now()) {
43
+ super(`Not downloading ${url} yet: the last try, ${formatAgo(now - cooldown.at)} ago, failed with ${cooldown.message}. It is tried again automatically after ${new Date(cooldown.retryAt).toLocaleTimeString()}.`);
44
+ this.name = "DownloadCooldownError";
45
+ this.url = url;
46
+ this.failedAt = cooldown.at;
47
+ this.retryAt = cooldown.retryAt;
48
+ this.lastMessage = cooldown.message;
49
+ }
50
+ };
51
+ function downloadFailureRecordPath() {
52
+ return path.join(dataDir(), "models", "download-failures.json");
53
+ }
54
+ function downloadHoldMs(failures) {
55
+ return Math.min(FIRST_HOLD_MS * 2 ** Math.max(0, failures - 1), MAX_HOLD_MS);
56
+ }
57
+ function hostOf(hostOrUrl) {
58
+ if (!hostOrUrl.includes("://")) return hostOrUrl.toLowerCase();
59
+ try {
60
+ return new URL(hostOrUrl).host.toLowerCase();
61
+ } catch {
62
+ return hostOrUrl.toLowerCase();
63
+ }
64
+ }
65
+ function isFailure(value) {
66
+ if (value === null || typeof value !== "object") return false;
67
+ const v = value;
68
+ return typeof v["url"] === "string" && typeof v["message"] === "string" && Number.isFinite(v["at"]) && Number.isInteger(v["failures"]) && v["failures"] >= 1;
69
+ }
70
+ function readRecord() {
71
+ let parsed;
72
+ try {
73
+ parsed = JSON.parse(fs.readFileSync(downloadFailureRecordPath(), "utf-8"));
74
+ } catch {
75
+ return {};
76
+ }
77
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) return {};
78
+ const out = {};
79
+ for (const [host, entry] of Object.entries(parsed)) if (isFailure(entry)) out[host] = entry;
80
+ return out;
81
+ }
82
+ function writeRecord(record) {
83
+ const file = downloadFailureRecordPath();
84
+ if (Object.keys(record).length === 0) fs.rmSync(file, { force: true });
85
+ else atomicWriteText(file, `${JSON.stringify(record, null, 2)}
86
+ `);
87
+ }
88
+ function lastDownloadFailure(hostOrUrl = MODEL_DOWNLOAD_HOST) {
89
+ return readRecord()[hostOf(hostOrUrl)] ?? null;
90
+ }
91
+ function activeDownloadCooldown(hostOrUrl = MODEL_DOWNLOAD_HOST, now = Date.now()) {
92
+ const host = hostOf(hostOrUrl);
93
+ const last = lastDownloadFailure(host);
94
+ if (!last || last.at > now + CLOCK_SKEW_MS) return null;
95
+ const retryAt = last.at + downloadHoldMs(last.failures);
96
+ return now < retryAt ? { ...last, host, retryAt } : null;
97
+ }
98
+ function updateRecord(mutate, now) {
99
+ const file = downloadFailureRecordPath();
100
+ const run = () => {
101
+ const record = readRecord();
102
+ for (const [host, entry] of Object.entries(record)) if (now - entry.at >= CONSECUTIVE_WINDOW_MS) delete record[host];
103
+ const value = mutate(record, now);
104
+ writeRecord(record);
105
+ return { value };
106
+ };
107
+ try {
108
+ ensureDirSync(path.dirname(file));
109
+ } catch {
110
+ }
111
+ return (withFileLock(`${file}.lock`, run, { waitMs: LOCK_WAIT_MS_HARDENED }) ?? run()).value;
112
+ }
113
+ function recordDownloadFailure(url, err, now = Date.now(), startedAt) {
114
+ const host = hostOf(url);
115
+ const message = typeof err === "string" ? err : describeCause(err);
116
+ return updateRecord((record) => {
117
+ const prev = record[host];
118
+ const known = prev !== void 0 && prev.at <= now + CLOCK_SKEW_MS && now - prev.at < CONSECUTIVE_WINDOW_MS;
119
+ const sameOutage = known && startedAt !== void 0 && prev.at >= startedAt;
120
+ const entry = { url, message, at: now, failures: !known ? 1 : sameOutage ? prev.failures : prev.failures + 1 };
121
+ record[host] = entry;
122
+ return entry;
123
+ }, now);
124
+ }
125
+ function clearDownloadFailure(url) {
126
+ const host = hostOf(url);
127
+ if (!(host in readRecord())) return;
128
+ updateRecord((record) => delete record[host], Date.now());
129
+ }
130
+ function detailOf(value) {
131
+ if (value instanceof AggregateError && value.errors.length > 0 && value.message === "") return detailOf(value.errors[0]);
132
+ if (value instanceof Error) return value.message !== "" ? value.message : String(value.code ?? value.name);
133
+ if (value !== null && typeof value === "object") return String(value.code ?? "");
134
+ return value === void 0 ? "" : String(value);
135
+ }
136
+ function describeCause(err) {
137
+ const head = detailOf(err);
138
+ const extra = [];
139
+ let seen = head;
140
+ let cursor = err instanceof Error ? err.cause : void 0;
141
+ for (let depth = 0; cursor !== void 0 && cursor !== null && depth < 5; depth++) {
142
+ const detail = detailOf(cursor);
143
+ if (detail !== "" && !seen.includes(detail)) {
144
+ extra.push(detail);
145
+ seen += ` ${detail}`;
146
+ }
147
+ cursor = cursor instanceof Error ? cursor.cause : void 0;
148
+ }
149
+ return extra.length > 0 ? `${head} (${extra.join("; ")})` : head;
150
+ }
151
+ function failedAtOf(err) {
152
+ let cursor = err;
153
+ for (let depth = 0; cursor !== null && typeof cursor === "object" && depth < 5; depth++) {
154
+ const at = cursor.failedAt;
155
+ if (typeof at === "number") return at;
156
+ cursor = cursor.cause;
157
+ }
158
+ return null;
159
+ }
160
+ function formatAgo(ms) {
161
+ const minutes = Math.max(0, Math.round(ms / 6e4));
162
+ if (minutes < 1) return "moments";
163
+ return minutes === 1 ? "1 minute" : `${minutes} minutes`;
164
+ }
165
+ var explicit = new AsyncLocalStorage();
166
+ function withExplicitDownload(fn) {
167
+ return explicit.run(true, fn);
168
+ }
169
+ function isExplicitDownload() {
170
+ return explicit.getStore() === true;
171
+ }
172
+
173
+ export {
174
+ MODEL_DOWNLOAD_HOST,
175
+ RUNTIME_DOWNLOAD_HOST,
176
+ DownloadFailedError,
177
+ DownloadCooldownError,
178
+ downloadFailureRecordPath,
179
+ downloadHoldMs,
180
+ lastDownloadFailure,
181
+ activeDownloadCooldown,
182
+ recordDownloadFailure,
183
+ clearDownloadFailure,
184
+ describeCause,
185
+ failedAtOf,
186
+ withExplicitDownload,
187
+ isExplicitDownload
188
+ };