token-goat 2.9.29 → 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 (131) hide show
  1. package/README.md +34 -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-PGTH2U4C.mjs → token-goat-chunk-4JJS54TR.mjs} +4 -3
  11. package/dist/token-goat-chunk-4LCCNRTG.mjs +313 -0
  12. package/dist/{token-goat-chunk-L7H3U27L.mjs → token-goat-chunk-54K3EUV3.mjs} +1 -1
  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-GLXRTTLE.mjs → token-goat-chunk-64FBPDTK.mjs} +12 -8
  19. package/dist/{token-goat-chunk-G23DWHV4.mjs → token-goat-chunk-664RTTUV.mjs} +28 -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-IVWI2OCK.mjs → token-goat-chunk-7F2UBPD3.mjs} +40 -11
  24. package/dist/{token-goat-chunk-TGOXNAHW.mjs → token-goat-chunk-7IN2MKDS.mjs} +682 -501
  25. package/dist/token-goat-chunk-7NADEDKJ.mjs +124 -0
  26. package/dist/{token-goat-chunk-KOPIR3KZ.mjs → token-goat-chunk-A3CK6N5Z.mjs} +618 -72
  27. package/dist/{token-goat-chunk-O6I2XU4P.mjs → token-goat-chunk-AFLYLHDH.mjs} +44 -31
  28. package/dist/{token-goat-chunk-TCQANXYC.mjs → token-goat-chunk-AM5V6GSX.mjs} +18 -2
  29. package/dist/{token-goat-chunk-E4ZOJIZK.mjs → token-goat-chunk-APGZXSPS.mjs} +39 -146
  30. package/dist/{token-goat-chunk-D4ETHJD6.mjs → token-goat-chunk-ARDNEC2U.mjs} +9 -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-BGYOZ6DO.mjs → token-goat-chunk-B45VMIIH.mjs} +6 -7
  34. package/dist/token-goat-chunk-BPGCUMR7.mjs +30 -0
  35. package/dist/{token-goat-chunk-TDUT2CL6.mjs → token-goat-chunk-C63JQV5K.mjs} +45 -6
  36. package/dist/{token-goat-chunk-ZER6EAXZ.mjs → token-goat-chunk-COBQGL5S.mjs} +2661 -2440
  37. package/dist/token-goat-chunk-COTXZHTS.mjs +39 -0
  38. package/dist/{token-goat-chunk-RQGGMPCR.mjs → token-goat-chunk-CYCEYAEO.mjs} +76 -16
  39. package/dist/token-goat-chunk-CZ3LUXYZ.mjs +4115 -0
  40. package/dist/{token-goat-chunk-ASLWOQ3I.mjs → token-goat-chunk-DZX2YDPT.mjs} +2 -1
  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-RTMVLHWX.mjs → token-goat-chunk-FBNQNSJK.mjs} +2555 -5127
  47. package/dist/{token-goat-chunk-NMTKNYGF.mjs → token-goat-chunk-FNFBKLRD.mjs} +74 -9
  48. package/dist/{token-goat-chunk-RLP6J7WR.mjs → token-goat-chunk-FZ3NEW5O.mjs} +33 -19
  49. package/dist/token-goat-chunk-G5PJ7AGM.mjs +36 -0
  50. package/dist/{token-goat-chunk-DNRPXHYH.mjs → token-goat-chunk-GFBSN7BD.mjs} +29 -401
  51. package/dist/{token-goat-chunk-XYWPOSCN.mjs → token-goat-chunk-GOLEOXZP.mjs} +763 -211
  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-HUYUHODZ.mjs → token-goat-chunk-HOJLCGDP.mjs} +12965 -11748
  57. package/dist/{token-goat-chunk-435UQTKD.mjs → token-goat-chunk-HYBFA5X3.mjs} +118 -19
  58. package/dist/token-goat-chunk-IVALLT3S.mjs +48 -0
  59. package/dist/{token-goat-chunk-UXSXQQIY.mjs → token-goat-chunk-IVKIZWAB.mjs} +3 -3
  60. package/dist/{token-goat-chunk-52NSDWYY.mjs → token-goat-chunk-JB6QN6VF.mjs} +6 -4
  61. package/dist/{token-goat-chunk-HNFZZHFW.mjs → token-goat-chunk-JDHE26RP.mjs} +10 -3
  62. package/dist/{token-goat-chunk-FTP4U4QA.mjs → token-goat-chunk-JDU3EXSU.mjs} +12 -11
  63. package/dist/token-goat-chunk-JDWCRD6M.mjs +253 -0
  64. package/dist/{token-goat-chunk-6AK46ZT7.mjs → token-goat-chunk-JN4XMLSD.mjs} +5 -1
  65. package/dist/token-goat-chunk-JTQQGXZH.mjs +733 -0
  66. package/dist/token-goat-chunk-KKUFXAPD.mjs +25 -0
  67. package/dist/token-goat-chunk-KQNZDCBD.mjs +47 -0
  68. package/dist/{token-goat-chunk-2WOUYWLM.mjs → token-goat-chunk-KWPNJBDH.mjs} +27 -3
  69. package/dist/{token-goat-chunk-DPNLUJWB.mjs → token-goat-chunk-LOBGHXPB.mjs} +30 -8
  70. package/dist/token-goat-chunk-MKPF4CL5.mjs +37 -0
  71. package/dist/token-goat-chunk-MNWKPRAL.mjs +13 -0
  72. package/dist/{token-goat-chunk-DNSPXQXQ.mjs → token-goat-chunk-N2NMER56.mjs} +25 -15
  73. package/dist/token-goat-chunk-NYKZLXMK.mjs +218 -0
  74. package/dist/token-goat-chunk-OJBNYTJP.mjs +3087 -0
  75. package/dist/token-goat-chunk-P4QMM4WK.mjs +295 -0
  76. package/dist/token-goat-chunk-PD5VKH46.mjs +184 -0
  77. package/dist/token-goat-chunk-PEPTHRFF.mjs +129 -0
  78. package/dist/{token-goat-chunk-NMBWLRHW.mjs → token-goat-chunk-PU7V3FD6.mjs} +8721 -11104
  79. package/dist/token-goat-chunk-PY533T7F.mjs +46 -0
  80. package/dist/token-goat-chunk-Q5VTGRH7.mjs +761 -0
  81. package/dist/{token-goat-chunk-67BNIKKO.mjs → token-goat-chunk-QCLDAQTS.mjs} +31 -20
  82. package/dist/{token-goat-chunk-SE6E4BKJ.mjs → token-goat-chunk-QSBRTGM2.mjs} +9 -2
  83. package/dist/{token-goat-chunk-VZQEWRVH.mjs → token-goat-chunk-RC35RBUL.mjs} +4 -4
  84. package/dist/{token-goat-chunk-VMFWNHGR.mjs → token-goat-chunk-RHXKCZX3.mjs} +873 -504
  85. package/dist/{token-goat-chunk-PYSUADX4.mjs → token-goat-chunk-RZRTDST7.mjs} +17 -7
  86. package/dist/{token-goat-chunk-ONXH6NZ5.mjs → token-goat-chunk-SJHWVNDQ.mjs} +15 -21
  87. package/dist/token-goat-chunk-SMVRN2HU.mjs +188 -0
  88. package/dist/{token-goat-chunk-QO3LXVVR.mjs → token-goat-chunk-SQSSNQPE.mjs} +2295 -1718
  89. package/dist/{token-goat-chunk-2AWQ2R5X.mjs → token-goat-chunk-T4FK7VOV.mjs} +2 -2
  90. package/dist/token-goat-chunk-U4N3BN2W.mjs +92 -0
  91. package/dist/token-goat-chunk-UA5V6P3P.mjs +122 -0
  92. package/dist/{token-goat-chunk-UA5BKWWQ.mjs → token-goat-chunk-UQ5UK2T7.mjs} +15 -4
  93. package/dist/token-goat-chunk-USILZ3T3.mjs +53 -0
  94. package/dist/{token-goat-chunk-MELOKFDJ.mjs → token-goat-chunk-VES7EL7O.mjs} +7 -1
  95. package/dist/{token-goat-chunk-7CPMDFGB.mjs → token-goat-chunk-VL3YIFHZ.mjs} +389 -14
  96. package/dist/{token-goat-chunk-E5TK5DNO.mjs → token-goat-chunk-VPBBTSJR.mjs} +356 -129
  97. package/dist/{token-goat-chunk-YOOVFPTP.mjs → token-goat-chunk-W3QCJS6G.mjs} +10 -2
  98. package/dist/{token-goat-chunk-LZNBQTDK.mjs → token-goat-chunk-WY3L4DVT.mjs} +11 -7
  99. package/dist/token-goat-chunk-XKI4SEMX.mjs +66 -0
  100. package/dist/token-goat-chunk-XU4P6Z24.mjs +133 -0
  101. package/dist/{token-goat-chunk-H5J3C56Q.mjs → token-goat-chunk-Y776AENC.mjs} +112 -26
  102. package/dist/token-goat-chunk-YARZFCZS.mjs +359 -0
  103. package/dist/{token-goat-chunk-S4VSXURL.mjs → token-goat-chunk-Z44YO3QZ.mjs} +4 -0
  104. package/dist/token-goat-chunk-Z57YODA2.mjs +35 -0
  105. package/dist/{token-goat-chunk-PQ53BSCF.mjs → token-goat-chunk-ZCDTCVIS.mjs} +48 -29
  106. package/dist/token-goat-chunk-ZEJVMUQH.mjs +48 -0
  107. package/dist/{token-goat-chunk-BGHSSJUA.mjs → token-goat-chunk-ZFOBKUWH.mjs} +1 -1
  108. package/dist/token-goat-chunk-ZMBL6UVV.mjs +110 -0
  109. package/dist/{token-goat-chunk-PKRWMHVP.mjs → token-goat-chunk-ZQSJMO2R.mjs} +338 -170
  110. package/dist/token-goat-hook-client.cjs +87 -23
  111. package/dist/token-goat-hook-client.mjs +3 -3
  112. package/dist/token-goat-hook.mjs +46 -30
  113. package/dist/token-goat.core.mjs +6 -6
  114. package/docs/C4_RUNTIME_ARCHITECTURE.md +1 -1
  115. package/docs/cli.md +80 -46
  116. package/docs/install.md +47 -14
  117. package/docs/security.md +7 -7
  118. package/package.json +17 -7
  119. package/scripts/verify-native-dist.mjs +386 -0
  120. package/dist/token-goat-chunk-2NNUA2LR.mjs +0 -143
  121. package/dist/token-goat-chunk-44BM7DDQ.mjs +0 -294
  122. package/dist/token-goat-chunk-C5YPNZKQ.mjs +0 -318
  123. package/dist/token-goat-chunk-CIQ2FTY3.mjs +0 -1990
  124. package/dist/token-goat-chunk-EUSDXRXU.mjs +0 -1429
  125. package/dist/token-goat-chunk-G7IWXCFF.mjs +0 -456
  126. package/dist/token-goat-chunk-JTKCQMQA.mjs +0 -418
  127. package/dist/token-goat-chunk-ORNFMIER.mjs +0 -295
  128. package/dist/token-goat-chunk-VQ6F6T7X.mjs +0 -36
  129. package/dist/token-goat-chunk-YAGLESS3.mjs +0 -23
  130. package/dist/token-goat-chunk-YKSRAWUU.mjs +0 -33
  131. package/dist/token-goat-chunk-Z6KBMOBI.mjs +0 -53
