uiver
by vvek475
README.md
# uiver
**Local-first UI version snapshots.** When an AI agent iterates on your website,
each build overwrites the last โ the "middle" versions vanish. uiver freezes
every iteration as a fully interactive, permanently browsable local webpage, so
you can step back through history and compare any two versions side by side.
- โก **Instant snapshots** โ content-addressed store; unchanged files are never stored twice
- ๐ **Every version stays live** โ real pages served at `http://127.0.0.1:4321/v/<project>/<id>/`, not screenshots
- ๐ **Compare dashboard** โ side-by-side with synced scrolling, viewport presets, `[` / `]` to scrub history
- ๐ท **Titles + prompts** โ each version records what changed and the request that produced it
- ๐ค **Agent-native** โ Claude Code skill + slash commands + MCP tools
- ๐งน **Auto-clean cycle** โ unpinned versions expire after N days (editable in the dashboard); pinned versions are kept forever
- ๐ฆ **Share across machines** โ export any version as a single portable `.uiver` bundle
Requires Node โฅ 18.17. Zero npm dependencies.
## Install
### As a Claude Code plugin (recommended)
```
/plugin marketplace add vvek475/uiver-plugin
/plugin install uiver@uiver
```
This gives Claude the `ui-snapshot` skill (it snapshots automatically after
finishing UI changes), the `/uiver:snap`, `/uiver:dashboard`, and
`/uiver:versions` commands, and MCP tools (`ui_snapshot`, `ui_get_url`,
`ui_screenshot`, โฆ).
### CLI on your PATH (optional, for manual use)
```bash
cd uiver-plugin && npm link # or: npm install -g .
```
## Quickstart
```bash
cd my-website
npm run build # if the site needs building
uiver snap --title "hero v1" --prompt "make the hero full-bleed"
uiver open # dashboard at http://127.0.0.1:4321
```
Snapshot again after each change. Identical output is deduplicated โ calling
`snap` when nothing changed is a no-op.
## CLI
```
uiver snap [dir] Snapshot a built site (auto-detects dist/build/out/_site)
--title --prompt --note --pin --project --force
uiver list List versions
uiver label [id] <title> Retitle a version (default: latest) [--pin]
uiver pin|unpin [id] Protect/unprotect from auto-clean
uiver delete <id> Delete and reclaim space
uiver serve [--port N] Dashboard server (foreground); --daemon for background
uiver open | stop | status Manage the server
uiver clean [--dry-run] Run the retention cycle now
uiver export <id> Write a portable .uiver bundle
uiver import <file> Import a bundle from another machine
uiver config [key value] port, retentionDays, cleanIntervalHours, autoClean
uiver mcp MCP server on stdio
```
## Dashboard
`uiver open` โ three views:
- **Single** โ browse one version; `[` / `]` step older/newer in place
- **Split** โ two versions side by side with synced scrolling and viewport presets
- **Manager** โ file-system-style view of everything stored: per-version sizes,
file lists, dedup savings, delete/export/import, and the auto-clean settings
(retention days, cycle interval, on/off)
## Sharing across machines
```bash
uiver export v12 # โ my-site-v12.uiver (single gzipped bundle)
# send the file any way you like, then on the other machine:
uiver import my-site-v12.uiver
```
Bundles are self-contained (manifest + all files, content-hash verified) and
idempotent โ importing the same bundle twice never duplicates. Alternatively,
sync the whole store by putting `~/.uiver` (or `UIVER_HOME`) in any synced folder.
## Screenshots (optional)
The `ui_screenshot` MCP tool and `/api/screenshot` endpoint render versions
headlessly. They require Playwright:
```bash
npm i -g playwright && npx playwright install chromium
```
Everything else works without it.
## Storage layout
```
~/.uiver/
config.json port, retention, clean cycle
objects/<sha256> every unique file, stored once
projects/<name>/manifest.json versions: id, title, prompt, file list
cache/screenshots/
```
Override the location with the `UIVER_HOME` env var.
## Notes & limitations
- Snapshots freeze the **frontend**. If a version calls a live API, it will hit
whatever that API returns today.
- Builds that hardcode absolute asset paths (`/assets/x.js`) are handled via a
Referer-based fallback redirect; setting your bundler's `base` path is cleaner.
- The server binds to `127.0.0.1` only.
## License
MIT
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues