claude-code-kanban 7.0.1 → 7.0.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/lib/parsers.js +27 -7
- package/package.json +1 -1
- package/public/app.js +1 -1
- package/server.js +2 -1
package/lib/parsers.js
CHANGED
|
@@ -646,28 +646,47 @@ function countTranscriptsBornBefore(dir, birthtimeMs) {
|
|
|
646
646
|
return n;
|
|
647
647
|
}
|
|
648
648
|
|
|
649
|
+
// Cache: jsonlPath -> { ino, size, mtimeMs }, the transcript as it last grew.
|
|
650
|
+
// Claude Code, `claude --resume` and backup tools set a transcript's mtime without writing
|
|
651
|
+
// to it (#50), so only a file that grew, shrank or was replaced counts as activity.
|
|
652
|
+
const logActivityCache = new Map();
|
|
653
|
+
|
|
654
|
+
function transcriptActivityMs(jsonlPath, stat) {
|
|
655
|
+
const prev = logActivityCache.get(jsonlPath);
|
|
656
|
+
if (prev && prev.ino === stat.ino && prev.size === stat.size) return prev.mtimeMs;
|
|
657
|
+
logActivityCache.delete(jsonlPath);
|
|
658
|
+
logActivityCache.set(jsonlPath, { ino: stat.ino, size: stat.size, mtimeMs: stat.mtimeMs });
|
|
659
|
+
if (logActivityCache.size > SESSION_INFO_CACHE_MAX) logActivityCache.delete(logActivityCache.keys().next().value);
|
|
660
|
+
sessionCacheDirty = true;
|
|
661
|
+
return stat.mtimeMs;
|
|
662
|
+
}
|
|
663
|
+
|
|
649
664
|
const sessionCachesDirty = () => sessionCacheDirty;
|
|
650
665
|
|
|
651
666
|
// Snapshot of the per-transcript caches for lib/session-cache.js. Entries of deleted
|
|
652
667
|
// transcripts are left out, so the snapshot never holds more than the live set.
|
|
653
668
|
function exportSessionCaches() {
|
|
654
669
|
sessionCacheDirty = false;
|
|
655
|
-
const livePaths = new Set([...sessionInfoCache.keys(), ...customTitleCache.keys()
|
|
670
|
+
const livePaths = new Set([...sessionInfoCache.keys(), ...customTitleCache.keys(), ...logActivityCache.keys()]);
|
|
671
|
+
for (const p of livePaths) if (!fs.existsSync(p)) livePaths.delete(p);
|
|
656
672
|
const live = (map) => [...map].filter(([p]) => livePaths.has(p));
|
|
657
|
-
return { info: live(sessionInfoCache), titles: live(customTitleCache) };
|
|
673
|
+
return { info: live(sessionInfoCache), titles: live(customTitleCache), activity: live(logActivityCache) };
|
|
658
674
|
}
|
|
659
675
|
|
|
660
676
|
function importSessionCaches(snapshot) {
|
|
661
|
-
const
|
|
662
|
-
const
|
|
677
|
+
const num = (v) => typeof v === 'number';
|
|
678
|
+
const scanned = (e) => num(e.ino) && num(e.scannedUpTo) && num(e.mtimeMs);
|
|
679
|
+
const grown = (e) => num(e.ino) && num(e.size) && num(e.mtimeMs);
|
|
680
|
+
const load = (map, entries, valid) => {
|
|
663
681
|
if (!Array.isArray(entries)) return;
|
|
664
682
|
for (const pair of entries) {
|
|
665
|
-
if (!Array.isArray(pair) || typeof pair[0] !== 'string' || !valid(pair[1])) continue;
|
|
683
|
+
if (!Array.isArray(pair) || typeof pair[0] !== 'string' || !pair[1] || typeof pair[1] !== 'object' || !valid(pair[1])) continue;
|
|
666
684
|
map.set(pair[0], pair[1]);
|
|
667
685
|
}
|
|
668
686
|
};
|
|
669
|
-
load(sessionInfoCache, snapshot?.info?.slice(-SESSION_INFO_CACHE_MAX));
|
|
670
|
-
load(customTitleCache, snapshot?.titles?.slice(-SESSION_INFO_CACHE_MAX));
|
|
687
|
+
load(sessionInfoCache, snapshot?.info?.slice(-SESSION_INFO_CACHE_MAX), scanned);
|
|
688
|
+
load(customTitleCache, snapshot?.titles?.slice(-SESSION_INFO_CACHE_MAX), scanned);
|
|
689
|
+
load(logActivityCache, snapshot?.activity?.slice(-SESSION_INFO_CACHE_MAX), grown);
|
|
671
690
|
}
|
|
672
691
|
|
|
673
692
|
// Background-task completion records arrive as a user message whose content is a
|
|
@@ -1972,6 +1991,7 @@ module.exports = {
|
|
|
1972
1991
|
exportSessionCaches,
|
|
1973
1992
|
importSessionCaches,
|
|
1974
1993
|
sessionCachesDirty,
|
|
1994
|
+
transcriptActivityMs,
|
|
1975
1995
|
countTranscriptsBornBefore,
|
|
1976
1996
|
readRecentMessages,
|
|
1977
1997
|
readMessagesPage,
|
package/package.json
CHANGED
package/public/app.js
CHANGED
|
@@ -11932,7 +11932,7 @@ const PANE_FRAME_LIMIT = 3;
|
|
|
11932
11932
|
const PANE_URL_SANDBOX = 'allow-scripts allow-same-origin allow-forms allow-popups allow-downloads';
|
|
11933
11933
|
const PANE_ICONS = {
|
|
11934
11934
|
board:
|
|
11935
|
-
'<svg class="kind" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
11935
|
+
'<svg class="kind" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M6 5v14"/><path d="M12 5v8"/><path d="M18 5v11"/></svg>',
|
|
11936
11936
|
url: '<svg class="kind" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15 15 0 0 1 0 20M12 2a15 15 0 0 0 0 20"/></svg>',
|
|
11937
11937
|
file: '<svg class="kind" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>',
|
|
11938
11938
|
warning:
|
package/server.js
CHANGED
|
@@ -24,6 +24,7 @@ const {
|
|
|
24
24
|
readRecentMessages: _readRecentMessagesUncached,
|
|
25
25
|
readMessagesPage: _readMessagesPageUncached,
|
|
26
26
|
readSessionInfoFromJsonl,
|
|
27
|
+
transcriptActivityMs,
|
|
27
28
|
modelDisplayName,
|
|
28
29
|
buildSessionDigest,
|
|
29
30
|
readCompactSummaries,
|
|
@@ -362,7 +363,7 @@ function getSessionLogStat(meta) {
|
|
|
362
363
|
if (!meta.jsonlPath) return { mtime: null, hasMessages: false };
|
|
363
364
|
try {
|
|
364
365
|
const st = statSync(meta.jsonlPath);
|
|
365
|
-
return { mtime:
|
|
366
|
+
return { mtime: transcriptActivityMs(meta.jsonlPath, st), hasMessages: st.size > 1000 };
|
|
366
367
|
} catch { return { mtime: null, hasMessages: false }; }
|
|
367
368
|
}
|
|
368
369
|
|