token-goat 2.9.10 → 2.9.12

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 (27) hide show
  1. package/README.md +54 -11
  2. package/SECURITY.md +17 -19
  3. package/THIRD_PARTY_NOTICES.md +667 -0
  4. package/dist/{token-goat-chunk-YFXFUG3L.mjs → token-goat-chunk-4CK445AW.mjs} +1275 -655
  5. package/dist/token-goat-chunk-6F5TLJC7.mjs +3728 -0
  6. package/dist/{token-goat-chunk-ATVQ6IIT.mjs → token-goat-chunk-6NIGPPN6.mjs} +10 -2
  7. package/dist/{token-goat-chunk-SLGOIXKF.mjs → token-goat-chunk-A6QTLAWO.mjs} +85 -328
  8. package/dist/{token-goat-chunk-7ALFFPJW.mjs → token-goat-chunk-GCXX67HM.mjs} +2699 -2175
  9. package/dist/{token-goat-chunk-PA5UXNOT.mjs → token-goat-chunk-GM6QZWCF.mjs} +5088 -7746
  10. package/dist/{token-goat-chunk-DSHYDU53.mjs → token-goat-chunk-HKFOH6JH.mjs} +11 -7
  11. package/dist/{token-goat-chunk-LYWIRYCF.mjs → token-goat-chunk-LHLQFGWQ.mjs} +1 -1
  12. package/dist/token-goat-chunk-LOCOX2ML.mjs +3564 -0
  13. package/dist/token-goat-chunk-OTW7LC4Y.mjs +5942 -0
  14. package/dist/{token-goat-chunk-FQD3OB5W.mjs → token-goat-chunk-QCQUIPIP.mjs} +6068 -1687
  15. package/dist/{token-goat-chunk-DCYHAUW3.mjs → token-goat-chunk-SBYRP3X4.mjs} +69 -37
  16. package/dist/{token-goat-chunk-JS44SRAX.mjs → token-goat-chunk-SF2CKCFQ.mjs} +3 -2
  17. package/dist/{token-goat-chunk-PXWBHSFB.mjs → token-goat-chunk-T6M7DAW3.mjs} +31 -4
  18. package/dist/{token-goat-chunk-ZQODJQTP.mjs → token-goat-chunk-THLHC6QJ.mjs} +354 -180
  19. package/dist/{token-goat-chunk-VCEK77ED.mjs → token-goat-chunk-TOGYS5A7.mjs} +5307 -6350
  20. package/dist/{token-goat-chunk-2TJBY5RD.mjs → token-goat-chunk-VRWX6QYW.mjs} +6 -5
  21. package/dist/token-goat-hook.mjs +6 -5
  22. package/dist/token-goat.core.mjs +8 -6
  23. package/docs/C4_RUNTIME_ARCHITECTURE.md +1 -1
  24. package/docs/cli.md +4 -1
  25. package/docs/install.md +131 -11
  26. package/docs/security.md +2 -0
  27. package/package.json +8 -3
@@ -25,7 +25,8 @@ import {
25
25
  runSkeleton,
26
26
  runSymbol,
27
27
  withPinnedReads
28
- } from "./token-goat-chunk-YFXFUG3L.mjs";
28
+ } from "./token-goat-chunk-4CK445AW.mjs";
29
+ import "./token-goat-chunk-6F5TLJC7.mjs";
29
30
  import {
30
31
  buildProjectMap,
31
32
  embeddingsDepsAvailable,
@@ -34,22 +35,26 @@ import {
34
35
  getProjectIndexCounts,
35
36
  isWorkerRunning,
36
37
  mapLookupBytesSaved
37
- } from "./token-goat-chunk-PA5UXNOT.mjs";
38
+ } from "./token-goat-chunk-GM6QZWCF.mjs";
38
39
  import {
39
- ENV_KEYS,
40
- VERSION,
41
- dataDir,
42
40
  envStrList,
43
- extractErrorMessage,
44
41
  getDb,
45
- globalDbPath,
46
42
  loadConfig,
47
- normalizePath,
48
43
  recordStat,
49
44
  resolveProjectRoot,
50
45
  savedTokensFromBytes
51
- } from "./token-goat-chunk-VCEK77ED.mjs";
46
+ } from "./token-goat-chunk-TOGYS5A7.mjs";
52
47
  import "./token-goat-chunk-EEIDFMEM.mjs";
48
+ import {
49
+ ENV_KEYS,
50
+ VERSION,
51
+ dataDir,
52
+ displaySafeJson,
53
+ extractErrorMessage,
54
+ foldCaseForContainment,
55
+ globalDbPath,
56
+ normalizePath
57
+ } from "./token-goat-chunk-LOCOX2ML.mjs";
53
58
  import {
54
59
  init_define_import_meta_env
55
60
  } from "./token-goat-chunk-A37V4PBF.mjs";
@@ -121,15 +126,16 @@ function toCallToolResultFromExitCode(fn) {
121
126
  const { code, text } = captureOutput(fn);
122
127
  return toCallToolResult({ text, code });
123
128
  }
124
- function realPathOrSelf(p) {
129
+ function realPathForContainment(p) {
125
130
  try {
126
131
  return fs.realpathSync.native(p);
127
- } catch {
128
- return p;
132
+ } catch (err) {
133
+ const code = err.code;
134
+ return code === "ENOENT" || code === "ENOTDIR" ? p : null;
129
135
  }
130
136
  }
131
137
  function forCompare(p) {
132
- return process.platform === "win32" ? p.toLowerCase() : p;
138
+ return process.platform === "win32" ? foldCaseForContainment(p) : p;
133
139
  }
134
140
  function resolveToolRoot(projectRoot) {
135
141
  const resolved = resolveProjectRoot(projectRoot !== void 0 ? { project: projectRoot } : {});
@@ -146,18 +152,40 @@ function assertRootAllowed(resolvedRoot) {
146
152
  `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.`
147
153
  );
148
154
  }
149
- function checkWithinProjectRoot(target, resolvedRoot) {
150
- const root = forCompare(normalizePath(realPathOrSelf(resolvedRoot)));
151
- const abs = path.resolve(resolvedRoot, normalizePath(target));
152
- let identity;
155
+ var NO_CHECK_PINS = [];
156
+ function identityOf(p) {
153
157
  try {
154
- identity = fileIdentity(fs.statSync(abs, { bigint: true }));
158
+ return fileIdentity(fs.statSync(p, { bigint: true }));
155
159
  } catch {
156
- identity = null;
160
+ return null;
157
161
  }
158
- const realNative = realPathOrSelf(abs);
159
- const real = forCompare(normalizePath(realNative));
160
- return { inside: real === root || real.startsWith(root.endsWith("/") ? root : root + "/"), abs, real: realNative, identity };
162
+ }
163
+ function pinsFor(abs, real, identity) {
164
+ const pinIdentity = identity ?? ABSENT_PIN;
165
+ return [
166
+ [pinKey(abs), pinIdentity],
167
+ [pinKey(real), pinIdentity]
168
+ ];
169
+ }
170
+ function checkWithinProjectRoot(target, resolvedRoot) {
171
+ const rootReal = realPathForContainment(resolvedRoot);
172
+ const abs = path.resolve(resolvedRoot, normalizePath(target));
173
+ const absRaw = path.resolve(resolvedRoot, target);
174
+ const identity = identityOf(absRaw);
175
+ const realNative = realPathForContainment(abs);
176
+ if (rootReal === null) return { inside: false, reason: "unresolvable-root", pins: NO_CHECK_PINS };
177
+ if (realNative === null) return { inside: false, reason: "unresolvable-target", pins: NO_CHECK_PINS };
178
+ const root = forCompare(normalizePath(rootReal));
179
+ const under = (real) => {
180
+ const r = forCompare(normalizePath(real));
181
+ return r === root || r.startsWith(root.endsWith("/") ? root : root + "/");
182
+ };
183
+ if (!under(realNative)) return { inside: false, reason: "outside", pins: NO_CHECK_PINS };
184
+ if (absRaw === abs) return { inside: true, reason: "inside", pins: pinsFor(abs, realNative, identity) };
185
+ const realRaw = realPathForContainment(absRaw);
186
+ if (realRaw === null) return { inside: false, reason: "unresolvable-target", pins: NO_CHECK_PINS };
187
+ if (!under(realRaw)) return { inside: false, reason: "outside", pins: NO_CHECK_PINS };
188
+ return { inside: true, reason: "inside", pins: [...pinsFor(abs, realNative, identity), ...pinsFor(absRaw, realRaw, identity)] };
161
189
  }
162
190
  function specFilePart(spec) {
163
191
  const range = parseLineRange(spec);
@@ -166,6 +194,17 @@ function specFilePart(spec) {
166
194
  return colonIdx === -1 ? spec : spec.slice(0, colonIdx);
167
195
  }
168
196
  var NO_PINS = /* @__PURE__ */ new Map();
197
+ function refusalText(file, resolvedRoot, reason) {
198
+ const escapeHatch = "Set mcp.confine_reads_to_project_root = false (or TOKEN_GOAT_MCP_CONFINE_READS=0) to allow cross-root reads.";
199
+ if (reason === "unresolvable-root") {
200
+ 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.`;
201
+ }
202
+ if (reason === "unresolvable-target") {
203
+ 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.`;
204
+ }
205
+ 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.";
206
+ return `refused: "${file}" is outside the project root "${resolvedRoot}". ${rootScope} ${escapeHatch}`;
207
+ }
169
208
  function confineTargets(targets, resolvedRoot, splitCommas = true) {
170
209
  if (!loadConfig(resolvedRoot).mcp.confine_reads_to_project_root) return { ok: true, targets, pins: NO_PINS };
171
210
  const checked = [];
@@ -177,17 +216,9 @@ function confineTargets(targets, resolvedRoot, splitCommas = true) {
177
216
  if (file === "") continue;
178
217
  const check = checkWithinProjectRoot(file, resolvedRoot);
179
218
  if (!check.inside) {
180
- return {
181
- ok: false,
182
- refusal: toCallToolResult({
183
- text: `refused: "${file}" is outside the project root. The MCP tools are confined to the workspace. Set mcp.confine_reads_to_project_root = false (or TOKEN_GOAT_MCP_CONFINE_READS=0) to allow cross-root reads.`,
184
- code: 1
185
- })
186
- };
219
+ return { ok: false, refusal: toCallToolResult({ text: refusalText(file, resolvedRoot, check.reason), code: 1 }) };
187
220
  }
188
- const pinIdentity = check.identity ?? ABSENT_PIN;
189
- pins.set(pinKey(check.abs), pinIdentity);
190
- pins.set(pinKey(check.real), pinIdentity);
221
+ for (const [key, identity] of check.pins) pins.set(key, identity);
191
222
  }
192
223
  checked.push(splitCommas ? parts.join(",") : parts[0]);
193
224
  }
@@ -211,7 +242,7 @@ function mcpToolAllowlist() {
211
242
  return names.length === 0 ? null : new Set(names);
212
243
  }
213
244
  async function createMcpServer() {
214
- const [{ McpServer }, { z }] = await Promise.all([import("./token-goat-chunk-LYWIRYCF.mjs"), import("./token-goat-chunk-PXWBHSFB.mjs")]);
245
+ const [{ McpServer }, { z }] = await Promise.all([import("./token-goat-chunk-LHLQFGWQ.mjs"), import("./token-goat-chunk-T6M7DAW3.mjs")]);
215
246
  const server = new McpServer({ name: "token-goat", version: VERSION });
216
247
  const allowlist = mcpToolAllowlist();
217
248
  if (allowlist !== null) {
@@ -473,7 +504,7 @@ async function createMcpServer() {
473
504
  embeddingsEnabled,
474
505
  embeddingsAvailable
475
506
  };
476
- return toCallToolResult({ text: JSON.stringify(status, null, 2), code: 0 });
507
+ return toCallToolResult({ text: displaySafeJson(status), code: 0 });
477
508
  }
478
509
  );
479
510
  server.registerTool(
@@ -678,7 +709,7 @@ async function createMcpServer() {
678
709
  text: z.string().max(CONTENT_MAX_INPUT_CHARS).describe("text to compress")
679
710
  }
680
711
  },
681
- (args) => toCallToolResult({ text: JSON.stringify(compressionPayload(compressText(args.text)), null, 2), code: 0 })
712
+ (args) => toCallToolResult({ text: displaySafeJson(compressionPayload(compressText(args.text))), code: 0 })
682
713
  );
683
714
  server.registerTool(
684
715
  "retrieve_text",
@@ -704,7 +735,7 @@ async function createMcpServer() {
704
735
  }
705
736
  },
706
737
  (args) => toCallToolResult({
707
- text: JSON.stringify(createHandoff(args.name, args.text, resolveToolRoot(args.projectRoot)), null, 2),
738
+ text: displaySafeJson(createHandoff(args.name, args.text, resolveToolRoot(args.projectRoot))),
708
739
  code: 0
709
740
  })
710
741
  );
@@ -723,12 +754,13 @@ async function createMcpServer() {
723
754
  projectRoot: resolveToolRoot(args.projectRoot),
724
755
  ...args.full === true ? { full: true } : {}
725
756
  });
