token-goat 2.9.30 → 2.9.31

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 (172) hide show
  1. package/README.md +24 -7
  2. package/SECURITY.md +10 -2
  3. package/THIRD_PARTY_NOTICES.md +1 -1
  4. package/dist/native/linux-arm64/tg-hook +0 -0
  5. package/dist/native/linux-x64/tg-hook +0 -0
  6. package/dist/native/win32-arm64/tg-hook.exe +0 -0
  7. package/dist/native/win32-x64/tg-hook.exe +0 -0
  8. package/dist/{token-goat-chunk-QSBRTGM2.mjs → token-goat-chunk-25TRAWET.mjs} +17 -7
  9. package/dist/token-goat-chunk-2KXO6V2B.mjs +203 -0
  10. package/dist/{token-goat-chunk-IVKIZWAB.mjs → token-goat-chunk-2M7E4PF7.mjs} +41 -12
  11. package/dist/{token-goat-chunk-SMVRN2HU.mjs → token-goat-chunk-2UPZGKKY.mjs} +2 -2
  12. package/dist/token-goat-chunk-2WLPWKHV.mjs +135 -0
  13. package/dist/token-goat-chunk-2XBMMDBD.mjs +126 -0
  14. package/dist/token-goat-chunk-32ZOY4N5.mjs +23 -0
  15. package/dist/token-goat-chunk-3EZRNKTK.mjs +188 -0
  16. package/dist/token-goat-chunk-4ADZHI7J.mjs +63 -0
  17. package/dist/token-goat-chunk-4GBVPH3D.mjs +242 -0
  18. package/dist/{token-goat-chunk-KWPNJBDH.mjs → token-goat-chunk-4GILLLWY.mjs} +7 -4
  19. package/dist/{token-goat-chunk-67TQJ76B.mjs → token-goat-chunk-4NAPX7BA.mjs} +36 -3
  20. package/dist/{token-goat-chunk-PU7V3FD6.mjs → token-goat-chunk-4SC7UJYV.mjs} +3354 -2553
  21. package/dist/token-goat-chunk-4SMRO4TO.mjs +366 -0
  22. package/dist/{token-goat-chunk-AFLYLHDH.mjs → token-goat-chunk-4ZBFWLXF.mjs} +283 -427
  23. package/dist/{token-goat-chunk-JDWCRD6M.mjs → token-goat-chunk-57BIAXJL.mjs} +73 -40
  24. package/dist/token-goat-chunk-5AC66HNP.mjs +115 -0
  25. package/dist/token-goat-chunk-5IMLKSOP.mjs +145 -0
  26. package/dist/token-goat-chunk-646E6U44.mjs +398 -0
  27. package/dist/token-goat-chunk-65N4RHP4.mjs +33 -0
  28. package/dist/{token-goat-chunk-JN4XMLSD.mjs → token-goat-chunk-6DG6HWP3.mjs} +8 -2
  29. package/dist/token-goat-chunk-6ENQSNRZ.mjs +573 -0
  30. package/dist/token-goat-chunk-6ZY4GNF2.mjs +91 -0
  31. package/dist/{token-goat-chunk-VPBBTSJR.mjs → token-goat-chunk-76FGDLRO.mjs} +262 -255
  32. package/dist/{token-goat-chunk-7IN2MKDS.mjs → token-goat-chunk-7EZTZOMC.mjs} +121 -289
  33. package/dist/{token-goat-chunk-OJBNYTJP.mjs → token-goat-chunk-7MAOA6X4.mjs} +640 -80
  34. package/dist/token-goat-chunk-7R2ZVVAX.mjs +218 -0
  35. package/dist/{token-goat-chunk-PD5VKH46.mjs → token-goat-chunk-AUNGYYQX.mjs} +2 -2
  36. package/dist/{token-goat-chunk-HG45AF2B.mjs → token-goat-chunk-AUQYRMMH.mjs} +794 -37
  37. package/dist/token-goat-chunk-B3PEKBYG.mjs +128 -0
  38. package/dist/{token-goat-chunk-A3CK6N5Z.mjs → token-goat-chunk-BA4HI6BW.mjs} +1309 -110
  39. package/dist/{token-goat-chunk-JB6QN6VF.mjs → token-goat-chunk-BFCWY73P.mjs} +59 -23
  40. package/dist/{token-goat-chunk-B45VMIIH.mjs → token-goat-chunk-BWGFUZZE.mjs} +7 -5
  41. package/dist/{token-goat-chunk-P4QMM4WK.mjs → token-goat-chunk-C75NA7PL.mjs} +50 -23
  42. package/dist/token-goat-chunk-CBIQ7WTD.mjs +87 -0
  43. package/dist/token-goat-chunk-CETM74KC.mjs +307 -0
  44. package/dist/{token-goat-chunk-H2PHHGM5.mjs → token-goat-chunk-CIMQ2BB3.mjs} +57 -12
  45. package/dist/{token-goat-chunk-N2NMER56.mjs → token-goat-chunk-CJLS3CDL.mjs} +46 -4
  46. package/dist/{token-goat-chunk-VES7EL7O.mjs → token-goat-chunk-CO3UYX6G.mjs} +1 -1
  47. package/dist/token-goat-chunk-COPNXRJM.mjs +154 -0
  48. package/dist/token-goat-chunk-CSJ5L3NL.mjs +479 -0
  49. package/dist/{token-goat-chunk-4LCCNRTG.mjs → token-goat-chunk-CVCEVUGK.mjs} +8 -6
  50. package/dist/{token-goat-chunk-B2RZZCSS.mjs → token-goat-chunk-CXHOFN7R.mjs} +37 -20
  51. package/dist/token-goat-chunk-D735C4QM.mjs +603 -0
  52. package/dist/{token-goat-chunk-APGZXSPS.mjs → token-goat-chunk-DGS2LVNA.mjs} +47 -30
  53. package/dist/{token-goat-chunk-54K3EUV3.mjs → token-goat-chunk-DOWRSMWO.mjs} +1 -1
  54. package/dist/token-goat-chunk-E45INMY3.mjs +71 -0
  55. package/dist/token-goat-chunk-EC5F37F4.mjs +244 -0
  56. package/dist/{token-goat-chunk-XTQAOTSO.mjs → token-goat-chunk-EDBDRVH5.mjs} +4 -1
  57. package/dist/{token-goat-chunk-5BCIJXMO.mjs → token-goat-chunk-EELTBKDM.mjs} +14 -10
  58. package/dist/{token-goat-chunk-W3QCJS6G.mjs → token-goat-chunk-F4HYL64R.mjs} +8 -6
  59. package/dist/token-goat-chunk-F6PAUIEK.mjs +624 -0
  60. package/dist/token-goat-chunk-FDSREWLX.mjs +692 -0
  61. package/dist/token-goat-chunk-GGGG7RWB.mjs +236 -0
  62. package/dist/{token-goat-chunk-C63JQV5K.mjs → token-goat-chunk-GL3ETKSC.mjs} +233 -15
  63. package/dist/token-goat-chunk-GVB2MUST.mjs +1298 -0
  64. package/dist/token-goat-chunk-GWFLAUMQ.mjs +307 -0
  65. package/dist/{token-goat-chunk-ZEJVMUQH.mjs → token-goat-chunk-HLPW63A7.mjs} +2 -2
  66. package/dist/{token-goat-chunk-GOLEOXZP.mjs → token-goat-chunk-HU4TORC5.mjs} +44 -26
  67. package/dist/{token-goat-chunk-Z57YODA2.mjs → token-goat-chunk-I7VKZZAW.mjs} +2 -2
  68. package/dist/{token-goat-chunk-NYKZLXMK.mjs → token-goat-chunk-IA6XSPE3.mjs} +6 -6
  69. package/dist/{token-goat-chunk-E3OQX2XT.mjs → token-goat-chunk-IAGXMHIK.mjs} +81 -42
  70. package/dist/{token-goat-chunk-HYBFA5X3.mjs → token-goat-chunk-IK2DRMFX.mjs} +24 -68
  71. package/dist/{token-goat-chunk-COBQGL5S.mjs → token-goat-chunk-INNPTRUX.mjs} +249 -299
  72. package/dist/{token-goat-chunk-7NADEDKJ.mjs → token-goat-chunk-JJ5BX4F4.mjs} +6 -1
  73. package/dist/{token-goat-chunk-PEPTHRFF.mjs → token-goat-chunk-JVFSHVFJ.mjs} +6 -6
  74. package/dist/token-goat-chunk-KGEFFSHD.mjs +50 -0
  75. package/dist/token-goat-chunk-KQBLRPBN.mjs +433 -0
  76. package/dist/{token-goat-chunk-Q5VTGRH7.mjs → token-goat-chunk-LCNQ2CNN.mjs} +55 -319
  77. package/dist/token-goat-chunk-M3LFJDPU.mjs +58 -0
  78. package/dist/token-goat-chunk-M52KPT3C.mjs +87 -0
  79. package/dist/token-goat-chunk-MBEG42H7.mjs +150 -0
  80. package/dist/{token-goat-chunk-EVC4TOLE.mjs → token-goat-chunk-METECDOH.mjs} +3 -12
  81. package/dist/{token-goat-chunk-T4FK7VOV.mjs → token-goat-chunk-MHX7XCC3.mjs} +2 -1
  82. package/dist/token-goat-chunk-N5LSOVSU.mjs +137 -0
  83. package/dist/{token-goat-chunk-LOBGHXPB.mjs → token-goat-chunk-N5MMR2IW.mjs} +1 -1
  84. package/dist/token-goat-chunk-N7B3JQ2C.mjs +160 -0
  85. package/dist/{token-goat-chunk-RHXKCZX3.mjs → token-goat-chunk-NISNMD7T.mjs} +2182 -2959
  86. package/dist/token-goat-chunk-NMD42SFQ.mjs +434 -0
  87. package/dist/token-goat-chunk-NOSS5VWY.mjs +174 -0
  88. package/dist/{token-goat-chunk-KQNZDCBD.mjs → token-goat-chunk-NSNSPPBG.mjs} +25 -3
  89. package/dist/token-goat-chunk-OBOFIHKN.mjs +38 -0
  90. package/dist/token-goat-chunk-OBRFJ5O5.mjs +76 -0
  91. package/dist/{token-goat-chunk-JTQQGXZH.mjs → token-goat-chunk-ODBT2USM.mjs} +124 -57
  92. package/dist/token-goat-chunk-OS5EM5PP.mjs +107 -0
  93. package/dist/token-goat-chunk-OUKDTVNU.mjs +1178 -0
  94. package/dist/token-goat-chunk-OXFMP75N.mjs +566 -0
  95. package/dist/{token-goat-chunk-DZX2YDPT.mjs → token-goat-chunk-OYIYKDDT.mjs} +2 -2
  96. package/dist/{token-goat-chunk-QCLDAQTS.mjs → token-goat-chunk-P6HQSWQ3.mjs} +50 -53
  97. package/dist/token-goat-chunk-P6VGNTQT.mjs +71 -0
  98. package/dist/{token-goat-chunk-7BXSNBY5.mjs → token-goat-chunk-PFWIMH2E.mjs} +23 -15
  99. package/dist/token-goat-chunk-PJZXIS3G.mjs +39 -0
  100. package/dist/token-goat-chunk-PUO5INXP.mjs +606 -0
  101. package/dist/{token-goat-chunk-GFBSN7BD.mjs → token-goat-chunk-PX5PQWTY.mjs} +22 -250
  102. package/dist/token-goat-chunk-Q5QDBC6O.mjs +111 -0
  103. package/dist/token-goat-chunk-QFNQXSDT.mjs +40 -0
  104. package/dist/{token-goat-chunk-FBNQNSJK.mjs → token-goat-chunk-QH7YVYOY.mjs} +2198 -2782
  105. package/dist/{token-goat-chunk-64FBPDTK.mjs → token-goat-chunk-QLMUHEPB.mjs} +12 -9
  106. package/dist/{token-goat-chunk-RZRTDST7.mjs → token-goat-chunk-QQOJIHL3.mjs} +37 -11
  107. package/dist/{token-goat-chunk-XKI4SEMX.mjs → token-goat-chunk-QQTWJY2O.mjs} +19 -0
  108. package/dist/{token-goat-chunk-U4N3BN2W.mjs → token-goat-chunk-QYHO5CPH.mjs} +3 -2
  109. package/dist/token-goat-chunk-RELAVWAD.mjs +27 -0
  110. package/dist/{token-goat-chunk-ETBHVDB6.mjs → token-goat-chunk-RSLPOBKQ.mjs} +22 -11
  111. package/dist/token-goat-chunk-SAMFDIS2.mjs +712 -0
  112. package/dist/token-goat-chunk-SDELXLDM.mjs +48 -0
  113. package/dist/{token-goat-chunk-4JJS54TR.mjs → token-goat-chunk-SOAFZNNZ.mjs} +161 -38
  114. package/dist/{token-goat-chunk-664RTTUV.mjs → token-goat-chunk-SRTHT7KV.mjs} +21 -16
  115. package/dist/{token-goat-chunk-4FVIAHSI.mjs → token-goat-chunk-T5P5ACNQ.mjs} +7 -6
  116. package/dist/token-goat-chunk-T5YGG4V3.mjs +45 -0
  117. package/dist/token-goat-chunk-TAUZ4OFS.mjs +110 -0
  118. package/dist/{token-goat-chunk-COTXZHTS.mjs → token-goat-chunk-TM6MC754.mjs} +4 -3
  119. package/dist/token-goat-chunk-TWUKBOMP.mjs +72 -0
  120. package/dist/{token-goat-chunk-3CHUNJ2O.mjs → token-goat-chunk-U2KSB4SG.mjs} +8 -5
  121. package/dist/{token-goat-chunk-3Z5S4KGM.mjs → token-goat-chunk-U4WHMG6Y.mjs} +29 -49
  122. package/dist/{token-goat-chunk-PY533T7F.mjs → token-goat-chunk-UGJHGR5A.mjs} +21 -15
  123. package/dist/{token-goat-chunk-CYCEYAEO.mjs → token-goat-chunk-UOUDVA5U.mjs} +1 -1
  124. package/dist/{token-goat-chunk-JDHE26RP.mjs → token-goat-chunk-URRJ33GR.mjs} +16 -5
  125. package/dist/{token-goat-chunk-56EIMS3E.mjs → token-goat-chunk-UZOROKIS.mjs} +23 -17
  126. package/dist/{token-goat-chunk-CZ3LUXYZ.mjs → token-goat-chunk-VIHGGGEI.mjs} +427 -308
  127. package/dist/token-goat-chunk-VTJLAA7P.mjs +21 -0
  128. package/dist/token-goat-chunk-VWDXLT4F.mjs +678 -0
  129. package/dist/{token-goat-chunk-YARZFCZS.mjs → token-goat-chunk-VWZA2H4P.mjs} +62 -53
  130. package/dist/{token-goat-chunk-SQSSNQPE.mjs → token-goat-chunk-VXEXMJDL.mjs} +3979 -4745
  131. package/dist/token-goat-chunk-WBA5SKT4.mjs +547 -0
  132. package/dist/{token-goat-chunk-SJHWVNDQ.mjs → token-goat-chunk-WDH44VAU.mjs} +7 -4
  133. package/dist/token-goat-chunk-X2SUP3EI.mjs +107 -0
  134. package/dist/token-goat-chunk-X3BELZSJ.mjs +125 -0
  135. package/dist/{token-goat-chunk-FZ3NEW5O.mjs → token-goat-chunk-XLRBNZCC.mjs} +13 -8
  136. package/dist/{token-goat-chunk-Z44YO3QZ.mjs → token-goat-chunk-XRKUX6CM.mjs} +1 -1
  137. package/dist/token-goat-chunk-XX6O25RN.mjs +82 -0
  138. package/dist/token-goat-chunk-XZSUHBVS.mjs +65 -0
  139. package/dist/{token-goat-chunk-WY3L4DVT.mjs → token-goat-chunk-Y2ZTQOCL.mjs} +13 -8
  140. package/dist/{token-goat-chunk-UQ5UK2T7.mjs → token-goat-chunk-YB4VMGK2.mjs} +1 -1
  141. package/dist/token-goat-chunk-YBIIY3HR.mjs +51 -0
  142. package/dist/{token-goat-chunk-ZQSJMO2R.mjs → token-goat-chunk-YHVDKQBR.mjs} +105 -105
  143. package/dist/{token-goat-chunk-H2K3QP6H.mjs → token-goat-chunk-YJB5XLWI.mjs} +8 -6
  144. package/dist/{token-goat-chunk-ZCDTCVIS.mjs → token-goat-chunk-YKB6AQG3.mjs} +5 -2
  145. package/dist/token-goat-chunk-YMTG2YA5.mjs +35 -0
  146. package/dist/token-goat-chunk-YPBZYQRV.mjs +40 -0
  147. package/dist/{token-goat-chunk-HOJLCGDP.mjs → token-goat-chunk-YY6AVUFL.mjs} +2033 -2251
  148. package/dist/token-goat-chunk-Z7N5OMMP.mjs +98 -0
  149. package/dist/token-goat-chunk-ZNMNUPAZ.mjs +938 -0
  150. package/dist/token-goat-hook-client.cjs +1 -1
  151. package/dist/token-goat-hook-client.mjs +3 -3
  152. package/dist/token-goat-hook.mjs +67 -38
  153. package/dist/token-goat.core.mjs +4 -4
  154. package/docs/C4_RUNTIME_ARCHITECTURE.md +1 -1
  155. package/docs/cli.md +40 -21
  156. package/docs/install.md +19 -9
  157. package/docs/security.md +5 -3
  158. package/package.json +2 -1
  159. package/dist/token-goat-chunk-5KDMCMF2.mjs +0 -362
  160. package/dist/token-goat-chunk-6QMAS7AB.mjs +0 -42
  161. package/dist/token-goat-chunk-7F2UBPD3.mjs +0 -397
  162. package/dist/token-goat-chunk-ARDNEC2U.mjs +0 -248
  163. package/dist/token-goat-chunk-ATCPY7EQ.mjs +0 -134
  164. package/dist/token-goat-chunk-EFHMMIGP.mjs +0 -68
  165. package/dist/token-goat-chunk-IVALLT3S.mjs +0 -48
  166. package/dist/token-goat-chunk-JDU3EXSU.mjs +0 -65
  167. package/dist/token-goat-chunk-MKPF4CL5.mjs +0 -37
  168. package/dist/token-goat-chunk-RC35RBUL.mjs +0 -312
  169. package/dist/token-goat-chunk-USILZ3T3.mjs +0 -53
  170. package/dist/token-goat-chunk-VL3YIFHZ.mjs +0 -2975
  171. package/dist/token-goat-chunk-XU4P6Z24.mjs +0 -133
  172. package/dist/token-goat-chunk-Y776AENC.mjs +0 -1597
