claude-code-cache-fix 2.0.0-beta.2 → 2.0.0-beta.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.
- package/package.json +1 -1
- package/preload.mjs +71 -1
package/package.json
CHANGED
package/preload.mjs
CHANGED
|
@@ -727,6 +727,7 @@ const _STATS_SCHEMA = {
|
|
|
727
727
|
git_status: { applied: 0, skipped: 0, lastApplied: null },
|
|
728
728
|
cwd_normalize: { applied: 0, skipped: 0, lastApplied: null },
|
|
729
729
|
smoosh_normalize: { applied: 0, skipped: 0, lastApplied: null },
|
|
730
|
+
smoosh_split: { applied: 0, skipped: 0, lastApplied: null },
|
|
730
731
|
};
|
|
731
732
|
|
|
732
733
|
function _createEmptyStats() {
|
|
@@ -1384,7 +1385,7 @@ globalThis.fetch = async function (url, options) {
|
|
|
1384
1385
|
if (block.type === "tool_result" && typeof block.content === "string" && block.content.includes("<system-reminder>")) {
|
|
1385
1386
|
let newContent = block.content;
|
|
1386
1387
|
for (let p = 0; p < smooshPatterns.length; p++) {
|
|
1387
|
-
smooshPatterns[p].lastIndex = 0;
|
|
1388
|
+
smooshPatterns[p].lastIndex = 0;
|
|
1388
1389
|
newContent = newContent.replace(smooshPatterns[p], smooshReplacements[p]);
|
|
1389
1390
|
}
|
|
1390
1391
|
if (newContent !== block.content) {
|
|
@@ -1392,6 +1393,18 @@ globalThis.fetch = async function (url, options) {
|
|
|
1392
1393
|
smooshNormalized++;
|
|
1393
1394
|
}
|
|
1394
1395
|
}
|
|
1396
|
+
// Unsmooshed standalone text blocks with dynamic system-reminder content
|
|
1397
|
+
if (block.type === "text" && typeof block.text === "string" && block.text.startsWith("<system-reminder>")) {
|
|
1398
|
+
let newText = block.text;
|
|
1399
|
+
for (let p = 0; p < smooshPatterns.length; p++) {
|
|
1400
|
+
smooshPatterns[p].lastIndex = 0;
|
|
1401
|
+
newText = newText.replace(smooshPatterns[p], smooshReplacements[p]);
|
|
1402
|
+
}
|
|
1403
|
+
if (newText !== block.text) {
|
|
1404
|
+
msg.content[i] = { ...block, text: newText };
|
|
1405
|
+
smooshNormalized++;
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1395
1408
|
}
|
|
1396
1409
|
}
|
|
1397
1410
|
}
|
|
@@ -1404,6 +1417,63 @@ globalThis.fetch = async function (url, options) {
|
|
|
1404
1417
|
}
|
|
1405
1418
|
}
|
|
1406
1419
|
|
|
1420
|
+
// Extension: smoosh_split — universal un-smoosh, complements smoosh_normalize.
|
|
1421
|
+
// CC's smooshSystemReminderSiblings (messages.ts:1835) folds any
|
|
1422
|
+
// `<system-reminder>`-prefixed text block adjacent to a tool_result
|
|
1423
|
+
// into that tool_result's content string with a leading `\n\n`.
|
|
1424
|
+
// The existing smoosh_normalize above stabilizes bytes for 4 enumerated
|
|
1425
|
+
// patterns (Token usage, USD budget, Output tokens, TodoWrite), but
|
|
1426
|
+
// hook-injected reminders (thinking-enrichment, action-tracker, MCP
|
|
1427
|
+
// deltas, custom user hooks) don't match those patterns and still drift.
|
|
1428
|
+
// smoosh_split peels any trailing `\n\n<system-reminder>...\n</system-reminder>`
|
|
1429
|
+
// off tool_result.content strings and restores it as a standalone text
|
|
1430
|
+
// block — the pre-smoosh shape. Dynamic drift in the peeled reminder
|
|
1431
|
+
// lives in a small block instead of a multi-KB tool_result string.
|
|
1432
|
+
// Composed with smoosh_normalize: normalize stabilizes known patterns
|
|
1433
|
+
// in-place; split peels any remainder. Full universal coverage.
|
|
1434
|
+
// Bug: anthropics/claude-code#49585
|
|
1435
|
+
// Opt-out via CACHE_FIX_SKIP_SMOOSH_SPLIT=1 (defaults ON).
|
|
1436
|
+
if (shouldApplyFix("smoosh_split") && payload.messages) {
|
|
1437
|
+
const TRAILING_SMOOSH_TAIL = /\n\n(<system-reminder>\n(?:(?!<\/system-reminder>)[\s\S])*?\n<\/system-reminder>)\s*$/;
|
|
1438
|
+
let splitApplied = 0;
|
|
1439
|
+
for (const msg of payload.messages) {
|
|
1440
|
+
if (msg.role !== "user" || !Array.isArray(msg.content)) continue;
|
|
1441
|
+
const out = [];
|
|
1442
|
+
let mutated = false;
|
|
1443
|
+
const peeledReminders = [];
|
|
1444
|
+
for (const block of msg.content) {
|
|
1445
|
+
if (block?.type === "tool_result" && typeof block.content === "string") {
|
|
1446
|
+
const reminders = [];
|
|
1447
|
+
let s = block.content;
|
|
1448
|
+
while (true) {
|
|
1449
|
+
const m = s.match(TRAILING_SMOOSH_TAIL);
|
|
1450
|
+
if (!m) break;
|
|
1451
|
+
reminders.unshift(m[1]);
|
|
1452
|
+
s = s.slice(0, m.index);
|
|
1453
|
+
}
|
|
1454
|
+
if (reminders.length > 0) {
|
|
1455
|
+
out.push({ ...block, content: s });
|
|
1456
|
+
for (const r of reminders) peeledReminders.push({ type: "text", text: r });
|
|
1457
|
+
splitApplied += reminders.length;
|
|
1458
|
+
mutated = true;
|
|
1459
|
+
continue;
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
out.push(block);
|
|
1463
|
+
}
|
|
1464
|
+
// Peeled reminders go AFTER all other blocks so tool_results stay
|
|
1465
|
+
// consecutive (avoids API 400 "tool use concurrency" errors).
|
|
1466
|
+
if (mutated) msg.content = [...out, ...peeledReminders];
|
|
1467
|
+
}
|
|
1468
|
+
if (splitApplied > 0) {
|
|
1469
|
+
modified = true;
|
|
1470
|
+
debugLog(`APPLIED: smoosh-split peeled ${splitApplied} trailing system-reminder(s) from tool_result.content`);
|
|
1471
|
+
recordFixResult("smoosh_split", "applied");
|
|
1472
|
+
} else {
|
|
1473
|
+
recordFixResult("smoosh_split", "skipped");
|
|
1474
|
+
}
|
|
1475
|
+
}
|
|
1476
|
+
|
|
1407
1477
|
// Bug 5: TTL enforcement (configurable per request type)
|
|
1408
1478
|
// The client gates 1h cache TTL behind a GrowthBook allowlist that checks
|
|
1409
1479
|
// querySource against patterns like "repl_main_thread*", "sdk", "auto_mode".
|