@@ -1,103 +1,124 @@
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-CZ3LUXYZ.mjs";
22
+ import "./token-goat-chunk-ZCDTCVIS.mjs";
23
+ import {
24
+ ABSENT_PIN,
25
+ ConfinementIdentityError,
26
+ expandSpecPath,
27
+ fileIdentity,
28
+ findSpecSeparator,
29
+ parseColonLineSpec,
30
+ parseLineRange,
31
+ pinKey,
32
+ resolveProjectConfinement,
33
+ runGrep,
34
+ runRead,
29
35
  withPinnedReads
30
- } from "./token-goat-chunk-NMBWLRHW.mjs";
31
- import "./token-goat-chunk-VZQEWRVH.mjs";
32
- import "./token-goat-chunk-PQ53BSCF.mjs";
36
+ } from "./token-goat-chunk-PU7V3FD6.mjs";
37
+ import "./token-goat-chunk-XKI4SEMX.mjs";
38
+ import "./token-goat-chunk-SMVRN2HU.mjs";
39
+ import "./token-goat-chunk-4JJS54TR.mjs";
40
+ import "./token-goat-chunk-RC35RBUL.mjs";
41
+ import "./token-goat-chunk-5RG5SBL6.mjs";
42
+ import "./token-goat-chunk-54K3EUV3.mjs";
43
+ import "./token-goat-chunk-YARZFCZS.mjs";
33
44
  import {
34
45
  buildProjectMap,
35
46
  formatProjectMap,
36
- getDirtyPathsFor,
37
47
  getEmbeddingCoverage,
38
48
  getProjectIndexCounts,
39
- isWorkerRunning,
49
+ isIndexEmptyForProject,
40
50
  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";
51
+ } from "./token-goat-chunk-FBNQNSJK.mjs";
52
+ import "./token-goat-chunk-MNWKPRAL.mjs";
53
+ import "./token-goat-chunk-67TQJ76B.mjs";
54
+ import {
55
+ getDirtyPathsFor
56
+ } from "./token-goat-chunk-H2PHHGM5.mjs";
57
+ import "./token-goat-chunk-P4QMM4WK.mjs";
58
+ import {
59
+ isWorkerRunning
60
+ } from "./token-goat-chunk-5KDMCMF2.mjs";
61
+ import "./token-goat-chunk-ATCPY7EQ.mjs";
62
+ import "./token-goat-chunk-VPBBTSJR.mjs";
63
+ import "./token-goat-chunk-Y776AENC.mjs";
64
+ import "./token-goat-chunk-SJHWVNDQ.mjs";
65
+ import "./token-goat-chunk-AFLYLHDH.mjs";
49
66
  import {
50
67
  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";
68
+ } from "./token-goat-chunk-BPGCUMR7.mjs";
69
+ import "./token-goat-chunk-C63JQV5K.mjs";
70
+ import "./token-goat-chunk-JB6QN6VF.mjs";
71
+ import {
72
+ embeddingsDepsAvailable
73
+ } from "./token-goat-chunk-RHXKCZX3.mjs";
74
+ import "./token-goat-chunk-EVMZJ27Z.mjs";
75
+ import {
76
+ pathSuffixClause
77
+ } from "./token-goat-chunk-HYBFA5X3.mjs";
78
+ import "./token-goat-chunk-5Y6ZYL6U.mjs";
79
+ import "./token-goat-chunk-ARDNEC2U.mjs";
56
80
  import {
57
81
  recordStat,
58
82
  savedTokensFromBytes
59
- } from "./token-goat-chunk-CIQ2FTY3.mjs";
60
- import "./token-goat-chunk-SE6E4BKJ.mjs";
61
- import "./token-goat-chunk-DNSPXQXQ.mjs";
62
- 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";
66
- import {
67
- checkEmbeddingPreflight,
68
- embeddingsDepsAvailable
69
- } from "./token-goat-chunk-VMFWNHGR.mjs";
70
- import "./token-goat-chunk-435UQTKD.mjs";
83
+ } from "./token-goat-chunk-3Z5S4KGM.mjs";
71
84
  import {
72
85
  getDb
73
- } from "./token-goat-chunk-7CPMDFGB.mjs";
86
+ } from "./token-goat-chunk-VL3YIFHZ.mjs";
87
+ import "./token-goat-chunk-XB5KKOCG.mjs";
88
+ import "./token-goat-chunk-QSBRTGM2.mjs";
89
+ import "./token-goat-chunk-N2NMER56.mjs";
90
+ import "./token-goat-chunk-3BTK54F3.mjs";
91
+ import "./token-goat-chunk-4FVIAHSI.mjs";
74
92
  import {
75
93
  loadConfig,
76
94
  resolveProjectRoot
77
- } from "./token-goat-chunk-TGOXNAHW.mjs";
78
- import "./token-goat-chunk-XB5KKOCG.mjs";
95
+ } from "./token-goat-chunk-7IN2MKDS.mjs";
96
+ import "./token-goat-chunk-U4N3BN2W.mjs";
79
97
  import "./token-goat-chunk-YZAAZU2S.mjs";
