token-goat 2.8.2 → 2.8.4

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.
@@ -3,8 +3,9 @@ const require = __cjsRequire(import.meta.url);
3
3
  import {
4
4
  loadConfig,
5
5
  redactSecrets,
6
+ resolveIndexPath,
6
7
  stripAnsiCodes
7
- } from "./token-goat-chunk-IVCTQPZD.mjs";
8
+ } from "./token-goat-chunk-E76UNTVK.mjs";
8
9
 
9
10
  // src/tool_filters/helpers.ts
10
11
  import * as fs from "node:fs";
@@ -1483,6 +1484,13 @@ var _CLINE_WANTS_EXECUTE_RE = /^\s*Cline\s+wants\s+to\s+(?:execute|run|write|rea
1483
1484
  var _CODEX_SEPARATOR_RE = /^-{4,}$/;
1484
1485
  var _CODEX_MODEL_RE = /^model\s*:\s*(?<model>\S+)/i;
1485
1486
  var _CODEX_TOKENS_USED_RE = /^tokens used$/i;
1487
+ var _CODEX_TOKEN_COUNT_RE = /^\d[\d,]*$/;
1488
+ function _trimBlankEdges(input) {
1489
+ let out = input;
1490
+ while (out.length && !(out[0] ?? "").trim()) out = out.slice(1);
1491
+ while (out.length && !(out[out.length - 1] ?? "").trim()) out = out.slice(0, -1);
1492
+ return out;
1493
+ }
1486
1494
  var ghCopilotFilter = makeAiCliFilter({
1487
1495
  name: "gh-copilot",
1488
1496
  binaries: ["gh"],
@@ -1678,34 +1686,42 @@ var CodexExecFilter = class extends ToolFilter {
1678
1686
  break;
1679
1687
  }
1680
1688
  }
1681
- let lastCodexIdx = null;
1682
- for (let i = secondSepIdx + 1; i < lines.length; i++) {
1683
- if ((lines[i] ?? "").trim().toLowerCase() === "codex") lastCodexIdx = i;
1684
- }
1685
- if (lastCodexIdx === null) return combined;
1686
1689
  let tokensLineIdx = null;
1690
+ let countLineIdx = null;
1687
1691
  let tokensCount = "?";
1688
- const searchFloor = Math.max(lastCodexIdx + 1, lines.length - 6);
1689
- for (let i = lines.length - 1; i >= searchFloor; i--) {
1690
- if (_CODEX_TOKENS_USED_RE.test((lines[i] ?? "").trim())) {
1691
- tokensLineIdx = i;
1692
- for (let j = i + 1; j < Math.min(i + 3, lines.length); j++) {
1693
- const candidate = (lines[j] ?? "").trim();
1694
- if (candidate) {
1695
- tokensCount = candidate;
1696
- break;
1697
- }
1692
+ for (let i = lines.length - 1; i > secondSepIdx; i--) {
1693
+ if (!_CODEX_TOKENS_USED_RE.test((lines[i] ?? "").trim())) continue;
1694
+ for (let j = i + 1; j < Math.min(i + 3, lines.length); j++) {
1695
+ const candidate = (lines[j] ?? "").trim();
1696
+ if (!candidate) continue;
1697
+ if (_CODEX_TOKEN_COUNT_RE.test(candidate)) {
1698
+ tokensLineIdx = i;
1699
+ countLineIdx = j;
1700
+ tokensCount = candidate;
1698
1701
  }
1699
1702
  break;
1700
1703
  }
1704
+ if (tokensLineIdx !== null) break;
1705
+ }
1706
+ let answerLines = null;
1707
+ let droppedTurns = 0;
1708
+ if (countLineIdx !== null) {
1709
+ const echo = _trimBlankEdges(lines.slice(countLineIdx + 1));
1710
+ if (echo.length) answerLines = echo;
1701
1711
  }
1702
- const answerEnd = tokensLineIdx !== null ? tokensLineIdx : lines.length;
1703
- let answerLines = lines.slice(lastCodexIdx + 1, answerEnd);
1704
- while (answerLines.length && !(answerLines[0] ?? "").trim()) answerLines = answerLines.slice(1);
1705
- while (answerLines.length && !(answerLines[answerLines.length - 1] ?? "").trim()) {
1706
- answerLines = answerLines.slice(0, -1);
1712
+ if (answerLines === null) {
1713
+ const scanEnd = tokensLineIdx !== null ? tokensLineIdx : lines.length;
1714
+ const labelIdxs = [];
1715
+ for (let i = secondSepIdx + 1; i < scanEnd; i++) {
1716
+ if ((lines[i] ?? "").trim().toLowerCase() === "codex") labelIdxs.push(i);
1717
+ }
1718
+ const lastCodexIdx = labelIdxs.length ? labelIdxs[labelIdxs.length - 1] : null;
1719
+ if (lastCodexIdx === null) return combined;
1720
+ droppedTurns = labelIdxs.length - 1;
1721
+ answerLines = _trimBlankEdges(lines.slice(lastCodexIdx + 1, scanEnd));
1707
1722
  }
1708
- const summary = `[codex: model=${model}, tokens=${tokensCount}]`;
1723
+ const dropped = droppedTurns > 0 ? `, ${droppedTurns} earlier turn(s) dropped` : "";
1724
+ const summary = `[codex: model=${model}, tokens=${tokensCount}${dropped}]`;
1709
1725
  return this.finalize([summary, ...answerLines]);
1710
1726
  }
1711
1727
  };
@@ -3244,6 +3260,7 @@ var _BANDIT_CODE_SCANNED_RE = /^Code scanned:/;
3244
3260
  var _BANDIT_TOTAL_ISSUES_RE = /^Total issues \(by/;
3245
3261
  var _BANDIT_STAT_LINE_RE = /^\s+\|?\s*\d/;
3246
3262
  var _BANDIT_TESTING_RE = /^testing\s/;
3263
+ var _BANDIT_SEPARATOR_RE = /^-{10,}\s*$/;
3247
3264
  var _TRIVY_LOG_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[^\s]*\s+(?:INFO|WARN|DEBUG|ERROR)\s/;
3248
3265
  var _TRIVY_TABLE_SEP_RE = /^[+|-]+$/;
3249
3266
  var _TRIVY_TABLE_ROW_RE = /^\|/;
@@ -3251,7 +3268,7 @@ var _TRIVY_TOTAL_RE = /^Total:\s*\d+/i;
3251
3268
  var _TRIVY_NO_VULN_RE = /no\s+vulnerabilit/i;
3252
3269
  var _TRIVY_TARGET_RE = /^(?:[-=]+\s+)?(?:Python|Ruby|Node\.js|Go|Java|PHP|Rust|OS Packages|Alpine|Debian|Ubuntu|RHEL|CentOS|npm|pip|gem|cargo|pom\.xml|Gemfile\.lock|requirements|package-lock|yarn\.lock|composer\.lock|go\.sum|Cargo\.lock|\S+\s+\()/i;
3253
3270
  var _SNYK_TESTING_RE = /^Testing\s/i;
3254
- var _SNYK_TREE_LINE_RE = /^(?:[├└│\s]|[|\\`][-\s]| {2})/;
3271
+ var _SNYK_TREE_LINE_RE = /^\s*(?:[├└│]|[|\\`][-\s])/;
3255
3272
  var _SNYK_VULN_HEADER_RE = /(?:✗|x|X)?\s*(?:Critical|High|Medium|Low|Info)\s+severity/i;
3256
3273
  var _SNYK_MORE_ABOUT_RE = /^\s*(?:More about this vulnerability|https?:\/\/\S+)/i;
3257
3274
  var _SNYK_SUMMARY_RE = /(?:✔|✗|Tested\s+\d+|unique vulnerabilities|no vulnerable paths|issues found)/i;
@@ -3442,6 +3459,7 @@ var GhRunLogFilter = class extends ToolFilter {
3442
3459
  const flushGroup = () => {
3443
3460
  if (!groupLines.length) return;
3444
3461
  if (groupHasFailure || groupLines.length <= GROUP_COLLAPSE_THRESHOLD) {
3462
+ if (groupName) kept.push(`[group: ${groupName}]`);
3445
3463
  kept.push(...groupLines);
3446
3464
  } else {
3447
3465
  kept.push(`[group: ${groupName} \u2014 ${groupLines.length} lines collapsed by token-goat]`);
@@ -3657,16 +3675,22 @@ var BanditFilter = class extends ToolFilter {
3657
3675
  let inIssue = false;
3658
3676
  let currentSeverity = "";
3659
3677
  let issueBuf = [];
3678
+ let dropTrailingSeparator = false;
3660
3679
  const flushIssue = () => {
3661
3680
  const sev = currentSeverity.toUpperCase();
3662
3681
  if (sev === "HIGH" || sev === "MEDIUM") {
3663
3682
  kept.push(...issueBuf);
3664
3683
  } else {
3665
3684
  lowDropped++;
3685
+ dropTrailingSeparator = true;
3666
3686
  }
3667
3687
  };
3668
3688
  let inStatsBlock = false;
3669
3689
  for (const line of lines) {
3690
+ if (dropTrailingSeparator) {
3691
+ dropTrailingSeparator = false;
3692
+ if (_BANDIT_SEPARATOR_RE.test(line)) continue;
3693
+ }
3670
3694
  if (_BANDIT_TESTING_RE.test(line)) continue;
3671
3695
  if (_BANDIT_CODE_SCANNED_RE.test(line) || _BANDIT_TOTAL_ISSUES_RE.test(line)) {
3672
3696
  if (inIssue) {
@@ -4023,6 +4047,7 @@ var _TF_STILL_RE = /^[a-z0-9_.[\]"-]+: Still (?:creating|modifying|destroying)\.
4023
4047
  var _TF_APPLY_COMPLETE_RE = /^Apply complete! Resources:/;
4024
4048
  var _TF_RESOURCE_COMPLETE_RE = /^[a-z0-9_.[\]"-]+: (?:Creation|Destruction|Modifications?) complete/i;
4025
4049
  var _TF_PLAN_ATTR_DIFF_RE = /^\s+[~+-]\s+\S/;
4050
+ var _TF_PLAN_ACTION_HDR_RE = /^\s*#\s+\S+\s+(?:will be|must be|has been|has moved|will no longer be)\b/;
4026
4051
  var _TF_KNOWN_AFTER_APPLY_RE = /\(known after apply\)/;
4027
4052
  var _TF_INIT_PROVIDER_RE = /^\s*-\s+(?:Finding|Installing|Installed|Downloading|Locking)\s+\S+/i;
4028
4053
  var _TF_SHOW_RESOURCE_HDR_RE = /^# (?:(?:module\.[^.\s]+\.)?[a-z][a-z0-9_]+\.[a-zA-Z0-9_.[\]-]+):$/;
@@ -4143,10 +4168,14 @@ ${stderr.replace(/\s+$/, "")}` : stderr;
4143
4168
  }
4144
4169
  let finalKept;
4145
4170
  if (summaryLine !== null) {
4146
- const tailLines = kept.filter((ln) => !_TF_REFRESH_RE.test(ln));
4147
- finalKept = [summaryLine];
4171
+ const tailLines = kept.filter((ln) => !_TF_REFRESH_RE.test(ln) && ln !== summaryLine);
4148
4172
  const tailStart = Math.max(0, tailLines.length - 20);
4149
- finalKept.push(...tailLines.slice(tailStart).filter((ln) => ln !== summaryLine));
4173
+ const head = tailLines.slice(0, tailStart);
4174
+ const headActions = head.filter((ln) => _TF_PLAN_ACTION_HDR_RE.test(ln));
4175
+ finalKept = [summaryLine, ...headActions];
4176
+ const omitted = head.length - headActions.length;
4177
+ if (omitted > 0) finalKept.push(`[token-goat: ${omitted} plan detail lines omitted]`);
4178
+ finalKept.push(...tailLines.slice(tailStart));
4150
4179
  } else {
4151
4180
  finalKept = kept;
4152
4181
  }
@@ -8935,17 +8964,26 @@ var EnvFilter = class extends ToolFilter {
8935
8964
  if (totalVars <= ENV_PASSTHROUGH_THRESHOLD) return merged;
8936
8965
  const kept = [];
8937
8966
  let suppressed = 0;
8967
+ let inSuppressedValue = false;
8938
8968
  for (const line of lines) {
8939
8969
  const m = ENV_LINE_RE.exec(line);
8940
8970
  if (!m) {
8971
+ if (line === "---") {
8972
+ inSuppressedValue = false;
8973
+ kept.push(line);
8974
+ continue;
8975
+ }
8976
+ if (inSuppressedValue) continue;
8941
8977
  kept.push(line);
8942
8978
  continue;
8943
8979
  }
8944
8980
  const varName = m[1];
8945
8981
  if (ENV_KEEP_VARS.has(varName) || ENV_KEEP_PREFIXES.some((p) => varName.startsWith(p))) {
8946
8982
  kept.push(line);
8983
+ inSuppressedValue = false;
8947
8984
  } else {
8948
8985
  suppressed++;
8986
+ inSuppressedValue = true;
8949
8987
  }
8950
8988
  }
8951
8989
  if (suppressed) {
@@ -9470,17 +9508,26 @@ function _compressKubectlDescribe(text) {
9470
9508
  }
9471
9509
  if (stripped.startsWith("Events:")) {
9472
9510
  kept.push("");
9473
- kept.push("Events:");
9474
- const eventLines = lines.slice(i + 1).filter((l) => l.trim());
9475
- if (eventLines.length > 0) {
9476
- if (eventLines.length > 10) {
9477
- kept.push(` [token-goat: ${eventLines.length - 10} earlier events elided]`);
9478
- kept.push(...eventLines.slice(-10));
9479
- } else {
9480
- kept.push(...eventLines);
9511
+ kept.push(line.replace(/\s+$/, ""));
9512
+ const eventIndent = line.length - line.trimStart().length;
9513
+ const eventLines = [];
9514
+ i++;
9515
+ while (i < lines.length) {
9516
+ const nxt = lines[i];
9517
+ if (nxt.trim()) {
9518
+ const nxtIndent = nxt.length - nxt.trimStart().length;
9519
+ if (nxtIndent <= eventIndent) break;
9520
+ eventLines.push(nxt);
9481
9521
  }
9522
+ i++;
9482
9523
  }
9483
- break;
9524
+ if (eventLines.length > 10) {
9525
+ kept.push(` [token-goat: ${eventLines.length - 10} earlier events elided]`);
9526
+ kept.push(...eventLines.slice(-10));
9527
+ } else {
9528
+ kept.push(...eventLines);
9529
+ }
9530
+ continue;
9484
9531
  }
9485
9532
  if (_KEY_PREFIXES.some((pfx) => stripped.startsWith(pfx))) {
9486
9533
  kept.push(line);
@@ -10917,7 +10964,12 @@ var _RUFF_SUCCESS_RE = /^(?:All checks passed!|No errors found\.?)\s*$/;
10917
10964
  var _RUFF_FORMAT_REFORMATTED_RE = /^reformatted\s+\S/;
10918
10965
  var _RUFF_FORMAT_WOULD_REFORMAT_RE = /^would reformat\s+\S/i;
10919
10966
  var _RUFF_CONTEXT_LINE_RE = /^\s*(?:\d+\s*)?\|/;
10920
- var _RUFF_HELP_LINE_RE = /^\s*=\s*help:/i;
10967
+ var _RUFF_HELP_LINE_RE = /^\s*(?:=\s*)?help:/i;
10968
+ var _RUFF_FULL_HEADER_RE = /^(?<code>[A-Z]+\d+)(?:\s+\[\*\])?\s+\S/;
10969
+ var _RUFF_FULL_LOCATION_RE = /^\s*-->\s*(?<file>.+?):\d+:\d+\s*$/;
10970
+ function _isRuffFullHeader(lines, i) {
10971
+ return _RUFF_FULL_HEADER_RE.test(lines[i] ?? "") && _RUFF_FULL_LOCATION_RE.test(lines[i + 1] ?? "");
10972
+ }
10921
10973
  var RuffFilter = class extends ToolFilter {
10922
10974
  name = "ruff";
10923
10975
  binaries = /* @__PURE__ */ new Set(["ruff"]);
@@ -10954,23 +11006,45 @@ var RuffFilter = class extends ToolFilter {
10954
11006
  const bucket = byCode.get(code) ?? [];
10955
11007
  bucket.push({ file, text });
10956
11008
  byCode.set(code, bucket);
10957
- indexed.push({ kind: "viol", code, file, text });
11009
+ indexed.push({ kind: "viol", code, file, text, headerLines: 1 });
11010
+ continue;
11011
+ }
11012
+ const fullHeader = _RUFF_FULL_HEADER_RE.exec(line);
11013
+ const fullLoc = fullHeader?.groups ? _RUFF_FULL_LOCATION_RE.exec(lines[i + 1] ?? "") : null;
11014
+ if (fullHeader?.groups && fullLoc?.groups) {
11015
+ const code = fullHeader.groups["code"];
11016
+ const file = fullLoc.groups["file"];
11017
+ const text = [line, lines[i + 1]];
11018
+ i += 2;
11019
+ while (i < lines.length && lines[i].trim() !== "" && !_RUFF_FOOTER_RE.test(lines[i]) && !_isRuffFullHeader(lines, i)) {
11020
+ text.push(lines[i]);
11021
+ i++;
11022
+ }
11023
+ const bucket = byCode.get(code) ?? [];
11024
+ bucket.push({ file, text });
11025
+ byCode.set(code, bucket);
11026
+ indexed.push({ kind: "viol", code, file, text, headerLines: 2 });
10958
11027
  } else {
10959
11028
  indexed.push({ kind: "other", line });
10960
11029
  i++;
10961
11030
  }
10962
11031
  }
10963
11032
  const summarised = /* @__PURE__ */ new Map();
11033
+ const contextCollapsed = /* @__PURE__ */ new Set();
10964
11034
  for (const [code, entries] of byCode) {
10965
11035
  const files = new Set(entries.map((e) => e.file));
10966
11036
  if (entries.length >= 3 && files.size >= 2) {
10967
11037
  const example = entries[0].text[0];
10968
11038
  summarised.set(code, `${code}: ${entries.length} occurrences in ${files.size} files (example: ${example})`);
11039
+ } else if (entries.length >= 3 && entries.some((e) => e.text.length > 1)) {
11040
+ contextCollapsed.add(code);
10969
11041
  }
10970
11042
  }
10971
11043
  const out = [];
10972
11044
  const emittedSummary = /* @__PURE__ */ new Set();
10973
11045
  const footerLines = [];
11046
+ const seenPerCode = /* @__PURE__ */ new Map();
11047
+ let contextBlocksDropped = 0;
10974
11048
  for (const seg of indexed) {
10975
11049
  if (seg.kind === "footer") {
10976
11050
  footerLines.push(seg.line);
@@ -10985,11 +11059,27 @@ var RuffFilter = class extends ToolFilter {
10985
11059
  out.push(summarised.get(seg.code));
10986
11060
  emittedSummary.add(seg.code);
10987
11061
  }
11062
+ } else if (contextCollapsed.has(seg.code)) {
11063
+ const seen = seenPerCode.get(seg.code) ?? 0;
11064
+ seenPerCode.set(seg.code, seen + 1);
11065
+ if (seen === 0 || seg.text.length <= seg.headerLines) {
11066
+ out.push(...seg.text);
11067
+ } else {
11068
+ out.push(...seg.text.slice(0, seg.headerLines));
11069
+ contextBlocksDropped++;
11070
+ }
10988
11071
  } else {
10989
11072
  out.push(...seg.text);
10990
11073
  }
10991
11074
  }
10992
11075
  out.push(...footerLines);
11076
+ const notes = [];
11077
+ maybeNote(
11078
+ notes,
11079
+ contextBlocksDropped,
11080
+ `dropped ${contextBlocksDropped} repeated source-context blocks (locations kept)`
11081
+ );
11082
+ this.emitNotes(out, notes);
10993
11083
  return squeezeBlankLines(out.join("\n"));
10994
11084
  }
10995
11085
  _compressFormat(merged, exitCode) {
@@ -11342,6 +11432,7 @@ var MypyFilter = class extends ToolFilter {
11342
11432
  var _GOLANGCI_ISSUE_RE = /^(?<file>[^:\s][^:]*\.go):(?<line>\d+)(?::\d+)?:\s+(?<msg>.+?)\s+\((?<linter>[^)]+)\)\s*$/;
11343
11433
  var _GOLANGCI_SUMMARY_RE = /^(?:Found \d+ issues?\.|Issues? found\.|Run with --fix)|^(?:ERRO\s|WARN\s)/i;
11344
11434
  var _GOLANGCI_NOISE_RE = /^(?:golangci-lint\s+version|time=|level=(?:info|debug)|msg="(?:Running|Starting|Finishing))/i;
11435
+ var _GOLANGCI_CARET_RE = /^\s*\^[~^]*\s*$/;
11345
11436
  var GolangciLintFilter = class _GolangciLintFilter extends ToolFilter {
11346
11437
  name = "golangci-lint";
11347
11438
  binaries = /* @__PURE__ */ new Set(["golangci-lint"]);
@@ -11359,7 +11450,9 @@ var GolangciLintFilter = class _GolangciLintFilter extends ToolFilter {
11359
11450
  const kept = [];
11360
11451
  let noiseDropped = 0;
11361
11452
  let issuesCollapsed = 0;
11362
- for (const line of lines) {
11453
+ let contextDropped = 0;
11454
+ for (let i = 0; i < lines.length; i++) {
11455
+ const line = lines[i];
11363
11456
  if (_GOLANGCI_NOISE_RE.test(line)) {
11364
11457
  noiseDropped++;
11365
11458
  continue;
@@ -11370,6 +11463,17 @@ var GolangciLintFilter = class _GolangciLintFilter extends ToolFilter {
11370
11463
  }
11371
11464
  const m = _GOLANGCI_ISSUE_RE.exec(line);
11372
11465
  if (m?.groups) {
11466
+ const next = lines[i + 1] ?? "";
11467
+ let source = null;
11468
+ let caret = null;
11469
+ if (!_GOLANGCI_ISSUE_RE.test(next) && !_GOLANGCI_SUMMARY_RE.test(next) && _GOLANGCI_CARET_RE.test(lines[i + 2] ?? "")) {
11470
+ source = next;
11471
+ caret = lines[i + 2];
11472
+ i += 2;
11473
+ } else if (_GOLANGCI_CARET_RE.test(next)) {
11474
+ caret = next;
11475
+ i += 1;
11476
+ }
11373
11477
  const filePath = m.groups["file"];
11374
11478
  const linter = m.groups["linter"];
11375
11479
  const key = `${filePath}\0${linter}`;
@@ -11377,9 +11481,15 @@ var GolangciLintFilter = class _GolangciLintFilter extends ToolFilter {
11377
11481
  issueCounts.set(key, count + 1);
11378
11482
  if (count < _GolangciLintFilter._KEEP_FIRST_N) {
11379
11483
  kept.push(line);
11380
- } else if (count === _GolangciLintFilter._KEEP_FIRST_N) {
11381
- kept.push(`[token-goat: __placeholder__${filePath}__${linter}__]`);
11382
- issuesCollapsed++;
11484
+ if (source !== null) contextDropped++;
11485
+ if (caret !== null) contextDropped++;
11486
+ } else {
11487
+ if (count === _GolangciLintFilter._KEEP_FIRST_N) {
11488
+ kept.push(`[token-goat: __placeholder__${filePath}__${linter}__]`);
11489
+ issuesCollapsed++;
11490
+ }
11491
+ if (source !== null) contextDropped++;
11492
+ if (caret !== null) contextDropped++;
11383
11493
  }
11384
11494
  continue;
11385
11495
  }
@@ -11401,6 +11511,7 @@ var GolangciLintFilter = class _GolangciLintFilter extends ToolFilter {
11401
11511
  }
11402
11512
  const notes = [];
11403
11513
  maybeNote(notes, noiseDropped, `dropped ${noiseDropped} structured-log noise lines`);
11514
+ maybeNote(notes, contextDropped, `dropped ${contextDropped} redundant source-context/caret lines`);
11404
11515
  if (issuesCollapsed) {
11405
11516
  const totalIssues = [...issueCounts.values()].reduce((a, b) => a + b, 0);
11406
11517
  const keptIssues = [...issueCounts.values()].reduce(
@@ -11417,7 +11528,8 @@ var GolangciLintFilter = class _GolangciLintFilter extends ToolFilter {
11417
11528
  };
11418
11529
  var _PYLINT_MODULE_RE = /^\*{10,}\s+Module\s/;
11419
11530
  var _PYLINT_ISSUE_RE = /^[^\s].*:\d+:\d+:\s+[CWEFR]\d{4}/;
11420
- var _PYLINT_CODE_RE = /\s([CWEFR]\d{4})\s/;
11531
+ var _PYLINT_CODE_RE = /\s([CWEFR]\d{4})(?=[\s:]|$)/;
11532
+ var _PYLINT_SYMBOL_RE = /\(([a-z][a-z0-9]*(?:-[a-z0-9]+)*)\)\s*$/;
11421
11533
  var _PYLINT_RATING_RE = /^Your code has been rated at/;
11422
11534
  var _PYLINT_SEPARATOR_RE = /^-{10,}$/;
11423
11535
  var _PYLINT_CONFIG_RE = /^(?:Using config file|Loading plugin|No config file found)/;
@@ -11431,6 +11543,7 @@ var PylintFilter = class _PylintFilter extends ToolFilter {
11431
11543
  const kept = [];
11432
11544
  const codeCounts = /* @__PURE__ */ new Map();
11433
11545
  const pendingPlaceholders = [];
11546
+ const codeSymbols = /* @__PURE__ */ new Map();
11434
11547
  let deduplicated = 0;
11435
11548
  let droppedSeparators = 0;
11436
11549
  let droppedConfig = 0;
@@ -11462,6 +11575,8 @@ var PylintFilter = class _PylintFilter extends ToolFilter {
11462
11575
  const code = m ? m[1] : "__unknown__";
11463
11576
  const severity = code[0] ?? "?";
11464
11577
  const key = `${currentModule ?? ""}\0${code}`;
11578
+ const symM = _PYLINT_SYMBOL_RE.exec(line);
11579
+ if (symM && !codeSymbols.has(key)) codeSymbols.set(key, symM[1]);
11465
11580
  const count = codeCounts.get(key) ?? 0;
11466
11581
  codeCounts.set(key, count + 1);
11467
11582
  const alwaysKeep = severity === "E" || severity === "F";
@@ -11474,12 +11589,11 @@ var PylintFilter = class _PylintFilter extends ToolFilter {
11474
11589
  moduleHasKeptIssue = true;
11475
11590
  } else {
11476
11591
  if (count === _PylintFilter._KEEP_PER_CODE) {
11477
- const codeName = code.slice(1);
11478
11592
  if (pendingModule !== null) {
11479
11593
  kept.push(pendingModule);
11480
11594
  pendingModule = null;
11481
11595
  }
11482
- pendingPlaceholders.push({ index: kept.length, code, codeName, key });
11596
+ pendingPlaceholders.push({ index: kept.length, code, key });
11483
11597
  kept.push("");
11484
11598
  moduleHasKeptIssue = true;
11485
11599
  }
@@ -11494,14 +11608,16 @@ var PylintFilter = class _PylintFilter extends ToolFilter {
11494
11608
  }
11495
11609
  kept.push(line);
11496
11610
  }
11497
- for (const { index, code, codeName, key } of pendingPlaceholders) {
11611
+ for (const { index, code, key } of pendingPlaceholders) {
11498
11612
  const elided = (codeCounts.get(key) ?? 0) - _PylintFilter._KEEP_PER_CODE;
11499
- kept[index] = `[token-goat: +${elided} more ${code} (${codeName}); disable via TOKEN_GOAT_BASH_COMPRESS]`;
11613
+ const symbol = codeSymbols.get(key);
11614
+ const label = symbol !== void 0 ? `${code} (${symbol})` : code;
11615
+ kept[index] = `[token-goat: +${elided} more ${label}; disable via TOKEN_GOAT_BASH_COMPRESS]`;
11500
11616
  }
11501
11617
  const notes = [];
11502
- maybeNote(notes, deduplicated, `deduplicated ${deduplicated} repeated-code issue lines`);
11503
- maybeNote(notes, droppedSeparators, `dropped ${droppedSeparators} separator lines`);
11504
- maybeNote(notes, droppedConfig, `dropped ${droppedConfig} config-loading lines`);
11618
+ maybeNote(notes, deduplicated, `deduplicated ${deduplicated} repeated-code issue line${plural(deduplicated)}`);
11619
+ maybeNote(notes, droppedSeparators, `dropped ${droppedSeparators} separator line${plural(droppedSeparators)}`);
11620
+ maybeNote(notes, droppedConfig, `dropped ${droppedConfig} config-loading line${plural(droppedConfig)}`);
11505
11621
  this.emitNotes(kept, notes);
11506
11622
  return this.finalize(kept);
11507
11623
  }
@@ -11710,7 +11826,7 @@ var LinterFilter = class extends ToolFilter {
11710
11826
  return _compressEslintStanza(merged);
11711
11827
  }
11712
11828
  };
11713
- var _KTLINT_ISSUE_RE = /^(.+\.kt):(\d+):(\d+):\s+(error|warning):\s+(.+)\s+\(([^)]+)\)$/i;
11829
+ var _KTLINT_ISSUE_RE = /^(.+\.kts?):(\d+):(\d+):\s+(?:(error|warning):\s+)?(.+)\s+\(([^)]+)\)$/i;
11714
11830
  var _KTLINT_CHECKSTYLE_TAG_RE = /^\s*<(?:\?xml|checkstyle|file)\b/i;
11715
11831
  var _KTLINT_CHECKSTYLE_ERROR_RE = /^\s*<error\b.*\bsource="([^"]+)"/i;
11716
11832
  var _KTLINT_SUMMARY_RE = /^\s*(?:\d+\s+lint\s+error|ktlint\s+\d+\.\d+|Kotlin\s+style\s+guide|No\s+lint\s+errors|Resolving|Checking|Formatting)/i;
@@ -11749,7 +11865,7 @@ var KtlintFilter = class _KtlintFilter extends ToolFilter {
11749
11865
  kept.push(line);
11750
11866
  } else {
11751
11867
  if (count === _KtlintFilter._KEEP_PER_RULE + 1) {
11752
- pendingPlaceholders.push({ index: kept.length, rule, suffix: "violations" });
11868
+ pendingPlaceholders.push({ index: kept.length, rule, suffix: "violations", indent: " " });
11753
11869
  kept.push("");
11754
11870
  }
11755
11871
  deduplicated++;
@@ -11758,7 +11874,7 @@ var KtlintFilter = class _KtlintFilter extends ToolFilter {
11758
11874
  }
11759
11875
  const m = _KTLINT_ISSUE_RE.exec(line);
11760
11876
  if (m) {
11761
- const severity = m[4].toLowerCase();
11877
+ const severity = (m[4] ?? "").toLowerCase();
11762
11878
  const rule = m[6];
11763
11879
  const count = (ruleCounts.get(rule) ?? 0) + 1;
11764
11880
  ruleCounts.set(rule, count);
@@ -11767,7 +11883,12 @@ var KtlintFilter = class _KtlintFilter extends ToolFilter {
11767
11883
  kept.push(line);
11768
11884
  } else {
11769
11885
  if (count === _KtlintFilter._KEEP_PER_RULE + 1) {
11770
- pendingPlaceholders.push({ index: kept.length, rule, suffix: "warnings" });
11886
+ pendingPlaceholders.push({
11887
+ index: kept.length,
11888
+ rule,
11889
+ suffix: severity === "warning" ? "warnings" : "violations",
11890
+ indent: ""
11891
+ });
11771
11892
  kept.push("");
11772
11893
  }
11773
11894
  deduplicated++;
@@ -11780,9 +11901,8 @@ var KtlintFilter = class _KtlintFilter extends ToolFilter {
11780
11901
  }
11781
11902
  kept.push(line);
11782
11903
  }
11783
- for (const { index, rule, suffix } of pendingPlaceholders) {
11904
+ for (const { index, rule, suffix, indent } of pendingPlaceholders) {
11784
11905
  const elided = (ruleCounts.get(rule) ?? 0) - _KtlintFilter._KEEP_PER_RULE;
11785
- const indent = suffix === "violations" ? " " : "";
11786
11906
  kept[index] = `${indent}[token-goat: +${elided} more ${rule} ${suffix}; disable via TOKEN_GOAT_BASH_COMPRESS for full list]`;
11787
11907
  }
11788
11908
  const notes = [];
@@ -12091,7 +12211,7 @@ var CppcheckFilter = class extends ToolFilter {
12091
12211
  };
12092
12212
  var _CLANG_TIDY_WARNINGS_GENERATED_RE = /^\d+\s+warning(?:s)?\s+generated\./;
12093
12213
  var _CLANG_TIDY_PROCESSING_RE = /^clang-tidy:\s+Processing\s+\d+/i;
12094
- var _CLANG_TIDY_DIAG_RE = /^.+\.(?:c|cpp|cxx|cc|h|hpp|hxx):\d+:\d+:\s+(?:error|warning|note|remark):/;
12214
+ var _CLANG_TIDY_DIAG_RE = /^.+\.(?:c|cpp|cxx|cc|h|hpp|hxx|cuh|cu|tcc|inl|mm|m):\d+:\d+:\s+(?:error|warning|note|remark):/;
12095
12215
  var _CLANG_TIDY_NOTE_RE = /^.+:\d+:\d+:\s+note:/;
12096
12216
  var _CLANG_TIDY_CONTEXT_RE = /^\s+(?:\^[~^]*|~+)\s*$|^\s{4,}\S/;
12097
12217
  var _CLANG_TIDY_INCLUDE_RE = /^In\s+file\s+included\s+from\s+/;
@@ -13520,15 +13640,27 @@ var TOOL_FILTERS = [
13520
13640
  ...MISC_FILTERS
13521
13641
  ];
13522
13642
  var PROFILE_CAPS = { aggressive: 50, balanced: 200, minimal: 500 };
13643
+ function peelLeadingCd(argv, cwd) {
13644
+ if (argv.length < 3 || argv[0] !== "cd") return null;
13645
+ const sep = argv[2];
13646
+ if (sep !== "&&" && sep !== ";") return null;
13647
+ const remainder = argv.slice(3);
13648
+ if (remainder.length === 0) return null;
13649
+ const dir = argv[1];
13650
+ return { argv: remainder, cwd: cwd === void 0 ? void 0 : resolveIndexPath(dir, cwd) };
13651
+ }
13523
13652
  function selectFilter(argv, cwd) {
13524
13653
  if (argv.length === 0) return null;
13525
- let resolved = stripPrefixes(argv);
13654
+ const peeled = peelLeadingCd(argv, cwd);
13655
+ const effectiveArgv = peeled !== null ? peeled.argv : argv;
13656
+ const effectiveCwd = peeled !== null ? peeled.cwd : cwd;
13657
+ let resolved = stripPrefixes(effectiveArgv);
13526
13658
  if (resolved.length === 0) {
13527
- resolved = argv.slice(0, 1);
13659
+ resolved = effectiveArgv.slice(0, 1);
13528
13660
  if (resolved.length === 0) return null;
13529
13661
  }
13530
- if (cwd !== void 0) {
13531
- const scriptArgv = resolvePackageManagerScript(resolved, cwd);
13662
+ if (effectiveCwd !== void 0) {
13663
+ const scriptArgv = resolvePackageManagerScript(resolved, effectiveCwd);
13532
13664
  if (scriptArgv !== null) {
13533
13665
  const scriptResolved = stripPrefixes(scriptArgv);
13534
13666
  if (scriptResolved.length > 0) {