Watch
1
0
Fork
You've already forked souveraine
0

agent sessions: show conversations, not storage ghosts

This commit is contained in:
Fimeg 2026-08-11 18:47:54 -04:00
commit dd19ab227f
2 changed files with 31 additions and 10 deletions

View file

@ -152,12 +152,20 @@ souveraine_json() {
local out="[]" local out="[]"
while IFS= read -r f; do while IFS= read -r f; do
[ -n "$f" ] || continue [ -n "$f" ] || continue
local s local s agent_id parent_id agent_name
s=$(jq -c ' agent_id=$(jq -r '.agent_id // empty' "$f" 2>/dev/null)
if .archived == true then empty else { parent_id=${agent_id%-sub}
agent_name=$(jq -r '.name // empty' "$dir/$parent_id/agent.json" 2>/dev/null)
[ -n "$agent_name" ] || agent_name="Souveraine"
s=$(jq -c --arg agentName "$agent_name" '
# A zero-message record is a newly-minted conversation slot, not
# an agent session. Rendering it made every panel restart add a
# plausible-looking ghost row.
if .archived == true or (.message_count // 0) == 0 then empty else {
provider: "souveraine", provider: "souveraine",
id: (.id // ""), id: (.id // ""),
agentId: (.agent_id // ""), agentId: (.agent_id // ""),
agentName: $agentName,
cwd: "", cwd: "",
model: "", model: "",
lastActivity: (.last_message_at // .updated_at // ""), lastActivity: (.last_message_at // .updated_at // ""),
@ -187,6 +195,7 @@ SOUV=$(souveraine_json); [ -n "$SOUV" ] || SOUV='{"available":false,"er
# timestamps would be a guess wearing the costume of a measurement. # timestamps would be a guess wearing the costume of a measurement.
jq -c -n \ jq -c -n \
--argjson now "$NOW" \ --argjson now "$NOW" \
--argjson window "$((WINDOW_MIN * 60))" \
--argjson claude "$CLAUDE" \ --argjson claude "$CLAUDE" \
--argjson codex "$CODEX" \ --argjson codex "$CODEX" \
--argjson souv "$SOUV" ' --argjson souv "$SOUV" '
@ -207,6 +216,10 @@ jq -c -n \
else "idle" end; else "idle" end;
( ($claude.sessions // []) + ($codex.sessions // []) + ($souv.sessions // []) ) ( ($claude.sessions // []) + ($codex.sessions // []) + ($souv.sessions // []) )
| map(. + {state: state($now), age: ($now - (.lastActivity | epoch))}) | map(. + {state: state($now), age: ($now - (.lastActivity | epoch))})
# `find -mmin` is only the cheap filesystem prefilter. Restores and copies
# can touch a May record today; enforce the promised window against the
# the record timestamp before anything calls it a current session.
| map(select(.age >= 0 and .age <= $window))
| sort_by(.age) | sort_by(.age)
as $all as $all
| { | {
@ -214,9 +227,9 @@ jq -c -n \
sessions: $all, sessions: $all,
active: ($all | map(select(.state == "active")) | length), active: ($all | map(select(.state == "active")) | length),
providers: { providers: {
claude: ($claude | del(.sessions)) + {sessions: ($claude.sessions // [] | length)}, claude: ($claude | del(.sessions)) + {sessions: ($all | map(select(.provider == "claude")) | length)},
codex: ($codex | del(.sessions)) + {sessions: ($codex.sessions // [] | length)}, codex: ($codex | del(.sessions)) + {sessions: ($all | map(select(.provider == "codex")) | length)},
souveraine: ($souv | del(.sessions)) + {sessions: ($souv.sessions // [] | length)} souveraine: ($souv | del(.sessions)) + {sessions: ($all | map(select(.provider == "souveraine")) | length)}
} }
}' 2>/dev/null \ }' 2>/dev/null \
|| printf '{"ts":%s,"sessions":[],"active":0,"providers":{"claude":{"available":false,"error":"merge failed"},"codex":{"available":false,"error":"merge failed"},"souveraine":{"available":false,"error":"merge failed"}}}\n' "$NOW" || printf '{"ts":%s,"sessions":[],"active":0,"providers":{"claude":{"available":false,"error":"merge failed"},"codex":{"available":false,"error":"merge failed"},"souveraine":{"available":false,"error":"merge failed"}}}\n' "$NOW"

View file

@ -92,15 +92,23 @@ Singleton {
} }
// Short human label for a session the project directory if we have one, // Short human label for a session the project directory if we have one,
// else the agent, else a truncated id. Never an empty string: a blank chip // else the configured agent name plus a conversation discriminator, else
// is indistinguishable from a broken one. // a truncated id. Never an empty string: a blank chip is indistinguishable
// from a broken one, and ten rows all called "agent" are only technically
// non-blank.
function sessionLabel(s) { function sessionLabel(s) {
if (!s) if (!s)
return ""; return "";
if (s.cwd && s.cwd.length > 0) if (s.cwd && s.cwd.length > 0)
return s.cwd.split("/").filter(x => x.length > 0).pop() ?? s.cwd; return s.cwd.split("/").filter(x => x.length > 0).pop() ?? s.cwd;
if (s.provider === "souveraine") if (s.provider === "souveraine") {
return s.subconscious ? "subconscious" : "agent"; const name = s.agentName && s.agentName.length > 0
? s.agentName : "Souveraine";
const id = (s.id ?? "").slice(0, 4);
return s.subconscious
? `${name} · subconscious · ${id}`
: `${name} · ${id}`;
}
return (s.id ?? "").slice(0, 8); return (s.id ?? "").slice(0, 8);
} }