Skip to content

Cursor hook stream-state files leak (no TTL pruning) #2

Description

@sketchymedia

Symptom

A real user's `status.js` reported `activeStreams: 333` in `~/.config/devclocked/cursor-hook-state`. Stream-state files accumulate without bound.

Root cause

`removeStreamState` is only called on `sessionEnd` (`hooks/ship.js`), and it only removes the session-root stream. Two leak paths:

  1. If Cursor never delivers `sessionEnd` (which the 333 count strongly implies), the root state is never removed.
  2. Sidechain/primary streams that get their own throttle-state file (`ship.js` saves `last_tick_at` under `throttleId`, which can be `primaryStreamId`) are never removed — `sessionEnd` only deletes the root id.

There is no time-based sweep of `STATE_DIR` anywhere.

Fix

Add a TTL-based `pruneStaleStreamState()` sweep (run once per ship pass, under the shipper lock) that deletes `stream_*.json` whose `last_tick_at || started_at` is older than a TTL (proposed 6h), plus orphans with no timestamp. Robust regardless of why `sessionEnd` is missing.

Impact

State-dir clutter; not data loss, but a reliability/hygiene bug and a signal that `sessionEnd` delivery is unreliable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions