Skip to content

re-frame2-pair

Pair-program with a live, running re-frame2 application. Attach via nREPL, inspect any frame's app-db, dispatch events, hot-swap handlers, walk epochs, and read the trace stream — through re-frame2's own Tool-Pair contract, no re-frame-10x dependency.

What it does

The re-frame2-pair skill is the AI pair-programming companion for a running re-frame2 app. The app is up behind shadow-cljs watch; the skill attaches to its nREPL session in :cljs mode and operates on the live runtime — not just static source files.

Three primitives carry the skill's agency, all part of re-frame2's Tool-Pair Spec:

  1. The REPL — ClojureScript forms evaluated against the real app, usually through helpers in the injected re-frame2-pair.runtime namespace.
  2. The trace stream(rf/register-listener! id listener) for live trace events; (re-frame.trace.tooling/trace-buffer opts) for the retain-N ring of recent events (rf/trace-buffer is a JVM-only alias, so CLJS callers use the re-frame.trace.tooling ns).
  3. The epoch history(rf/epoch-history frame-id) returns the per-frame ring of :rf/epoch-record values, each carrying :db-before, :db-after, :trace-events, and the assembled :sub-runs / :renders / :effects projections.

The skill is multi-frame aware (Spec 002 — most apps run with one frame, larger apps run several). It registers exactly one trace listener (:re-frame2-pair) and one epoch listener (:re-frame2-pair-epoch) so it coexists with other tools (e.g. re-frame-10x v2) on the same bus. Mutating ops refuse with :ambiguous-frame when the operating frame is unclear.

The cardinal rule: REPL changes are ephemeral, source edits are permanent. After any source edit, the skill waits on the hot-reload protocol before dispatching or tracing — otherwise you interact with the pre-reload code.

When to reach for it

Load this skill when the user mentions a running re-frame2 app, or any of: re-frame2, app-db, dispatch, subscribe, reg-event, reg-sub, reg-fx, reg-machine, frame, epoch, interceptor, sub-cache, trace-buffer, register-listener!, register-epoch-listener!, restore-epoch, re-com, shadow-cljs — and the question is about the live runtime, not about writing new code.

Do not use this skill for:

Kickoff

Every session starts with discover-app, called via the re-frame2-pair-mcp server (the only skill-facing transport — see Transport below). The scripts/ shims are not part of the skill surface — they exist only for the project's own e2e harness and ad-hoc manual use, so they are not part of a skill session:

discover-app

This locates the shadow-cljs nREPL port, connects, switches to :cljs mode for the running build, verifies re-frame2 is loaded with interop/debug-enabled? true, and injects the runtime namespace. Failures return a structured edn shape like {:ok? false :missing :re-frame2} which the skill reports verbatim and routes to the matching recovery in references/errors.md.

Transport

The skill is MCP-only: a single skill-facing transport.

  • MCP server@day8/re-frame2-pair-mcp, an npm-installable stdio JSON-RPC server holding one persistent nREPL connection per session. Per-op latency ~5–50ms. Install via npm install -g @day8/re-frame2-pair-mcp and add to your agent host's MCP config. Source: tools/re-frame2-pair-mcp/.

The MCP server is the one implementation of every operation. The bash/babashka transport that originally fronted these ops (scripts/ops.clj + shell wrappers) has been removed; the live connect/dispatch/trace/hot-reload coverage now drives the MCP server over stdio from tools/re-frame2-pair-mcp/test/live-e2e-fixture.cjs.

To force-load in Claude Code:

/skill re-frame2-pair

After connect, work in structured ops (read, write, trace, DOM bridge, watch, hot-reload, time-travel) rather than ad-hoc repl/eval — the escape hatch is available for probes that don't fit the catalogue.

Where the skill lives