# Debug Broken UI

Find out why something in a running web app does not work, when the console is empty...

- Repository: https://github.com/reticlehq/reticle (1299 stars)
- Category: Git and review
- License: Apache-2.0
- Last updated: 2026-11-01
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add reticlehq/reticle --skill debug-broken-ui -g -a claude-code -y`
Codex: `npx skills add reticlehq/reticle --skill debug-broken-ui -g -a codex -y`
Cursor: `npx skills add reticlehq/reticle --skill debug-broken-ui -g -a cursor -y`
Gemini CLI: `npx skills add reticlehq/reticle --skill debug-broken-ui -g -a gemini-cli -y`
Claude Code plugin marketplace: `/plugin marketplace add reticlehq/reticle`

## Description

Find out why something in a running web app does not work, when the console is empty and the code looks correct. Reads the click, the request, the store and the console together and returns the file:line to open. Use when a button does nothing, a form will not submit, data will not load, a page renders blank or stale, a modal will not close, or the user says "it's broken" and the code review says it is fine.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# The app is broken and the code looks fine

Reading the source again will not tell you why. The evidence is in the running app, and most of it never reaches the screen: the request that failed, the store that never moved, the handler that was never bound, the element covered by something invisible.

**Reticle** reads all of it from inside the page. Not set up? Follow the [`reticle`](https://github.com/reticlehq/reticle/blob/main/skills/reticle/SKILL.md) skill: it installs Reticle, asks the user before `init` changes the app's files, and proves one flow.

## Do not start by guessing. Start by reproducing.

```
reticle_look({ action: "page", sessionId, mode: "interactive" })   // controls only, with refs
reticle_act_and_wait({ sessionId, ref, action: "click", until: { kind: "element", query: { testid: "..." } } })
```

The verdict already narrows it: `no` / `contradicted` means a channel saw something incompatible with the UI: you have the bug. `unknown` means Reticle drove it and could not tell, which is a different investigation from "it failed".

**Read the act result before you call anything else.** Its `summary` block already carries the whole causal window of that one click: `net {total, errors, headline}`, `consoleErrors`, `stateDiffs [{path, from, to}]`, `storageDiffs [{key, from, to}]`, `route`, `signals`, `layoutShift`, `longTasks`: real before→after diffs, not counts. The console, network, storage and state calls below are for going DEEPER into something the summary already pointed at. Calling all three straight after an act pays three model round trips (and, in an approval-gated client, three human clicks) for evidence you were already holding.

The rest: https://github.com/reticlehq/reticle/blob/HEAD/skills/debug-broken-ui/SKILL.md
