@aiplumber/session-recall 1.9.0 → 1.9.2
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 +29 -12
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aiplumber/session-recall",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.2",
|
|
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.2';
|
|
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 {
|
|
@@ -1330,7 +1337,8 @@ async function cmdLast(arg1, arg2, opts) {
|
|
|
1330
1337
|
// Handle --compactions mode: show last N compaction phases instead of sessions
|
|
1331
1338
|
if (opts.compactionPhases) {
|
|
1332
1339
|
const session = selected[0]; // Use only the most recent session
|
|
1333
|
-
|
|
1340
|
+
// Use pre-scanned markers if available (for large files), otherwise scan now
|
|
1341
|
+
const compactions = session.compactionMarkers || scanCompactionMarkers(session.msgs);
|
|
1334
1342
|
|
|
1335
1343
|
if (compactions.length === 0) {
|
|
1336
1344
|
console.log('[session-recall v' + VERSION + '] No compaction events found - showing full session as single phase');
|
|
@@ -1545,7 +1553,8 @@ async function cmdLast(arg1, arg2, opts) {
|
|
|
1545
1553
|
}
|
|
1546
1554
|
// Apply before-compaction filter for dry-run
|
|
1547
1555
|
if (opts.beforeCompaction && selected.length > 0) {
|
|
1548
|
-
|
|
1556
|
+
// Use pre-scanned markers if available (for large files), otherwise scan now
|
|
1557
|
+
const compactions = selected[0].compactionMarkers || scanCompactionMarkers(selected[0].msgs);
|
|
1549
1558
|
if (compactions.length > 0) {
|
|
1550
1559
|
const n = opts.beforeCompactionN || compactions.length;
|
|
1551
1560
|
if (n < 1 || n > compactions.length) {
|
|
@@ -1627,7 +1636,8 @@ async function cmdLast(arg1, arg2, opts) {
|
|
|
1627
1636
|
|
|
1628
1637
|
// Filter to only show messages BEFORE the selected compaction boundary
|
|
1629
1638
|
if (opts.beforeCompaction) {
|
|
1630
|
-
|
|
1639
|
+
// Use pre-scanned markers if available (for large files), otherwise scan now
|
|
1640
|
+
const compactions = session.compactionMarkers || scanCompactionMarkers(session.msgs);
|
|
1631
1641
|
if (compactions.length > 0) {
|
|
1632
1642
|
const n = opts.beforeCompactionN || compactions.length;
|
|
1633
1643
|
if (n < 1 || n > compactions.length) {
|
|
@@ -2394,12 +2404,19 @@ function scanSessionTangents(filePath) {
|
|
|
2394
2404
|
// ========== COMPACTION DETECTION ==========
|
|
2395
2405
|
|
|
2396
2406
|
// Check if a message is a compaction marker
|
|
2407
|
+
// Supports both old format (progress + hook) and new format (system + subtype)
|
|
2397
2408
|
function isCompactionMarker(msg) {
|
|
2398
|
-
|
|
2399
|
-
if (
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2409
|
+
// New format (Claude Code 2.1+): system message with compact_boundary subtype
|
|
2410
|
+
if (msg.type === 'system' && msg.subtype === 'compact_boundary') {
|
|
2411
|
+
return true;
|
|
2412
|
+
}
|
|
2413
|
+
// Old format: progress message with hook
|
|
2414
|
+
if (msg.type === 'progress' && msg.data) {
|
|
2415
|
+
return msg.data.type === 'hook_progress' &&
|
|
2416
|
+
msg.data.hookEvent === 'SessionStart' &&
|
|
2417
|
+
msg.data.hookName === 'SessionStart:compact';
|
|
2418
|
+
}
|
|
2419
|
+
return false;
|
|
2403
2420
|
}
|
|
2404
2421
|
|
|
2405
2422
|
// Scan session for compaction markers with deduplication
|