@@ -1,67 +1,66 @@
1
1
  import { createRequire as __cjsRequire } from 'node:module';
2
2
  const require = __cjsRequire(import.meta.url);
3
+ import {
4
+ projectNotesFor
5
+ } from "./token-goat-chunk-GWFLAUMQ.mjs";
3
6
  import {
4
7
  computeAdaptiveBudget,
5
- formatAge,
6
8
  getContextPressure,
7
9
  isNoisePath,
10
+ loadSessionCache
11
+ } from "./token-goat-chunk-NMD42SFQ.mjs";
12
+ import {
8
13
  listSiblingSessionStates,
9
- loadSessionCache,
10
14
  sessionSidecarPath
11
- } from "./token-goat-chunk-Y776AENC.mjs";
15
+ } from "./token-goat-chunk-WBA5SKT4.mjs";
12
16
  import {
13
- getBashOutput,
14
- indexRecallEntry
15
- } from "./token-goat-chunk-AFLYLHDH.mjs";
16
- import {
17
- WEB_FETCH_KEY_SEP,
18
- getSessionBashOutputs,
19
- getSessionBashReruns,
20
- getSessionFiles,
21
- getSessionWebFetches
22
- } from "./token-goat-chunk-C63JQV5K.mjs";
17
+ getBashOutput
18
+ } from "./token-goat-chunk-KQBLRPBN.mjs";
23
19
  import {
24
20
  blobPath,
21
+ indexRecallEntry,
25
22
  isBlobStale,
26
23
  loadBlob,
27
24
  storeBlob
28
- } from "./token-goat-chunk-ARDNEC2U.mjs";
25
+ } from "./token-goat-chunk-4ZBFWLXF.mjs";
26
+ import {
27
+ WEB_FETCH_KEY_SEP,
28
+ epochReadCounts,
29
+ getSessionBashOutputs,
30
+ getSessionBashReruns,
31
+ getSessionFiles,
32
+ getSessionWebFetches,
33
+ mergeEpochBase,
34
+ wasEditedSinceCompaction
35
+ } from "./token-goat-chunk-GL3ETKSC.mjs";
29
36
  import {
30
37
  redactSecrets
31
- } from "./token-goat-chunk-4FVIAHSI.mjs";
38
+ } from "./token-goat-chunk-T5P5ACNQ.mjs";
39
+ import {
40
+ loadConfig
41
+ } from "./token-goat-chunk-7EZTZOMC.mjs";
32
42
  import {
33
- findProject,
34
- loadConfig,
35
43
  shortFingerprint
36
- } from "./token-goat-chunk-7IN2MKDS.mjs";
44
+ } from "./token-goat-chunk-4GBVPH3D.mjs";
37
45
  import {
38
46
  registerReset
39
47
  } from "./token-goat-chunk-YZAAZU2S.mjs";
