Re Frame Pair banner
day8 day8

Re Frame Pair

Development community

Description

A Skill for pair-programing with Claude Code on a re-frame app.

Installation

This entry records only its repository, not the path inside it, so there is no exact command to give. Open the source below and copy the folder into ~/.claude/skills/, or the file into ~/.claude/agents/.

README

re-frame-pair

Lets an AI (Claude, Codex?) debug and develop against your **running re-frame application**.

Claude can inspect `app-db`, dispatch events, trace the 6 dominoes, hot-swap handlers, time-travel, and map visible UI back to source code — all live against the runtime, with no source edits required for probes.

A coding agent working with just static code is working with a limited perspective. It can read handlers, subscriptions, and views, but it has to guess what happened in the browser at runtime. With re-frame-pair, Claude can ask the running app: which event fired, what changed in `app-db`, which effects fired, which subscriptions re-ran or cache-hit, which views rendered, and where the relevant source lives.

The intended loop is empirical:

  1. Observe the current runtime state.
  2. Inspect the relevant epoch.
  3. Form a hypothesis.
  4. Undo state, probe with a new dispatch, read app-db, hot-swap handlers, side-effect stub, or REPL eval.
  5. Compare the new epoch with the baseline.
  6. Only then edit source.

REPL changes are **ephemeral** (try-and-discard); source edits **stick**.

Post-mortems are a core use case. Instead of asking the developer to describe every click and state transition that led to a bug, Claude can inspect the recent epoch trail and identify the event that introduced the bad value, including its parent dispatch, effects, `app-db` diff, subscriptions, renders, and source call sites.

Examples

**You**: What changes did the last event make to `app-db` under `:shopping-cart`?

**Claude**: 2 items, subtotal 47.50, no coupon. `{:items [{:sku "BK-42" :qty 2} {:sku "TS-9" :qty 1}] :total 47.50 :coupon nil}`


**You**: I dispatched `[:profile/save ...]` but the name in the header isn't changing.

**Claude**: The header reads `[:user/display-name]`, derived from `[:user/profile]`. Your handler wrote to `[:user :pending-profile]`, not `[:user :profile]`. Layer 2 returned `=`, the Layer 3 short-circuited, the header didn'