token-goat 2.9.29 → 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 (197) hide show
  1. package/README.md +53 -42
  2. package/SECURITY.md +37 -11
  3. package/THIRD_PARTY_NOTICES.md +41 -4
  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/ort-wasm-simd-threaded.mjs +59 -0
  9. package/dist/{token-goat-chunk-SE6E4BKJ.mjs → token-goat-chunk-25TRAWET.mjs} +23 -6
  10. package/dist/token-goat-chunk-2KXO6V2B.mjs +203 -0
  11. package/dist/{token-goat-chunk-UXSXQQIY.mjs → token-goat-chunk-2M7E4PF7.mjs} +43 -14
  12. package/dist/token-goat-chunk-2UPZGKKY.mjs +188 -0
  13. package/dist/token-goat-chunk-2WLPWKHV.mjs +135 -0
  14. package/dist/token-goat-chunk-2XBMMDBD.mjs +126 -0
  15. package/dist/token-goat-chunk-32ZOY4N5.mjs +23 -0
  16. package/dist/token-goat-chunk-3EZRNKTK.mjs +188 -0
  17. package/dist/token-goat-chunk-4ADZHI7J.mjs +63 -0
  18. package/dist/token-goat-chunk-4GBVPH3D.mjs +242 -0
  19. package/dist/{token-goat-chunk-2WOUYWLM.mjs → token-goat-chunk-4GILLLWY.mjs} +34 -7
  20. package/dist/token-goat-chunk-4NAPX7BA.mjs +90 -0
  21. package/dist/{token-goat-chunk-NMBWLRHW.mjs → token-goat-chunk-4SC7UJYV.mjs} +9981 -11563
  22. package/dist/token-goat-chunk-4SMRO4TO.mjs +366 -0
  23. package/dist/{token-goat-chunk-O6I2XU4P.mjs → token-goat-chunk-4ZBFWLXF.mjs} +310 -441
  24. package/dist/token-goat-chunk-57BIAXJL.mjs +286 -0
  25. package/dist/token-goat-chunk-5AC66HNP.mjs +115 -0
  26. package/dist/token-goat-chunk-5IMLKSOP.mjs +145 -0
  27. package/dist/token-goat-chunk-5RG5SBL6.mjs +221 -0
  28. package/dist/{token-goat-chunk-RRNZMM3A.mjs → token-goat-chunk-5Y6ZYL6U.mjs} +21 -2
  29. package/dist/token-goat-chunk-646E6U44.mjs +398 -0
  30. package/dist/token-goat-chunk-65N4RHP4.mjs +33 -0
  31. package/dist/{token-goat-chunk-6AK46ZT7.mjs → token-goat-chunk-6DG6HWP3.mjs} +13 -3
  32. package/dist/token-goat-chunk-6ENQSNRZ.mjs +573 -0
  33. package/dist/token-goat-chunk-6ZY4GNF2.mjs +91 -0
  34. package/dist/{token-goat-chunk-E5TK5DNO.mjs → token-goat-chunk-76FGDLRO.mjs} +574 -340
  35. package/dist/{token-goat-chunk-TGOXNAHW.mjs → token-goat-chunk-7EZTZOMC.mjs} +780 -767
  36. package/dist/token-goat-chunk-7MAOA6X4.mjs +3647 -0
  37. package/dist/token-goat-chunk-7R2ZVVAX.mjs +218 -0
  38. package/dist/{token-goat-chunk-TCQANXYC.mjs → token-goat-chunk-AM5V6GSX.mjs} +18 -2
  39. package/dist/token-goat-chunk-AUNGYYQX.mjs +184 -0
  40. package/dist/token-goat-chunk-AUQYRMMH.mjs +2985 -0
  41. package/dist/token-goat-chunk-B3PEKBYG.mjs +128 -0
  42. package/dist/{token-goat-chunk-KOPIR3KZ.mjs → token-goat-chunk-BA4HI6BW.mjs} +1910 -165
  43. package/dist/{token-goat-chunk-52NSDWYY.mjs → token-goat-chunk-BFCWY73P.mjs} +58 -20
  44. package/dist/token-goat-chunk-BPGCUMR7.mjs +30 -0
  45. package/dist/token-goat-chunk-BWGFUZZE.mjs +25 -0
  46. package/dist/token-goat-chunk-C75NA7PL.mjs +322 -0
  47. package/dist/token-goat-chunk-CBIQ7WTD.mjs +87 -0
  48. package/dist/token-goat-chunk-CETM74KC.mjs +307 -0
  49. package/dist/token-goat-chunk-CIMQ2BB3.mjs +233 -0
  50. package/dist/{token-goat-chunk-DNSPXQXQ.mjs → token-goat-chunk-CJLS3CDL.mjs} +70 -18
  51. package/dist/{token-goat-chunk-MELOKFDJ.mjs → token-goat-chunk-CO3UYX6G.mjs} +7 -1
  52. package/dist/token-goat-chunk-COPNXRJM.mjs +154 -0
  53. package/dist/token-goat-chunk-CSJ5L3NL.mjs +479 -0
  54. package/dist/token-goat-chunk-CVCEVUGK.mjs +315 -0
  55. package/dist/token-goat-chunk-CXHOFN7R.mjs +371 -0
  56. package/dist/token-goat-chunk-D735C4QM.mjs +603 -0
  57. package/dist/{token-goat-chunk-E4ZOJIZK.mjs → token-goat-chunk-DGS2LVNA.mjs} +70 -160
  58. package/dist/{token-goat-chunk-L7H3U27L.mjs → token-goat-chunk-DOWRSMWO.mjs} +1 -1
  59. package/dist/token-goat-chunk-E45INMY3.mjs +71 -0
  60. package/dist/token-goat-chunk-EC5F37F4.mjs +244 -0
  61. package/dist/{token-goat-chunk-XTQAOTSO.mjs → token-goat-chunk-EDBDRVH5.mjs} +4 -1
  62. package/dist/token-goat-chunk-EELTBKDM.mjs +613 -0
  63. package/dist/token-goat-chunk-EVMZJ27Z.mjs +147 -0
  64. package/dist/token-goat-chunk-EXKGNHEG.mjs +2096 -0
  65. package/dist/{token-goat-chunk-YOOVFPTP.mjs → token-goat-chunk-F4HYL64R.mjs} +12 -2
  66. package/dist/token-goat-chunk-F6PAUIEK.mjs +624 -0
  67. package/dist/token-goat-chunk-FDSREWLX.mjs +692 -0
  68. package/dist/{token-goat-chunk-NMTKNYGF.mjs → token-goat-chunk-FNFBKLRD.mjs} +74 -9
  69. package/dist/token-goat-chunk-G5PJ7AGM.mjs +36 -0
  70. package/dist/token-goat-chunk-GGGG7RWB.mjs +236 -0
  71. package/dist/{token-goat-chunk-TDUT2CL6.mjs → token-goat-chunk-GL3ETKSC.mjs} +276 -19
  72. package/dist/{token-goat-chunk-7CPMDFGB.mjs → token-goat-chunk-GVB2MUST.mjs} +265 -1567
  73. package/dist/token-goat-chunk-GWFLAUMQ.mjs +307 -0
  74. package/dist/token-goat-chunk-HAVAOB3S.mjs +87 -0
  75. package/dist/token-goat-chunk-HLPW63A7.mjs +48 -0
  76. package/dist/token-goat-chunk-HU4TORC5.mjs +1377 -0
  77. package/dist/token-goat-chunk-I7VKZZAW.mjs +35 -0
  78. package/dist/token-goat-chunk-IA6XSPE3.mjs +218 -0
  79. package/dist/token-goat-chunk-IAGXMHIK.mjs +863 -0
  80. package/dist/{token-goat-chunk-435UQTKD.mjs → token-goat-chunk-IK2DRMFX.mjs} +129 -74
  81. package/dist/{token-goat-chunk-ZER6EAXZ.mjs → token-goat-chunk-INNPTRUX.mjs} +2954 -2783
  82. package/dist/token-goat-chunk-JJ5BX4F4.mjs +129 -0
  83. package/dist/token-goat-chunk-JVFSHVFJ.mjs +129 -0
  84. package/dist/token-goat-chunk-KGEFFSHD.mjs +50 -0
  85. package/dist/token-goat-chunk-KKUFXAPD.mjs +25 -0
  86. package/dist/token-goat-chunk-KQBLRPBN.mjs +433 -0
  87. package/dist/token-goat-chunk-LCNQ2CNN.mjs +497 -0
  88. package/dist/token-goat-chunk-M3LFJDPU.mjs +58 -0
  89. package/dist/token-goat-chunk-M52KPT3C.mjs +87 -0
  90. package/dist/token-goat-chunk-MBEG42H7.mjs +150 -0
  91. package/dist/{token-goat-chunk-EVC4TOLE.mjs → token-goat-chunk-METECDOH.mjs} +3 -12
  92. package/dist/{token-goat-chunk-2AWQ2R5X.mjs → token-goat-chunk-MHX7XCC3.mjs} +3 -2
  93. package/dist/token-goat-chunk-MNWKPRAL.mjs +13 -0
  94. package/dist/token-goat-chunk-N5LSOVSU.mjs +137 -0
  95. package/dist/{token-goat-chunk-DPNLUJWB.mjs → token-goat-chunk-N5MMR2IW.mjs} +30 -8
  96. package/dist/token-goat-chunk-N7B3JQ2C.mjs +160 -0
  97. package/dist/{token-goat-chunk-VMFWNHGR.mjs → token-goat-chunk-NISNMD7T.mjs} +2545 -2953
  98. package/dist/token-goat-chunk-NMD42SFQ.mjs +434 -0
  99. package/dist/token-goat-chunk-NOSS5VWY.mjs +174 -0
  100. package/dist/token-goat-chunk-NSNSPPBG.mjs +69 -0
  101. package/dist/token-goat-chunk-OBOFIHKN.mjs +38 -0
  102. package/dist/token-goat-chunk-OBRFJ5O5.mjs +76 -0
  103. package/dist/token-goat-chunk-ODBT2USM.mjs +800 -0
  104. package/dist/token-goat-chunk-OS5EM5PP.mjs +107 -0
  105. package/dist/token-goat-chunk-OUKDTVNU.mjs +1178 -0
  106. package/dist/token-goat-chunk-OXFMP75N.mjs +566 -0
  107. package/dist/{token-goat-chunk-ASLWOQ3I.mjs → token-goat-chunk-OYIYKDDT.mjs} +2 -1
  108. package/dist/{token-goat-chunk-67BNIKKO.mjs → token-goat-chunk-P6HQSWQ3.mjs} +55 -47
  109. package/dist/token-goat-chunk-P6VGNTQT.mjs +71 -0
  110. package/dist/token-goat-chunk-PFWIMH2E.mjs +261 -0
  111. package/dist/token-goat-chunk-PJZXIS3G.mjs +39 -0
  112. package/dist/token-goat-chunk-PUO5INXP.mjs +606 -0
  113. package/dist/token-goat-chunk-PX5PQWTY.mjs +462 -0
  114. package/dist/token-goat-chunk-Q5QDBC6O.mjs +111 -0
  115. package/dist/token-goat-chunk-QFNQXSDT.mjs +40 -0
  116. package/dist/token-goat-chunk-QH7YVYOY.mjs +3957 -0
  117. package/dist/token-goat-chunk-QLMUHEPB.mjs +43 -0
  118. package/dist/{token-goat-chunk-PYSUADX4.mjs → token-goat-chunk-QQOJIHL3.mjs} +50 -14
  119. package/dist/token-goat-chunk-QQTWJY2O.mjs +85 -0
  120. package/dist/token-goat-chunk-QYHO5CPH.mjs +93 -0
  121. package/dist/token-goat-chunk-RELAVWAD.mjs +27 -0
  122. package/dist/token-goat-chunk-RSLPOBKQ.mjs +339 -0
  123. package/dist/token-goat-chunk-SAMFDIS2.mjs +712 -0
  124. package/dist/token-goat-chunk-SDELXLDM.mjs +48 -0
  125. package/dist/{token-goat-chunk-PGTH2U4C.mjs → token-goat-chunk-SOAFZNNZ.mjs} +164 -40
  126. package/dist/{token-goat-chunk-G23DWHV4.mjs → token-goat-chunk-SRTHT7KV.mjs} +33 -15
  127. package/dist/token-goat-chunk-T5P5ACNQ.mjs +212 -0
  128. package/dist/token-goat-chunk-T5YGG4V3.mjs +45 -0
  129. package/dist/token-goat-chunk-TAUZ4OFS.mjs +110 -0
  130. package/dist/token-goat-chunk-TM6MC754.mjs +40 -0
  131. package/dist/token-goat-chunk-TWUKBOMP.mjs +72 -0
  132. package/dist/token-goat-chunk-U2KSB4SG.mjs +56 -0
  133. package/dist/token-goat-chunk-U4WHMG6Y.mjs +898 -0
  134. package/dist/token-goat-chunk-UA5V6P3P.mjs +122 -0
  135. package/dist/token-goat-chunk-UGJHGR5A.mjs +52 -0
  136. package/dist/{token-goat-chunk-RQGGMPCR.mjs → token-goat-chunk-UOUDVA5U.mjs} +76 -16
  137. package/dist/{token-goat-chunk-HNFZZHFW.mjs → token-goat-chunk-URRJ33GR.mjs} +22 -4
  138. package/dist/token-goat-chunk-UZOROKIS.mjs +165 -0
  139. package/dist/token-goat-chunk-VIHGGGEI.mjs +4234 -0
  140. package/dist/token-goat-chunk-VTJLAA7P.mjs +21 -0
  141. package/dist/token-goat-chunk-VWDXLT4F.mjs +678 -0
  142. package/dist/token-goat-chunk-VWZA2H4P.mjs +368 -0
  143. package/dist/{token-goat-chunk-QO3LXVVR.mjs → token-goat-chunk-VXEXMJDL.mjs} +2964 -3153
  144. package/dist/token-goat-chunk-WBA5SKT4.mjs +547 -0
  145. package/dist/{token-goat-chunk-ONXH6NZ5.mjs → token-goat-chunk-WDH44VAU.mjs} +19 -22
  146. package/dist/token-goat-chunk-X2SUP3EI.mjs +107 -0
  147. package/dist/token-goat-chunk-X3BELZSJ.mjs +125 -0
  148. package/dist/{token-goat-chunk-RLP6J7WR.mjs → token-goat-chunk-XLRBNZCC.mjs} +40 -21
  149. package/dist/{token-goat-chunk-S4VSXURL.mjs → token-goat-chunk-XRKUX6CM.mjs} +4 -0
  150. package/dist/token-goat-chunk-XX6O25RN.mjs +82 -0
  151. package/dist/token-goat-chunk-XZSUHBVS.mjs +65 -0
  152. package/dist/token-goat-chunk-Y2ZTQOCL.mjs +35 -0
  153. package/dist/{token-goat-chunk-UA5BKWWQ.mjs → token-goat-chunk-YB4VMGK2.mjs} +15 -4
  154. package/dist/token-goat-chunk-YBIIY3HR.mjs +51 -0
  155. package/dist/{token-goat-chunk-PKRWMHVP.mjs → token-goat-chunk-YHVDKQBR.mjs} +389 -221
  156. package/dist/token-goat-chunk-YJB5XLWI.mjs +26 -0
  157. package/dist/{token-goat-chunk-PQ53BSCF.mjs → token-goat-chunk-YKB6AQG3.mjs} +53 -31
  158. package/dist/token-goat-chunk-YMTG2YA5.mjs +35 -0
  159. package/dist/token-goat-chunk-YPBZYQRV.mjs +40 -0
  160. package/dist/{token-goat-chunk-HUYUHODZ.mjs → token-goat-chunk-YY6AVUFL.mjs} +13246 -12247
  161. package/dist/token-goat-chunk-Z7N5OMMP.mjs +98 -0
  162. package/dist/{token-goat-chunk-BGHSSJUA.mjs → token-goat-chunk-ZFOBKUWH.mjs} +1 -1
  163. package/dist/token-goat-chunk-ZMBL6UVV.mjs +110 -0
  164. package/dist/token-goat-chunk-ZNMNUPAZ.mjs +938 -0
  165. package/dist/token-goat-hook-client.cjs +87 -23
  166. package/dist/token-goat-hook-client.mjs +3 -3
  167. package/dist/token-goat-hook.mjs +76 -31
  168. package/dist/token-goat.core.mjs +6 -6
  169. package/docs/C4_RUNTIME_ARCHITECTURE.md +2 -2
  170. package/docs/cli.md +113 -60
  171. package/docs/install.md +63 -20
  172. package/docs/security.md +10 -8
  173. package/package.json +18 -7
  174. package/scripts/verify-native-dist.mjs +386 -0
  175. package/dist/token-goat-chunk-2NNUA2LR.mjs +0 -143
  176. package/dist/token-goat-chunk-44BM7DDQ.mjs +0 -294
  177. package/dist/token-goat-chunk-BGYOZ6DO.mjs +0 -24
  178. package/dist/token-goat-chunk-C5YPNZKQ.mjs +0 -318
  179. package/dist/token-goat-chunk-CIQ2FTY3.mjs +0 -1990
  180. package/dist/token-goat-chunk-D4ETHJD6.mjs +0 -246
  181. package/dist/token-goat-chunk-DNRPXHYH.mjs +0 -1062
  182. package/dist/token-goat-chunk-EUSDXRXU.mjs +0 -1429
  183. package/dist/token-goat-chunk-FTP4U4QA.mjs +0 -64
  184. package/dist/token-goat-chunk-G7IWXCFF.mjs +0 -456
  185. package/dist/token-goat-chunk-GLXRTTLE.mjs +0 -36
  186. package/dist/token-goat-chunk-H5J3C56Q.mjs +0 -1511
  187. package/dist/token-goat-chunk-IVWI2OCK.mjs +0 -368
  188. package/dist/token-goat-chunk-JTKCQMQA.mjs +0 -418
  189. package/dist/token-goat-chunk-LZNBQTDK.mjs +0 -26
  190. package/dist/token-goat-chunk-ORNFMIER.mjs +0 -295
  191. package/dist/token-goat-chunk-RTMVLHWX.mjs +0 -7113
  192. package/dist/token-goat-chunk-VQ6F6T7X.mjs +0 -36
  193. package/dist/token-goat-chunk-VZQEWRVH.mjs +0 -312
  194. package/dist/token-goat-chunk-XYWPOSCN.mjs +0 -807
  195. package/dist/token-goat-chunk-YAGLESS3.mjs +0 -23
  196. package/dist/token-goat-chunk-YKSRAWUU.mjs +0 -33
  197. package/dist/token-goat-chunk-Z6KBMOBI.mjs +0 -53