726
- 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: JSON.stringify(compressionPayload(result), null, 2), code: 0 });
757
+ 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 });
727
758
  }
728
759
  );
729
760
  return server;
730
761
  }
731
762
  export {
763
+ checkWithinProjectRoot,
732
764
  createMcpServer,
733
765
  mcpToolAllowlist
734
766
  };
@@ -3,7 +3,7 @@ const require = __cjsRequire(import.meta.url);
3
3
  import {
4
4
  deliveredOutputBytes,
5
5
  wrappedShell
6
- } from "./token-goat-chunk-ATVQ6IIT.mjs";
6
+ } from "./token-goat-chunk-6NIGPPN6.mjs";
7
7
  import {
8
8
  ToolFilter,
9
9
  capTokens,
@@ -15,8 +15,9 @@ import {
15
15
  recordStat,
16
16
  selectFilter,
17
17
  shlexSplit
18
- } from "./token-goat-chunk-VCEK77ED.mjs";
18
+ } from "./token-goat-chunk-TOGYS5A7.mjs";
19
19
  import "./token-goat-chunk-EEIDFMEM.mjs";
20
+ import "./token-goat-chunk-LOCOX2ML.mjs";
20
21
  import {
21
22
  init_define_import_meta_env
22
23
  } from "./token-goat-chunk-A37V4PBF.mjs";
