@aiplumber/session-recall 1.9.0 → 1.9.3
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/session-recall +53 -13
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aiplumber/session-recall",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.3",
|
|
4
4
|
"description": "Pull context from previous Claude Code sessions. Sessions end, context resets - this tool lets you continue where you left off.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"session-recall": "./session-recall"
|
package/session-recall
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
const VERSION = '1.9.
|
|
3
|
+
const VERSION = '1.9.3';
|
|
4
4
|
|
|
5
5
|
const fs = require('fs');
|
|
6
6
|
const path = require('path');
|
|
@@ -121,8 +121,8 @@ async function streamScanCompactions(filePath) {
|
|
|
121
121
|
|
|
122
122
|
rl.on('line', (line) => {
|
|
123
123
|
lineNum++;
|
|
124
|
-
// Quick string check before parsing
|
|
125
|
-
if (!line.includes('SessionStart:compact')) return;
|
|
124
|
+
// Quick string check before parsing - check both old and new formats
|
|
125
|
+
if (!line.includes('SessionStart:compact') && !line.includes('compact_boundary')) return;
|
|
126
126
|
|
|
127
127
|
try {
|
|
128
128
|
const msg = JSON.parse(line);
|
|
@@ -1293,9 +1293,16 @@ async function cmdLast(arg1, arg2, opts) {
|
|
|
1293
1293
|
const candidateCount = Math.min(allSessions.length, n + 5);
|
|
1294
1294
|
for (let i = 0; i < candidateCount; i++) {
|
|
1295
1295
|
const s = allSessions[i];
|
|
1296
|
-
// Use streaming for large files, sync for small files
|
|
1297
1296
|
const stats = fs.statSync(s.filePath);
|
|
1298
1297
|
const sizeMB = stats.size / (1024 * 1024);
|
|
1298
|
+
|
|
1299
|
+
// If we need compaction markers (for --before-compaction or --compactions),
|
|
1300
|
+
// scan for them FIRST before loading messages (since streaming filters them out)
|
|
1301
|
+
if ((opts.beforeCompaction || opts.compactionPhases) && sizeMB > 100) {
|
|
1302
|
+
s.compactionMarkers = await streamScanCompactions(s.filePath);
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1305
|
+
// Use streaming for large files, sync for small files
|
|
1299
1306
|
if (sizeMB > 100) {
|
|
1300
1307
|
s.msgs = await streamReadJsonl(s.filePath);
|
|
1301
1308
|
} else {
|
|
@@ -1329,8 +1336,32 @@ async function cmdLast(arg1, arg2, opts) {
|
|
|
1329
1336
|
|
|
1330
1337
|
// Handle --compactions mode: show last N compaction phases instead of sessions
|
|
1331
1338
|
if (opts.compactionPhases) {
|
|
1332
|
-
|
|
1333
|
-
|
|
1339
|
+
let session = selected[0]; // Use only the most recent session
|
|
1340
|
+
// Use pre-scanned markers if available (for large files), otherwise scan now
|
|
1341
|
+
let compactions = session.compactionMarkers || scanCompactionMarkers(session.msgs);
|
|
1342
|
+
|
|
1343
|
+
// If no compactions in current session, check previous session (new session fallback)
|
|
1344
|
+
if (compactions.length === 0 && inactiveSessions.length > 1) {
|
|
1345
|
+
const prevSession = inactiveSessions[1];
|
|
1346
|
+
// Load previous session if not already loaded
|
|
1347
|
+
if (!prevSession.msgs) {
|
|
1348
|
+
const stats = fs.statSync(prevSession.filePath);
|
|
1349
|
+
const sizeMB = stats.size / (1024 * 1024);
|
|
1350
|
+
if (sizeMB > 100) {
|
|
1351
|
+
prevSession.compactionMarkers = await streamScanCompactions(prevSession.filePath);
|
|
1352
|
+
prevSession.msgs = await streamReadJsonl(prevSession.filePath);
|
|
1353
|
+
} else {
|
|
1354
|
+
prevSession.msgs = readJsonl(prevSession.filePath);
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1357
|
+
const prevCompactions = prevSession.compactionMarkers || scanCompactionMarkers(prevSession.msgs);
|
|
1358
|
+
if (prevCompactions.length > 0) {
|
|
1359
|
+
console.log('[session-recall v' + VERSION + '] No compactions in current session - using previous session');
|
|
1360
|
+
console.log('---');
|
|
1361
|
+
session = prevSession;
|
|
1362
|
+
compactions = prevCompactions;
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
1334
1365
|
|
|
1335
1366
|
if (compactions.length === 0) {
|
|
1336
1367
|
console.log('[session-recall v' + VERSION + '] No compaction events found - showing full session as single phase');
|
|
@@ -1545,7 +1576,8 @@ async function cmdLast(arg1, arg2, opts) {
|
|
|
1545
1576
|
}
|
|
1546
1577
|
// Apply before-compaction filter for dry-run
|
|
1547
1578
|
if (opts.beforeCompaction && selected.length > 0) {
|
|
1548
|
-
|
|
1579
|
+
// Use pre-scanned markers if available (for large files), otherwise scan now
|
|
1580
|
+
const compactions = selected[0].compactionMarkers || scanCompactionMarkers(selected[0].msgs);
|
|
1549
1581
|
if (compactions.length > 0) {
|
|
1550
1582
|
const n = opts.beforeCompactionN || compactions.length;
|
|
1551
1583
|
if (n < 1 || n > compactions.length) {
|
|
@@ -1627,7 +1659,8 @@ async function cmdLast(arg1, arg2, opts) {
|
|
|
1627
1659
|
|
|
1628
1660
|
// Filter to only show messages BEFORE the selected compaction boundary
|
|
1629
1661
|
if (opts.beforeCompaction) {
|
|
1630
|
-
|
|
1662
|
+
// Use pre-scanned markers if available (for large files), otherwise scan now
|
|
1663
|
+
const compactions = session.compactionMarkers || scanCompactionMarkers(session.msgs);
|
|
1631
1664
|
if (compactions.length > 0) {
|
|
1632
1665
|
const n = opts.beforeCompactionN || compactions.length;
|
|
1633
1666
|
if (n < 1 || n > compactions.length) {
|
|
@@ -2394,12 +2427,19 @@ function scanSessionTangents(filePath) {
|
|
|
2394
2427
|
// ========== COMPACTION DETECTION ==========
|
|
2395
2428
|
|
|
2396
2429
|
// Check if a message is a compaction marker
|
|
2430
|
+
// Supports both old format (progress + hook) and new format (system + subtype)
|
|
2397
2431
|
function isCompactionMarker(msg) {
|
|
2398
|
-
|
|
2399
|
-
if (
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2432
|
+
// New format (Claude Code 2.1+): system message with compact_boundary subtype
|
|
2433
|
+
if (msg.type === 'system' && msg.subtype === 'compact_boundary') {
|
|
2434
|
+
return true;
|
|
2435
|
+
}
|
|
2436
|
+
// Old format: progress message with hook
|
|
2437
|
+
if (msg.type === 'progress' && msg.data) {
|
|
2438
|
+
return msg.data.type === 'hook_progress' &&
|
|
2439
|
+
msg.data.hookEvent === 'SessionStart' &&
|
|
2440
|
+
msg.data.hookName === 'SessionStart:compact';
|
|
2441
|
+
}
|
|
2442
|
+
return false;
|
|
2403
2443
|
}
|
|
2404
2444
|
|
|
2405
2445
|
// Scan session for compaction markers with deduplication
|