Dismiss broken sessions, and hide ones untouched for a week

A broken session that will never be repaired kept the bar's warning dot lit
forever. repair-session now takes --ignore/--unignore/--unignore-all/--ignored,
recorded in ~/.claude-mode/ignored-sessions.json, and the scan hides broken
transcripts older than --max-age days (default 7, 0 disables,
CM_IGNORE_AGE_DAYS sets it). Hidden sessions move to a separate ignored[]
list with a reason, and --all always names how many it held back.

A repair clears the session's dismissal, and entries whose transcript is gone
are pruned, so a session that breaks again is never silently hidden.

The panel gets an Ignore button beside Repair and a collapsed "hidden (N)"
section with Restore. The dot still counts broken sessions only.

Bumps to 1.10.0 and fixes the widget manifest, which still said 1.8.0.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
smoido
2026-09-14 23:40:24 +03:00
co-authored by Claude Opus 5
parent f776ce099e
commit cbd3b1d8a9
7 changed files with 543 additions and 69 deletions
+20 -1
View File
@@ -132,6 +132,12 @@ BarWidget {
// to sit on a timer: ~60ms for 59 transcripts here, against 5s for the naive
// version that read every byte of every one.
property var brokenSessions: []
// Dismissed, or broken but untouched for longer than the age limit. Kept
// out of the dot on purpose: hiding one is how you tell the bar to stop
// asking about it.
property var ignoredSessions: []
property int ignoreAgeDays: 7
property bool rescanPending: false
Process {
id: scanProc
@@ -143,11 +149,24 @@ BarWidget {
var d = null
try { d = JSON.parse(String(text || "")) } catch (e) { d = null }
root.brokenSessions = (d && d.broken) ? d.broken : []
root.ignoredSessions = (d && d.ignored) ? d.ignored : []
if (d && d.maxAgeDays !== undefined) root.ignoreAgeDays = Number(d.maxAgeDays)
}
}
// A scan already under way was started before whatever asked for this
// one, so its answer may predate the change - run once more after it.
onExited: function (code) {
if (root.rescanPending) {
root.rescanPending = false
Qt.callLater(root.scanSessions)
}
}
}
function scanSessions() { if (!scanProc.running) scanProc.running = true }
function scanSessions() {
if (scanProc.running) root.rescanPending = true
else scanProc.running = true
}
Timer {
interval: 20 * 60 * 1000