@@ -1,103 +1,149 @@
1
1
  import { createRequire as __cjsRequire } from 'node:module';
2
2
  const require = __cjsRequire(import.meta.url);
3
3
  import {
4
- ABSENT_PIN,
5
4
  CONTENT_MAX_INPUT_CHARS,
6
- ConfinementIdentityError,
5
+ checkSemanticReadiness,
7
6
  compressText,
8
7
  createHandoff,
9
- fileIdentity,
10
- findSpecSeparator,
11
- parseColonLineSpec,
12
- parseLineRange,
13
- pinKey,
14
8
  resolveHandoff,
15
9
  retrieveText,
16
10
  runBrief,
17
11
  runChanged,
18
12
  runExports,
19
- runGrep,
20
13
  runImports,
21
14
  runOutline,
22
- runRead,
23
15
  runRefs,
24
16
  runSection,
25
17
  runSemantic,
26
18
  runSkeleton,
27
19
  runSymbol,
28
- statThroughHandle,
20
+ statThroughHandle
21
+ } from "./token-goat-chunk-VIHGGGEI.mjs";
22
+ import "./token-goat-chunk-YKB6AQG3.mjs";
23
+ import "./token-goat-chunk-COPNXRJM.mjs";
24
+ import {
25
+ ABSENT_PIN,
26
+ ConfinementIdentityError,
27
+ expandSpecPath,
28
+ fileIdentity,
29
+ pinKey,
30
+ resolveProjectConfinement,
31
+ runGrep,
32
+ runRead,
33
+ specFilePart,
29
34
  withPinnedReads
30
- } from "./token-goat-chunk-NMBWLRHW.mjs";
31
- import "./token-goat-chunk-VZQEWRVH.mjs";
32
- import "./token-goat-chunk-PQ53BSCF.mjs";
35
+ } from "./token-goat-chunk-4SC7UJYV.mjs";
36
+ import "./token-goat-chunk-QQTWJY2O.mjs";
37
+ import "./token-goat-chunk-EC5F37F4.mjs";
33
38
  import {
34
39
  buildProjectMap,
35
40
  formatProjectMap,
36
- getDirtyPathsFor,
37
41
  getEmbeddingCoverage,
38
42
  getProjectIndexCounts,
39
- isWorkerRunning,
43
+ isIndexEmptyForProject,
40
44
  mapLookupBytesSaved
41
- } from "./token-goat-chunk-RTMVLHWX.mjs";
42
- import "./token-goat-chunk-L7H3U27L.mjs";
43
- import "./token-goat-chunk-RRNZMM3A.mjs";
44
- import "./token-goat-chunk-E5TK5DNO.mjs";
45
- import "./token-goat-chunk-ZER6EAXZ.mjs";
46
- import "./token-goat-chunk-EUSDXRXU.mjs";
47
- import "./token-goat-chunk-H5J3C56Q.mjs";
48
- import "./token-goat-chunk-TDUT2CL6.mjs";
45
+ } from "./token-goat-chunk-ZNMNUPAZ.mjs";
46
+ import "./token-goat-chunk-32ZOY4N5.mjs";
47
+ import "./token-goat-chunk-SOAFZNNZ.mjs";
48
+ import "./token-goat-chunk-M52KPT3C.mjs";
49
+ import "./token-goat-chunk-CJLS3CDL.mjs";
50
+ import "./token-goat-chunk-2UPZGKKY.mjs";
51
+ import "./token-goat-chunk-5RG5SBL6.mjs";
52
+ import "./token-goat-chunk-DOWRSMWO.mjs";
53
+ import "./token-goat-chunk-VWZA2H4P.mjs";
54
+ import "./token-goat-chunk-N5LSOVSU.mjs";
55
+ import "./token-goat-chunk-OBOFIHKN.mjs";
56
+ import "./token-goat-chunk-QH7YVYOY.mjs";
57
+ import "./token-goat-chunk-NOSS5VWY.mjs";
58
+ import "./token-goat-chunk-NMD42SFQ.mjs";
59
+ import "./token-goat-chunk-SAMFDIS2.mjs";
60
+ import "./token-goat-chunk-4SMRO4TO.mjs";
61
+ import "./token-goat-chunk-WBA5SKT4.mjs";
62
+ import "./token-goat-chunk-MNWKPRAL.mjs";
63
+ import {
64
+ getDirtyPathsFor
65
+ } from "./token-goat-chunk-CIMQ2BB3.mjs";
66
+ import "./token-goat-chunk-WDH44VAU.mjs";
49
67
  import {
50
68
  claudeConfigDir
51
- } from "./token-goat-chunk-ONXH6NZ5.mjs";
52
- import "./token-goat-chunk-O6I2XU4P.mjs";
53
- import "./token-goat-chunk-D4ETHJD6.mjs";
54
- import "./token-goat-chunk-52NSDWYY.mjs";
55
- import "./token-goat-chunk-2WOUYWLM.mjs";
69
+ } from "./token-goat-chunk-BPGCUMR7.mjs";
70
+ import "./token-goat-chunk-KQBLRPBN.mjs";
71
+ import "./token-goat-chunk-4ZBFWLXF.mjs";
72
+ import "./token-goat-chunk-C75NA7PL.mjs";
73
+ import {
74
+ displaySafeFailureText
75
+ } from "./token-goat-chunk-CBIQ7WTD.mjs";
76
+ import "./token-goat-chunk-P6VGNTQT.mjs";
77
+ import "./token-goat-chunk-76FGDLRO.mjs";
78
+ import "./token-goat-chunk-GL3ETKSC.mjs";
79
+ import "./token-goat-chunk-OXFMP75N.mjs";
80
+ import {
81
+ embeddingsDepsAvailable
82
+ } from "./token-goat-chunk-NISNMD7T.mjs";
83
+ import "./token-goat-chunk-EVMZJ27Z.mjs";
84
+ import "./token-goat-chunk-IK2DRMFX.mjs";
85
+ import "./token-goat-chunk-5Y6ZYL6U.mjs";
86
+ import "./token-goat-chunk-4NAPX7BA.mjs";
56
87
  import {
57
88
  recordStat,
58
89
  savedTokensFromBytes
59
- } from "./token-goat-chunk-CIQ2FTY3.mjs";
60
- import "./token-goat-chunk-SE6E4BKJ.mjs";
61
- import "./token-goat-chunk-DNSPXQXQ.mjs";
90
+ } from "./token-goat-chunk-U4WHMG6Y.mjs";
91
+ import {
92
+ getDb,
93
+ pathSuffixClause
94
+ } from "./token-goat-chunk-GVB2MUST.mjs";
95
+ import "./token-goat-chunk-XB5KKOCG.mjs";
96
+ import "./token-goat-chunk-OUKDTVNU.mjs";
62
97
  import "./token-goat-chunk-3BTK54F3.mjs";