40
48
  import {
41
- LOCK_WAIT_MS_HARDENED,
42
- atomicWriteText,
43
49
  ensureDirSync,
44
50
  runGit,
45
- toKB,
46
- withFileLock,
47
- withRetryOnLock
48
- } from "./token-goat-chunk-GOLEOXZP.mjs";
51
+ toKB
52
+ } from "./token-goat-chunk-HU4TORC5.mjs";
49
53
  import {
50
54
  foldPath,
51
55
  resolveOnPath,
52
- sleepSync,
53
56
  spawnResolvedSync
54
57
  } from "./token-goat-chunk-AM5V6GSX.mjs";
55
58
  import {
56
59
  UNTRUSTED_FILE_TAG,
57
60
  displaySafePath,
58
61
  displaySafeText,
59
- fenceUntrustedFileContent,
60
62
  neutralizeSpokenMarkers
61
63
  } from "./token-goat-chunk-FNFBKLRD.mjs";
62
- import {
63
- dataDir
64
- } from "./token-goat-chunk-VES7EL7O.mjs";
65
64
  import {
66
65
  init_define_import_meta_env
67
66
  } from "./token-goat-chunk-A37V4PBF.mjs";
@@ -133,271 +132,6 @@ registerReset(() => {
133
132
  _urlIndex = /* @__PURE__ */ new Map();
134
133
  }, { perRequest: true });
