Skip to content

feat(chat): self-heal the session list from chat logs when the cache is lost#102

Closed
viniciussouzax wants to merge 1 commit into
evolution-foundation:mainfrom
viniciussouzax:fix/session-index-self-heal
Closed

feat(chat): self-heal the session list from chat logs when the cache is lost#102
viniciussouzax wants to merge 1 commit into
evolution-foundation:mainfrom
viniciussouzax:fix/session-index-self-heal

Conversation

@viniciussouzax

Copy link
Copy Markdown

Fixes #101.

Problem

sessions.json (under ~/.claude-code-web, i.e. /root/.claude-code-web in
the container) is only a fast-access cache; the JSONL logs under
workspace/ADWs/logs/chat are the durable source of truth. When the cache
directory isn't persisted (e.g. a container redeploy where it wasn't mounted on
a volume), the conversation list comes back empty even though the history is
intact on disk, because the list is built from the in-memory Map (seeded from
the cache), not from the logs. See #101 for the full root-cause analysis.

Change

Rebuild the in-memory index from the logs when the loaded cache is empty:

  • ChatLogger.listSessions() enumerates sessions from the log filenames
    ({agentName}_{shortId}.jsonl), splitting on the last underscore so agent
    names that contain underscores still parse correctly.
  • TerminalServer.rebuildSessionsFromLogs() reads each log back into a
    session entry. It is invoked from loadPersistedSessions() only when the
    cache is empty
    , then persists the rebuilt index.

Properties:

  • Idempotent — never duplicates or overrides cached sessions (only adds
    ids not already present).
  • Respects TTL — timestamps come from the logs, so stale sessions are still
    dropped by the existing save / GC policy. No behavior change when the cache is
    present.
  • Makes sessions.json a true cache (no longer a single point of failure for
    the conversation list).

This is option (4) from #101. It composes with the deployment-side mitigation
(mounting a volume at the cache dir) but removes the need for it to avoid data
becoming unreachable.

Tests

Added to dashboard/terminal-server/test/server.test.js (node --test):

  • ChatLogger.listSessions parses agent and session id, including agent names
    with underscores, and ignores non-.jsonl files.
  • TerminalServer rebuilds the index from chat logs when the cache is empty,
    and a second pass is a no-op (idempotent).

Notes

Recovered session ids use the 8-char short id from the log filename (the same
id ChatLogger keys on), so continuing a recovered conversation appends to the
same log. Full chat history is restored into the entry; the existing 50-message
cap in SessionStore.saveSessions is unchanged and out of scope here.

…is lost

sessions.json (under ~/.claude-code-web) is only a fast-access cache; the JSONL
logs under workspace/ADWs/logs/chat are the durable source of truth. When the
cache directory is not persisted (e.g. a container redeploy where it wasn't on
a volume), the conversation list came back empty even though the history was
intact on disk.

Rebuild the in-memory index from the logs when the loaded cache is empty:

- ChatLogger.listSessions() enumerates sessions from the log filenames
  ({agentName}_{shortId}.jsonl), splitting on the last underscore so agent
  names containing underscores still parse correctly.
- TerminalServer.rebuildSessionsFromLogs() reads each log back into a session
  entry and is invoked from loadPersistedSessions() only when the cache is
  empty, then persists the rebuilt index. It is idempotent and never
  duplicates cached sessions; timestamps come from the logs so the normal TTL
  policy still drops stale sessions.

Adds tests for listSessions() parsing and the empty-cache rebuild.

Refs #101

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @viniciussouzax, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@viniciussouzax viniciussouzax closed this by deleting the head repository Jun 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Chat session list is wiped on container redeploy: session index lives in ephemeral /root/.claude-code-web

1 participant