80
98
  import {
81
99
  envStrList
82
100
  } from "./token-goat-chunk-IVE6U7KV.mjs";
101
+ import "./token-goat-chunk-XTQAOTSO.mjs";
102
+ import "./token-goat-chunk-AH6QILZM.mjs";
103
+ import "./token-goat-chunk-Y4AFKTHK.mjs";
83
104
  import {
84
105
  extractErrorMessage
85
- } from "./token-goat-chunk-XYWPOSCN.mjs";
106
+ } from "./token-goat-chunk-GOLEOXZP.mjs";
86
107
  import {
87
108
  foldCaseForContainment
88
- } from "./token-goat-chunk-TCQANXYC.mjs";
109
+ } from "./token-goat-chunk-AM5V6GSX.mjs";
89
110
  import {
90
111
  displaySafeJson,
91
112
  normalizePath
92
- } from "./token-goat-chunk-NMTKNYGF.mjs";
113
+ } from "./token-goat-chunk-FNFBKLRD.mjs";
93
114
  import {
94
115
  ENV_KEYS,
95
116
  VERSION,
96
117
  dataDir,
97
118
  globalDbPath
98
- } from "./token-goat-chunk-MELOKFDJ.mjs";
99
- import "./token-goat-chunk-Y4AFKTHK.mjs";
100
- import "./token-goat-chunk-JTKCQMQA.mjs";
119
+ } from "./token-goat-chunk-VES7EL7O.mjs";
120
+ import "./token-goat-chunk-KWPNJBDH.mjs";
121
+ import "./token-goat-chunk-HAVAOB3S.mjs";
101
122
  import {
102
123
  init_define_import_meta_env
103
124
  } from "./token-goat-chunk-A37V4PBF.mjs";