63
- import "./token-goat-chunk-XTQAOTSO.mjs";
64
- import "./token-goat-chunk-AH6QILZM.mjs";
65
- import "./token-goat-chunk-PGTH2U4C.mjs";
98
+ import "./token-goat-chunk-4GILLLWY.mjs";
99
+ import "./token-goat-chunk-BFCWY73P.mjs";
66
100
  import {
67
- checkEmbeddingPreflight,
68
- embeddingsDepsAvailable
69
- } from "./token-goat-chunk-VMFWNHGR.mjs";
70
- import "./token-goat-chunk-435UQTKD.mjs";
101
+ forClient,
102
+ mcpFriendlyText
103
+ } from "./token-goat-chunk-KGEFFSHD.mjs";
104
+ import "./token-goat-chunk-XX6O25RN.mjs";
105
+ import "./token-goat-chunk-HAVAOB3S.mjs";
71
106
  import {
72
- getDb
73
- } from "./token-goat-chunk-7CPMDFGB.mjs";
107
+ isWorkerRunning
108
+ } from "./token-goat-chunk-F6PAUIEK.mjs";
109
+ import "./token-goat-chunk-65N4RHP4.mjs";
110
+ import "./token-goat-chunk-X2SUP3EI.mjs";
111
+ import "./token-goat-chunk-25TRAWET.mjs";
112
+ import "./token-goat-chunk-T5P5ACNQ.mjs";
113
+ import {
114
+ loadConfig
115
+ } from "./token-goat-chunk-7EZTZOMC.mjs";
116
+ import "./token-goat-chunk-QYHO5CPH.mjs";
74
117
  import {
75
- loadConfig,
76
118
  resolveProjectRoot
77
- } from "./token-goat-chunk-TGOXNAHW.mjs";
78
- import "./token-goat-chunk-XB5KKOCG.mjs";
119
+ } from "./token-goat-chunk-4GBVPH3D.mjs";
79
120
  import "./token-goat-chunk-YZAAZU2S.mjs";
