Describe a machine in words — get an inspectable 3D model and a verified, reproducible implementation.
Visioned Vibe Coding for hardware, chips, and algorithms — powered entirely by the Claude (or Codex) CLI you already have. No API keys. No cloud. No accounts.
npx visually-3d![]() Quadcopter UAV |
![]() Apollo Command/Service Module |
![]() EHang 216-S eVTOL |
![]() Tabby EVO open EV platform |
![]() OpenHand robotic actuator |
![]() Prusa i3 MK3S 3D printer |
![]() 50 kW wind turbine |
![]() XiangShan RISC-V floorplan |
Every model above started as a single text prompt. Browse the source JSON →
Type a machine name and visually opens it in your browser as an inspectable react-three-fiber scene — orbit around it, click a part to read what it is, trace its connections. Alongside the model sits its reverse-implementation (Verilog / Python) and the verification that the implementation actually checks out:
Detail view of the CFNTT Radix-2/4 NTT accelerator (FPGA) — exploded 3D model, the spec-derived implementation, and the live verification panel, side by side for one scene.
The 3D render is only half of it. A visually-3d scene is two things at once: a 3D model (what the machine looks like) and a spec (the parameters, ports, operations, and named properties of the real system). The point of the tool is the loop that grows both together and keeps them consistent — describe a system in plain language, and watch a checkable artifact converge until it's both convincing to look at and faithfully reproducible. We call the loop Visioned Self-Improvement.
┌──────────────────────────────────────────────────────────┐
│ │
▼ │
┌─────────┐ ┌───────────┐ ┌────────────────────┐ ┌───┴────┐
│ improve │ ──► │ reproduce │ ──► │ verify (SMT / sim) │ ──►│ amend │
│ (visual)│ │ (N impls) │ │ + judge fidelity │ │(→ spec)│
└─────────┘ └───────────┘ └────────────────────┘ └────────┘
render→critique reverse-impl run each impl's write the
→rewrite the from the spec self-check; LLM-judge findings back
scene ALONE reproducibility+fidelity into the scene
- improve renders the scene offscreen and lets the model critique its own work visually as well as structurally, then rewrites it. (A part buried inside an opaque box is genuinely hidden in the render — if you can't see it, the scene is hiding it.)
- reproduce has N independent agents reverse-implement the system from the spec alone, runs each one through a backend (Z3 SMT for digital/compute subjects, MuJoCo physics for physical machines), and an LLM-judge scores two axes: reproducibility (could an engineer rebuild it with no guessing?) and fidelity (is it this specific paper/datasheet's system, not merely a working one?).
- amend routes the discovered values, resolved ambiguities, and counterexamples back into the scene's spec — so the next reproduce reads them, the independent implementations converge, and the score climbs. It quotes the source where it can, tags each fact's provenance, and never invents architectural detail the source doesn't support.
refine drives improve → reproduce → amend each round; create runs the same loop automatically after generating a draft, so a fresh scene is convincing and reproducible out of the box. Each round streams the model's reasoning live and prints visual · repro (▲/▼) · fidelity · self-check · spec field count:
The TUI driving
visually refine ntt-fpga — the closed 3D ⇄ implementation loop, working toward visual ≥ 90 · reproducibility ≥ 80 · self-check passing.
Keeping the loop honest. A self-improving loop is only as trustworthy as the signal it grades itself on — and here amend writes into the very spec the self-check measures against, so a bad write can corrupt its own grading key (we hit exactly this: a wrong modular inverse folded into the spec made every faithful implementation fail). Three guards close that gap:
- Arithmetic guard — fully-numeric derived constants (
x = b⁻¹ mod q,bᵉ mod q = r,floor(a/b) = c) are machine-checked and auto-corrected before they ever enter the spec, at every write/read point. No false constant survives on any path. - Honest verdicts — a self-check that fails to run (syntax error, timeout, crash) is a harness fault, not a wrong implementation: it's classified, repaired once, and counted separately instead of silently tanking the score.
- Ratchet — each round keeps the best-scoring scene; the loop never ends worse than the best round it actually measured.
📐 Full architecture: docs/visioned-self-improvement.md — the spec substrate, the return edge, the two verification axes, and automatic backend selection. Development history: docs/visioned-self-improvement-changelog.md — including the failure modes the guards above were built to prevent.
This tool never handles an API key. All model calls go through whatever claude (or codex) is already on your $PATH, using the subscription / OAuth you've already set up. The Node process only serves the built React frontend and spawns claude -p "<prompt>" as a subprocess, streaming its output back to the browser over SSE. No telemetry, no backend, no accounts — and the sample gallery works even with no CLI installed.
- Node.js 18+ to run the package (building from source needs Node 20+, a Vite requirement).
- Claude CLI (or Codex CLI) on your
$PATHto generate, refine, or verify scenes — the gallery works without it. - GitHub CLI (
gh) only if you want touploadscenes via pull request. - Optional: a Python with
z3-solver(auto-provisioned viauv run --with z3-solverwhen present) for the SMT backend. Verification degrades gracefully if neither is available.
claude --version # verify your CLI is installed + authenticatednpx visually-3d # bare TTY → interactive TUI; otherwise the GUI on http://localhost:3131or install it:
npm install -g visually-3d
visually-3dUse --no-open (or VISUALLY_NO_OPEN=1) to skip auto-opening the browser, and PORT=… to change the default 3131 (it probes the next 15 ports if one's taken).
Bare visually in a terminal launches the interactive TUI; with no subcommand in a non-TTY context it starts the GUI.
visually create "CFNTT Radix-2/4 NTT accelerator" --url https://tches.iacr.org/...
# generate, then auto-run the closed refine loop
visually refine ntt-fpga --rounds 3 # closed 3D ⇄ implementation loop on an existing scene
visually reproduce ntt-fpga # measure reproducibility + fidelity + self-check (no edits)
visually amend ntt-fpga # fold the latest findings back into the spec
visually improve apollo-csm 5 # visual-only self-improvement (up to 5 passes)
visually check apollo-csm # open it in the browser to inspect
visually check apollo-csm --png # …or render a headless 2×2 contact-sheet PNG
visually upload apollo-csm # open a PR adding it to the samples gallery
visually serve # the GUI (default in a non-TTY context)Scenes you create live in a workspace at ~/.visually-3d/scenes/ (override with $VISUALLY_HOME). They show up in the gallery automatically — no rebuild needed. The full per-round history (prompts, renders, thinking traces, before/after, verification reports) is kept under ~/.visually-3d/runs/.
Mode (hardware / algorithm / architecture) is auto-detected from the subject, and the verification backend is auto-selected from what the subject is — digital/compute → SMT, physical machine → sim. Override either with --mode / --backend.
Command reference
visually create "<machine name>" [--hint <text>] [--url <url>] \
[--mode hardware|algorithm|architecture] \
[--refine N | --no-refine] \
[--driver claude|codex] [--id <id>] [--force]Runs your local claude -p (or codex exec with --driver codex), validates the output against the scene schema, writes ~/.visually-3d/scenes/<id>.json, stamps the auto-selected backend and the --url as metadata.reference, then runs ≥3 closed-loop refine rounds (--no-refine to skip, --refine N to set the count).
visually refine <scene> [--rounds 3] [--visual 90] [--repro 80] [--iters 2] \
[--backend <id>] [--no-amend] [--driver claude|codex] [--model <m>]Each round runs improve → reproduce → amend, seeding the visual pass with the previous round's verification gaps. Stops when the visual score and reproducibility both clear their thresholds and the self-check passes — or at the round cap.
visually reproduce <scene> [--n 2] [--backend python-smt|sim] [--no-verify] [--model <m>]N independent agents reverse-implement the scene from the spec alone; each implementation's self-check runs through the backend; an LLM-judge scores reproducibility (completeness of the spec) and fidelity (match to the specific source) without changing the scene.
visually amend <scene> [--n 2] [--backend python-smt|sim] [--no-verify] [--model <m>]Takes reproduce's missing fields, divergences, counterexamples, and fidelity gaps and writes concrete values into the spec substrate (parts[].spec / metadata.spec), routing each fact to the part it belongs to. The merged scene passes the same parse/validate gate as create, plus the arithmetic guard that verifies and auto-corrects any derived numeric constant, before it's committed.
visually improve <scene> [iterations] [--driver codex|claude] [--model <m>]Renders the scene to an offscreen contact-sheet PNG, has the model critique it visually and from the JSON, then writes back an improved scene — stopping on convergence, a score plateau, or the iteration cap.
visually check <scene> # launch the GUI
visually check <scene> --png [--out file.png] # headless render, no GPUvisually upload <scene> [--repo owner/name] [--title <t>] [--dry-run]Uses your own gh auth to fork the repo (if needed), add the scene under public/samples/, register it in index.json, and open a pull request. --dry-run prepares the commit locally without pushing.
Every scene is a MachineSceneDescriptor — geometry plus an optional functional spec:
{
machine_name: string
assembly_instructions?: string
metadata?: {
reference?: string // the source paper/datasheet (fidelity is judged against it)
backend?: 'python-smt' | 'sim' // auto-stamped at create time
spec?: object // global spec facts
[k: string]: unknown
}
parts: Array<{
id: string
name: string
shape: 'box' | 'cylinder' | 'sphere' | 'cone' | 'torus' | 'capsule' | 'complex'
position: [number, number, number]
rotation?: [number, number, number] // Euler radians, optional
size: number[]
material: string
role: string
connections?: string[]
spec?: { // the functional genome — read & written by the loop
params?: Record<string, number | string>
widths?: Record<string, number>
ports?: Array<{ name: string; dir: 'in' | 'out'; width: number }>
ops?: string[]
fsm?: string[]
properties?: string[]
notes?: string
}
}>
}The schema is .loose() and every spec field is optional, so it's fully back- and forward-compatible: old geometry-only scenes still validate, and amend may add fields the schema doesn't yet name.
visually-3d/
├── bin/visually.ts CLI dispatcher (tui / serve / create / refine / reproduce / amend / improve / check / upload)
├── lib/ Subcommands + shared scene/workspace helpers
│ ├── serve.ts HTTP server: static + /api + workspace-merged /samples
│ ├── create.ts Generate a scene, then run the closed refine loop
│ ├── refine.ts Loop driver: improve → reproduce → amend per round
│ ├── reproduce.ts Reverse-implement from the spec; judge reproducibility + fidelity
│ ├── amend.ts Return edge: fold verification findings back into the spec
│ ├── improve.ts Visual self-improvement (offscreen render → critique → rewrite)
│ ├── backends/ Verification backends (python-smt via Z3, sim via MuJoCo)
│ ├── impls.ts Canonical per-scene impl store under ~/.visually-3d/impls/
│ ├── check.ts Browser / headless-PNG inspection
│ ├── upload.ts Fork + PR a scene to the gallery via `gh`
│ ├── scene.ts zod schemas + parse/validate/extract + spec coverage
│ ├── types.ts Spec substrate types
│ └── paths.ts Package paths + ~/.visually-3d workspace resolution
├── server/analyst.ts System prompt, `claude -p` spawn + SSE, JSON extraction
├── lib/tui/app.ts Ink + htm interactive control panel
├── scripts/ Offscreen renderer (shipped)
├── prompts/self-improve.md Visual self-improvement rubric
├── src/ React + three.js frontend (hash router, gallery + detail)
├── public/samples/*.json Showcase scenes (built into dist/)
├── docs/ Architecture write-ups + assets
└── dist/ Built frontend (shipped with the npm package)
git clone https://github.com/NyxFoundation/visually-3d.git
cd visually-3d
npm install # or: bun install
npm run build # required before `serve` (builds the CLI + dist/)Then run any of:
node bin/visually.js serve # or any subcommand
node bin/visually.js create "Drone"
npm run serve # alias for `serve`
npm run cli -- create "Drone" # pass subcommand args after `--`
npm link && visually-3d serve # use the real global commandcreate, refine, reproduce, amend, improve, and check --png don't need a frontend build — only the browser GUI (serve / check) requires dist/.
The CLI (lib/ server/ bin/) is TypeScript under strict, compiled in place to sibling .js (see CLAUDE.md). The gate before every commit:
npm run lint && npm run build && npm test && npm run smokeHot-reloading frontend dev loop:
npm run build && npm start # terminal 1: production server on :3131
npm run dev # terminal 2: Vite on :5173, proxies /api → :3131The static bundle (gallery only — no server, no CLI) deploys to Cloudflare Workers:
npx wrangler login
npm run deploy # builds + publishes dist/ to the "visually-3d" WorkerThe deployed build detects the absence of /api/health and hides the Analyze input automatically.
PRs are welcome — especially new sample scenes. The easiest path:
visually create "<your machine>" # generates + refines through the closed loop
visually refine <id> # run extra rounds if you want a higher score
visually upload <id> # opens the PR for you…or by hand: drop a JSON file under public/samples/, register it in public/samples/index.json, and open a PR.
MIT © NyxFoundation