@@ -182,8 +203,86 @@ function realPathForContainment(p) {
182
203
  function forCompare(p) {
183
204
  return process.platform === "win32" ? foldCaseForContainment(p) : p;
184
205
  }
185
- function resolveToolRoot(projectRoot) {
186
- const resolved = resolveProjectRoot(projectRoot !== void 0 ? { project: projectRoot } : {});
206
+ function inferProjectRootFromTarget(target) {
207
+ const file = specFilePart(target);
208
+ if (!file) return null;
209
+ if (path.isAbsolute(file)) {
210
+ if (fs.existsSync(file)) {
211
+ try {
212
+ return resolveProjectRoot({ project: path.dirname(file) });
213
+ } catch {
214
+ return null;
215
+ }
216
+ }
217
+ return null;
218
+ }
219
+ try {
220
+ if (fs.existsSync(path.resolve(process.cwd(), file))) {
221
+ return null;
222
+ }
223
+ } catch {
224
+ }
225
+ const dbPath = globalDbPath();
226
+ if (fs.existsSync(dbPath)) {
227
+ try {
228
+ const db = getDb(dbPath);
229
+ const suffix = pathSuffixClause("path");
230
+ const rows = db.prepare(`SELECT path FROM files WHERE ${suffix.clause} ORDER BY length(path), path LIMIT 5`).all(...suffix.params(normalizePath(file)));
231
+ for (const row of rows) {
232
+ if (fs.existsSync(row.path)) {
233
+ return resolveProjectRoot({ project: path.dirname(row.path) });
234
+ }
235
+ }
236
+ } catch {
237
+ }
238
+ }
239
+ if (!file.includes("/") && !file.includes("\\") && !file.includes(".")) {
240
+ if (fs.existsSync(dbPath)) {
241
+ try {
242
+ const db = getDb(dbPath);
243
+ const rows = db.prepare(`SELECT file_path FROM symbols WHERE name = ? LIMIT 5`).all(file);
244
+ for (const row of rows) {
245
+ if (fs.existsSync(row.file_path)) {
246
+ return resolveProjectRoot({ project: path.dirname(row.file_path) });
247
+ }
248
+ }
249
+ } catch {
250
+ }
251
+ }
252
+ }
253
+ return null;
254
+ }
255
+ function rootHasIndexedFiles(root) {
256
+ const dbPath = globalDbPath();
257
+ if (!fs.existsSync(dbPath)) return false;
258
+ try {
259
+ const prefix = normalizePath(root).toLowerCase().replace(/\/+$/, "") + "/";
260
+ const row = getDb(dbPath).prepare(`SELECT 1 FROM files WHERE TG_LOWER(substr(path, 1, ?)) = ? LIMIT 1`).get(prefix.length, prefix);
261
+ return row !== void 0;
262
+ } catch {
263
+ return false;
264
+ }
265
+ }
266
+ function resolveToolRoot(projectRoot, candidateTargets) {
267
+ if (projectRoot !== void 0) {
268
+ const resolved2 = resolveProjectRoot({ project: projectRoot });
269
+ assertRootAllowed(resolved2);
270
+ return resolved2;
271
+ }
272
+ if (candidateTargets && candidateTargets.length > 0) {
273
+ for (const target of candidateTargets) {
274
+ if (!target) continue;
275
+ const inferred = inferProjectRootFromTarget(target);
276
+ if (inferred && rootHasIndexedFiles(inferred)) {
277
+ try {
278
+ assertRootAllowed(inferred);
279
+ return inferred;
280
+ } catch {
281
+ }
282
+ }
283
+ }
284
+ }
285
+ const resolved = resolveProjectRoot({});
187
286
  assertRootAllowed(resolved);
188
287
  return resolved;
189
288
  }
@@ -251,8 +350,9 @@ function pinsFor(abs, real, identity) {
251
350
  }
252
351
  function checkWithinProjectRoot(target, resolvedRoot) {
253
352
  const rootReal = realPathForContainment(resolvedRoot);
254
- const abs = path.resolve(resolvedRoot, normalizePath(target));
255
- const absRaw = path.resolve(resolvedRoot, target);
353
+ const spelled = expandSpecPath(target);
354
+ const abs = path.resolve(resolvedRoot, normalizePath(spelled));
355
+ const absRaw = path.resolve(resolvedRoot, spelled);
256
356
  const identity = identityOf(absRaw);
257
357
  const realNative = realPathForContainment(abs);
258
358
  if (rootReal === null) return { inside: false, reason: "unresolvable-root", pins: NO_CHECK_PINS };
@@ -277,19 +377,26 @@ function specFilePart(spec) {
277
377
  const colonIdx = findSpecSeparator(spec);
278
378
  return colonIdx === -1 ? spec : spec.slice(0, colonIdx);
279
379
  }
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;
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 "${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 "${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: "${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: "${file}" is outside the project root "${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,12 +448,28 @@ 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 "${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
469
  return names.length === 0 ? null : new Set(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-JN4XMLSD.mjs"), import("./token-goat-chunk-CHLHM42P.mjs")]);
349
473
  const server = new McpServer({ name: "token-goat", version: VERSION });
350
474
  const allowlist = mcpToolAllowlist();
351
475
  if (allowlist !== null) {
@@ -381,27 +505,32 @@ async function createMcpServer() {
381
505
  },
382
506
  (args) => {
383
507
  const { name, limit, file, kind, json, projectRoot } = args;
384
- const root = resolveToolRoot(projectRoot);
508
+ const projectRootWasOmitted = projectRoot === void 0;
509
+ const root = resolveToolRoot(projectRoot, file ? [file] : name ? [name] : void 0);
385
510
  let confinedFile = file;
386
511
  let pins = NO_PINS;
387
512
  if (file !== void 0) {
388
- const gate = confineTargets([file], root);
513
+ const gate = confineTargets([file], root, true, projectRootWasOmitted);
389
514
  if (!gate.ok) return gate.refusal;
390
515
  confinedFile = gate.targets[0];
391
516
  pins = gate.pins;
392
517
  }
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
- )
518
+ return noteOmittedProjectRoot(
519
+ withConfinedRead(
520
+ pins,
521
+ () => toCallToolResult(
522
+ runSymbol({
523
+ name,
524
+ limit: limit ?? 20,
525
+ ...confinedFile !== void 0 ? { file: confinedFile } : {},
526
+ ...kind !== void 0 ? { kind } : {},
527
+ ...json === true ? { json: true } : {},
528
+ projectRoot: root
529
+ })
530
+ )
531
+ ),
532
+ root,
533
+ projectRootWasOmitted
405
534
  );
406
535
  }
407
536
  );
@@ -421,20 +550,25 @@ async function createMcpServer() {
421
550
  },
422
551
  (args) => {
423
552
  const { spec, json, forceRefresh, stats, projectRoot } = args;
424
- const root = resolveToolRoot(projectRoot);
425
- const gate = confineTargets([spec], root);
553
+ const projectRootWasOmitted = projectRoot === void 0;
554
+ const root = resolveToolRoot(projectRoot, [spec]);
555
+ const gate = confineTargets([spec], root, true, projectRootWasOmitted);
426
556
  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
- )
557
+ return noteOmittedProjectRoot(
558
+ withConfinedRead(
559
+ gate.pins,
560
+ () => toCallToolResult(
561
+ runRead({
562
+ spec: gate.targets[0],
563
+ ...json === true ? { json: true } : {},
564
+ ...forceRefresh === true ? { forceRefresh: true } : {},
565
+ ...stats === true ? { stats: true } : {},
566
+ projectRoot: root
567
+ })
568
+ )
569
+ ),
570
+ root,
571
+ projectRootWasOmitted
438
572
  );
439
573
  }
440
574
  );
@@ -451,18 +585,23 @@ async function createMcpServer() {
451
585
  },
452
586
  (args) => {
453
587
  const { spec, json, projectRoot } = args;
454
- const root = resolveToolRoot(projectRoot);
455
- const gate = confineTargets([spec], root);
588
+ const projectRootWasOmitted = projectRoot === void 0;
589
+ const root = resolveToolRoot(projectRoot, [spec]);
590
+ const gate = confineTargets([spec], root, true, projectRootWasOmitted);
456
591
  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
- )
592
+ return noteOmittedProjectRoot(
593
+ withConfinedRead(
594
+ gate.pins,
595
+ () => toCallToolResult(
596
+ runSection({
597
+ spec: gate.targets[0],
598
+ ...json === true ? { json: true } : {},
599
+ projectRoot: root
600
+ })
601
+ )
602
+ ),
603
+ root,
604
+ projectRootWasOmitted
466
605
  );
467
606
  }
468
607
  );
@@ -482,21 +621,26 @@ async function createMcpServer() {
482
621
  },
483
622
  (args) => {
484
623
  const { file, json, minLines, forceRefresh, stats, projectRoot } = args;
485
- const root = resolveToolRoot(projectRoot);
486
- const gate = confineTargets([file], root);
624
+ const projectRootWasOmitted = projectRoot === void 0;
625
+ const root = resolveToolRoot(projectRoot, [file]);
626
+ const gate = confineTargets([file], root, true, projectRootWasOmitted);
487
627
  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
- )
628
+ return noteOmittedProjectRoot(
629
+ withConfinedRead(
630
+ gate.pins,
631
+ () => toCallToolResult(
632
+ runSkeleton({
633
+ file: gate.targets[0],
634
+ ...json === true ? { json: true } : {},
635
+ ...minLines !== void 0 ? { minLines } : {},
636
+ ...forceRefresh === true ? { forceRefresh: true } : {},
637
+ ...stats === true ? { stats: true } : {},
638
+ projectRoot: root
639
+ })
640
+ )
641
+ ),
642
+ root,
643
+ projectRootWasOmitted
500
644
  );
501
645
  }