135
134
 
136
- // src/project_memory.ts
137
- init_define_import_meta_env();
138
- import * as fs2 from "node:fs";
139
- import * as path from "node:path";
140
- var MAX_ENTRIES = 30;
141
- var MAX_VALUE_LEN = 300;
142
- var MAX_TOTAL_CHARS = 4e3;
143
- var KEY_RE = /^[A-Za-z0-9_-]{1,80}$/;
144
- var SET_AT_RE = /^#\s*set\s+(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z)$/;
145
- var ANCHOR_RE = /^#\s*anchor:\s*(\S.*)::([^:@\s]+)@([0-9a-f]{64})$/;
146
- function anchorLabel(status) {
147
- if (status === "changed") return " (changed since note)";
148
- if (status === "gone") return " (anchored symbol gone)";
149
- return "";
150
- }
151
- function anchorLine(anchor) {
152
- const line = `# anchor: ${anchor.file}::${anchor.symbol}@${anchor.sha}`;
153
- const back = ANCHOR_RE.exec(line);
154
- return back !== null && back[1] === anchor.file && back[2] === anchor.symbol ? line : null;
155
- }
156
- function noteMap() {
157
- return /* @__PURE__ */ Object.create(null);
158
- }
159
- function ordinal(a, b) {
160
- return a < b ? -1 : a > b ? 1 : 0;
161
- }
162
- function memoryPath(projectHash) {
163
- return path.join(dataDir(), "projects", `${projectHash}_memory.toml`);
164
- }
165
- function validateKey(key) {
166
- if (!KEY_RE.test(key)) {
167
- throw new Error(
168
- `Invalid memory key ${JSON.stringify(key)}: use only letters, digits, hyphens, underscores (max 80 chars)`
169
- );
170
- }
171
- }
172
- function parseTOML(content, unparsed = [], setAt = /* @__PURE__ */ new Map(), anchors = /* @__PURE__ */ new Map()) {
173
- const result = noteMap();
174
- let pendingSetAt;
175
- let pendingAnchor;
176
- for (const [i, line] of content.split("\n").entries()) {
177
- const trimmed = line.trim();
178
- if (!trimmed) {
179
- continue;
180
- }
181
- if (trimmed.startsWith("#")) {
182
- const time = SET_AT_RE.exec(trimmed)?.[1];
183
- if (time !== void 0 && !Number.isNaN(Date.parse(time))) pendingSetAt = time;
184
- const anchor = ANCHOR_RE.exec(trimmed);
185
- if (anchor !== null) pendingAnchor = { file: anchor[1], symbol: anchor[2], sha: anchor[3] };
186
- continue;
187
- }
188
- const entrySetAt = pendingSetAt;
189
- const entryAnchor = pendingAnchor;
190
- pendingSetAt = void 0;
191
- pendingAnchor = void 0;
192
- const match = trimmed.match(/^([A-Za-z0-9_-]+)\s*=\s*"(.*)"\s*$/s);
193
- if (match) {
194
- const [, key, value] = match;
195
- if (key && value !== void 0) {
196
- const unescaped = value.replace(/\\(u202[89]|[\\nrt"])/g, (_, c) => {
197
- switch (c) {
198
- case "u2028":
199
- return "\u2028";
200
- case "u2029":
201
- return "\u2029";
202
- case "\\":
203
- return "\\";
204
- case "n":
205
- return "\n";
206
- case "r":
207
- return "\r";
208
- case '"':
209
- return '"';
210
- default:
211
- return _;
212
- }
213
- });
214
- result[key] = unescaped;
215
- if (entrySetAt === void 0) setAt.delete(key);
216
- else setAt.set(key, entrySetAt);
217
- if (entryAnchor === void 0) anchors.delete(key);
218
- else anchors.set(key, entryAnchor);
219
- }
220
- } else {
221
- unparsed.push(i + 1);
222
- }
223
- }
224
- return result;
225
- }
226
- function loadRaw(filePath, forUpdate = false, setAt, anchors) {
227
- let content = "";
228
- try {
229
- withRetryOnLock(() => {
230
- content = fs2.readFileSync(filePath, "utf-8");
231
- });
232
- } catch (err) {
233
- if (err.code === "ENOENT") return noteMap();
234
- throw err;
235
- }
236
- const unparsed = [];
237
- const entries = parseTOML(content, unparsed, setAt, anchors);
238
- if (forUpdate && unparsed.length > 0) {
239
- const one = unparsed.length === 1;
240
- throw new Error(`Not updating ${filePath}: ${one ? "line" : "lines"} ${unparsed.join(", ")} ${one ? "is" : "are"} not in the key = "value" form, and saving would drop ${one ? "it" : "them"}. Fix or remove ${one ? "it" : "them"}, then try again.`);
241
- }
242
- return entries;
243
- }
244
- function save(filePath, entries, setAt = /* @__PURE__ */ new Map(), anchors = /* @__PURE__ */ new Map()) {
245
- const lines = [];
246
- const sorted = Object.entries(entries).sort(([a], [b]) => ordinal(a, b));
247
- for (const [k, v] of sorted) {
248
- const escaped = v.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\r/g, "\\r").replace(/\n/g, "\\n").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
249
- const time = setAt.get(k);
250
- if (time !== void 0) lines.push(`# set ${time}`);
251
- const anchor = anchors.get(k);
252
- const anchored = anchor === void 0 ? null : anchorLine(anchor);
253
- if (anchored !== null) lines.push(anchored);
254
- lines.push(`${k} = "${escaped}"`);
255
- }
256
- const content = lines.length > 0 ? lines.join("\n") + "\n" : "";
257
- const dir = path.dirname(filePath);
258
- ensureDirSync(dir);
259
- atomicWriteText(filePath, content);
260
- }
261
- function loadEntries(projectHash) {
262
- return loadRaw(memoryPath(projectHash));
263
- }
264
- function loadDatedEntries(projectHash) {
265
- const setAt = /* @__PURE__ */ new Map();
266
- const anchors = /* @__PURE__ */ new Map();
267
- const entries = loadRaw(memoryPath(projectHash), false, setAt, anchors);
268
- const result = noteMap();
269
- for (const [key, value] of Object.entries(entries)) {
270
- const note = { value };
271
- const time = setAt.get(key);
272
- if (time !== void 0) note.setAt = time;
273
- const anchor = anchors.get(key);
274
- if (anchor !== void 0) note.anchor = anchor;
275
- result[key] = note;
276
- }
277
- return result;
278
- }
279
- function noteAgeLabel(note, now = Date.now()) {
280
- if (note.setAt === void 0) return "";
281
- return ` (set ${formatAge(Math.max(0, now - Date.parse(note.setAt)))} ago)`;
282
- }
283
- function oneLineNoteValue(value) {
284
- return value.replace(/\r\n|[\r\n\u0085\u2028\u2029]/g, "\\n");
285
- }
286
- function byRecency(a, aSetAt, b, bSetAt) {
287
- const ta = aSetAt === void 0 ? Number.NEGATIVE_INFINITY : Date.parse(aSetAt);
288
- const tb = bSetAt === void 0 ? Number.NEGATIVE_INFINITY : Date.parse(bSetAt);
289
- return ta !== tb ? ta > tb ? -1 : 1 : ordinal(a, b);
290
- }
291
- function setEntry(projectHash, key, value, anchor) {
292
- validateKey(key);
293
- const p = memoryPath(projectHash);
294
- const dir = path.dirname(p);
295
- ensureDirSync(dir);
296
- const result = { evicted: [] };
297
- const doSet = () => {
298
- const setAt = /* @__PURE__ */ new Map();
299
- const anchors = /* @__PURE__ */ new Map();
300
- const entries = loadRaw(p, true, setAt, anchors);
301
- const old = Object.hasOwn(entries, key) ? entries[key] : void 0;
302
- if (old !== void 0) result.previous = old;
303
- const isNewKey = !Object.hasOwn(entries, key);
304
- if (isNewKey && Object.keys(entries).length >= MAX_ENTRIES) {
305
- const keysToKeep = MAX_ENTRIES - 1;
306
- const allKeys = Object.keys(entries).sort((a, b) => byRecency(a, setAt.get(a), b, setAt.get(b)));
307
- for (const k of allKeys.slice(keysToKeep)) {
308
- result.evicted.push(k);
309
- delete entries[k];
310
- setAt.delete(k);
311
- anchors.delete(k);
312
- }
313
- }
314
- entries[key] = value;
315
- setAt.set(key, (/* @__PURE__ */ new Date()).toISOString());
316
- if (anchor === void 0) anchors.delete(key);
317
- else anchors.set(key, anchor);
318
- save(p, entries, setAt, anchors);
319
- return true;
320
- };
321
- underNotesLock(p, doSet);
322
- return result;
323
- }
324
- function underNotesLock(p, update) {
325
- const lockPath = `${p}.lock`;
326
- ensureDirSync(path.dirname(p));
327
- for (let attempt = 1; attempt <= 3; attempt++) {
328
- if (withFileLock(lockPath, update, { waitMs: LOCK_WAIT_MS_HARDENED }) !== void 0) return;
329
- if (fs2.existsSync(lockPath)) break;
330
- if (attempt < 3) sleepSync(50 * attempt);
331
- }
332
- throw new Error(`Could not lock ${p} for writing; no note was changed. Another token-goat process may be writing notes: try again.`);
333
- }
334
- function unsetEntry(projectHash, key) {
335
- validateKey(key);
336
- const p = memoryPath(projectHash);
337
- let removed = false;
338
- const doUnset = () => {
339
- const setAt = /* @__PURE__ */ new Map();
340
- const anchors = /* @__PURE__ */ new Map();
341
- const entries = loadRaw(p, true, setAt, anchors);
342
- if (Object.hasOwn(entries, key)) {
343
- delete entries[key];
344
- save(p, entries, setAt, anchors);
345
- removed = true;
346
- }
347
- return true;
348
- };
349
- underNotesLock(p, doUnset);
350
- return removed;
351
- }
352
- function clearAll(projectHash) {
353
- const p = memoryPath(projectHash);
354
- const doClear = () => {
355
- if (fs2.existsSync(p)) {
356
- save(p, {});
357
- }
358
- return true;
359
- };
360
- underNotesLock(p, doClear);
361
- }
362
- function buildInjection(projectHash, root, statusOf) {
363
- try {
364
- const entries = loadDatedEntries(projectHash);
365
- if (Object.keys(entries).length === 0) {
366
- return null;
367
- }
368
- const now = Date.now();
369
- const header = '### Project notes (`token-goat note set <key> "<finding>"`)';
370
- const render2 = (shown2, skipped) => {
371
- const parts = [header];
372
- if (shown2.length > 0) parts.push(fenceUntrustedFileContent(shown2.join("\n")));
373
- if (skipped > 0) parts.push(`- (+${skipped} more memory entries omitted)`);
374
- return parts.join("\n");
375
- };
376
- const entries_list = Object.entries(entries).sort(([a, na], [b, nb]) => byRecency(a, na.setAt, b, nb.setAt));
377
- const shown = [];
378
- for (const [key, note] of entries_list.slice(0, MAX_ENTRIES)) {
379
- const val = note.value;
380
- const display = val.length <= MAX_VALUE_LEN ? val : val.slice(0, MAX_VALUE_LEN) + "\u2026";
381
- const flag = root === void 0 || statusOf === void 0 || note.anchor === void 0 ? "" : anchorLabel(statusOf(root, note.anchor));
382
- const line = `- **${key}**${noteAgeLabel(note, now)}${flag}: ${oneLineNoteValue(display)}`;
383
- if (render2([...shown, line], entries_list.length - shown.length - 1).length > MAX_TOTAL_CHARS) break;
384
- shown.push(line);
385
- }
386
- return render2(shown, entries_list.length - shown.length);
387
- } catch {
388
- return null;
389
- }
390
- }
391
- function projectNotesFor(cwd, statusOf) {
392
- if (cwd === void 0) return null;
393
- try {
394
- const project = findProject(cwd);
395
- return project === null ? null : buildInjection(project.hash, project.root, statusOf);
396
- } catch {
397
- return null;
398
- }
399
- }
400
-
401
135
  // src/manifest_fit.ts
