token-goat 2.9.14 → 2.9.15

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 (41) hide show
  1. package/README.md +15 -1
  2. package/dist/token-goat-chunk-2X2EBBC6.mjs +277 -0
  3. package/dist/{token-goat-chunk-XQF5J25J.mjs → token-goat-chunk-3NSDDTGL.mjs} +5 -4
  4. package/dist/token-goat-chunk-4EXFN2AW.mjs +29 -0
  5. package/dist/{token-goat-chunk-4SDX3QP3.mjs → token-goat-chunk-5V7DAC7V.mjs} +5 -4
  6. package/dist/token-goat-chunk-6DLVZDB6.mjs +34 -0
  7. package/dist/{token-goat-chunk-XEH6KBWW.mjs → token-goat-chunk-7ZYK25AO.mjs} +4 -3
  8. package/dist/{token-goat-chunk-7OGKZ7AP.mjs → token-goat-chunk-A4JYKD5H.mjs} +5 -3
  9. package/dist/{token-goat-chunk-2ESBO4IN.mjs → token-goat-chunk-ASYEPR3S.mjs} +10 -7
  10. package/dist/{token-goat-chunk-PGGDW7DZ.mjs → token-goat-chunk-ATIFTMRC.mjs} +9 -6
  11. package/dist/{token-goat-chunk-IT6O3PNN.mjs → token-goat-chunk-BL5LNGBG.mjs} +813 -4613
  12. package/dist/{token-goat-chunk-PRJVGIC5.mjs → token-goat-chunk-C5JIO6HK.mjs} +7 -5
  13. package/dist/{token-goat-chunk-YTQHZJXW.mjs → token-goat-chunk-DQ4J5AFF.mjs} +40 -17
  14. package/dist/token-goat-chunk-ERTXEKB6.mjs +228 -0
  15. package/dist/{token-goat-chunk-ASVVF4JV.mjs → token-goat-chunk-GIIHUSZX.mjs} +137 -19
  16. package/dist/{token-goat-chunk-DAMXYVIW.mjs → token-goat-chunk-GMQQA7E4.mjs} +296 -276
  17. package/dist/{token-goat-chunk-T2IWWTHB.mjs → token-goat-chunk-IVUQLQWN.mjs} +33 -1142
  18. package/dist/{token-goat-chunk-POBYR64E.mjs → token-goat-chunk-K7F2BFIK.mjs} +801 -3
  19. package/dist/{token-goat-chunk-RUDOKYPJ.mjs → token-goat-chunk-LCZBPOIN.mjs} +1733 -1360
  20. package/dist/token-goat-chunk-LMFO66YD.mjs +331 -0
  21. package/dist/{token-goat-chunk-EZNVAIR3.mjs → token-goat-chunk-LT7JRU6K.mjs} +4 -3
  22. package/dist/{token-goat-chunk-YHGTGG6K.mjs → token-goat-chunk-MZDIJJ3R.mjs} +29 -5
  23. package/dist/{token-goat-chunk-O5WAMISC.mjs → token-goat-chunk-NDPO7GAH.mjs} +26 -16
  24. package/dist/token-goat-chunk-NDRP4KJQ.mjs +4371 -0
  25. package/dist/{token-goat-chunk-ZFM4PWXL.mjs → token-goat-chunk-NU7TLMQK.mjs} +3 -3
  26. package/dist/token-goat-chunk-OSUFN2FV.mjs +326 -0
  27. package/dist/token-goat-chunk-OUGNPMDA.mjs +959 -0
  28. package/dist/{token-goat-chunk-AMYCQJX4.mjs → token-goat-chunk-PM76YS22.mjs} +49 -256
  29. package/dist/{token-goat-chunk-SAQ5PG4L.mjs → token-goat-chunk-S4XRY446.mjs} +5 -2
  30. package/dist/{token-goat-chunk-DBNY4RLN.mjs → token-goat-chunk-SFAS46RE.mjs} +5 -3
  31. package/dist/{token-goat-chunk-XVZ4MNQC.mjs → token-goat-chunk-SZWYESBS.mjs} +221 -78
  32. package/dist/{token-goat-chunk-HF6H7RNK.mjs → token-goat-chunk-XEPXYDPI.mjs} +3 -2
  33. package/dist/{token-goat-chunk-EG3663UT.mjs → token-goat-chunk-YKG35VHC.mjs} +4 -2
  34. package/dist/{token-goat-chunk-VZYD4OZB.mjs → token-goat-chunk-YQ7WI2CO.mjs} +78 -266
  35. package/dist/{token-goat-chunk-3XQPEJMV.mjs → token-goat-chunk-YZX7EFG4.mjs} +1 -1
  36. package/dist/token-goat-hook.mjs +13 -9
  37. package/dist/token-goat.core.mjs +21 -16
  38. package/docs/cli.md +8 -6
  39. package/package.json +1 -1
  40. package/dist/token-goat-chunk-ZD4EM4LR.mjs +0 -30
  41. package/dist/token-goat-chunk-ZYNNQ36L.mjs +0 -479
