Source-grounded visual perception for coding agents.
Inspect, focus, and verify UI and 3D work at full quality.
SceneProof lets coding agents see the interfaces and Three.js scenes they build. It reconstructs the real source, exposes the structure that explains the render, and produces exactly the context or detail view needed for reliable visual judgment.
Agents can finally recognize what they made, understand why it looks wrong, and prove that it is visually finished—instead of coding UI and 3D blind.
SceneProof requires Bun 1.3.14 or newer and a local Chrome or Chromium installation.
bun add --global github:ReyJ94/SceneProof
sceneproof --helpThat is the complete installation. It installs SceneProof directly from this
repository, including its runtime dependencies and global sceneproof command.
I do not have Bun yet
On macOS or Linux:
curl -fsSL https://bun.com/install | bashOn Windows PowerShell:
powershell -c "irm bun.sh/install.ps1|iex"Open a new terminal, confirm bun --version, then run the SceneProof install
command above.
sceneproof: command not found
Bun places global commands in ~/.bun/bin. If that directory is not already on
your PATH, add these lines to ~/.zshrc or ~/.bashrc, then open a new
terminal:
export BUN_INSTALL="$HOME/.bun"
export PATH="$BUN_INSTALL/bin:$PATH"Chrome is not detected
Point SceneProof at the local executable:
export SCENEPROOF_CHROME_PATH="/path/to/chrome"
sceneproof doctorChromium is blocked by an agent sandbox
Run sceneproof as the direct command with the agent's
unsandboxed/local-render permission. Do not hide it inside a compound shell,
pipe, or wrapper: those can prevent Chromium from starting before SceneProof can
return its own diagnostic.
sceneproof doctordoctor reports executable discovery, browser launch, WebGL availability, the
active renderer, and the required execution guidance. A failed check exits
non-zero.
Coding agents are strong at reading source and changing it. Their visual feedback remains weak.
Source code can prove that a component or mesh exists, but not that it is legible, well-composed, correctly lit, or even visible. A screenshot shows pixels, but loses hierarchy, material state, geometry, and ownership. Enlarging that screenshot does not recover detail that was never rendered. A browser harness can click through an application, but interaction is not visual understanding.
SceneProof closes the loop:
- Map the real UI or scene into stable semantic targets.
- Inspect the exact structure behind the uncertain result.
- Frame the relevant component, region, object, or world-space patch so it occupies an informative part of the image.
- Render fresh evidence from source at the quality the remaining judgment requires.
- Verify the artifact instead of inferring visual quality from plausible code.
Camera and region selection come before pixel density. More pixels help only when the image already presents the evidence that matters.
| Need | SceneProof evidence |
|---|---|
| Find the relevant thing | Compact React and Three.js trees with deterministic IDs |
| Understand why it looks wrong | Bounds, styles, geometry, attribute ranges, materials, uniforms, lights, cameras, and relationships |
| See it in context | Fresh source-based context renders |
| Inspect small detail | Target or logical-region rerenders, not enlarged screenshots |
| Understand 3D form | Source, fitted, filled, or alternate camera views |
| Find useful evidence quickly | A one-lifecycle Scout portfolio for context, source detail, close detail, and shape |
| Compare an interaction | Deterministic before/time/settled frames from one bundle and one live scene |
| Preserve model context | Compact briefings with lossless evidence available by path only when needed |
SceneProof keeps two accounts of the result:
- Structural truth: what the source produced—hierarchy, identity, bounds, transforms, styles, geometry, materials, lights, cameras, and visibility.
- Perceptual truth: what the result presents—composition, hierarchy, silhouette, depth, density, contrast, clipping, and small-scale detail.
The render reveals that something is wrong. The structure often reveals why. Neither replaces the other.
inspect and scout return compact, decision-complete briefings. Warnings,
target identity, omission counts, provenance, and the next useful evidence stay
inline. Exact lossless JSON is written automatically and exposed through
evidence.full.path; the agent opens it only when an omitted fact can change
the decision.
Piped output is compact JSON for model efficiency. Interactive terminal output remains formatted for humans.
| Verb | Purpose |
|---|---|
tree |
Navigate semantic structure |
node |
Inspect one exact target and its immediate relationships |
inspect |
Reconstruct the source and preserve the canonical scene artifact |
scout |
Discover useful Three.js target cameras in one scene lifecycle |
render |
Produce fresh context or target evidence |
render-region |
Rerender an exact logical viewport patch |
doctor |
Prove Chromium and WebGL readiness and explain required permissions |
SceneProof owns renderer setup and evidence persistence. The agent chooses the real source boundary, declared state, semantic target, framing, and evidence needed to resolve the uncertainty.
The included knowledge-graph scene is self-contained:
sceneproof tree examples/three/knowledge-graph.ts \
--export createScene
sceneproof scout examples/three/knowledge-graph.ts \
three:concepts \
--export createScene \
--focus-node three:planet-earth \
--out artifacts/knowledge-graph-scoutOpen artifacts/knowledge-graph-scout/contact-sheet.png. The compact Scout
briefing explains whether framing or raster resolution is limiting and provides
reproducible commands for the useful alternatives.
Use an existing product export whenever it already represents the real visual boundary. If deterministic setup is needed:
- put a reusable repository-owned inspector in
scripts/sceneproof/<surface>.scene.ts; - put its state snapshots in
scripts/sceneproof/fixtures/; - put a disposable investigation under
/tmp/sceneproof-inspectors/; - never put SceneProof adapters, copied geometry, or invented state in
application
src.
An inspector may import the production owner unchanged, supply deterministic props and providers, expose semantic targets, and translate a domain action into the real scene lifecycle. It must not reconstruct how the application “probably” looks. Source reconstruction proves the current code under the declared fixture state; it does not prove parity with an unrecorded live browser state.
If the real boundary cannot be loaded without manufacturing the behavior under test, visual verification is blocked rather than approximated.
SceneProof accepts a named component export, deterministic JSON props, source CSS, workspace aliases, and Tailwind v4 styles:
sceneproof tree tests/fixtures/DemoCard.tsx \
--export DemoCard \
--props tests/fixtures/props.json
sceneproof node tests/fixtures/DemoCard.tsx \
dom:demo-card \
--export DemoCard \
--props tests/fixtures/props.json
sceneproof render tests/fixtures/DemoCard.tsx \
dom:demo-card \
--export DemoCard \
--props tests/fixtures/props.json \
--scale 4 \
--out artifacts/demo-card.pngUse render-region when the surrounding viewport coordinate system matters.
It performs a fresh render at the requested device scale; it does not crop and
enlarge an earlier PNG.
A Three.js entry may use any export name. With --renderer auto, SceneProof
selects the requested export and detects Three.js from its { scene, camera }
return contract. --renderer three is the deterministic escape hatch when a
factory has browser-specific setup. defineThreeFixture from
sceneproof/three brands a factory so auto detection does not need to invoke it
in the probe.
First inspect structure, then let Scout discover informative framing when the useful camera is uncertain:
sceneproof node scripts/sceneproof/inquiry-field.scene.ts \
three:selected-instrument \
--export createInquiryEvidence \
--props scripts/sceneproof/fixtures/selected.json
sceneproof scout scripts/sceneproof/inquiry-field.scene.ts \
three:selected-instrument \
--export createInquiryEvidence \
--props scripts/sceneproof/fixtures/selected.json \
--out artifacts/inquiry-scout--view original --framing source preserves the complete source camera
literally. fit contains the target. fill prioritizes target visibility and
allows controlled clipping for close inspection. Scout provides four different
evidence intentions:
context: literal source composition;sourceDetail: a fresh source-camera region render;detail: a close view ranked for target visibility;shape: an alternate view ranked for form evidence.
Only increase --scale when those views already frame the relevant evidence
and raster detail is still limiting.
Fixture-owned actions and deterministic timeline sampling keep transient evidence in one real scene lifecycle:
sceneproof render scripts/sceneproof/inquiry-field.scene.ts \
three:selected-instrument \
--export createInquiryEvidence \
--props scripts/sceneproof/fixtures/selected.json \
--action select \
--frames before,0,80,160,settled \
--framing source \
--out artifacts/select-transition.pngFor the exact lifecycle, semantic target, instance ID, camera, and diagnostic contracts, read the Three.js fixture protocol.
SceneProof currently supports:
- TypeScript and JavaScript source entries;
- React DOM, computed styles, semantic text and roles, SVG subtrees, and logical-region rendering;
- workspace
@/imports, JSON props, source CSS, and Tailwind v4; - Three.js scene graphs, transforms, world bounds, BufferGeometry attributes, materials, shader uniforms, textures, lights, cameras, and relationships;
- custom-named Three.js factories, deterministic props/actions/time, source
camera preservation, semantic targets, stable
InstancedMeshinstance IDs, and single-lifecycle frame sequences; - full-quality source rerendering, target-aware camera control, bounded source region rendering, information-gain Scout portfolios, and compact evidence briefings.
SVG-native export and before/after compare are not implemented yet. The Bun
compiled binary is experimental for arbitrary workspace entries with nested
package imports; linked source mode is the supported development path.
Work from source
git clone https://github.com/ReyJ94/SceneProof.git
cd SceneProof
bun install --frozen-lockfile
bun run cli --helpLocal quality gate
bun run checkThe public gate runs lint, strict TypeScript 7 typechecking, the self-contained browser-backed test harness, and the Bun compiled build.
See the changelog for release-level behavior changes.
MIT © 2026 ReyJ94