@@ -19,6 +19,9 @@ import {
19
19
  ZodCUID2,
20
20
  ZodCatch,
21
21
  ZodCodec,
22
+ ZodCompileAsyncError,
23
+ ZodCompileUnsupportedError,
24
+ ZodCreditCard,
22
25
  ZodCustom,
23
26
  ZodCustomStringFormat,
24
27
  ZodDate,
@@ -110,6 +113,7 @@ import {
110
113
  _null,
111
114
  _overwrite,
112
115
  _positive,
116
+ _properties,
113
117
  _property,
114
118
  _regex,
115
119
  _size,
@@ -133,14 +137,17 @@ import {
133
137
  clone,
134
138
  codec,
135
139
  coerce_exports,
140
+ compile,
136
141
  config,
137
142
  core_exports,
143
+ creditCard,
138
144
  cuid,
139
145
  cuid2,
140
146
  custom,
141
147
  date,
142
148
  decode,
143
149
  decodeAsync,
150
+ deepPartial,
144
151
  describe,
145
152
  discriminatedUnion,
146
153
  e164,
@@ -156,6 +163,7 @@ import {
156
163
  float64,
157
164
  formatError,
158
165
  fromJSONSchema,
166
+ getDiscriminatedOption,
159
167
  getErrorMap,
160
168
  globalRegistry,
161
169
  guid,
@@ -163,6 +171,7 @@ import {
163
171
  hex,
164
172
  hostname,
165
173
  httpUrl,
174
+ input,
166
175
  int,
167
176
  int32,
168
177
  int64,
@@ -182,6 +191,7 @@ import {
182
191
  looseRecord,
183
192
  mac,
184
193
  map,
194
+ memoizer,
185
195
  meta,
186
196
  nan,
187
197
  nanoid,
@@ -193,6 +203,7 @@ import {
193
203
  number,
194
204
  object,
195
205
  optional,
206
+ output,
196
207
  parse,
197
208
  parseAsync,
198
209
  partialRecord,
@@ -223,6 +234,7 @@ import {
223
234
  symbol,
224
235
  templateLiteral,
225
236
  toJSONSchema,
237
+ toZod,
226
238
  transform,
227
239
  treeifyError,
228
240
  tuple,
@@ -237,10 +249,11 @@ import {
237
249
  uuidv4,
238
250
  uuidv6,
239
251
  uuidv7,
252
+ validate,
253
+ validateAsync,
240
254
  xid,
241
- xor,
242
- zod_default
243
- } from "./token-goat-chunk-FQD3OB5W.mjs";
255
+ xor
256
+ } from "./token-goat-chunk-QCQUIPIP.mjs";
244
257
  import "./token-goat-chunk-A37V4PBF.mjs";
245
258
  export {
246
259
  $brand,
@@ -261,6 +274,9 @@ export {
261
274
  ZodCUID2,
262
275
  ZodCatch,
263
276
  ZodCodec,
277
+ ZodCompileAsyncError,
278
+ ZodCompileUnsupportedError,
279
+ ZodCreditCard,
264
280
  ZodCustom,
265
281
  ZodCustomStringFormat,
266
282
  ZodDate,
@@ -341,15 +357,18 @@ export {
341
357
  clone,
342
358
  codec,
343
359
  coerce_exports as coerce,
360
+ compile,
344
361
  config,
345
362
  core_exports as core,
363
+ creditCard,
346
364
  cuid,
347
365
  cuid2,
348
366
  custom,
349
367
  date,
350
368
  decode,
351
369
  decodeAsync,
352
- zod_default as default,
370
+ deepPartial,
371
+ external_exports as default,
353
372
  describe,
354
373
  discriminatedUnion,
355
374
  e164,
@@ -367,6 +386,7 @@ export {
367
386
  formatError,
368
387
  fromJSONSchema,
369
388
  _function as function,
389
+ getDiscriminatedOption,
370
390
  getErrorMap,
371
391
  globalRegistry,
372
392
  _gt as gt,
@@ -377,6 +397,7 @@ export {
377
397
  hostname,
378
398
  httpUrl,
379
399
  _includes as includes,
400
+ input,
380
401
  _instanceof as instanceof,
381
402
  int,
382
403
  int32,
@@ -403,6 +424,7 @@ export {
403
424
  map,
404
425
  _maxLength as maxLength,
405
426
  _maxSize as maxSize,
427
+ memoizer,
406
428
  meta,
407
429
  _mime as mime,
408
430
  _minLength as minLength,
@@ -423,6 +445,7 @@ export {
423
445
  number,
424
446
  object,
425
447
  optional,
448
+ output,
426
449
  _overwrite as overwrite,
427
450
  parse,
428
451
  parseAsync,
@@ -433,6 +456,7 @@ export {
433
456
  preprocess,
434
457
  prettifyError,
435
458
  promise,
459
+ _properties as properties,
436
460
  _property as property,
437
461
  readonly,
438
462
  record,
@@ -462,6 +486,7 @@ export {
462
486
  toJSONSchema,
463
487
  _toLowerCase as toLowerCase,
464
488
  _toUpperCase as toUpperCase,
489
+ toZod,
465
490
  transform,
466
491
  treeifyError,
467
492
  _trim as trim,
@@ -479,6 +504,8 @@ export {
479
504
  uuidv4,
480
505
  uuidv6,
481
506
  uuidv7,
507
+ validate,
508
+ validateAsync,
482
509
  _void as void,
483
510
  xid,
484
511
  xor,