The Problem

Developers who use large‑language‑model (LLM) agents often lose context: the agents cannot recall what the user has typed, opened, or edited outside the current session. Re‑creating that personal history requires manual logging or external services that break privacy.

What This Does

catchme captures a user’s digital footprint locally and exposes it through a lightweight CLI skill. The core collector lives in catchme/recorder.py and the platform‑specific recorders under catchme/recorders/. Configuration lives in catchme/config.py, which is imported by 18 other modules – it is the primary hub for paths, storage locations, and LLM settings. The data model is defined in catchme/store.py and persisted as plain files, keeping the system “vectorless” and privacy‑first.

How It Is Wired

Execution starts at catchme/__main__.py, which parses CLI arguments and calls catchme/run.py::main(). run.py imports a wide set of sub‑modules (catchme/engine.py, catchme/web.py, the pipeline package, etc.) and orchestrates the workflow:

  1. Configuration loadcatchme/config.py reads catchme/services/config.example.json and environment overrides.
  2. Recorder startupcatchme/recorder.py instantiates platform‑specific recorders (catchme/recorders/keyboard_*.py, mouse.py, clipboard.py, etc.) and registers callbacks.
  3. Event capture – each recorder writes raw events to catchme/store.py, which provides add_event() and query() helpers.
  4. Pipeline processing – user‑triggered commands (e.g., catchme retrieve) invoke catchme/pipelines/retrieve.py. This module pulls stored events, passes them through catchme/services/llm.py (LLM provider defined in catchme/services/providers.py), and returns a synthesized answer.
  5. Web UIcatchme/web.py launches an Express‑based server (detected in the repo) serving the static UI in catchme/static/. The UI loads catchme/static/js/app.js, which calls the backend endpoints to fetch activity trees (tree.js) and chat logs.

The most connected modules are catchme/config (imported by 18 modules, no outgoing imports) and catchme/run (imports 10 others, instability 0.91). These act as blast‑radius points: changes to config.py or run.py propagate widely.

How To Use It

# Clone the repo
git clone https://github.com/moses-y/CatchMe
cd CatchMe

# Install the package (pyproject.toml is the manifest)
pip install -e .

# Optional: edit the example config
cp catchme/services/config.example.json catchme/services/config.json
# adjust paths, LLM API key, etc.

# Start the recorder (captures keyboard, mouse, clipboard, etc.)
python -m catchme

# Query the memory via CLI
python -m catchme retrieve --query "What files did I edit yesterday?"

To run the optional web UI:

# Install Node dependencies (express is listed in package.json)
npm install   # or pnpm install if a lockfile existed
npm start     # runs the Express server defined in catchme/web.py

(If the repo does not contain a package.json, the UI can be served directly by the Python server.)

Real‑World Use

A developer integrates catchme into their daily workflow. While coding, the keyboard recorder logs every keystroke and file save. Later, they ask their Claude‑based assistant: catchme retrieve --query "What function did I refactor last week?". The request travels from the CLI → run.pypipelines/retrieve.pyservices/llm.py, which calls the configured OpenAI model and returns the relevant snippet from the locally stored event log. No external database is involved, preserving privacy.

Code Health & Issues

  • High – lockfile missingpyproject.toml declares dependencies but no lockfile; reproducibility is at risk.
  • Medium – Dependabot not configured – no .github/dependabot.yml; security updates are manual.
  • Medium – No dependency scan in CI.github/workflows/ci.yml lacks a vulnerability‑review step.
  • Medium – Large binary assetsassets/catchme-logo.png (≈10 MB) inflates repo size; consider Git LFS.
  • Medium – Checkout persists token – CI checkout keeps the GitHub token; set persist-credentials: false.
  • Low – Workflow timeout missing – CI jobs have no timeout-minutes; add a reasonable bound.

Additional observations: the codebase relies heavily on broad except: clauses (e.g., in recorder.py and services/llm.py), deep nesting (up to six levels), and several files exceed 800 lines, making maintenance harder. The static assets and UI are JavaScript‑heavy, but no package-lock.json or similar lockfile exists.

The Bottom Line

CatchMe provides a functional, locally‑hosted memory layer for LLM agents with clear entry points and a modest dependency surface. The architecture is understandable, but the hub module (config.py) and the oversized pipeline files pose a maintenance risk. Adding a lockfile, automated dependency scanning, and refactoring the large modules would improve reliability for production use. The project is suitable for teams that need privacy‑first personal context and are comfortable addressing the highlighted code‑health concerns.