80
121
  import {
81
122
  envStrList
82
123
  } from "./token-goat-chunk-IVE6U7KV.mjs";
124
+ import "./token-goat-chunk-EDBDRVH5.mjs";
125
+ import "./token-goat-chunk-AH6QILZM.mjs";
126
+ import "./token-goat-chunk-Y4AFKTHK.mjs";
83
127
  import {
84
128
  extractErrorMessage
85
- } from "./token-goat-chunk-XYWPOSCN.mjs";
129
+ } from "./token-goat-chunk-HU4TORC5.mjs";
130
+ import {
131
+ echoedValue,
132
+ stripUnsafeSuggestions
133
+ } from "./token-goat-chunk-GGGG7RWB.mjs";
86
134
  import {
87
135
  foldCaseForContainment
88
- } from "./token-goat-chunk-TCQANXYC.mjs";
136
+ } from "./token-goat-chunk-AM5V6GSX.mjs";
89
137
  import {
90
138
  displaySafeJson,
91
139
  normalizePath
92
- } from "./token-goat-chunk-NMTKNYGF.mjs";
140
+ } from "./token-goat-chunk-FNFBKLRD.mjs";
93
141
  import {
94
142
  ENV_KEYS,
95
143
  VERSION,
96
144
  dataDir,
97
145
  globalDbPath
98
- } from "./token-goat-chunk-MELOKFDJ.mjs";
99
- import "./token-goat-chunk-Y4AFKTHK.mjs";
100
- import "./token-goat-chunk-JTKCQMQA.mjs";
146
+ } from "./token-goat-chunk-CO3UYX6G.mjs";
101
147
  import {
102
148
  init_define_import_meta_env
103
149
  } from "./token-goat-chunk-A37V4PBF.mjs";
@@ -107,32 +153,15 @@ init_define_import_meta_env();
107
153
  import * as fs from "fs";
108
154
  import * as os from "os";
109
155
  import * as path from "path";
110
- var TOKEN_GOAT_RETRY_RE = /token-goat (\w[\w-]*) "([^"]+)"/g;
111
156
  var MCP_MAX_LIMIT = 1e3;
112
157
  var MCP_MAX_CONTEXT_LINES = 50;
113
158
  var MCP_MAX_OUTPUT_LINES = 1e4;
114
159
  var MCP_MAX_MIN_LINES = 1e5;
115
- var RETRY_PARAM_BY_COMMAND = {
116
- read: "spec",
117
- section: "spec",
118
- symbol: "name",
119
- skeleton: "file",
120
- outline: "file"
121
- };
122
- function mcpFriendlyText(text) {
123
- let out = text.replace(TOKEN_GOAT_RETRY_RE, (_match, cmd, arg) => {
124
- const param = RETRY_PARAM_BY_COMMAND[cmd] ?? "parameter";
125
- return `the "${cmd}" tool again with a more specific ${param} (e.g. "${arg}")`;
126
- });
127
- out = out.replace(/--json\b/g, "the json parameter");
128
- out = out.replace(/--limit\b/g, "the limit parameter");
129
- out = out.replace(/--top\b/g, "the top parameter");
130
- out = out.replace(/--grep PATTERN, --section HEADING, or --tail N/g, "a narrower query");
131
- return out;
132
- }
160
+ var DEFAULT_MCP_TOOLS = ["symbol", "read", "section", "outline", "semantic", "refs", "retrieve_text"];
133
161
  function toCallToolResult(result) {
162
+ const text = result.code === 0 ? result.text : mcpFriendlyText(stripUnsafeSuggestions(displaySafeFailureText(result.text)));
134
163
  return {
135
- content: [{ type: "text", text: mcpFriendlyText(result.text) }],
164
+ content: [{ type: "text", text }],
136
165
  isError: result.code !== 0
137
166
  };
138
167
  }
@@ -149,16 +178,16 @@ function toRawCallToolResult(result) {
149
178
  }