402
136
  init_define_import_meta_env();
403
137
  var RESERVE_SHARE = 0.25;
@@ -456,7 +190,7 @@ function fitSections(sections, budget) {
456
190
  }
457
191
 
458
192
  // src/manifest.ts
459
- var MEM_EPOCH_TIMEOUT_MS = 800;
193
+ var MEM_EPOCH_TIMEOUT_MS = 2e3;
460
194
  var MAX_ROWS = 40;
461
195
  function renderReadRow(entry) {
462
196
  const kb = Math.max(1, toKB(entry.sizeBytes));
@@ -478,14 +212,22 @@ function mergeManifestFiles(parent, siblingFiles) {
478
212
  continue;
479
213
  }
480
214
  const mergedSymbols = [.../* @__PURE__ */ new Set([...prev.symbols_read ?? [], ...f.symbols_read ?? []])];
215
+ const fullReadCount = Math.max(prev.fullReadCount ?? 0, f.fullReadCount ?? 0);
216
+ const lastFullReadAt = Math.max(prev.lastFullReadAt ?? -1, f.lastFullReadAt ?? -1);
217
+ const epochBase = mergeEpochBase(prev.epochBase, f.epochBase);
218
+ const lastEditedAt = Math.max(prev.lastEditedAt ?? 0, f.lastEditedAt ?? 0);
481
219
  byPath.set(key, {
482
220
  path: prev.path,
483
221
  readCount: Math.max(prev.readCount, f.readCount),
484
222
  lastReadAt: Math.max(prev.lastReadAt, f.lastReadAt),
223
+ ...fullReadCount > 0 ? { fullReadCount } : {},
224
+ ...lastFullReadAt >= 0 ? { lastFullReadAt } : {},
485
225
  wasEdited: prev.wasEdited || f.wasEdited,
226
+ ...lastEditedAt > 0 ? { lastEditedAt } : {},
486
227
  sizeBytes: f.lastReadAt >= prev.lastReadAt ? f.sizeBytes : prev.sizeBytes,
487
228
  ...prev.wasTruncated || f.wasTruncated ? { wasTruncated: true } : {},
488
- ...mergedSymbols.length > 0 ? { symbols_read: mergedSymbols } : {}
229
+ ...mergedSymbols.length > 0 ? { symbols_read: mergedSymbols } : {},
230
+ ...epochBase !== void 0 ? { epochBase } : {}
489
231
  });
490
232
  }