@@ -4,19 +4,20 @@ import {
4
4
  canRunWrappedShell,
5
5
  clipToDeliveryCap,
6
6
  deliveredOutputBytes
7
- } from "./token-goat-chunk-3XQPEJMV.mjs";
7
+ } from "./token-goat-chunk-YZX7EFG4.mjs";
8
8
  import {
9
9
  DEFAULT_RECONCILE_BUDGET_MS,
10
10
  HOOK_EVENTS,
11
11
  buildCommandManifest,
12
12
  checkSymbolBodySize,
13
+ diagnoseSqlFailure,
13
14
  flattenCommandNames,
14
15
  getWebOutput,
15
16
  isReconcileClean,
16
17
  readStdinJson,
17
18
  reconcileProject,
18
19
  storeWebOutput
19
- } from "./token-goat-chunk-ZYNNQ36L.mjs";
20
+ } from "./token-goat-chunk-OUGNPMDA.mjs";
20
21
  import {
21
22
  GENERIC_SERVED_OUTPUT_KEY,
22
23
  OUTLINE_MAX_REPLACEMENT_RATIO,
@@ -35,14 +36,12 @@ import {
35
36
  enqueueDirtyPathSafe,
36
37
  ensureWorkerAlive,
37
38
  extractCompactFromMarker,
38
- extractMarkdownHeadings,
39
39
  fenceUntrusted,
40
40
  fenceUntrustedSpans,
41
41
  fenceWithMatches,
42
42
  foldDelivery,
43
43
  foldDetail,
44
44
  foldingEnabled,
45
- formatHeadingTreeParts,
46
45
  formatProjectMap,
47
46
  formatShrinkSummary,
48
47
  getBashOutputId,
@@ -119,7 +118,7 @@ import {
119
118
  wasCliReadThisSession,
120
119
  wasFileReadThisSession,
121
120
  wasHintShown
122
- } from "./token-goat-chunk-IT6O3PNN.mjs";
121
+ } from "./token-goat-chunk-BL5LNGBG.mjs";
123
122
  import {
124
123
  BASH_OUTPUT_SUBDIR,
125
124
  BODY_FIRST_TOOL_RESPONSE_KEYS,
@@ -127,7 +126,6 @@ import {
127
126
  commandHash,
128
127
  compressOutput,
129
128
  contextOutput,
130
- countSymbols,
131
129
  dedupeConsecutive,
132
130
  denyOutput,
133
131
  detectFromCommand,
@@ -169,17 +167,26 @@ import {
169
167
  storeBashOutput,
170
168
  summarizeOutputDelta,
171
169
  withPreservedBlocks
172
- } from "./token-goat-chunk-VZYD4OZB.mjs";
170
+ } from "./token-goat-chunk-YQ7WI2CO.mjs";
171
+ import {
172
+ extractMarkdownHeadings,
173
+ formatHeadingTreeParts
174
+ } from "./token-goat-chunk-NDRP4KJQ.mjs";
175
+ import {
176
+ countSymbols
177
+ } from "./token-goat-chunk-2X2EBBC6.mjs";
173
178
  import {
174
- detectLanguage,
175
- getDb,
176
- languageHasFlag,
177
179
  recordStat,
178
180
  redactSecrets,
179
181
  savedTokensFromBytes,
180
182
  storeBlob,
181
183
  stripAnsiEscapes
182
- } from "./token-goat-chunk-T2IWWTHB.mjs";
184
+ } from "./token-goat-chunk-IVUQLQWN.mjs";
185
+ import {
186
+ detectLanguage,
187
+ getDb,
188
+ languageHasFlag
189
+ } from "./token-goat-chunk-K7F2BFIK.mjs";
183
190
  import {
184
191
  detectHarness,
185
192
  envBool,
@@ -189,34 +196,36 @@ import {
189
196
  isUnderSystemTemp,
190
197
  loadConfig,
191
198
  shortFingerprint
192
- } from "./token-goat-chunk-SAQ5PG4L.mjs";
199
+ } from "./token-goat-chunk-S4XRY446.mjs";
193
200
  import {
194
201
  ENV_KEYS,
195
202
  IDENTICAL_READ_MIN_BODY_BYTES,
196
203
  PER_FILE_COUNTERFACTUAL_CEILING,
197
- UNTRUSTED_TOOL_TAG,
198
204
  VERSION,
199
205
  atomicWriteText,
200
206
  containsLineRun,
201
207
  countNoun,
202
208
  dataDir,
203
- displaySafePath,
204
- displaySafeText,
205
209
  ensureDirSync,
206
210
  escapesOntoNetworkThroughLinks,
207
211
  extractErrorMessage,
208
- fenceUntrustedFileContent,
209
212
  foldPath,
210
213
  globalDbPath,
211
214
  hasCreatedConfig,
212
215
  isInsideRoot,
216
+ runGit,
217
+ toKB
218
+ } from "./token-goat-chunk-PM76YS22.mjs";
219
+ import {
220
+ UNTRUSTED_TOOL_TAG,
221
+ displaySafePath,
222
+ displaySafeText,
223
+ fenceUntrustedFileContent,
213
224
  neutralizeSpokenMarkers,
214
225
  normalizePath,
215
226
  resolveIndexPath,
216
- runGit,
217
- toDisplayPath,
218
- toKB
219
- } from "./token-goat-chunk-AMYCQJX4.mjs";
227
+ toDisplayPath
228
+ } from "./token-goat-chunk-ERTXEKB6.mjs";
220
229
  import {
221
230
  init_define_import_meta_env
222
231
  } from "./token-goat-chunk-A37V4PBF.mjs";
@@ -936,7 +945,7 @@ init_define_import_meta_env();
936
945
  var TRACKED_SKILL = "token-goat";
937
946
  var MAX_COMMANDS_SHOWN = 8;
938
947
  async function currentCommandNames() {
939
- const { buildProgram } = await import("./token-goat-chunk-O5WAMISC.mjs");
948
+ const { buildProgram } = await import("./token-goat-chunk-NDPO7GAH.mjs");
940
949
  return flattenCommandNames(buildCommandManifest(buildProgram()));
941
950
  }
