## Inspiration

Coding agents changed how fast software moves. After a week of agent-driven work, I realized I no longer knew my own codebase: what the parts were, how a request flowed through them, or what had changed while I wasn't looking. Existing tools summarize a repo's current state or a single pull request, and most let a language model describe code freely, which means confident descriptions of functions that don't exist. I wanted a tool I could trust: never lose track of your codebase.

## What it does

Catchup turns a TypeScript/JavaScript repository into one zoomable map:

  • Architecture and Flows: system → parts → files → functions, and the main user journeys step by step, from the button click through client, server, AI model and database, down to the source.
  • Ask: a read-only Claude agent answers questions with citations; the boxes it cites light up.
  • Preview: save a file and within seconds see what your uncommitted change does: a new Stripe route, a removed ownership check.
  • Timelapse: replay a codebase's history; boxes keep their place, and each step's caption cites the commits responsible.

## How I built it: Claude via the Factory Droid SDK

The core idea: code decides what exists, Claude decides what matters, and code checks Claude.

  • Deterministic analysis. The TypeScript compiler API extracts files, functions, calls, client → server links and entry points, then builds call trees and signals. Every identifier and every diff is computed by code.
  • Claude through the Factory Droid SDK. Each Claude pass runs as a Droid SDK session with Claude Sonnet and structured JSON output. A custom permission handler makes every agent read-only: only Read, Grep, Glob and LS inside the repository; writes, shell commands and secrets files are denied. Claude groups code into parts, picks journeys and steps, writes explanations, answers Ask questions and captions history. Each session has a tool budget and logs every tool call.
  • Code checks Claude. Every answer is validated with Zod and against the facts: each cited file, function, box and commit must exist. If C is the set of citations in an answer and F is everything that exists, I require:

$$\frac{|C \cap F|}{|C|} = 1$$

Otherwise Claude gets one retry listing exactly what was wrong, and then the run fails loudly.

  • Edit, don't regenerate. Each commit's map evolves from the previous one; only journeys whose code changed go back to Claude, so unchanged boxes keep their IDs, text and position.

It's a pnpm monorepo of six strict-TypeScript packages with 231 tests, and the dashboard is React with deterministic elkjs layouts.

## Challenges I ran into

Keeping identity across history. A box must stay the same box through renames and rewrites. I match boxes between checkpoints when their file sets A and B overlap enough:

$$\frac{|A \cap B|}{|A \cup B|} \geq 0.4$$

Every frame is then drawn on one shared layout, so nothing jumps.

Stopping the model from inventing things. Each failure (malformed citations, one-function "journeys") became a code-checked rule instead of prompt wording.

Static analysis limits. Deleting one if (chat.userId !== session.user.id) removes no function, so I added a deterministic count of early-exit guards; a dropped guard is now reported as a removed check.

Securing an agent with file access. Paths are checked after resolving symlinks, so the agent can't escape the repo or read .env, and the local dashboard refuses requests from other websites.

## Accomplishments that I'm proud of

  • On a repo with four planted changes, Catchup reported all four and nothing else, using two Claude calls.
  • On Vercel's ai-chatbot: 576 commits in a 12-frame timelapse; all 42 cited commits are real.
  • Preview updates ~3 seconds after a save, with no model call.
  • Asked about a removed check, Claude answered: "any signed-in user can now vote on someone else's chat", citing the right function.

## What I learned

  • LLMs are best as editors, not sources of truth. Once code owns what exists, Claude's output becomes verifiable.
  • Validators beat prompts. Rules checked in code stay fixed; prompt tweaks don't.
  • A strict agent sandbox is what makes giving an agent file access safe. The Droid SDK's permission hooks made a read-only agent simple to enforce.

## What's next

More languages (Python first), database and config layers, pull request comments, and runtime tracing to fill static-analysis gaps.

Built With

Share this project:

Updates

Submission history