150
179
  function captureOutput(fn) {
151
180
  const chunks = [];
152
- const record = (chunk, encodingOrCb, maybeCb) => {
153
- chunks.push(typeof chunk === "string" ? chunk : Buffer.from(chunk).toString("utf-8"));
181
+ const recorder = (word) => (chunk, encodingOrCb, maybeCb) => {
182
+ chunks.push(word(typeof chunk === "string" ? chunk : Buffer.from(chunk).toString("utf-8")));
154
183
  const callback = typeof encodingOrCb === "function" ? encodingOrCb : typeof maybeCb === "function" ? maybeCb : void 0;
155
184
  if (typeof callback === "function") callback();
156
185
  return true;
157
186
  };
158
187
  const origStdoutWrite = process.stdout.write.bind(process.stdout);
159
188
  const origStderrWrite = process.stderr.write.bind(process.stderr);
160
- process.stdout.write = record;
161
- process.stderr.write = record;
189
+ process.stdout.write = recorder((text) => text);
190
+ process.stderr.write = recorder(forClient);
162
191
  try {
163
192
  const code = fn();
164
193
  return { code, text: chunks.join("") };
@@ -182,8 +211,86 @@ function realPathForContainment(p) {
182
211
  function forCompare(p) {
183
212
  return process.platform === "win32" ? foldCaseForContainment(p) : p;
184
213
  }
185
- function resolveToolRoot(projectRoot) {
186
- const resolved = resolveProjectRoot(projectRoot !== void 0 ? { project: projectRoot } : {});
214
+ function inferProjectRootFromTarget(target) {
215
+ const file = specFilePart(target);
216
+ if (!file) return null;
217
+ if (path.isAbsolute(file)) {
218
+ if (fs.existsSync(file)) {
219
+ try {
220
+ return resolveProjectRoot({ project: path.dirname(file) });
221
+ } catch {
222
+ return null;
223
+ }
224
+ }
225
+ return null;
226
+ }
227
+ try {
228
+ if (fs.existsSync(path.resolve(process.cwd(), file))) {
229
+ return null;
230
+ }
231
+ } catch {
232
+ }
233
+ const dbPath = globalDbPath();
234
+ if (fs.existsSync(dbPath)) {
235
+ try {
236
+ const db = getDb(dbPath);
237
+ const suffix = pathSuffixClause("path");
238
+ const rows = db.prepare(`SELECT path FROM files WHERE ${suffix.clause} ORDER BY length(path), path LIMIT 5`).all(...suffix.params(normalizePath(file)));
239
+ for (const row of rows) {
240
+ if (fs.existsSync(row.path)) {
241
+ return resolveProjectRoot({ project: path.dirname(row.path) });
242
+ }
243
+ }
244
+ } catch {
245
+ }
246
+ }
247
+ if (!file.includes("/") && !file.includes("\\") && !file.includes(".")) {
248
+ if (fs.existsSync(dbPath)) {
249
+ try {
250
+ const db = getDb(dbPath);
251
+ const rows = db.prepare(`SELECT file_path FROM symbols WHERE name = ? LIMIT 5`).all(file);
252
+ for (const row of rows) {
253
+ if (fs.existsSync(row.file_path)) {
254
+ return resolveProjectRoot({ project: path.dirname(row.file_path) });
255
+ }
256
+ }
257
+ } catch {
258
+ }
259
+ }
260
+ }
261
+ return null;
262
+ }
263
+ function rootHasIndexedFiles(root) {
264
+ const dbPath = globalDbPath();
265
+ if (!fs.existsSync(dbPath)) return false;
266
+ try {
267
+ const prefix = normalizePath(root).toLowerCase().replace(/\/+$/, "") + "/";
268
+ const row = getDb(dbPath).prepare(`SELECT 1 FROM files WHERE TG_LOWER(substr(path, 1, ?)) = ? LIMIT 1`).get(prefix.length, prefix);
269
+ return row !== void 0;
270
+ } catch {
271
+ return false;
272
+ }
273
+ }
274
+ function resolveToolRoot(projectRoot, candidateTargets) {
275
+ if (projectRoot !== void 0) {
276
+ const resolved2 = resolveProjectRoot({ project: projectRoot });
277
+ assertRootAllowed(resolved2);
278
+ return resolved2;
279
+ }
280
+ if (candidateTargets && candidateTargets.length > 0) {
281
+ for (const target of candidateTargets) {
282
+ if (!target) continue;
283
+ const inferred = inferProjectRootFromTarget(target);
284
+ if (inferred && rootHasIndexedFiles(inferred)) {
285
+ try {
286
+ assertRootAllowed(inferred);
287
+ return inferred;
288
+ } catch {
289
+ }
290
+ }
291
+ }
292
+ }
293
+ const resolved = resolveProjectRoot({});
187
294
  assertRootAllowed(resolved);
188
295
  return resolved;
189
296
  }
@@ -225,7 +332,7 @@ function assertRootAllowed(resolvedRoot) {
225
332
  if (allowedRoots.some((allowed) => checkWithinProjectRoot(resolvedRoot, allowed).inside)) return;
226
333
  if (getStandardAuxiliaryRoots(resolvedRoot).some((aux) => checkWithinProjectRoot(resolvedRoot, aux).inside)) return;
227
334
  throw new RootNotAllowedError(
228
- `refused: "${resolvedRoot}" is not inside any root listed in mcp.allowed_roots. A caller-supplied projectRoot is untrusted input, so this deployment pins which roots may be named; add the root to mcp.allowed_roots (or TOKEN_GOAT_MCP_ALLOWED_ROOTS) to permit it.`
335
+ `refused: ${echoedValue(resolvedRoot)} is not inside any root listed in mcp.allowed_roots. A caller-supplied projectRoot is untrusted input, so this deployment pins which roots may be named; add the root to mcp.allowed_roots (or TOKEN_GOAT_MCP_ALLOWED_ROOTS) to permit it.`
229
336
  );
230
337
  }
231
338
  var NO_CHECK_PINS = [];
@@ -251,8 +358,9 @@ function pinsFor(abs, real, identity) {
251
358
  }
252
359
  function checkWithinProjectRoot(target, resolvedRoot) {
253
360
  const rootReal = realPathForContainment(resolvedRoot);
254
- const abs = path.resolve(resolvedRoot, normalizePath(target));
255
- const absRaw = path.resolve(resolvedRoot, target);
361
+ const spelled = expandSpecPath(target);
362
+ const abs = path.resolve(resolvedRoot, normalizePath(spelled));
363
+ const absRaw = path.resolve(resolvedRoot, spelled);
256
364
  const identity = identityOf(absRaw);
257
365
  const realNative = realPathForContainment(abs);
258
366
  if (rootReal === null) return { inside: false, reason: "unresolvable-root", pins: NO_CHECK_PINS };
@@ -269,27 +377,26 @@ function checkWithinProjectRoot(target, resolvedRoot) {
269
377
  if (!under(realRaw)) return { inside: false, reason: "outside", pins: NO_CHECK_PINS };
270
378
  return { inside: true, reason: "inside", pins: [...pinsFor(abs, realNative, identity), ...pinsFor(absRaw, realRaw, identity)] };
271
379
  }
272
- function specFilePart(spec) {
273
- const range = parseLineRange(spec);
274
- if (range !== null) return range.file;
275
- const region = parseColonLineSpec(spec);
276
- if (region !== null) return region.file;
277
- const colonIdx = findSpecSeparator(spec);
278
- return colonIdx === -1 ? spec : spec.slice(0, colonIdx);
380
+ function specFileCandidates(spec) {
381
+ const file = specFilePart(spec);
382
+ const out = [file];
383
+ for (let idx = file.indexOf("::"); idx !== -1; idx = file.indexOf("::", idx + 1)) if (idx > 0) out.push(file.slice(0, idx));
384
+ return out;
279
385
  }
280
386
  var NO_PINS = /* @__PURE__ */ new Map();
281
- function refusalText(file, resolvedRoot, reason) {
387
+ function refusalText(file, resolvedRoot, reason, projectRootWasOmitted = false) {
282
388
  const escapeHatch = "Set mcp.confine_reads_to_project_root = false (or TOKEN_GOAT_MCP_CONFINE_READS=0) to allow cross-root reads.";
389
+ const omittedNote = projectRootWasOmitted ? ` Note: projectRoot was omitted and defaulted to server process cwd ${echoedValue(resolvedRoot)}. Pass projectRoot: "<workspace-path>" if your target is in another directory.` : "";
283
390
  if (reason === "unresolvable-root") {
284
- return `refused: the project root "${resolvedRoot}" could not be resolved, so no path can be confirmed to sit inside it. This is a broken workspace root -- an unmounted share, a deleted directory, or a permission change on a parent -- not a request to read outside the project.`;
391
+ return `refused: the project root ${echoedValue(resolvedRoot)} could not be resolved, so no path can be confirmed to sit inside it. This is a broken workspace root -- an unmounted share, a deleted directory, or a permission change on a parent -- not a request to read outside the project.` + omittedNote;
285
392
  }
286
393
  if (reason === "unresolvable-target") {
287
- return `refused: "${file}" could not be resolved to a real location, so it cannot be confirmed to sit inside the project root. A symlink loop, a permission error on a parent directory, or a path past the operating system's length limit all produce this. The check fails closed rather than falling back to comparing the text of the path.`;
394
+ return `refused: ${echoedValue(file)} could not be resolved to a real location, so it cannot be confirmed to sit inside the project root. A symlink loop, a permission error on a parent directory, or a path past the operating system's length limit all produce this. The check fails closed rather than falling back to comparing the text of the path.` + omittedNote;
288
395
  }
289
396
  const rootScope = loadConfig().mcp.allowed_roots.length === 0 ? "Each call is confined to the projectRoot it names, and that root comes from the caller: set mcp.allowed_roots (or TOKEN_GOAT_MCP_ALLOWED_ROOTS) to pin which roots may be named at all." : "Each call is confined to the projectRoot it names, which must itself sit inside mcp.allowed_roots.";
290
- return `refused: "${file}" is outside the project root "${resolvedRoot}". ${rootScope} ${escapeHatch}`;
397
+ return `refused: ${echoedValue(file)} is outside the project root ${echoedValue(resolvedRoot)}. ${rootScope} ${escapeHatch}${omittedNote}`;
291
398
  }
292
- function confineTargets(targets, resolvedRoot, splitCommas = true) {
399
+ function confineTargets(targets, resolvedRoot, splitCommas = true, projectRootWasOmitted = false) {
293
400
  if (!loadConfig(resolvedRoot).mcp.confine_reads_to_project_root) return { ok: true, targets, pins: NO_PINS };
294
401
  const allowedRoots = loadConfig().mcp.allowed_roots;
295
402
  const checked = [];
@@ -297,31 +404,32 @@ function confineTargets(targets, resolvedRoot, splitCommas = true) {
297
404
  for (const raw of targets) {
298
405
  const parts = splitCommas ? raw.split(",") : [raw];
299
406
  for (const part of parts) {
300
- const file = specFilePart(part);
301
- if (file === "") continue;
302
- let check = checkWithinProjectRoot(file, resolvedRoot);
303
- if (!check.inside) {
304
- for (const allowed of allowedRoots) {
305
- const altCheck = checkWithinProjectRoot(file, allowed);
306
- if (altCheck.inside) {
307
- check = altCheck;
308
- break;
407
+ for (const file of specFileCandidates(part)) {
408
+ if (file === "") continue;
409
+ let check = checkWithinProjectRoot(file, resolvedRoot);
410
+ if (!check.inside) {
411
+ for (const allowed of allowedRoots) {
412
+ const altCheck = checkWithinProjectRoot(file, allowed);
413
+ if (altCheck.inside) {
414
+ check = altCheck;
415
+ break;
416
+ }
309
417
  }
310
418
  }
311
- }
312
- if (!check.inside) {
313
- for (const aux of getStandardAuxiliaryRoots(file)) {
314
- const auxCheck = checkWithinProjectRoot(file, aux);
315
- if (auxCheck.inside) {
316
- check = auxCheck;
317
- break;
419
+ if (!check.inside) {
420
+ for (const aux of getStandardAuxiliaryRoots(file)) {
421
+ const auxCheck = checkWithinProjectRoot(file, aux);
422
+ if (auxCheck.inside) {
423
+ check = auxCheck;
424
+ break;
425
+ }
318
426
  }
319
427
  }
428
+ if (!check.inside) {
429
+ return { ok: false, refusal: toCallToolResult({ text: refusalText(file, resolvedRoot, check.reason, projectRootWasOmitted), code: 1 }) };
430
+ }
431
+ for (const [key, identity] of check.pins) pins.set(key, identity);
320
432
  }
321
- if (!check.inside) {
322
- return { ok: false, refusal: toCallToolResult({ text: refusalText(file, resolvedRoot, check.reason), code: 1 }) };
323
- }
324
- for (const [key, identity] of check.pins) pins.set(key, identity);
325
433
  }
326
434
  checked.push(splitCommas ? parts.join(",") : parts[0]);
327
435
  }
@@ -340,31 +448,45 @@ function withConfinedRead(pins, fn) {
340
448
  throw err;
341
449
  }
342
450
  }
451
+ function noteOmittedProjectRoot(result, root, projectRootWasOmitted) {
452
+ if (!projectRootWasOmitted) return result;
453
+ if (!isIndexEmptyForProject(globalDbPath(), root)) return result;
454
+ const note = `
455
+ (Note: projectRoot was omitted and defaulted to server cwd ${echoedValue(root)}, which has no files indexed. Pass projectRoot: "<workspace-path>" to target your workspace.)`;
456
+ const contents = result.content;
457
+ if (!Array.isArray(contents)) return result;
458
+ for (const item of contents) {
459
+ if (item && typeof item === "object" && "text" in item && typeof item.text === "string") {
460
+ if (!item.text.includes("projectRoot was omitted")) {
461
+ item.text += note;
462
+ }
463
+ }
464
+ }
465
+ return result;
466
+ }
343
467
  function mcpToolAllowlist() {
344
468
  const names = envStrList(ENV_KEYS.MCP_TOOLS, [], ",");
345
- return names.length === 0 ? null : new Set(names);
469
+ return new Set(names.length === 0 ? DEFAULT_MCP_TOOLS : names);
346
470
  }
347
471
  async function createMcpServer() {
348
- const [{ McpServer }, { z }] = await Promise.all([import("./token-goat-chunk-6AK46ZT7.mjs"), import("./token-goat-chunk-CHLHM42P.mjs")]);
472
+ const [{ McpServer }, { z }] = await Promise.all([import("./token-goat-chunk-6DG6HWP3.mjs"), import("./token-goat-chunk-CHLHM42P.mjs")]);
349
473
  const server = new McpServer({ name: "token-goat", version: VERSION });
350
474
  const allowlist = mcpToolAllowlist();
351
- if (allowlist !== null) {
352
- const matched = /* @__PURE__ */ new Set();
353
- const registerAll = server.registerTool.bind(server);
354
- server.registerTool = ((name, definition, handler) => {
355
- if (!allowlist.has(name)) return;
356
- matched.add(name);
357
- registerAll(name, definition, handler);
358
- });
359
- setTimeout(() => {
360
- const unmatched = [...allowlist].filter((n) => !matched.has(n));
361
- if (unmatched.length > 0) {
362
- process.stderr.write(`token-goat: ${ENV_KEYS.MCP_TOOLS} names no such tool: ${unmatched.join(", ")}
475
+ const matched = /* @__PURE__ */ new Set();
476
+ const registerAll = server.registerTool.bind(server);
477
+ server.registerTool = ((name, definition, handler) => {
478
+ if (!allowlist.has(name)) return;
479
+ matched.add(name);
480
+ registerAll(name, definition, handler);
481
+ });
482
+ setTimeout(() => {
483
+ const unmatched = [...allowlist].filter((n) => !matched.has(n));
484
+ if (unmatched.length > 0) {
485
+ process.stderr.write(`token-goat: ${ENV_KEYS.MCP_TOOLS} names no such tool: ${unmatched.join(", ")}
363
486
  `);
364
- }
365
- }, 0).unref();
366
- }
367
- const projectRootField = z.string().optional().describe("absolute workspace root; defaults to the server's cwd, which may not be the workspace, so pass it when unsure");
487
+ }
488
+ }, 0).unref();
489
+ const projectRootField = z.string().optional().describe("absolute workspace root; defaults to the server's cwd, which may not be your workspace");
368
490
  server.registerTool(
369
491
  "symbol",
370
492
  {
@@ -381,27 +503,32 @@ async function createMcpServer() {
381
503
  },
382
504
  (args) => {
383
505
  const { name, limit, file, kind, json, projectRoot } = args;
384
- const root = resolveToolRoot(projectRoot);
506
+ const projectRootWasOmitted = projectRoot === void 0;
507
+ const root = resolveToolRoot(projectRoot, file ? [file] : name ? [name] : void 0);
385
508
  let confinedFile = file;
386
509
  let pins = NO_PINS;
387
510
  if (file !== void 0) {
388
- const gate = confineTargets([file], root);
511
+ const gate = confineTargets([file], root, true, projectRootWasOmitted);
389
512
  if (!gate.ok) return gate.refusal;
390
513
  confinedFile = gate.targets[0];
391
514
  pins = gate.pins;
392
515
  }
393
- return withConfinedRead(
394
- pins,
395
- () => toCallToolResult(
396
- runSymbol({
397
- name,
398
- limit: limit ?? 20,
399
- ...confinedFile !== void 0 ? { file: confinedFile } : {},
400
- ...kind !== void 0 ? { kind } : {},
401
- ...json === true ? { json: true } : {},
402
- projectRoot: root
403
- })
404
- )
516
+ return noteOmittedProjectRoot(
517
+ withConfinedRead(
518
+ pins,
519
+ () => toCallToolResult(
520
+ runSymbol({
521
+ name,
522
+ limit: limit ?? 20,
523
+ ...confinedFile !== void 0 ? { file: confinedFile } : {},
524
+ ...kind !== void 0 ? { kind } : {},
525
+ ...json === true ? { json: true } : {},
526
+ projectRoot: root
527
+ })
528
+ )
529
+ ),
530
+ root,
531
+ projectRootWasOmitted
405
532
  );
406
533
  }
407
534
  );
@@ -421,20 +548,25 @@ async function createMcpServer() {
421
548
  },
422
549
  (args) => {
423
550
  const { spec, json, forceRefresh, stats, projectRoot } = args;
424
- const root = resolveToolRoot(projectRoot);
425
- const gate = confineTargets([spec], root);
551
+ const projectRootWasOmitted = projectRoot === void 0;
552
+ const root = resolveToolRoot(projectRoot, [spec]);
553
+ const gate = confineTargets([spec], root, true, projectRootWasOmitted);
426
554
  if (!gate.ok) return gate.refusal;
427
- return withConfinedRead(
428
- gate.pins,
429
- () => toCallToolResult(
430
- runRead({
431
- spec: gate.targets[0],
432
- ...json === true ? { json: true } : {},
433
- ...forceRefresh === true ? { forceRefresh: true } : {},
434
- ...stats === true ? { stats: true } : {},
435
- projectRoot: root
436
- })
437
- )
555
+ return noteOmittedProjectRoot(
556
+ withConfinedRead(
557
+ gate.pins,
558
+ () => toCallToolResult(
559
+ runRead({
560
+ spec: gate.targets[0],
561
+ ...json === true ? { json: true } : {},
562
+ ...forceRefresh === true ? { forceRefresh: true } : {},
563
+ ...stats === true ? { stats: true } : {},
564
+ projectRoot: root
565
+ })
566
+ )
567
+ ),
568
+ root,
569
+ projectRootWasOmitted
438
570
  );
439
571
  }
440
572
  );
@@ -451,18 +583,23 @@ async function createMcpServer() {
451
583
  },
452
584
  (args) => {
453
585
  const { spec, json, projectRoot } = args;
454
- const root = resolveToolRoot(projectRoot);
455
- const gate = confineTargets([spec], root);
586
+ const projectRootWasOmitted = projectRoot === void 0;
587
+ const root = resolveToolRoot(projectRoot, [spec]);
588
+ const gate = confineTargets([spec], root, true, projectRootWasOmitted);
456
589
  if (!gate.ok) return gate.refusal;
457
- return withConfinedRead(
458
- gate.pins,
459
- () => toCallToolResult(
460
- runSection({
461
- spec: gate.targets[0],
462
- ...json === true ? { json: true } : {},
463
- projectRoot: root
464
- })
465
- )
590
+ return noteOmittedProjectRoot(
591
+ withConfinedRead(
592
+ gate.pins,
593
+ () => toCallToolResult(
594
+ runSection({
595
+ spec: gate.targets[0],
596
+ ...json === true ? { json: true } : {},
597
+ projectRoot: root
598
+ })
599
+ )
600
+ ),
601
+ root,
602
+ projectRootWasOmitted
466
603
  );
467
604
  }
468
605
  );
@@ -482,21 +619,26 @@ async function createMcpServer() {
482
619
  },
483
620
  (args) => {
484
621
  const { file, json, minLines, forceRefresh, stats, projectRoot } = args;
485
- const root = resolveToolRoot(projectRoot);
486
- const gate = confineTargets([file], root);
622
+ const projectRootWasOmitted = projectRoot === void 0;
623
+ const root = resolveToolRoot(projectRoot, [file]);
624
+ const gate = confineTargets([file], root, true, projectRootWasOmitted);
487
625
  if (!gate.ok) return gate.refusal;
488
- return withConfinedRead(
489
- gate.pins,
490
- () => toCallToolResult(
491
- runSkeleton({
492
- file: gate.targets[0],
493
- ...json === true ? { json: true } : {},
494
- ...minLines !== void 0 ? { minLines } : {},
495
- ...forceRefresh === true ? { forceRefresh: true } : {},
496
- ...stats === true ? { stats: true } : {},
497
- projectRoot: root
498
- })
499
- )
626
+ return noteOmittedProjectRoot(
627
+ withConfinedRead(
628
+ gate.pins,
629
+ () => toCallToolResult(
630
+ runSkeleton({
631
+ file: gate.targets[0],
632
+ ...json === true ? { json: true } : {},
633
+ ...minLines !== void 0 ? { minLines } : {},
634
+ ...forceRefresh === true ? { forceRefresh: true } : {},
635
+ ...stats === true ? { stats: true } : {},
636
+ projectRoot: root
637
+ })
638
+ )
639
+ ),
640
+ root,
641
+ projectRootWasOmitted
500
642
  );
501
643
  }
502
644
  );
@@ -516,21 +658,26 @@ async function createMcpServer() {
516
658
  },
517
659
  (args) => {
518
660
  const { file, json, minLines, forceRefresh, stats, projectRoot } = args;
519
- const root = resolveToolRoot(projectRoot);
520
- const gate = confineTargets([file], root);
661
+ const projectRootWasOmitted = projectRoot === void 0;
662
+ const root = resolveToolRoot(projectRoot, [file]);
663
+ const gate = confineTargets([file], root, true, projectRootWasOmitted);
521
664
  if (!gate.ok) return gate.refusal;
522
- return withConfinedRead(
523
- gate.pins,
524
- () => toCallToolResult(
525
- runOutline({
526
- file: gate.targets[0],
527
- ...json === true ? { json: true } : {},
528
- ...minLines !== void 0 ? { minLines } : {},
529
- ...forceRefresh === true ? { forceRefresh: true } : {},
530
- ...stats === true ? { stats: true } : {},
531
- projectRoot: root
532
- })
533
- )
665
+ return noteOmittedProjectRoot(
666
+ withConfinedRead(
667
+ gate.pins,
668
+ () => toCallToolResult(
669
+ runOutline({
670
+ file: gate.targets[0],
671
+ ...json === true ? { json: true } : {},
672
+ ...minLines !== void 0 ? { minLines } : {},
673
+ ...forceRefresh === true ? { forceRefresh: true } : {},
674
+ ...stats === true ? { stats: true } : {},
675
+ projectRoot: root
676
+ })
677
+ )
678
+ ),
679
+ root,
680
+ projectRootWasOmitted
534
681
  );
535
682
  }
536
683
  );
@@ -607,7 +754,7 @@ async function createMcpServer() {
607
754
  }
608
755
  }
609
756
  const embeddingsEnabled = loadConfig(rootDir).indexing?.embeddings_enabled ?? true;
610
- const preflight = await checkEmbeddingPreflight({
757
+ const preflight = await checkSemanticReadiness({
611
758
  projectRoot: rootDir,
612
759
  ...coverage !== void 0 ? { coverage } : {}
613
760
  });
@@ -647,9 +794,16 @@ async function createMcpServer() {
647
794
  },
648
795
  (args) => {
649
796
  const { spec, callers, limit, top, json, projectRoot } = args;
650
- const root = resolveToolRoot(projectRoot);
651
- const gate = confineTargets([spec], root);
797
+ const projectRootWasOmitted = projectRoot === void 0;
798
+ const root = resolveToolRoot(projectRoot, [spec]);
799
+ const gate = confineTargets([spec], root, true, projectRootWasOmitted);
652
800
  if (!gate.ok) return gate.refusal;
801
+ if (projectRootWasOmitted && isIndexEmptyForProject(globalDbPath(), root)) {
802
+ return toCallToolResult({
803
+ text: `Error: projectRoot was omitted and defaulted to server cwd ${echoedValue(root)}, which has no files indexed. Pass projectRoot: "<workspace-path>" to target your workspace.`,
804
+ code: 1
805
+ });
806
+ }
653
807
  return withConfinedRead(
654
808
  gate.pins,
655
809
  () => toCallToolResultFromExitCode(
@@ -682,22 +836,27 @@ async function createMcpServer() {
682
836
  },
683
837
  (args) => {
684
838
  const { spec, limit, json, context, excludeTests, grep, projectRoot } = args;
685
- const root = resolveToolRoot(projectRoot);
686
- const gate = confineTargets([spec], root);
839
+ const projectRootWasOmitted = projectRoot === void 0;
840
+ const root = resolveToolRoot(projectRoot, [spec]);
841
+ const gate = confineTargets([spec], root, true, projectRootWasOmitted);
687
842
  if (!gate.ok) return gate.refusal;
688
- return withConfinedRead(
689
- gate.pins,
690
- () => toCallToolResultFromExitCode(
691
- () => runBrief({
692
- spec: gate.targets[0],
693
- ...json === true ? { json: true } : {},
694
- ...limit !== void 0 ? { limit } : {},
695
- ...context !== void 0 ? { context } : {},
696
- ...excludeTests === true ? { excludeTests: true } : {},
697
- ...grep !== void 0 ? { grep } : {},
698
- projectRoot: root
699
- })
700
- )
843
+ return noteOmittedProjectRoot(
844
+ withConfinedRead(
845
+ gate.pins,
846
+ () => toCallToolResultFromExitCode(
847
+ () => runBrief({
848
+ spec: gate.targets[0],
849
+ ...json === true ? { json: true } : {},
850
+ ...limit !== void 0 ? { limit } : {},
851
+ ...context !== void 0 ? { context } : {},
852
+ ...excludeTests === true ? { excludeTests: true } : {},
853
+ ...grep !== void 0 ? { grep } : {},
854
+ projectRoot: root
855
+ })
856
+ )
857
+ ),
858
+ root,
859
+ projectRootWasOmitted
701
860
  );
702
861
  }
703
862
  );
@@ -713,7 +872,10 @@ async function createMcpServer() {
713
872
  },
714
873
  (args) => {
715
874
  const { compact, projectRoot } = args;
716
- const map = buildProjectMap(resolveToolRoot(projectRoot), { compact: compact === true });
875
+ const root = resolveToolRoot(projectRoot);
876
+ const projectDenial = resolveProjectConfinement(root).denial;
877
+ if (projectDenial !== null) return toCallToolResult({ text: projectDenial, code: 1 });
878
+ const map = buildProjectMap(root, { compact: compact === true });
717
879
  const text = formatProjectMap(map, map.compact);
718
880
  const bytesSaved = mapLookupBytesSaved(map, text);
719
881
  recordStat("map_lookup", bytesSaved, savedTokensFromBytes(bytesSaved));
@@ -739,7 +901,8 @@ async function createMcpServer() {
739
901
  ...ref !== void 0 ? { ref } : {},
740
902
  ...symbolMode === true ? { symbolMode: true } : {},
741
903
  ...json === true ? { json: true } : {},
742
- projectRoot: resolveToolRoot(projectRoot)
904
+ projectRoot: resolveToolRoot(projectRoot),
905
+ projectRootResolved: true
743
906
  })
744
907
  );
745
908
  }
@@ -762,8 +925,9 @@ async function createMcpServer() {
762
925
  },
763
926
  (args) => {
764
927
  const { pattern, path: searchPath, maxLines, json, recursive, context, projectRoot } = args;
765
- const root = resolveToolRoot(projectRoot);
766
- const gate = confineTargets(searchPath === void 0 ? [root] : searchPath, root, false);
928
+ const projectRootWasOmitted = projectRoot === void 0;
929
+ const root = resolveToolRoot(projectRoot, searchPath);
930
+ const gate = confineTargets(searchPath === void 0 ? [root] : searchPath, root, false, projectRootWasOmitted);
767
931
  if (!gate.ok) return gate.refusal;
768
932
  const confinedPath = searchPath === void 0 ? void 0 : [...gate.targets];
769
933
  return withConfinedRead(
@@ -795,8 +959,9 @@ async function createMcpServer() {
795
959
  },
796
960
  (args) => {
797
961
  const { file, json, projectRoot } = args;
798
- const root = resolveToolRoot(projectRoot);
799
- const gate = confineTargets([file], root);
962
+ const projectRootWasOmitted = projectRoot === void 0;
963
+ const root = resolveToolRoot(projectRoot, [file]);
964
+ const gate = confineTargets([file], root, true, projectRootWasOmitted);
800
965
  if (!gate.ok) return gate.refusal;
801
966
  return withConfinedRead(
802
967
  gate.pins,
@@ -819,8 +984,9 @@ async function createMcpServer() {
819
984
  },
820
985
  (args) => {
821
986
  const { file, json, projectRoot } = args;
822
- const root = resolveToolRoot(projectRoot);
823
- const gate = confineTargets([file], root);
987
+ const projectRootWasOmitted = projectRoot === void 0;
988
+ const root = resolveToolRoot(projectRoot, [file]);
989
+ const gate = confineTargets([file], root, true, projectRootWasOmitted);
824
990
  if (!gate.ok) return gate.refusal;
825
991
  return withConfinedRead(
826
992
  gate.pins,
@@ -889,13 +1055,15 @@ async function createMcpServer() {
889
1055
  projectRoot: resolveToolRoot(args.projectRoot),
890
1056
  ...args.full === true ? { full: true } : {}
891
1057
  });
892
- return result === null ? toCallToolResult({ text: `no local handoff named "${args.name}" in this project`, code: 1 }) : typeof result === "string" ? toRawCallToolResult({ text: result, code: 0 }) : toCallToolResult({ text: displaySafeJson(compressionPayload(result)), code: 0 });
1058
+ return result === null ? toCallToolResult({ text: `no local handoff named ${echoedValue(args.name)} in this project`, code: 1 }) : typeof result === "string" ? toRawCallToolResult({ text: result, code: 0 }) : toCallToolResult({ text: displaySafeJson(compressionPayload(result)), code: 0 });
893
1059
  }
894
1060
  );
895
1061
  return server;
896
1062
  }
897
1063
  export {
1064
+ DEFAULT_MCP_TOOLS,
898
1065
  checkWithinProjectRoot,
899
1066
  createMcpServer,
1067
+ inferProjectRootFromTarget,
900
1068
  mcpToolAllowlist
901
1069
  };