491
233
  return Array.from(byPath.values());
@@ -552,10 +294,10 @@ function buildManifestParts(sessionId, cwd, transcriptPath) {
552
294
  for (const { entries, section } of fileSections) {
553
295
  const count = fit.shown[sections.indexOf(section)] ?? 0;
554
296
  for (const entry of entries.slice(0, count)) {
555
- const path2 = displaySafePath(entry.path);
556
- if (seen.has(path2)) continue;
557
- seen.add(path2);
558
- printed.push(path2);
297
+ const path = displaySafePath(entry.path);
298
+ if (seen.has(path)) continue;
299
+ seen.add(path);
300
+ printed.push(path);
559
301
  }
560
302
  }
561
303
  return { text: fit.text, printed };
@@ -630,6 +372,11 @@ function notesSection(notes) {
630
372
  }
631
373
  return { header: ["", ...lines.slice(0, open + 1)], rows, footer: lines.slice(close), priority: 2, maxRows: MAX_ROWS };
632
374
  }
375
+ function readIsSuperseded(f) {
376
+ const { reads, fullReads } = epochReadCounts(f);
377
+ if (wasEditedSinceCompaction(f)) return fullReads > 0;
378
+ return fullReads > 1 || reads > 1 && fullReads > 0 && f.lastFullReadAt !== void 0 && f.lastFullReadAt >= f.lastReadAt;
379
+ }
633
380
  function buildSafeToDiscardSection(files) {
634
381
  const rerunHashes = getSessionBashReruns();
635
382
  const bashOutputs = getSessionBashOutputs();
@@ -645,8 +392,8 @@ function buildSafeToDiscardSection(files) {
645
392
  }
646
393
  const supersededReadRows = [];
647
394
  for (const f of files) {
648
- if (f.readCount > 1 || f.wasEdited && f.readCount > 0) {
649
- const reason = f.wasEdited ? "edited after being read" : "re-read " + f.readCount + "x";
395
+ if (readIsSuperseded(f)) {
396
+ const reason = wasEditedSinceCompaction(f) ? "edited after being read" : "re-read " + epochReadCounts(f).reads + "x";
650
397
  supersededReadRows.push("- " + displaySafePath(f.path) + " (" + reason + " \u2014 only the latest content already in context is current)");
651
398
  }
652
399
  }
@@ -673,14 +420,14 @@ function buildSafeToDiscardSection(files) {
673
420
  }
674
421
  return sections;
675
422
  }
676
- function buildMemEpochSection() {
423
+ function buildMemEpochSection(timeoutMs = MEM_EPOCH_TIMEOUT_MS) {
677
424
  let result;
678
425
  try {
679
426
  const resolved = resolveOnPath("mem");
680
427
  if (resolved === null) return [];
681
428
  result = spawnResolvedSync(resolved, ["epoch"], {
682
429
  encoding: "utf-8",
683
- timeout: MEM_EPOCH_TIMEOUT_MS,
430
+ timeout: timeoutMs,
684
431
  windowsHide: true
685
432
  });
686
433
  } catch {
@@ -705,8 +452,8 @@ function summaryBudgetDirective(budgetChars) {
705
452
 
706
453
  // src/compact_dropped.ts
707
454
  init_define_import_meta_env();
708
- import { readFileSync as readFileSync2, rmSync, writeFileSync } from "node:fs";
709
- import { dirname as dirname2 } from "node:path";
455
+ import { readFileSync, rmSync, writeFileSync } from "node:fs";
456
+ import { dirname } from "node:path";
710
457
  var DROPPED_SUFFIX = ".compact-dropped";
711
458
  function recordCompactDroppedPaths(stateKey, paths) {
712
459
  const target = sessionSidecarPath(stateKey, DROPPED_SUFFIX);
@@ -716,7 +463,7 @@ function recordCompactDroppedPaths(stateKey, paths) {
716
463
  rmSync(target, { force: true });
717
464
  return;
718
465
  }
719
- ensureDirSync(dirname2(target));
466
+ ensureDirSync(dirname(target));
720
467
  writeFileSync(target, JSON.stringify(paths), "utf8");
721
468
  } catch {
722
469
  }
@@ -725,7 +472,7 @@ function readCompactDroppedPaths(stateKey) {
725
472
  const target = sessionSidecarPath(stateKey, DROPPED_SUFFIX);
726
473
  if (target === null) return [];
727
474
  try {
728
- const parsed = JSON.parse(readFileSync2(target, "utf8"));
475
+ const parsed = JSON.parse(readFileSync(target, "utf8"));
729
476
  return Array.isArray(parsed) ? parsed.filter((p) => typeof p === "string" && p !== "") : [];
730
477
  } catch {
731
478
  return [];
@@ -738,17 +485,6 @@ export {
738
485
  getWebOutput,
739
486
  getWebOutputRaw,
740
487
  getWebOutputByUrlFromDisk,
741
- MAX_ENTRIES,
742
- anchorLabel,
743
- anchorLine,
744
- loadEntries,
745
- loadDatedEntries,
746
- noteAgeLabel,
747
- oneLineNoteValue,
748
- setEntry,
749
- unsetEntry,
750
- clearAll,
751
- projectNotesFor,
752
488
  renderWebFetchRows,
753
489
  manifestPrintedPaths,
754
490
  buildManifest,
@@ -0,0 +1,58 @@
1
+ import { createRequire as __cjsRequire } from 'node:module';
2
+ const require = __cjsRequire(import.meta.url);
3
+ import {
4
+ getDb,
5
+ pathEqClause
6
+ } from "./token-goat-chunk-GVB2MUST.mjs";
7
+ import {
8
+ findProject
9
+ } from "./token-goat-chunk-4GBVPH3D.mjs";
10
+ import {
11
+ canonicalize,
12
+ foldPath
13
+ } from "./token-goat-chunk-AM5V6GSX.mjs";
14
+ import {
15
+ normalizePath
16
+ } from "./token-goat-chunk-FNFBKLRD.mjs";
17
+ import {
18
+ globalDbPath
19
+ } from "./token-goat-chunk-CO3UYX6G.mjs";
20
+ import {
21
+ init_define_import_meta_env
22
+ } from "./token-goat-chunk-A37V4PBF.mjs";
23
+
24
+ // src/indexed_roots.ts
25
+ init_define_import_meta_env();
26
+ import * as path from "node:path";
27
+ function indexedRootOf(dir) {
28
+ const project = findProject(dir);
29
+ if (project !== null) return normalizePath(project.root);
30
+ try {
31
+ return normalizePath(canonicalize(path.resolve(dir)));
32
+ } catch {
33
+ return null;
34
+ }
35
+ }
36
+ function recordIndexedRoot(dir, dbPath = globalDbPath()) {
37
+ try {
38
+ const root = indexedRootOf(dir);
39
+ if (root === null) return;
40
+ getDb(dbPath).prepare("INSERT INTO indexed_roots (root, indexed_ms) VALUES (?, ?) ON CONFLICT(root) DO UPDATE SET indexed_ms = excluded.indexed_ms").run(root, Date.now());
41
+ } catch {
42
+ }
43
+ }
44
+ function isIndexedRoot(dir, dbPath = globalDbPath()) {
45
+ if (dir === void 0) return false;
46
+ try {
47
+ const root = indexedRootOf(dir);
48
+ if (root === null) return false;
49
+ return getDb(dbPath).prepare(`SELECT 1 FROM indexed_roots WHERE ${pathEqClause("root")} LIMIT 1`).get(foldPath(root)) !== void 0;
50
+ } catch {
51
+ return false;
52
+ }
53
+ }
54
+
55
+ export {
56
+ recordIndexedRoot,
57
+ isIndexedRoot
58
+ };
@@ -0,0 +1,87 @@
1
+ import { createRequire as __cjsRequire } from 'node:module';
2
+ const require = __cjsRequire(import.meta.url);
3
+ import {
4
+ fenceUntrusted,
5
+ fenceWithMatches
6
+ } from "./token-goat-chunk-4NAPX7BA.mjs";
7
+ import {
8
+ estimateTokens,
9
+ trimToBudget
10
+ } from "./token-goat-chunk-BFCWY73P.mjs";
11
+ import {
12
+ GUARD_UNITS_PER_TOKEN,
13
+ guardUnits
14
+ } from "./token-goat-chunk-XX6O25RN.mjs";
15
+ import {
16
+ redactSecrets
17
+ } from "./token-goat-chunk-T5P5ACNQ.mjs";
18
+ import {
19
+ loadConfig
20
+ } from "./token-goat-chunk-7EZTZOMC.mjs";
21
+ import {
22
+ UNTRUSTED_FILE_TAG,
23
+ scanForInjectionPatterns
24
+ } from "./token-goat-chunk-FNFBKLRD.mjs";
25
+ import {
26
+ init_define_import_meta_env
27
+ } from "./token-goat-chunk-A37V4PBF.mjs";
28
+
29
+ // src/fence_cap.ts
30
+ init_define_import_meta_env();
31
+ function guardThenFence(text, command, tag) {
32
+ const cfg = loadConfig();
33
+ if (!cfg.overflow_guard.enabled) return fenceUntrusted(text, tag);
34
+ const budget = cfg.overflow_guard.max_tokens;
35
+ let capped = trimToBudget(text, budget, command);
36
+ let reserve = 0;
37
+ for (let pass = 0; pass < 8; pass++) {
38
+ const excess = estimateTokens(fenceThenMarker(capped, text, (body) => fenceWithMatches(body, scanUnrecorded(body), tag))) - budget;
39
+ if (excess <= 0) break;
40
+ reserve += excess;
41
+ capped = trimToBudget(text, budget, command, { reserveTokens: reserve });
42
+ }
43
+ return fenceThenMarker(capped, text, (body) => fenceUntrusted(body, tag));
44
+ }
45
+ function fenceThenMarker(capped, text, fence) {
46
+ if (capped === text) return fence(text);
47
+ const markerAt = capped.lastIndexOf("\n");
48
+ return `${fence(capped.slice(0, markerAt))}
49
+ ${capped.slice(markerAt + 1)}`;
50
+ }
51
+ function scanUnrecorded(text) {
52
+ try {
53
+ return scanForInjectionPatterns(text);
54
+ } catch {
55
+ return [];
56
+ }
57
+ }
58
+ function guardRedactAndFence(text, command, tag) {
59
+ return guardThenFence(redactSecrets(text).text, command, tag);
60
+ }
61
+ function guardAndFenceFileText(text, command) {
62
+ return guardRedactAndFence(text, command, UNTRUSTED_FILE_TAG);
63
+ }
64
+ function capListField(obj, key, render) {
65
+ const full = render(obj);
66
+ const cfg = loadConfig();
67
+ if (!cfg.overflow_guard.enabled) return full;
68
+ const budget = cfg.overflow_guard.max_tokens * GUARD_UNITS_PER_TOKEN;
69
+ const items = obj[key];
70
+ if (guardUnits(full) <= budget || items.length <= 1) return full;
71
+ const cut = (kept) => render({ ...obj, [key]: items.slice(0, kept), truncated: true, totalCount: items.length });
72
+ let lo = 1;
73
+ let hi = items.length - 1;
74
+ while (lo < hi) {
75
+ const mid = lo + hi + 1 >> 1;
76
+ if (guardUnits(cut(mid)) <= budget) lo = mid;
77
+ else hi = mid - 1;
78
+ }
79
+ return cut(lo);
80
+ }
81
+
82
+ export {
83
+ guardThenFence,
84
+ guardRedactAndFence,
85
+ guardAndFenceFileText,
86
+ capListField
87
+ };