@probelabs/probe 0.6.0-rc285 → 0.6.0-rc287

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.
@@ -24981,7 +24981,11 @@ async function extractBinary(assetPath, outputDir) {
24981
24981
  if (process.env.DEBUG === "1" || process.env.VERBOSE === "1") {
24982
24982
  console.log(`Extracting zip to ${extractDir}...`);
24983
24983
  }
24984
- await exec(`unzip -q "${assetPath}" -d "${extractDir}"`);
24984
+ if (isWindows) {
24985
+ await exec(`powershell -NoProfile -Command "Expand-Archive -Path '${assetPath}' -DestinationPath '${extractDir}' -Force"`);
24986
+ } else {
24987
+ await exec(`unzip -q "${assetPath}" -d "${extractDir}"`);
24988
+ }
24985
24989
  } else {
24986
24990
  if (process.env.DEBUG === "1" || process.env.VERBOSE === "1") {
24987
24991
  console.log(`Copying binary directly to ${binaryPath}`);
@@ -27066,7 +27070,14 @@ function parseTargets(targets) {
27066
27070
  }
27067
27071
  function parseAndResolvePaths(pathStr, cwd) {
27068
27072
  if (!pathStr) return [];
27069
- const paths = pathStr.split(",").map((p) => p.trim()).filter((p) => p.length > 0);
27073
+ let paths = pathStr.split(",").map((p) => p.trim()).filter((p) => p.length > 0);
27074
+ paths = paths.flatMap((p) => {
27075
+ if (!/\s/.test(p)) return [p];
27076
+ const parts = p.split(/\s+/).filter(Boolean);
27077
+ if (parts.length <= 1) return [p];
27078
+ const allLookLikePaths = parts.every((part) => /[/\\]/.test(part) || /\.\w+/.test(part));
27079
+ return allLookLikePaths ? parts : [p];
27080
+ });
27070
27081
  return paths.map((p) => {
27071
27082
  if ((0, import_path5.isAbsolute)(p)) {
27072
27083
  return p;
@@ -27299,11 +27310,24 @@ function normalizeTargets(targets) {
27299
27310
  if (typeof target !== "string") continue;
27300
27311
  const trimmed = target.trim();
27301
27312
  if (!trimmed || seen.has(trimmed)) continue;
27302
- seen.add(trimmed);
27303
- normalized.push(trimmed);
27313
+ const subTargets = splitSpaceSeparatedPaths(trimmed);
27314
+ for (const sub of subTargets) {
27315
+ if (!seen.has(sub)) {
27316
+ seen.add(sub);
27317
+ normalized.push(sub);
27318
+ }
27319
+ }
27304
27320
  }
27305
27321
  return normalized;
27306
27322
  }
27323
+ function splitSpaceSeparatedPaths(target) {
27324
+ if (!/\s/.test(target)) return [target];
27325
+ const parts = target.split(/\s+/).filter(Boolean);
27326
+ if (parts.length <= 1) return [target];
27327
+ const allLookLikePaths = parts.every((p) => /[/\\]/.test(p) || /\.\w+/.test(p));
27328
+ if (allLookLikePaths) return parts;
27329
+ return [target];
27330
+ }
27307
27331
  function extractJsonSnippet(text) {
27308
27332
  const jsonBlockMatch = text.match(/```json\s*([\s\S]*?)```/i);
27309
27333
  if (jsonBlockMatch) {
@@ -27789,14 +27813,15 @@ var init_vercel = __esm({
27789
27813
  const parsedTargets = parseTargets(targets);
27790
27814
  extractFiles = parsedTargets.map((target) => resolveTargetPath(target, effectiveCwd));
27791
27815
  if (options.allowedFolders && options.allowedFolders.length > 0) {
27816
+ const { join: pathJoin, sep: pathSep } = await import("path");
27792
27817
  extractFiles = extractFiles.map((target) => {
27793
27818
  const { filePart, suffix } = splitTargetSuffix(target);
27794
27819
  if ((0, import_fs4.existsSync)(filePart)) return target;
27795
- const cwdPrefix = effectiveCwd.endsWith("/") ? effectiveCwd : effectiveCwd + "/";
27820
+ const cwdPrefix = effectiveCwd.endsWith(pathSep) ? effectiveCwd : effectiveCwd + pathSep;
27796
27821
  const relativePart = filePart.startsWith(cwdPrefix) ? filePart.slice(cwdPrefix.length) : null;
27797
27822
  if (relativePart) {
27798
27823
  for (const folder of options.allowedFolders) {
27799
- const candidate = folder + "/" + relativePart;
27824
+ const candidate = pathJoin(folder, relativePart);
27800
27825
  if ((0, import_fs4.existsSync)(candidate)) {
27801
27826
  if (debug) console.error(`[extract] Auto-fixed path: ${filePart} \u2192 ${candidate}`);
27802
27827
  return candidate + suffix;
@@ -27804,11 +27829,12 @@ var init_vercel = __esm({
27804
27829
  }
27805
27830
  }
27806
27831
  for (const folder of options.allowedFolders) {
27807
- const folderPrefix = folder.endsWith("/") ? folder : folder + "/";
27808
- const wsParent = folderPrefix.replace(/[^/]+\/$/, "");
27832
+ const folderPrefix = folder.endsWith(pathSep) ? folder : folder + pathSep;
27833
+ const sepEscaped = pathSep === "\\" ? "\\\\" : pathSep;
27834
+ const wsParent = folderPrefix.replace(new RegExp("[^" + sepEscaped + "]+" + sepEscaped + "$"), "");
27809
27835
  if (filePart.startsWith(wsParent)) {
27810
27836
  const tail = filePart.slice(wsParent.length);
27811
- const candidate = folderPrefix + tail;
27837
+ const candidate = pathJoin(folderPrefix, tail);
27812
27838
  if (candidate !== filePart && (0, import_fs4.existsSync)(candidate)) {
27813
27839
  if (debug) console.error(`[extract] Auto-fixed path via workspace: ${filePart} \u2192 ${candidate}`);
27814
27840
  return candidate + suffix;
@@ -62006,6 +62032,7 @@ var init_parser2 = __esm({
62006
62032
  { ALT: () => this.CONSUME(Identifier) },
62007
62033
  { ALT: () => this.CONSUME(Text) },
62008
62034
  { ALT: () => this.CONSUME(NumberLiteral) },
62035
+ { ALT: () => this.CONSUME(ColorValue) },
62009
62036
  // Note: RoundOpen and RoundClose (parentheses) are NOT allowed in unquoted labels
62010
62037
  // to match Mermaid's behavior - use quoted labels like ["text (with parens)"] instead
62011
62038
  // Allow HTML-like tags (e.g., <br/>) inside labels
@@ -62097,6 +62124,7 @@ var init_parser2 = __esm({
62097
62124
  { ALT: () => this.CONSUME(Identifier) },
62098
62125
  { ALT: () => this.CONSUME(Text) },
62099
62126
  { ALT: () => this.CONSUME(NumberLiteral) },
62127
+ { ALT: () => this.CONSUME(ColorValue) },
62100
62128
  // Allow HTML-like angle brackets and slashes for <br/>, <i>, etc.
62101
62129
  { ALT: () => this.CONSUME(AngleLess) },
62102
62130
  { ALT: () => this.CONSUME(AngleOpen) },
@@ -63272,13 +63300,24 @@ function mapFlowchartParserError(err, text) {
63272
63300
  length: len
63273
63301
  };
63274
63302
  }
63275
- if (tokType === "QuotedString" || tokType === "SquareOpen" || tokType === "SquareClose") {
63303
+ if (tokType === "QuotedString" || tokType === "SquareOpen" || tokType === "SquareClose" || tokType === "DiamondOpen" || tokType === "DiamondClose") {
63276
63304
  const context = err?.context;
63277
63305
  const inLinkRule = context?.ruleStack?.includes("linkTextInline") || context?.ruleStack?.includes("link") || false;
63278
63306
  const lineContent = allLines[Math.max(0, line - 1)] || "";
63279
63307
  const beforeQuote = lineContent.slice(0, Math.max(0, column - 1));
63280
63308
  const hasLinkBefore = beforeQuote.match(/--\s*$|==\s*$|-\.\s*$|-\.-\s*$|\[\s*$/);
63281
63309
  if (inLinkRule || hasLinkBefore) {
63310
+ if (tokType === "DiamondOpen" || tokType === "DiamondClose") {
63311
+ return {
63312
+ line,
63313
+ column,
63314
+ severity: "error",
63315
+ code: "FL-EDGE-LABEL-CURLY-IN-PIPES",
63316
+ message: "Curly braces { } are not supported inside pipe-delimited edge labels.",
63317
+ hint: "Use HTML entities &#123; and &#125; inside |...|, e.g., --|Resolve $&#123;VAR&#125;|-->",
63318
+ length: len
63319
+ };
63320
+ }
63282
63321
  if (tokType === "SquareOpen" || tokType === "SquareClose") {
63283
63322
  return {
63284
63323
  line,
@@ -63340,6 +63379,17 @@ function mapFlowchartParserError(err, text) {
63340
63379
  length: len
63341
63380
  };
63342
63381
  }
63382
+ if (tokType === "DiamondOpen" || tokType === "DiamondClose") {
63383
+ return {
63384
+ line,
63385
+ column,
63386
+ severity: "error",
63387
+ code: "FL-LABEL-CURLY-IN-UNQUOTED",
63388
+ message: "Curly braces are not supported inside unquoted node labels.",
63389
+ hint: "Use &#123; and &#125; for literal braces, e.g., C[Substitute &#123;params&#125;].",
63390
+ length: len
63391
+ };
63392
+ }
63343
63393
  {
63344
63394
  const caret0 = Math.max(0, column - 1);
63345
63395
  const openIdx = lineStr.lastIndexOf("[", caret0);
@@ -63381,9 +63431,20 @@ function mapFlowchartParserError(err, text) {
63381
63431
  length: len
63382
63432
  };
63383
63433
  }
63434
+ if (seg.includes("{") || seg.includes("}")) {
63435
+ return {
63436
+ line,
63437
+ column,
63438
+ severity: "error",
63439
+ code: "FL-LABEL-CURLY-IN-UNQUOTED",
63440
+ message: "Curly braces are not supported inside unquoted node labels.",
63441
+ hint: "Use &#123; and &#125; for literal braces, e.g., C[Substitute &#123;params&#125;].",
63442
+ length: len
63443
+ };
63444
+ }
63384
63445
  }
63385
63446
  }
63386
- if (tokType === "QuotedString" || tokType === "SquareOpen" || tokType === "SquareClose") {
63447
+ if (tokType === "QuotedString") {
63387
63448
  return {
63388
63449
  line,
63389
63450
  column,
@@ -63394,6 +63455,17 @@ function mapFlowchartParserError(err, text) {
63394
63455
  length: len
63395
63456
  };
63396
63457
  }
63458
+ if (tokType === "SquareOpen" || tokType === "SquareClose") {
63459
+ return {
63460
+ line,
63461
+ column,
63462
+ severity: "error",
63463
+ code: "FL-LABEL-BRACKET-IN-UNQUOTED",
63464
+ message: "Square brackets are not supported inside unquoted node labels.",
63465
+ hint: 'Use &#91; and &#93; for literal brackets or wrap the label in quotes, e.g., C["bind_paths[]"]',
63466
+ length: len
63467
+ };
63468
+ }
63397
63469
  const q = findInnerQuoteIssue("[");
63398
63470
  if (q?.kind === "escaped") {
63399
63471
  return { line, column: q.column, severity: "error", code: "FL-LABEL-ESCAPED-QUOTE", message: 'Escaped quotes (\\") in node labels are not supported by Mermaid. Use &quot; instead.', hint: 'Prefer "He said &quot;Hi&quot;".', length: 2 };
@@ -63404,7 +63476,7 @@ function mapFlowchartParserError(err, text) {
63404
63476
  return { line, column, severity: "error", code: "FL-NODE-UNCLOSED-BRACKET", message: "Unclosed '['. Add a matching ']' before the arrow or newline.", hint: "Example: A[Label] --> B", length: 1 };
63405
63477
  }
63406
63478
  if (expecting(err, "RoundClose")) {
63407
- if (tokType === "QuotedString" || tokType === "SquareOpen" || tokType === "SquareClose") {
63479
+ if (tokType === "QuotedString") {
63408
63480
  return {
63409
63481
  line,
63410
63482
  column,
@@ -63415,6 +63487,17 @@ function mapFlowchartParserError(err, text) {
63415
63487
  length: len
63416
63488
  };
63417
63489
  }
63490
+ if (tokType === "SquareOpen" || tokType === "SquareClose") {
63491
+ return {
63492
+ line,
63493
+ column,
63494
+ severity: "error",
63495
+ code: "FL-LABEL-BRACKET-IN-UNQUOTED",
63496
+ message: "Square brackets are not supported inside unquoted node labels.",
63497
+ hint: 'Use &#91; and &#93; for literal brackets or wrap the label in quotes, e.g., C["bind_paths[]"]',
63498
+ length: len
63499
+ };
63500
+ }
63418
63501
  {
63419
63502
  const caret0 = Math.max(0, column - 1);
63420
63503
  const openIdx = lineStr.lastIndexOf("(", caret0);
@@ -63443,7 +63526,7 @@ function mapFlowchartParserError(err, text) {
63443
63526
  return { line, column, severity: "error", code: "FL-NODE-UNCLOSED-BRACKET", message: "Unclosed '('. Add a matching ')'.", hint: "Example: B(Label)", length: 1 };
63444
63527
  }
63445
63528
  if (expecting(err, "DiamondClose")) {
63446
- if (tokType === "QuotedString" || tokType === "SquareOpen" || tokType === "SquareClose") {
63529
+ if (tokType === "QuotedString") {
63447
63530
  return {
63448
63531
  line,
63449
63532
  column,
@@ -63454,6 +63537,17 @@ function mapFlowchartParserError(err, text) {
63454
63537
  length: len
63455
63538
  };
63456
63539
  }
63540
+ if (tokType === "SquareOpen" || tokType === "SquareClose") {
63541
+ return {
63542
+ line,
63543
+ column,
63544
+ severity: "error",
63545
+ code: "FL-LABEL-BRACKET-IN-UNQUOTED",
63546
+ message: "Square brackets are not supported inside unquoted node labels.",
63547
+ hint: 'Use &#91; and &#93; for literal brackets or wrap the label in quotes, e.g., C["bind_paths[]"]',
63548
+ length: len
63549
+ };
63550
+ }
63457
63551
  {
63458
63552
  const caret0 = Math.max(0, column - 1);
63459
63553
  const openIdx = lineStr.lastIndexOf("{", caret0);
@@ -64296,7 +64390,7 @@ function validateFlowchart(text, options = {}) {
64296
64390
  const byLine = /* @__PURE__ */ new Map();
64297
64391
  const collect = (arr) => {
64298
64392
  for (const e of arr || []) {
64299
- if (e && (e.code === "FL-LABEL-PARENS-UNQUOTED" || e.code === "FL-LABEL-AT-IN-UNQUOTED" || e.code === "FL-LABEL-QUOTE-IN-UNQUOTED" || e.code === "FL-LABEL-SLASH-UNQUOTED")) {
64393
+ if (e && (e.code === "FL-LABEL-PARENS-UNQUOTED" || e.code === "FL-LABEL-AT-IN-UNQUOTED" || e.code === "FL-LABEL-QUOTE-IN-UNQUOTED" || e.code === "FL-LABEL-SLASH-UNQUOTED" || e.code === "FL-LABEL-CURLY-IN-UNQUOTED" || e.code === "FL-LABEL-BRACKET-IN-UNQUOTED")) {
64300
64394
  const ln = e.line ?? 0;
64301
64395
  const col = e.column ?? 1;
64302
64396
  const list = byLine.get(ln) || [];
@@ -64378,6 +64472,9 @@ function validateFlowchart(text, options = {}) {
64378
64472
  const hasParens = seg.includes("(") || seg.includes(")");
64379
64473
  const hasAt = seg.includes("@");
64380
64474
  const hasQuote = seg.includes('"');
64475
+ const hasCurly = seg.includes("{") || seg.includes("}");
64476
+ const hasBracket = seg.includes("[") || seg.includes("]");
64477
+ const isDoubleSquare = raw.slice(i, i + 2) === "[[" && raw.slice(j - 2, j) === "]]";
64381
64478
  const isSingleQuoted = /^'[^]*'$/.test(trimmed);
64382
64479
  const hasLeadingSlash = lsp === "/" || lsp === "\\";
64383
64480
  if (!covered && !isQuoted && !isParenWrapped && hasParens) {
@@ -64395,6 +64492,16 @@ function validateFlowchart(text, options = {}) {
64395
64492
  existing.push({ start: startCol, end: endCol });
64396
64493
  byLine.set(ln, existing);
64397
64494
  }
64495
+ if (!covered && !isQuoted && !isSlashPair && hasCurly) {
64496
+ errs.push({ line: ln, column: startCol, severity: "error", code: "FL-LABEL-CURLY-IN-UNQUOTED", message: "Curly braces are not supported inside unquoted node labels.", hint: "Use &#123; and &#125; for literal braces, e.g., C[Substitute &#123;params&#125;]." });
64497
+ existing.push({ start: startCol, end: endCol });
64498
+ byLine.set(ln, existing);
64499
+ }
64500
+ if (!covered && !isQuoted && !isSlashPair && !isDoubleSquare && hasBracket) {
64501
+ errs.push({ line: ln, column: startCol, severity: "error", code: "FL-LABEL-BRACKET-IN-UNQUOTED", message: "Square brackets are not supported inside unquoted node labels.", hint: 'Use &#91; and &#93; for literal brackets or wrap the label in quotes, e.g., C["bind_paths[]"]' });
64502
+ existing.push({ start: startCol, end: endCol });
64503
+ byLine.set(ln, existing);
64504
+ }
64398
64505
  if (!covered && !isQuoted && !isSlashPair && hasQuote && !isSingleQuoted) {
64399
64506
  errs.push({ line: ln, column: startCol, severity: "error", code: "FL-LABEL-QUOTE-IN-UNQUOTED", message: "Quotes are not allowed inside unquoted node labels. Use &quot; for quotes or wrap the entire label in quotes.", hint: 'Example: C["HTML Output: data-trigger-visibility=&quot;true&quot;"]' });
64400
64507
  existing.push({ start: startCol, end: endCol });
@@ -66755,7 +66862,7 @@ function computeFixes(text, errors, level = "safe") {
66755
66862
  }
66756
66863
  continue;
66757
66864
  }
66758
- if (is("FL-EDGE-LABEL-BRACKET", e)) {
66865
+ if (is("FL-EDGE-LABEL-BRACKET", e) || is("FL-EDGE-LABEL-CURLY-IN-PIPES", e)) {
66759
66866
  const lineText = lineTextAt(text, e.line);
66760
66867
  const firstBar = lineText.indexOf("|");
66761
66868
  const secondBar = firstBar >= 0 ? lineText.indexOf("|", firstBar + 1) : -1;
@@ -66763,7 +66870,8 @@ function computeFixes(text, errors, level = "safe") {
66763
66870
  const before = lineText.slice(0, firstBar + 1);
66764
66871
  const label = lineText.slice(firstBar + 1, secondBar);
66765
66872
  const after = lineText.slice(secondBar);
66766
- const fixedLabel = label.replace(/\[/g, "&#91;").replace(/\]/g, "&#93;");
66873
+ let fixedLabel = label.replace(/\[/g, "&#91;").replace(/\]/g, "&#93;");
66874
+ fixedLabel = fixedLabel.replace(/\{/g, "&#123;").replace(/\}/g, "&#125;");
66767
66875
  const fixedLine = before + fixedLabel + after;
66768
66876
  const finalLine = fixedLine.replace(/\[([^\]]*)\]/g, (m, seg) => "[" + String(seg).replace(/`/g, "") + "]");
66769
66877
  edits.push({ start: { line: e.line, column: 1 }, end: { line: e.line, column: lineText.length + 1 }, newText: finalLine });
@@ -67403,7 +67511,7 @@ function computeFixes(text, errors, level = "safe") {
67403
67511
  }
67404
67512
  continue;
67405
67513
  }
67406
- if (is("FL-LABEL-PARENS-UNQUOTED", e) || is("FL-LABEL-AT-IN-UNQUOTED", e) || is("FL-LABEL-SLASH-UNQUOTED", e)) {
67514
+ if (is("FL-LABEL-PARENS-UNQUOTED", e) || is("FL-LABEL-AT-IN-UNQUOTED", e) || is("FL-LABEL-SLASH-UNQUOTED", e) || is("FL-LABEL-CURLY-IN-UNQUOTED", e) || is("FL-LABEL-BRACKET-IN-UNQUOTED", e)) {
67407
67515
  if (level === "safe" || level === "all") {
67408
67516
  if (patchedLines.has(e.line))
67409
67517
  continue;
@@ -67444,7 +67552,7 @@ function computeFixes(text, errors, level = "safe") {
67444
67552
  if (openIdx === -1)
67445
67553
  break;
67446
67554
  const contentStart = openIdx + shape.open.length;
67447
- const closeIdx = shape.open === "(" && shape.close === ")" ? findMatchingCloser(lineText, openIdx, shape.open, shape.close) : lineText.indexOf(shape.close, contentStart);
67555
+ const closeIdx = shape.open === "(" && shape.close === ")" || shape.open === "[" && shape.close === "]" ? findMatchingCloser(lineText, openIdx, shape.open, shape.close) : lineText.indexOf(shape.close, contentStart);
67448
67556
  if (closeIdx === -1)
67449
67557
  break;
67450
67558
  if (openIdx <= caret0 && caret0 < closeIdx) {
@@ -67464,11 +67572,21 @@ function computeFixes(text, errors, level = "safe") {
67464
67572
  const isSlashPair = (l, r) => l === "/" && r === "/" || l === "\\" && r === "\\" || l === "/" && r === "\\" || l === "\\" && r === "/";
67465
67573
  const isParallelogramShape = core.length >= 2 && isSlashPair(left, right);
67466
67574
  let replaced;
67467
- if (!isParallelogramShape) {
67468
- const escaped = inner.replace(/`/g, "").replace(/\"/g, "&quot;").replace(/"/g, "&quot;");
67575
+ if (is("FL-LABEL-BRACKET-IN-UNQUOTED", e) && !isParallelogramShape) {
67576
+ const hasOtherHazards = /[(){}@]/.test(inner) || inner.includes('"') || inner.includes('\\"');
67577
+ if (hasOtherHazards) {
67578
+ const escaped = inner.replace(/`/g, "").replace(/\\"/g, "&quot;").replace(/"/g, "&quot;");
67579
+ replaced = '"' + escaped + '"';
67580
+ } else {
67581
+ replaced = inner.replace(/\[/g, "&#91;").replace(/\]/g, "&#93;");
67582
+ }
67583
+ } else if (is("FL-LABEL-CURLY-IN-UNQUOTED", e)) {
67584
+ replaced = inner.replace(/\{/g, "&#123;").replace(/\}/g, "&#125;");
67585
+ } else if (!isParallelogramShape) {
67586
+ const escaped = inner.replace(/`/g, "").replace(/\\"/g, "&quot;").replace(/"/g, "&quot;");
67469
67587
  replaced = '"' + escaped + '"';
67470
67588
  } else {
67471
- replaced = inner.replace(/`/g, "").replace(/\(/g, "&#40;").replace(/\)/g, "&#41;").replace(/\"/g, "&quot;").replace(/"/g, "&quot;");
67589
+ replaced = inner.replace(/`/g, "").replace(/\(/g, "&#40;").replace(/\)/g, "&#41;").replace(/\[/g, "&#91;").replace(/\]/g, "&#93;").replace(/\\"/g, "&quot;").replace(/"/g, "&quot;");
67472
67590
  }
67473
67591
  if (replaced !== inner) {
67474
67592
  edits.push({ start: { line: e.line, column: contentStart + 1 }, end: { line: e.line, column: closeIdx + 1 }, newText: replaced });
@@ -97556,14 +97674,6 @@ var init_FallbackManager = __esm({
97556
97674
  });
97557
97675
 
97558
97676
  // src/agent/contextCompactor.js
97559
- var contextCompactor_exports = {};
97560
- __export(contextCompactor_exports, {
97561
- calculateCompactionStats: () => calculateCompactionStats,
97562
- compactMessages: () => compactMessages,
97563
- handleContextLimitError: () => handleContextLimitError,
97564
- identifyMessageSegments: () => identifyMessageSegments,
97565
- isContextLimitError: () => isContextLimitError
97566
- });
97567
97677
  function isContextLimitError(error40) {
97568
97678
  if (!error40) return false;
97569
97679
  const errorMessage = (typeof error40 === "string" ? error40 : error40?.message || "").toLowerCase();
@@ -101879,6 +101989,16 @@ You are working with a workspace. Available paths: ${workspaceDesc}
101879
101989
  userMessage
101880
101990
  ];
101881
101991
  }
101992
+ if (this.history.length > 0) {
101993
+ const compacted = compactMessages(currentMessages, { keepLastSegment: true, minSegmentsToKeep: 1 });
101994
+ if (compacted.length < currentMessages.length) {
101995
+ const stats = calculateCompactionStats(currentMessages, compacted);
101996
+ if (this.debug) {
101997
+ console.log(`[DEBUG] Proactive history compaction: ${currentMessages.length} \u2192 ${compacted.length} messages (${stats.reductionPercent}% reduction, ~${stats.tokensSaved} tokens saved)`);
101998
+ }
101999
+ currentMessages = compacted;
102000
+ }
102001
+ }
101882
102002
  let currentIteration = 0;
101883
102003
  let finalResult = "I was unable to complete your request due to reaching the maximum number of tool iterations.";
101884
102004
  const baseMaxIterations = options._maxIterationsOverride || this.maxIterations || MAX_TOOL_ITERATIONS;
@@ -102579,7 +102699,6 @@ Double-check your response based on the criteria above. If everything looks good
102579
102699
  * @returns {Object} Compaction statistics
102580
102700
  */
102581
102701
  async compactHistory(options = {}) {
102582
- const { compactMessages: compactMessages2, calculateCompactionStats: calculateCompactionStats2 } = await Promise.resolve().then(() => (init_contextCompactor(), contextCompactor_exports));
102583
102702
  if (this.history.length === 0) {
102584
102703
  if (this.debug) {
102585
102704
  console.log(`[DEBUG] No history to compact for session ${this.sessionId}`);
@@ -102594,8 +102713,8 @@ Double-check your response based on the criteria above. If everything looks good
102594
102713
  tokensSaved: 0
102595
102714
  };
102596
102715
  }
102597
- const compactedMessages = compactMessages2(this.history, options);
102598
- const stats = calculateCompactionStats2(this.history, compactedMessages);
102716
+ const compactedMessages = compactMessages(this.history, options);
102717
+ const stats = calculateCompactionStats(this.history, compactedMessages);
102599
102718
  this.history = compactedMessages;
102600
102719
  try {
102601
102720
  await this.storageAdapter.clearHistory(this.sessionId);