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:
- Configuration load –
catchme/config.pyreadscatchme/services/config.example.jsonand environment overrides. - Recorder startup –
catchme/recorder.pyinstantiates platform‑specific recorders (catchme/recorders/keyboard_*.py,mouse.py,clipboard.py, etc.) and registers callbacks. - Event capture – each recorder writes raw events to
catchme/store.py, which providesadd_event()andquery()helpers. - Pipeline processing – user‑triggered commands (e.g.,
catchme retrieve) invokecatchme/pipelines/retrieve.py. This module pulls stored events, passes them throughcatchme/services/llm.py(LLM provider defined incatchme/services/providers.py), and returns a synthesized answer. - Web UI –
catchme/web.pylaunches an Express‑based server (detected in the repo) serving the static UI incatchme/static/. The UI loadscatchme/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.py → pipelines/retrieve.py → services/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 missing –
pyproject.tomldeclares 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.ymllacks a vulnerability‑review step. - Medium – Large binary assets –
assets/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.