502
646
  );
@@ -516,21 +660,26 @@ async function createMcpServer() {
516
660
  },
517
661
  (args) => {
518
662
  const { file, json, minLines, forceRefresh, stats, projectRoot } = args;
519
- const root = resolveToolRoot(projectRoot);
520
- const gate = confineTargets([file], root);
663
+ const projectRootWasOmitted = projectRoot === void 0;
664
+ const root = resolveToolRoot(projectRoot, [file]);
665
+ const gate = confineTargets([file], root, true, projectRootWasOmitted);
521
666
  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
- )
667
+ return noteOmittedProjectRoot(
668
+ withConfinedRead(
669
+ gate.pins,
670
+ () => toCallToolResult(
671
+ runOutline({
672
+ file: gate.targets[0],
673
+ ...json === true ? { json: true } : {},
674
+ ...minLines !== void 0 ? { minLines } : {},
675
+ ...forceRefresh === true ? { forceRefresh: true } : {},
676
+ ...stats === true ? { stats: true } : {},
677
+ projectRoot: root
678
+ })
679
+ )
680
+ ),
681
+ root,
682
+ projectRootWasOmitted
534
683
  );
535
684
  }
536
685
  );
@@ -607,7 +756,7 @@ async function createMcpServer() {
607
756
  }
608
757
  }
609
758
  const embeddingsEnabled = loadConfig(rootDir).indexing?.embeddings_enabled ?? true;
610
- const preflight = await checkEmbeddingPreflight({
759
+ const preflight = await checkSemanticReadiness({
611
760
  projectRoot: rootDir,
612
761
  ...coverage !== void 0 ? { coverage } : {}
613
762
  });
@@ -647,9 +796,16 @@ async function createMcpServer() {
647
796
  },
648
797
  (args) => {
649
798
  const { spec, callers, limit, top, json, projectRoot } = args;
650
- const root = resolveToolRoot(projectRoot);
651
- const gate = confineTargets([spec], root);
799
+ const projectRootWasOmitted = projectRoot === void 0;
800
+ const root = resolveToolRoot(projectRoot, [spec]);
801
+ const gate = confineTargets([spec], root, true, projectRootWasOmitted);
652
802
  if (!gate.ok) return gate.refusal;
803
+ if (projectRootWasOmitted && isIndexEmptyForProject(globalDbPath(), root)) {
804
+ return toCallToolResult({
805
+ text: `Error: projectRoot was omitted and defaulted to server cwd "${root}", which has no files indexed. Pass projectRoot: "<workspace-path>" to target your workspace.`,
806
+ code: 1
807
+ });
808
+ }
653
809
  return withConfinedRead(
654
810
  gate.pins,
655
811
  () => toCallToolResultFromExitCode(
@@ -682,22 +838,27 @@ async function createMcpServer() {
682
838
  },
683
839
  (args) => {
684
840
  const { spec, limit, json, context, excludeTests, grep, projectRoot } = args;
685
- const root = resolveToolRoot(projectRoot);
686
- const gate = confineTargets([spec], root);
841
+ const projectRootWasOmitted = projectRoot === void 0;
842
+ const root = resolveToolRoot(projectRoot, [spec]);
843
+ const gate = confineTargets([spec], root, true, projectRootWasOmitted);
687
844
  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
- )
845
+ return noteOmittedProjectRoot(
846
+ withConfinedRead(
847
+ gate.pins,
848
+ () => toCallToolResultFromExitCode(
849
+ () => runBrief({
850
+ spec: gate.targets[0],
851
+ ...json === true ? { json: true } : {},
852
+ ...limit !== void 0 ? { limit } : {},
853
+ ...context !== void 0 ? { context } : {},
854
+ ...excludeTests === true ? { excludeTests: true } : {},
855
+ ...grep !== void 0 ? { grep } : {},
856
+ projectRoot: root
857
+ })
858
+ )
859
+ ),
860
+ root,
861
+ projectRootWasOmitted
701
862
  );
702
863
  }
703
864
  );
@@ -713,7 +874,10 @@ async function createMcpServer() {
713
874
  },
714
875
  (args) => {
715
876
  const { compact, projectRoot } = args;
716
- const map = buildProjectMap(resolveToolRoot(projectRoot), { compact: compact === true });
877
+ const root = resolveToolRoot(projectRoot);
878
+ const projectDenial = resolveProjectConfinement(root).denial;
879
+ if (projectDenial !== null) return toCallToolResult({ text: projectDenial, code: 1 });
880
+ const map = buildProjectMap(root, { compact: compact === true });
717
881
  const text = formatProjectMap(map, map.compact);
718
882
  const bytesSaved = mapLookupBytesSaved(map, text);
719
883
  recordStat("map_lookup", bytesSaved, savedTokensFromBytes(bytesSaved));
@@ -762,8 +926,9 @@ async function createMcpServer() {
762
926
  },
763
927
  (args) => {
764
928
  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);
929
+ const projectRootWasOmitted = projectRoot === void 0;
930
+ const root = resolveToolRoot(projectRoot, searchPath);
931
+ const gate = confineTargets(searchPath === void 0 ? [root] : searchPath, root, false, projectRootWasOmitted);
767
932
  if (!gate.ok) return gate.refusal;
768
933
  const confinedPath = searchPath === void 0 ? void 0 : [...gate.targets];
769
934
  return withConfinedRead(
@@ -795,8 +960,9 @@ async function createMcpServer() {
795
960
  },
796
961
  (args) => {
797
962
  const { file, json, projectRoot } = args;
798
- const root = resolveToolRoot(projectRoot);
799
- const gate = confineTargets([file], root);
963
+ const projectRootWasOmitted = projectRoot === void 0;
964
+ const root = resolveToolRoot(projectRoot, [file]);
965
+ const gate = confineTargets([file], root, true, projectRootWasOmitted);
800
966
  if (!gate.ok) return gate.refusal;
801
967
  return withConfinedRead(
802
968
  gate.pins,
@@ -819,8 +985,9 @@ async function createMcpServer() {
819
985
  },
820
986
  (args) => {
821
987
  const { file, json, projectRoot } = args;
822
- const root = resolveToolRoot(projectRoot);
823
- const gate = confineTargets([file], root);
988
+ const projectRootWasOmitted = projectRoot === void 0;
989
+ const root = resolveToolRoot(projectRoot, [file]);
990
+ const gate = confineTargets([file], root, true, projectRootWasOmitted);
824
991
  if (!gate.ok) return gate.refusal;
825
992
  return withConfinedRead(
826
993
  gate.pins,
@@ -897,5 +1064,6 @@ async function createMcpServer() {
897
1064
  export {
898
1065
  checkWithinProjectRoot,
899
1066
  createMcpServer,
1067
+ inferProjectRootFromTarget,
900
1068
  mcpToolAllowlist
901
1069
  };