942
951
  async function recordSkillVersionSnapshot(sessionId, skillName) {
@@ -7656,11 +7665,11 @@ import { statSync as statSync5 } from "node:fs";
7656
7665
  // src/bash_extractors.ts
7657
7666
  init_define_import_meta_env();
7658
7667
  import { statSync as statSync4, openSync as openSync2, readSync, closeSync as closeSync2 } from "node:fs";
7659
- function surgicalHintFor(hintPath, isEnv, isConfig, isDoc) {
7660
- return isEnv ? 'Use `token-goat config-get "' + hintPath + '" KEY_NAME` to read a specific variable.' : isConfig ? 'Use `token-goat config-get "' + hintPath + '" KEY_NAME` or `token-goat section "' + hintPath + '::sectionName"` to read a specific value.' : isDoc ? 'Use `token-goat section "' + hintPath + '::SectionHeading"` to read one section.' : 'Use `token-goat read "' + hintPath + '::SymbolName"` to read one function or class.';
7668
+ function surgicalHintFor(hintPath, isEnv, isConfig, isDoc, isXml = false) {
7669
+ return isXml ? 'Use `token-goat xml-outline "' + hintPath + '"` to inspect structure, or `token-goat xml-query "' + hintPath + '" "<selector>"` to query specific nodes.' : isEnv ? 'Use `token-goat config-get "' + hintPath + '" KEY_NAME` to read a specific variable.' : isConfig ? 'Use `token-goat config-get "' + hintPath + '" KEY_NAME` or `token-goat section "' + hintPath + '::sectionName"` to read a specific value.' : isDoc ? 'Use `token-goat section "' + hintPath + '::SectionHeading"` to read one section.' : 'Use `token-goat read "' + hintPath + '::SymbolName"` to read one function or class.';
7661
7670
  }
7662
- function surgicalHintForConfigDoc(filePath, isConfig, isDoc, isSql) {
7663
- return isConfig ? 'Use `token-goat config-get "' + filePath + '" KEY_NAME` or `token-goat section "' + filePath + '::sectionName"` to read a specific value.' : isSql ? 'Use `token-goat section "' + filePath + '::table_name"` to pull one CREATE TABLE / CREATE TYPE block.' : isDoc ? 'Use `token-goat section "' + filePath + '::SectionHeading"` to read one section.' : 'Use `token-goat read "' + filePath + '::SymbolName"` or `token-goat skeleton "' + filePath + '"` to see the file structure.';
7671
+ function surgicalHintForConfigDoc(filePath, isConfig, isDoc, isSql, isXml = false) {
7672
+ return isXml ? 'Use `token-goat xml-outline "' + filePath + '"` to inspect structure, or `token-goat xml-query "' + filePath + '" "<selector>"` to query specific nodes.' : isConfig ? 'Use `token-goat config-get "' + filePath + '" KEY_NAME` or `token-goat section "' + filePath + '::sectionName"` to read a specific value.' : isSql ? 'Use `token-goat section "' + filePath + '::table_name"` to pull one CREATE TABLE / CREATE TYPE block.' : isDoc ? 'Use `token-goat section "' + filePath + '::SectionHeading"` to read one section.' : 'Use `token-goat read "' + filePath + '::SymbolName"` or `token-goat skeleton "' + filePath + '"` to see the file structure.';
7664
7673
  }
7665
7674
  function splitShellSegments(cmd) {
7666
7675
  const segments = [];
@@ -7713,19 +7722,21 @@ function extractCatSourceFile(cmd) {
7713
7722
  function classifyFileExtensions(filePath) {
7714
7723
  const basename3 = (filePath.includes("/") ? filePath.split("/").at(-1) : filePath.split("\\").at(-1)) ?? filePath;
7715
7724
  const isEnvFile = /^\.env(\.\w+)?$/i.test(basename3);
7716
- const hasKnownExt = /\.(?:java|py|ts|tsx|js|jsx|go|rb|rs|cpp|cc|cxx|c|h|hpp|kt|swift|cs|php|scala|clj|css|scss|sass|less|md|mdx|rst|txt|json|yaml|yml|toml|xml|conf|cfg|ini|properties|sql|ps1|psm1|env)$/i.test(filePath);
7725
+ const hasKnownExt = /\.(?:java|py|ts|tsx|js|jsx|go|rb|rs|cpp|cc|cxx|c|h|hpp|kt|swift|cs|php|scala|clj|css|scss|sass|less|md|mdx|rst|txt|json|yaml|yml|toml|xml|dtsx|ampkg|xaml|conf|cfg|ini|properties|sql|ps1|psm1|env)$/i.test(filePath);
7717
7726
  if (!hasKnownExt && !isEnvFile) return null;
7718
7727
  const isSql = /\.sql$/i.test(filePath);
7719
7728
  const isDoc = /\.(?:md|mdx|rst|txt)$/i.test(filePath);
7720
7729
  const isEnv = isEnvFile || /\.env$/i.test(filePath);
7721
7730
  const isConfig = /\.(?:json|yaml|yml|toml|conf|cfg|ini|properties)$/i.test(filePath);
7722
- return { isDoc, isEnv, isConfig, isSql };
7731
+ const isXml = /\.(?:xml|dtsx|ampkg|xaml)$/i.test(filePath);
7732
+ return { isDoc, isEnv, isConfig, isSql, isXml };
7723
7733
  }
7724
7734
  function classifyDocConfig(filePath) {
7725
7735
  const isDoc = /\.(?:md|mdx|rst|txt)$/i.test(filePath);
7726
7736
  const isConfig = /\.(?:json|yaml|yml|toml|conf|cfg|ini|properties)$/i.test(filePath);
7727
7737
  const isSql = /\.sql$/i.test(filePath);
7728
- return { isDoc, isConfig, isSql };
7738
+ const isXml = /\.(?:xml|dtsx|ampkg|xaml)$/i.test(filePath);
7739
+ return { isDoc, isConfig, isSql, isXml };
7729
7740
  }
7730
7741
  function classifyCatPath(filePath, cmd0) {
7731
7742
  if (isTempPath(filePath)) return null;
@@ -7802,10 +7813,10 @@ function extractPowerShellFileMethodRead(cmd, event) {
7802
7813
  }
7803
7814
  const flags = classifyFileExtensions(filePath);
7804
7815
  if (flags === null) {
7805
- const { isDoc, isConfig, isSql } = classifyDocConfig(filePath);
7806
- return { filePath, isDoc, isEnv: false, isConfig, isSql };
7816
+ const { isDoc, isConfig, isSql, isXml } = classifyDocConfig(filePath);
7817
+ return { filePath, isDoc, isEnv: false, isConfig, isSql, isXml };
7807
7818
  }
7808
- return { filePath, isDoc: flags.isDoc, isEnv: flags.isEnv, isConfig: flags.isConfig, isSql: flags.isSql };
7819
+ return { filePath, isDoc: flags.isDoc, isEnv: flags.isEnv, isConfig: flags.isConfig, isSql: flags.isSql, isXml: flags.isXml };
7809
7820
  }
7810
7821
  function extractRgSymbolSearch(cmd) {
7811
7822
  if (!/^(?:rg|grep)\s+/.test(cmd)) return null;
@@ -7960,7 +7971,7 @@ function pythonOpenPathsAreAllLiteral(text) {
7960
7971
  const calls = pythonOpenCalls(text);
7961
7972
  return calls.length > 0 && calls.every((call) => call.pathLiteral !== null);
7962
7973
  }
7963
- var KNOWN_PYTHON_EXT_STR = "java|py|ts|tsx|js|jsx|go|rb|rs|cpp|cc|cxx|c|h|hpp|kt|swift|cs|php|scala|clj|css|scss|sass|less|md|mdx|rst|txt|json|yaml|yml|toml|xml|html|htm|conf|cfg|ini|properties|sql|ps1|psm1|env";
7974
+ var KNOWN_PYTHON_EXT_STR = "java|py|ts|tsx|js|jsx|go|rb|rs|cpp|cc|cxx|c|h|hpp|kt|swift|cs|php|scala|clj|css|scss|sass|less|md|mdx|rst|txt|json|yaml|yml|toml|xml|dtsx|ampkg|xaml|html|htm|conf|cfg|ini|properties|sql|ps1|psm1|env";
7964
7975
  var OPEN_EXT = new RegExp(`\\.(?:${KNOWN_PYTHON_EXT_STR})$`, "i");
7965
7976
  function extractPythonFileRead(cmd) {
7966
7977
  let inner = cmd.trim();
@@ -7986,11 +7997,11 @@ function extractPythonFileRead(cmd) {
7986
7997
  const classifyResult = (filePath) => {
7987
7998
  const flags = classifyFileExtensions(filePath);
7988
7999
  if (flags !== null) {
7989
- return { filePath, isDoc: flags.isDoc, isConfig: flags.isConfig, isEnv: flags.isEnv, isSql: flags.isSql, isOutputFile: false };
8000
+ return { filePath, isDoc: flags.isDoc, isConfig: flags.isConfig, isEnv: flags.isEnv, isSql: flags.isSql, isXml: flags.isXml, isOutputFile: false };
7990
8001
  }
7991
- const { isDoc, isConfig, isSql } = classifyDocConfig(filePath);
8002
+ const { isDoc, isConfig, isSql, isXml } = classifyDocConfig(filePath);
7992
8003
  const isEnv = /\.env(\.\w+)?$/i.test(filePath);
7993
- return { filePath, isDoc, isConfig, isEnv, isSql, isOutputFile: false };
8004
+ return { filePath, isDoc, isConfig, isEnv, isSql, isXml, isOutputFile: false };
7994
8005
  };
7995
8006
  const heredocMatch = /^python3?\s+-\s+<<\s*'?(\w+)'?\s*\n([\s\S]*?)\n\1\s*$/.exec(pythonBody);
7996
8007
  if (heredocMatch) {
@@ -8044,9 +8055,9 @@ function extractHeadFile(cmd) {
8044
8055
  const filePath = direct !== null ? direct[3] ?? direct[4] ?? direct[5] : piped[1] ?? piped[2] ?? piped[3];
8045
8056
  if (filePath === void 0) return null;
8046
8057
  if (isTempPath(filePath)) return null;
8047
- if (!/\.(?:ts|tsx|js|jsx|py|go|java|rs|rb|cs|md|mdx|rst|txt|json|yaml|yml|toml|sql|sh)$/i.test(filePath)) return null;
8048
- const { isDoc, isConfig, isSql } = classifyDocConfig(filePath);
8049
- return { filePath, isDoc, isConfig, isSql, n };
8058
+ if (!/\.(?:ts|tsx|js|jsx|py|go|java|rs|rb|cs|md|mdx|rst|txt|json|yaml|yml|toml|sql|sh|xml|dtsx|ampkg|xaml)$/i.test(filePath)) return null;
8059
+ const { isDoc, isConfig, isSql, isXml } = classifyDocConfig(filePath);
8060
+ return { filePath, isDoc, isConfig, isSql, isXml, n };
8050
8061
  }
8051
8062
  function extractSedRange(cmd) {
8052
8063
  const m = /^sed\s+-n\s+(?:['"]((?:\d+,\d+p)(?:;\d+,\d+p)*)['"]|(\d+,\d+p))\s+(?:"([^"]+)"|'([^']+)'|(\S+))(?:\s+2>(?:\/dev\/null|&1))?\s*$/.exec(cmd);
@@ -8148,7 +8159,7 @@ function leadingLinesHint(lead, hintPath, start, end, flags, preHookCwd) {
8148
8159
  const key = resolveIndexPath(hintPath, preHookCwd ?? process.cwd());
8149
8160
  const prior = findRangeOverlap(getFileLineRanges(key), start, end);
8150
8161
  if (prior !== null) return sedOverlapHint(hintPath, prior, start, end);
8151
- return lead + surgicalHintForConfigDoc(hintPath, flags.isConfig, flags.isDoc, flags.isSql);
8162
+ return lead + surgicalHintForConfigDoc(hintPath, flags.isConfig, flags.isDoc, flags.isSql, flags.isXml ?? false);
8152
8163
  }
8153
8164
  function findRangeOverlap(prior, start, end) {
8154
8165
  let best = null;
@@ -8205,9 +8216,9 @@ function extractTailFile(cmd) {
8205
8216
  const filePath = direct !== null ? direct[3] ?? direct[4] ?? direct[5] : piped[1] ?? piped[2] ?? piped[3];
8206
8217
  if (!filePath) return null;
8207
8218
  if (isTempPath(filePath)) return null;
8208
- if (!/\.(?:ts|tsx|js|jsx|py|go|java|rs|rb|cs|md|mdx|rst|txt|json|yaml|yml|toml|sql|sh)$/i.test(filePath)) return null;
8209
- const { isDoc, isConfig, isSql } = classifyDocConfig(filePath);
8210
- return { filePath, isDoc, isConfig, isSql };
8219
+ if (!/\.(?:ts|tsx|js|jsx|py|go|java|rs|rb|cs|md|mdx|rst|txt|json|yaml|yml|toml|sql|sh|xml|dtsx|ampkg|xaml)$/i.test(filePath)) return null;
8220
+ const { isDoc, isConfig, isSql, isXml } = classifyDocConfig(filePath);
8221
+ return { filePath, isDoc, isConfig, isSql, isXml };
8211
8222
  }
8212
8223
  function extractGetContentTail(cmd) {
8213
8224
  const tailMatch = /-Tail\s+(\d+)/i.exec(cmd);
@@ -8222,9 +8233,9 @@ function extractGetContentTail(cmd) {
8222
8233
  const filePath = (beforeTail || afterTail).replace(/^["']|["']$/g, "");
8223
8234
  if (!filePath) return null;
8224
8235
  if (isTempPath(filePath)) return null;
8225
- if (!/\.(?:ts|tsx|js|jsx|py|go|java|rs|rb|cs|md|mdx|rst|txt|json|yaml|yml|toml|sql|sh|ps1|psm1)$/i.test(filePath)) return null;
8226
- const { isDoc, isConfig, isSql } = classifyDocConfig(filePath);
8227
- return { filePath, isDoc, isConfig, isSql };
8236
+ if (!/\.(?:ts|tsx|js|jsx|py|go|java|rs|rb|cs|md|mdx|rst|txt|json|yaml|yml|toml|sql|sh|ps1|psm1|xml|dtsx|ampkg|xaml)$/i.test(filePath)) return null;
8237
+ const { isDoc, isConfig, isSql, isXml } = classifyDocConfig(filePath);
8238
+ return { filePath, isDoc, isConfig, isSql, isXml };
8228
8239
  }
8229
8240
  function extractGetContentSelectFirst(cmd) {
8230
8241
  const m = /^(Get-Content|gc)\s+([^|]+)\s*\|\s*(Select-Object|select)\s+(-First\s+(\d+))/i.exec(cmd);
@@ -8234,9 +8245,9 @@ function extractGetContentSelectFirst(cmd) {
8234
8245
  if (n <= 10) return null;
8235
8246
  if (!filePath) return null;
8236
8247
  if (isTempPath(filePath)) return null;
8237
- if (!/\.(?:ts|tsx|js|jsx|py|go|java|rs|rb|cs|md|mdx|rst|txt|json|yaml|yml|toml|sql|sh|ps1|psm1)$/i.test(filePath)) return null;
8238
- const { isDoc, isConfig, isSql } = classifyDocConfig(filePath);
8239
- return { filePath, isDoc, isConfig, isSql, n };
8248
+ if (!/\.(?:ts|tsx|js|jsx|py|go|java|rs|rb|cs|md|mdx|rst|txt|json|yaml|yml|toml|sql|sh|ps1|psm1|xml|dtsx|ampkg|xaml)$/i.test(filePath)) return null;
8249
+ const { isDoc, isConfig, isSql, isXml } = classifyDocConfig(filePath);
8250
+ return { filePath, isDoc, isConfig, isSql, isXml, n };
8240
8251
  }
8241
8252
  function taskOutputIsJsonlTranscript(outPath) {
8242
8253
  let fd = null;
@@ -8611,6 +8622,42 @@ function isCompressibleSingleCommand(cmd) {
8611
8622
  if (hasBareBackgroundOrNewline(cmd)) return false;
8612
8623
  return true;
8613
8624
  }
8625
+ function extractTerminalXmlParsing(cmd) {
8626
+ const trimmed = cmd.trim();
8627
+ if (!trimmed) return null;
8628
+ const selectXmlM = /\bSelect-Xml\b(?:\s+(?:-Path\s+)?["']?([^"'\s|;]+(?:\.xml|\.dtsx|\.ampkg|\.xaml))["']?)?/i.exec(trimmed);
8629
+ if (selectXmlM) {
8630
+ const rawPath = selectXmlM[1];
8631
+ const filePath = rawPath && !rawPath.startsWith("-") ? rawPath : void 0;
8632
+ return { filePath, toolOrScript: "Select-Xml" };
8633
+ }
8634
+ const psXmlCastM = /\[(?:xml|System\.Xml\.XmlDocument)\]/i.exec(trimmed);
8635
+ if (psXmlCastM) {
8636
+ const fileM = /["']([^"'\r\n]+\.(?:xml|dtsx|ampkg|xaml))["']/i.exec(trimmed) || /(?:Get-Content|gc|ReadAllText)\s+["']?([^"'\s|;)]+\.(?:xml|dtsx|ampkg|xaml))["']?/i.exec(trimmed);
8637
+ const filePath = fileM?.[1];
8638
+ return { filePath, toolOrScript: psXmlCastM[0] };
8639
+ }
8640
+ const inspectScriptM = /(?:powershell|pwsh|&|\.)?\s*["']?(\.?[/\\]?inspect_[^"'\s|;]+\.ps1)["']/i.exec(trimmed) || /\b(inspect_[^"'\s|;]+\.ps1)\b/i.exec(trimmed);
8641
+ if (inspectScriptM) {
8642
+ const fileM = /["']([^"'\r\n]+\.(?:xml|dtsx|ampkg|xaml))["']/i.exec(trimmed);
8643
+ const filePath = fileM?.[1];
8644
+ return { filePath, toolOrScript: inspectScriptM[1] ?? "inspect script" };
8645
+ }
8646
+ const pyXmlM = /\bpython(?:\d+(?:\.\d+)?)?(?:\.exe)?\b.*-c\s+["'].*?\b(xml\.etree|BeautifulSoup|minidom|lxml)\b/i.exec(trimmed);
8647
+ if (pyXmlM) {
8648
+ const fileM = /["']([^"'\r\n]+\.(?:xml|dtsx|ampkg|xaml))["']/i.exec(trimmed);
8649
+ const filePath = fileM?.[1];
8650
+ return { filePath, toolOrScript: `python ${pyXmlM[1]}` };
8651
+ }
8652
+ const cliXmlM = /\b(xmllint|xmlstarlet|xidel)\b/i.exec(trimmed);
8653
+ if (cliXmlM) {
8654
+ const fileM = /["']?([^"'\s|;]+\.(?:xml|dtsx|ampkg|xaml))["']?/i.exec(trimmed);
8655
+ const rawPath = fileM?.[1];
8656
+ const filePath = rawPath && !rawPath.startsWith("-") ? rawPath : void 0;
8657
+ return { filePath, toolOrScript: cliXmlM[1] };
8658
+ }
8659
+ return null;
8660
+ }
8614
8661
 
8615
8662
  // src/hooks_bash_commands.ts
8616
8663
  var CD_PREFIX_RE = /^(?:cd\s+(?:"[^"]*"|'[^']*'|\S+)[ \t]*(?:&&|;|\r?\n)\s*)+/;
@@ -9281,9 +9328,9 @@ async function maybeElideServedGenericOutput(cmd, output, exitCode, cwd, cacheMi
9281
9328
  if (rewrittenText === null) return null;
9282
9329
  return emitRewrite(rewrittenText, "already-served shell output collapsed", { kind: "bash_compress:generic-served-elision", originalBytes: deliveredOutputBytes(originalBytes) });
9283
9330
  }
9284
- async function maybeCompressCompoundOutput(cmd, output, exitCode, cwd, cacheMinBytes) {
9331
+ async function maybeCompressCompoundOutput(cmd, output, exitCode, cwd, cacheMinBytes, isUnwrapped = false) {
9285
9332
  if (process.env["TOKEN_GOAT_BASH_COMPRESS"] === "0") return null;
9286
- if (isCompressibleSingleCommand(cmd)) return null;
9333
+ if (!isUnwrapped && isCompressibleSingleCommand(cmd)) return null;
9287
9334
  if (exitCode !== null && exitCode !== 0) return null;
9288
9335
  let cfg;
9289
9336
  try {
@@ -9293,7 +9340,7 @@ async function maybeCompressCompoundOutput(cmd, output, exitCode, cwd, cacheMinB
9293
9340
  }
9294
9341
  if (!cfg.enabled || cfg.disabled_filters.includes("generic")) return null;
9295
9342
  if (Buffer.byteLength(output, "utf-8") < cacheMinBytes) return null;
9296
- const shaped = pipelineShapeFilter(cmd, cwd);
9343
+ const shaped = pipelineShapeFilter(cmd, cwd) ?? (isUnwrapped ? detectFromCommand(cmd, cwd ?? void 0)?.filter ?? null : null);
9297
9344
  const filter3 = shaped !== null && !cfg.disabled_filters.includes(shaped.name) ? shaped : filterByName("generic");
9298
9345
  if (filter3 === null) return null;
9299
9346
  const compressed = compressOutput(filter3, output, "", exitCode ?? 0, [], {
@@ -9436,6 +9483,15 @@ function preBashHandlerInner(event) {
9436
9483
  "Use `token-goat outline <file>` to see symbol names and line counts without loading files."
9437
9484
  );
9438
9485
  }
9486
+ const terminalXml = extractTerminalXmlParsing(cmd);
9487
+ if (terminalXml !== null) {
9488
+ const { filePath, toolOrScript } = terminalXml;
9489
+ recordStat("session_hint", 0, 0);
9490
+ const target = filePath ? displaySafePath(cdStripped ? resolveCdHintPath(rawCmd, filePath, hintCwd) : filePath) : "<file>";
9491
+ return contextOutput(
9492
+ `token-goat available for this file type, consider 'token-goat xml-query "${target}" "<xpath>"' or 'token-goat xml-outline "${target}"' first instead of terminal XML parsing (${toolOrScript}).`
9493
+ );
9494
+ }
9439
9495
  const singleLineRangeRead = extractLineRangeRead(cmd);
9440
9496
  const sedReads = singleLineRangeRead !== null ? [singleLineRangeRead] : extractLineRangeReadsCompound(cmd);
9441
9497
  if (sedReads !== null) {
@@ -9462,17 +9518,17 @@ function preBashHandlerInner(event) {
9462
9518
  }
9463
9519
  const gcTailResult = extractGetContentTail(cmd);
9464
9520
  if (gcTailResult !== null) {
9465
- const { filePath, isDoc, isConfig, isSql } = gcTailResult;
9521
+ const { filePath, isDoc, isConfig, isSql, isXml } = gcTailResult;
9466
9522
  const hintPath = displaySafePath(cdStripped ? resolveCdHintPath(rawCmd, filePath, hintCwd) : filePath);
9467
9523
  recordStat("session_hint", 0, 0);
9468
- return contextOutput("`Get-Content -Tail` bypasses read hooks. " + surgicalHintForConfigDoc(hintPath, isConfig, isDoc, isSql));
9524
+ return contextOutput("`Get-Content -Tail` bypasses read hooks. " + surgicalHintForConfigDoc(hintPath, isConfig, isDoc, isSql, isXml));
9469
9525
  }
9470
9526
  const gcSelectResult = extractGetContentSelectFirst(cmd);
9471
9527
  if (gcSelectResult !== null) {
9472
- const { filePath, isDoc, isConfig, isSql, n } = gcSelectResult;
9528
+ const { filePath, isDoc, isConfig, isSql, isXml, n } = gcSelectResult;
9473
9529
  const hintPath = displaySafePath(cdStripped ? resolveCdHintPath(rawCmd, filePath, hintCwd) : filePath);
9474
9530
  recordStat("session_hint", 0, 0);
9475
- return contextOutput(leadingLinesHint("`Select-Object -First` bypasses read hooks. ", hintPath, 1, n, { isConfig, isDoc, isSql }, preHookCwd));
9531
+ return contextOutput(leadingLinesHint("`Select-Object -First` bypasses read hooks. ", hintPath, 1, n, { isConfig, isDoc, isSql, isXml }, preHookCwd));
9476
9532
  }
9477
9533
  const catJsonPipe = extractCatJsonPipe(cmd);
9478
9534
  if (catJsonPipe !== null) {
@@ -9485,7 +9541,7 @@ function preBashHandlerInner(event) {
9485
9541
  }
9486
9542
  const catResult = extractCatFile(cmd);
9487
9543
  if (catResult !== null) {
9488
- const { filePath, isDoc, isEnv, isConfig, isSql, cmd0, advisoryOnly } = catResult;
9544
+ const { filePath, isDoc, isEnv, isConfig, isSql, isXml, cmd0, advisoryOnly } = catResult;
9489
9545
  const hintPath = displaySafePath(cdStripped ? resolveCdHintPath(rawCmd, filePath, hintCwd) : filePath);
9490
9546
  recordStat("session_hint", 0, 0);
9491
9547
  if (isSql) {
@@ -9493,16 +9549,16 @@ function preBashHandlerInner(event) {
9493
9549
  "`" + cmd0 + '` loads the entire file into context. Use `token-goat section "' + hintPath + '::table_name"` to pull one CREATE TABLE / CREATE TYPE block.'
9494
9550
  );
9495
9551
  }
9496
- const hint = surgicalHintFor(hintPath, isEnv, isConfig, isDoc);
9552
+ const hint = surgicalHintFor(hintPath, isEnv, isConfig, isDoc, isXml);
9497
9553
  return cdStripped || advisoryOnly ? contextOutput("`" + cmd0 + "` loads the entire file into context. " + hint) : denyOutput("`" + cmd0 + "` loads the entire file into context. " + hint);
9498
9554
  }
9499
9555
  const catMulti = extractCatFilesMulti(cmd);
9500
9556
  if (catMulti !== null) {
9501
9557
  recordStat("session_hint", 0, 0);
9502
9558
  const cmd0 = catMulti[0].cmd0;
9503
- const perPath = catMulti.map(({ filePath, isDoc, isEnv, isConfig, isSql }) => {
9559
+ const perPath = catMulti.map(({ filePath, isDoc, isEnv, isConfig, isSql, isXml }) => {
9504
9560
  const hintPath = displaySafePath(cdStripped ? resolveCdHintPath(rawCmd, filePath, hintCwd) : filePath);
9505
- const how = isSql ? 'token-goat section "' + hintPath + '::table_name"' : isEnv || isConfig ? 'token-goat config-get "' + hintPath + '" KEY_NAME' : isDoc ? 'token-goat section "' + hintPath + '::SectionHeading"' : 'token-goat read "' + hintPath + '::SymbolName"';
9561
+ const how = isXml ? 'token-goat xml-outline "' + hintPath + '" or token-goat xml-query "' + hintPath + '" "<selector>"' : isSql ? 'token-goat section "' + hintPath + '::table_name"' : isEnv || isConfig ? 'token-goat config-get "' + hintPath + '" KEY_NAME' : isDoc ? 'token-goat section "' + hintPath + '::SectionHeading"' : 'token-goat read "' + hintPath + '::SymbolName"';
9506
9562
  return " " + hintPath + " -> `" + how + "`";
9507
9563
  });
9508
9564
  const msg = "`" + cmd0 + "` on multiple files loads them all into context. Read each surgically instead:\n" + perPath.join("\n");
@@ -9510,19 +9566,19 @@ function preBashHandlerInner(event) {
9510
9566
  }
9511
9567
  const psGetContentResult = extractPowerShellWrappedGetContent(cmd, event);
9512
9568
  if (psGetContentResult !== null) {
9513
- const { filePath, isDoc, isEnv, isConfig, isSql } = psGetContentResult;
9569
+ const { filePath, isDoc, isEnv, isConfig, isSql, isXml } = psGetContentResult;
9514
9570
  const hintPath = displaySafePath(cdStripped ? resolveCdHintPath(rawCmd, filePath, hintCwd) : filePath);
9515
9571
  recordStat("session_hint", 0, 0);
9516
9572
  const lead = "`Get-Content` via a `powershell -Command` wrapper bypasses read hooks and loads the entire file into context. ";
9517
9573
  if (isSql) {
9518
9574
  return contextOutput(lead + 'Use `token-goat section "' + hintPath + '::table_name"` to pull one CREATE TABLE / CREATE TYPE block.');
9519
9575
  }
9520
- const hint = surgicalHintFor(hintPath, isEnv, isConfig, isDoc);
9576
+ const hint = surgicalHintFor(hintPath, isEnv, isConfig, isDoc, isXml);
9521
9577
  return cdStripped ? contextOutput(lead + hint) : denyOutput(lead + hint);
9522
9578
  }
9523
9579
  const wslCatResult = extractWslCatFile(cmd);
9524
9580
  if (wslCatResult !== null) {
9525
- const { filePath, isDoc, isEnv, isConfig, isSql } = wslCatResult;
9581
+ const { filePath, isDoc, isEnv, isConfig, isSql, isXml } = wslCatResult;
9526
9582
  const hintPath = displaySafePath(cdStripped ? resolveCdHintPath(rawCmd, filePath, hintCwd) : filePath);
9527
9583
  recordStat("session_hint", 0, 0);
9528
9584
  if (isSql) {
@@ -9530,12 +9586,12 @@ function preBashHandlerInner(event) {
9530
9586
  '`cat` loads the entire file into context. Use `token-goat section "' + hintPath + '::table_name"` to pull one CREATE TABLE / CREATE TYPE block.'
9531
9587
  );
9532
9588
  }
9533
- const hint = surgicalHintFor(hintPath, isEnv, isConfig, isDoc);
9589
+ const hint = surgicalHintFor(hintPath, isEnv, isConfig, isDoc, isXml);
9534
9590
  return cdStripped ? contextOutput("`cat` loads the entire file into context. " + hint) : denyOutput("`cat` loads the entire file into context. " + hint);
9535
9591
  }
9536
9592
  const pyRead = extractPythonFileRead(cmd);
9537
9593
  if (pyRead !== null) {
9538
- const { filePath, isDoc, isConfig, isEnv, isSql, isOutputFile } = pyRead;
9594
+ const { filePath, isDoc, isConfig, isEnv, isSql, isXml, isOutputFile } = pyRead;
9539
9595
  const hintPath = displaySafePath(cdStripped ? resolveCdHintPath(rawCmd, filePath, hintCwd) : filePath);
9540
9596
  recordStat("session_hint", 0, 0);
9541
9597
  if (isOutputFile) {
@@ -9552,22 +9608,22 @@ function preBashHandlerInner(event) {
9552
9608
  'Python `open()` file reads bypass read hooks. Use `token-goat section "' + hintPath + '::table_name"` to pull one CREATE TABLE / CREATE TYPE block.'
9553
9609
  );
9554
9610
  }
9555
- const hint = surgicalHintFor(hintPath, isEnv, isConfig, isDoc);
9611
+ const hint = surgicalHintFor(hintPath, isEnv, isConfig, isDoc, isXml);
9556
9612
  return cdStripped ? contextOutput("Python `open()` file reads bypass read hooks. " + hint) : denyOutput("Python `open()` file reads bypass read hooks. " + hint);
9557
9613
  }
9558
9614
  const tailResult = extractTailFile(cmd);
9559
9615
  if (tailResult !== null) {
9560
- const { filePath, isDoc, isConfig, isSql } = tailResult;
9616
+ const { filePath, isDoc, isConfig, isSql, isXml } = tailResult;
9561
9617
  const hintPath = displaySafePath(cdStripped ? resolveCdHintPath(rawCmd, filePath, hintCwd) : filePath);
9562
9618
  recordStat("session_hint", 0, 0);
9563
- return contextOutput("`tail` bypasses read hooks. " + surgicalHintForConfigDoc(hintPath, isConfig, isDoc, isSql));
9619
+ return contextOutput("`tail` bypasses read hooks. " + surgicalHintForConfigDoc(hintPath, isConfig, isDoc, isSql, isXml));
9564
9620
  }
9565
9621
  const headResult = extractHeadFile(cmd);
9566
9622
  if (headResult !== null) {
9567
- const { filePath, isDoc, isConfig, isSql, n } = headResult;
9623
+ const { filePath, isDoc, isConfig, isSql, isXml, n } = headResult;
9568
9624
  const hintPath = displaySafePath(cdStripped ? resolveCdHintPath(rawCmd, filePath, hintCwd) : filePath);
9569
9625
  recordStat("session_hint", 0, 0);
9570
- return contextOutput(leadingLinesHint("`head` bypasses read hooks. ", hintPath, 1, n, { isConfig, isDoc, isSql }, preHookCwd));
9626
+ return contextOutput(leadingLinesHint("`head` bypasses read hooks. ", hintPath, 1, n, { isConfig, isDoc, isSql, isXml }, preHookCwd));
9571
9627
  }
9572
9628
  const nodeRead = extractNodeFileRead(cmd);
9573
9629
  if (nodeRead !== null) {
@@ -9584,14 +9640,14 @@ function preBashHandlerInner(event) {
9584
9640
  }
9585
9641
  const psMethodRead = extractPowerShellFileMethodRead(cmd, event);
9586
9642
  if (psMethodRead !== null) {
9587
- const { filePath, isDoc, isEnv, isConfig, isSql } = psMethodRead;
9643
+ const { filePath, isDoc, isEnv, isConfig, isSql, isXml } = psMethodRead;
9588
9644
  const hintPath = displaySafePath(cdStripped ? resolveCdHintPath(rawCmd, filePath, hintCwd) : filePath);
9589
9645
  const lead = "PowerShell `[IO.File]::ReadAllText()` bypasses read hooks. ";
9590
9646
  if (isSql) {
9591
9647
  recordStat("session_hint", 0, 0);
9592
9648
  return contextOutput(lead + 'Use `token-goat section "' + hintPath + '::table_name"` to pull one CREATE TABLE / CREATE TYPE block.');
9593
9649
  }
9594
- const hint = surgicalHintFor(hintPath, isEnv, isConfig, isDoc);
9650
+ const hint = surgicalHintFor(hintPath, isEnv, isConfig, isDoc, isXml);
9595
9651
  recordStat("session_hint", 0, 0);
9596
9652
  return cdStripped ? contextOutput(lead + hint) : denyOutput(lead + hint);
9597
9653
  }
@@ -9763,15 +9819,25 @@ function extractExitCode(raw) {
9763
9819
  return null;
9764
9820
  }
9765
9821
  var GH_SECURITY_PATHS = ["/security_advisories", "/advisories", "security_events"];
9766
- var GH_SCOPE_PHRASES = ["Must have push access", "Resource not accessible by integration", "Must be an admin"];
9822
+ var GH_SCOPE_PHRASES = [
9823
+ "Must have push access",
9824
+ "Resource not accessible by integration",
9825
+ "Must be an admin",
9826
+ "You are not authorized to perform this operation"
9827
+ ];
9828
+ var GH_NOT_FOUND = /^gh: .*\(HTTP 404\)|"status":\s*"404"/m;
9767
9829
  function buildGhApiHint(cmd, stdout, exitCode) {
9768
9830
  if (stdout === "" || !cmd.startsWith("gh api")) return null;
9769
9831
  const hints = [];
9770
9832
  const isSecurityPath = GH_SECURITY_PATHS.some((p) => cmd.includes(p));
9771
9833
  const hasScopePhrase = GH_SCOPE_PHRASES.some((p) => stdout.includes(p));
9772
- const failedSecurityCall = exitCode !== null && exitCode !== 0 && isSecurityPath;
9773
- if (hasScopePhrase || failedSecurityCall) {
9834
+ const ambiguousSecurity404 = exitCode !== null && exitCode !== 0 && isSecurityPath && GH_NOT_FOUND.test(stdout);
9835
+ if (hasScopePhrase) {
9774
9836
  hints.push("[token-goat] GitHub API scope issue: try gh auth refresh -s security_events");
9837
+ } else if (ambiguousSecurity404) {
9838
+ hints.push(
9839
+ "[token-goat] GitHub answers 404 both for a resource that does not exist and for one your token cannot see: check the owner/repo spelling, then gh auth status for the security_events scope."
9840
+ );
9775
9841
  }
9776
9842
  const trimmed = stdout.trimStart();
9777
9843
  if (trimmed.startsWith("{")) {
@@ -9845,6 +9911,7 @@ async function postBashHandler(event) {
9845
9911
  try {
9846
9912
  const rawCmdRaw = extractCommand(event);
9847
9913
  if (rawCmdRaw === void 0) return passOutput();
9914
+ const isUnwrapped = unwrapCompressCommand(rawCmdRaw) === null;
9848
9915
  const rawCmd = unwrapCompressCommand(rawCmdRaw) ?? rawCmdRaw;
9849
9916
  const cmd = stripCdPrefix(rawCmd);
9850
9917
  const output = extractBashOutput(event.raw);
@@ -9928,13 +9995,19 @@ async function postBashHandler(event) {
9928
9995
  const gitScopedCacheId = await storeBashOutput(cmd, output, exitCode ?? 0, cwd);
9929
9996
  recordBashOutput(gitScopedCacheHash, gitScopedCacheId, Buffer.byteLength(output, "utf-8"));
9930
9997
  }
9998
+ if (isUnwrapped && /^git(?:\s+-[^\s]+|\s+--[^\s]+)*\s+diff\b/i.test(cmd)) {
9999
+ const unwrappedCompressed = await maybeCompressCompoundOutput(cmd, output, exitCode, cwd, cacheMinBytes, isUnwrapped);
10000
+ if (unwrappedCompressed !== null) return unwrappedCompressed;
10001
+ }
9931
10002
  const isMonitoring = getMonitoringRecallHint(cmd) !== null;
9932
10003
  const isFileRead = pureFileReadPath(cmd) !== null;
9933
10004
  if (isFileRead || !isMonitoring && !isBuildCommand(cmd) && !isCurlGetCommand(cmd)) {
9934
10005
  const identical = await maybeCollapseIdenticalRead(cmd, rawCmd, output, exitCode, cwd, cacheMinBytes);
9935
10006
  if (identical !== null) return identical;
9936
- const compound = await maybeCompressCompoundOutput(cmd, output, exitCode, cwd, cacheMinBytes);
9937
- if (compound !== null) return compound;
10007
+ if (!isFileRead && (!isUnwrapped || !isCompressibleSingleCommand(cmd))) {
10008
+ const compound = await maybeCompressCompoundOutput(cmd, output, exitCode, cwd, cacheMinBytes, isUnwrapped);
10009
+ if (compound !== null) return compound;
10010
+ }
9938
10011
  if (!isFileRead && extractLineRangeReadsCompound(cmd) === null) {
9939
10012
  const genericElision = await maybeElideServedGenericOutput(cmd, output, exitCode, cwd, cacheMinBytes);
9940
10013
  if (genericElision !== null) return genericElision;
@@ -10275,6 +10348,7 @@ function postToolUseFailureHandler(event) {
10275
10348
  const ledger = readLedger(target);
10276
10349
  const priorState = ledger.seen[signature];
10277
10350
  const editDiagnostic = diagnoseEditFailure(event, errorText);
10351
+ const sqlDiagnostic = diagnoseSqlFailure(event, errorText);
10278
10352
  if (priorState === void 0) {
10279
10353
  ledger.seen[signature] = false;
10280
10354
  ledger.order.push(signature);
@@ -10288,6 +10362,11 @@ function postToolUseFailureHandler(event) {
10288
10362
  writeLedger(target, ledger);
10289
10363
  return contextOutput(editDiagnostic);
10290
10364
  }
10365
+ if (sqlDiagnostic !== null) {
10366
+ ledger.seen[signature] = true;
10367
+ writeLedger(target, ledger);
10368
+ return contextOutput(sqlDiagnostic);
10369
+ }
10291
10370
  return passOutput();
10292
10371
  }
10293
10372
  if (priorState) return passOutput();
@@ -10296,6 +10375,9 @@ function postToolUseFailureHandler(event) {
10296
10375
  if (editDiagnostic !== null) {
10297
10376
  return contextOutput(editDiagnostic);
10298
10377
  }
10378
+ if (sqlDiagnostic !== null) {
10379
+ return contextOutput(sqlDiagnostic);
10380
+ }
10299
10381
  return contextOutput(repeatFailureNotice(toolName));
10300
10382
  } catch {
10301
10383
  return passOutput();
@@ -10572,6 +10654,37 @@ function compressGithubMcpResult(toolName, resultText) {
10572
10654
  const stripped = deepStrip(parsed, githubShouldStrip);
10573
10655
  return finishWithGenericPass(resultText, stripped);
10574
10656
  }
10657
+ var ATLASSIAN_TOOL_RE = /(?:jira|confluence|atlassian)/i;
10658
+ var ATLASSIAN_STRIP_EXACT_KEYS = /* @__PURE__ */ new Set([
10659
+ "avatarUrls",
10660
+ "avatarUrl",
10661
+ "iconUrl",
10662
+ "iconUrls",
10663
+ "self",
10664
+ "expand",
10665
+ "schema",
10666
+ "operations",
10667
+ "editmeta",
10668
+ "names",
10669
+ "_links",
10670
+ "_expandable",
10671
+ "extensions",
10672
+ "timeZone"
10673
+ ]);
10674
+ function atlassianShouldStrip(key) {
10675
+ return ATLASSIAN_STRIP_EXACT_KEYS.has(key);
10676
+ }
10677
+ function compressAtlassianMcpResult(toolName, resultText) {
10678
+ if (!ATLASSIAN_TOOL_RE.test(toolName)) return null;
10679
+ let parsed;
10680
+ try {
10681
+ parsed = JSON.parse(resultText);
10682
+ } catch {
10683
+ return null;
10684
+ }
10685
+ const stripped = deepStrip(parsed, atlassianShouldStrip);
10686
+ return finishWithGenericPass(resultText, stripped);
10687
+ }
10575
10688
  var BROWSER_TOOL_RE = /^mcp__.*(?:chrome-devtools|claude-in-chrome|playwright).*__/i;
10576
10689
  var BROWSER_CONSOLE_METHOD_RE = /(?:^|_)(?:read|list)_console_messages$/i;
10577
10690
  var BROWSER_NETWORK_METHOD_RE = /(?:^|_)(?:read|list)_network_requests$/i;
@@ -10722,10 +10835,11 @@ function stripBase64DataUrls(resultText) {
10722
10835
  function compressMcpResultWithPacks(toolName, resultText) {
10723
10836
  const base64Stripped = stripBase64DataUrls(resultText);
10724
10837
  const text = base64Stripped ?? resultText;
10725
- return compressGithubMcpResult(toolName, text) ?? compressBrowserMcpResult(toolName, text) ?? compressGWorkspaceMcpResult(toolName, text) ?? base64Stripped;
10838
+ return compressGithubMcpResult(toolName, text) ?? compressAtlassianMcpResult(toolName, text) ?? compressBrowserMcpResult(toolName, text) ?? compressGWorkspaceMcpResult(toolName, text) ?? base64Stripped;
10726
10839
  }
10727
10840
 
10728
10841
  // src/hooks_mcp.ts
10842
+ var MCP_OVERSIZED_THRESHOLD_BYTES = 25e3;
10729
10843
  function preMcpHandler(event) {
10730
10844
  const toolName = getToolName(event);
10731
10845
  if (!toolName || !event.sessionId) return passOutput();
@@ -10783,9 +10897,15 @@ function postMcpHandler(event) {
10783
10897
  minNetSavingsBytes: resolveMinNetSavingsBytes()
10784
10898
  });
10785
10899
  if (worthwhile) {
10900
+ const bodyBytes = Buffer.byteLength(redactedBody, "utf-8");
10901
+ let finalBody = redactedBody;
10902
+ if (bodyBytes >= MCP_OVERSIZED_THRESHOLD_BYTES) {
10903
+ const preview = clipToDeliveryCap(redactedBody, Buffer.byteLength(notice, "utf-8") + 500);
10904
+ finalBody = preview.text + (preview.clipped ? "\n\n...[preview truncated by token-goat; use mcp-output above to query full payload]..." : "");
10905
+ }
10786
10906
  return preserve(
10787
10907
  emitRewrite(
10788
- `${notice}${fenceWithMatches(redactedBody, injectionMatches, UNTRUSTED_TOOL_TAG)}`,
10908
+ `${notice}${fenceWithMatches(finalBody, injectionMatches, UNTRUSTED_TOOL_TAG)}`,
10789
10909
  "mcp",
10790
10910
  { kind: "mcp:compress", originalBytes }
10791
10911
  )
@@ -10794,6 +10914,29 @@ function postMcpHandler(event) {
10794
10914
  }
10795
10915
  }
10796
10916
  }
10917
+ const rawBytes = Buffer.byteLength(resultText, "utf-8");
10918
+ if (rawBytes >= MCP_OVERSIZED_THRESHOLD_BYTES && process.env["TOKEN_GOAT_MCP_COMPRESS"] !== "0") {
10919
+ if (id === null) id = storeMcpOutput(event.sessionId, toolName, toolInput, resultText);
10920
+ if (id !== null) {
10921
+ const notice = `[token-goat: oversized MCP result (${rawBytes} bytes) cached as ${id}]
10922
+ The full payload was cached to prevent harness context spill. Slicing commands:
10923
+ token-goat mcp-output ${id} --json-query '<path>' (e.g. 'issues[*].key', 'values[*].id')
10924
+ token-goat mcp-output ${id} --section '<heading>'
10925
+ token-goat mcp-output ${id} --grep '<regex>' --max-matches 20
10926
+ token-goat mcp-output ${id} --head 50
10927
+
10928
+ `;
10929
+ const preview = clipToDeliveryCap(redactedResult.text, Buffer.byteLength(notice, "utf-8") + 500);
10930
+ const previewBody = preview.text + (preview.clipped ? "\n\n...[preview truncated by token-goat; use mcp-output above to query full payload]..." : "");
10931
+ return preserve(
10932
+ emitRewrite(
10933
+ `${notice}${fenceWithMatches(previewBody, injectionMatches, UNTRUSTED_TOOL_TAG)}`,
10934
+ "mcp",
10935
+ { kind: "mcp:oversized", originalBytes: rawBytes }
10936
+ )
10937
+ );
10938
+ }
10939
+ }
10797
10940
  return passOrFence();
10798
10941
  }
10799
10942
  registerHook("pre_tool_use", preMcpHandler, { toolPattern: "^mcp__" });