Skip to content
Open
46 changes: 46 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,51 @@
# Changelog

## Unreleased

### Updating after code changes

- Each crawl records the git commit it shot, on a `visualice-source` line in
`visualice.routes.md` and as `source` in the run's `crawl-map.json` (branch, files with
uncommitted changes, whether the target was local, a hash of the config).
- `visualice changes` diffs the project against that commit: the commits and files since,
the changes that reach every page (dependencies, global styles, root layouts, header
and footer, the config), the pages file-based routing ties changed files to, and the
files left for an agent to trace. It gives a verdict (`none`, `partial`, `full`,
`unknown`) and the command to run; `--discover` also lists new and removed pages.
- `crawl --only=<paths>` shoots only those pages (paths or globs) and carries every
other page's shots over from the last finished run, as hard links where the disk
allows, so the new run is still the whole site. A page the last run can't cover (new,
or missing shots) is shot anyway. With `--replay` the named pages' states are
discovered again. `--dry-run` shows what would be shot and carried.
- The skill and `/visualice` follow it: run `changes`, trace the affected pages, ask
whether to rerun those or everything, then run it.

### Viewer

- Shots a partial run took carry an **updated** tag; a carried shot's details say which
run and commit it was really taken in.
- **Compare with another version** in the details panel shows the same shot from another
run beside this one.

### Update notice

- An installed CLI tells you when a newer visualice is out (checked against npm at most
once a day, in the background, never in the way), with the command to update the
plugin or the CLI. The skill passes it on. Off with `--quiet`, in CI, or with
`VISUALICE_NO_UPDATE_CHECK=1`.
- `visualice serve` shows the same news as a banner across the top of the viewer, with
the update steps and a copy button for each command. Dismissed, it stays away until
the next version; a shared export never shows it.
- The README says how to turn on auto-update for the plugin: a marketplace plugin
doesn't update itself unless you do.

### Fixes

- A very long page, above all on a high-density phone, no longer fails its shot with
"Processed image is too large for the WebP format": the viewer's preview images are
scaled down to fit WebP's 16383px limit, and the full PNG is untouched. With
`screenshot.format: "webp"`, a page too tall for WebP now says so and how to fix it.

## 0.1.1

### Fixes
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ Needs Node 22.18 or newer.
/plugin install visualice@visualice
```

Plugins from a marketplace like this one don't update on their own unless you ask: turn
it on under `/plugin` → **Marketplaces** → visualice → **Enable auto-update**, or update
by hand with `claude plugin update visualice@visualice`. The CLI also says when a newer
version is out.

Then run `/visualice https://your.site`, or just ask Claude to "run visualice on
https://your.site". It maps the site, shows you the plan (the kinds of page, how many
screenshots, anything exploring would change on the site) and asks once, explores each
Expand Down
Empty file modified cli/visualice.mjs
100644 → 100755
Empty file.
4 changes: 4 additions & 0 deletions commands/visualice.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ configured in `visualice.config.json` in the current directory.
map with a dry run, show the user the page types, shot count and any writes and
confirm once, dispatch one `visualice:visualice-explorer` agent per page type,
then `visualice author` and `visualice crawl --replay`.
- **Already mapped, and the routes file records a commit** (a `visualice-source`
line) → run `visualice changes --json` first and follow the skill's
`references/update-mode.md`: trace the affected pages, ask the user whether to
rerun just those (`crawl --replay --only=…`, carrying the rest over) or everything.
- **Already mapped** → `visualice crawl --replay --json --quiet`, then explore only
what's new (pages added to the routes file, `wanted` lines), per "Later runs" in
the same reference. `/visualice-explore` is for widening it on purpose.
Expand Down
16 changes: 16 additions & 0 deletions docs/crawling.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ visualice crawl --resume # continue the newest interrupted run, keepin
visualice crawl --dry-run # discover, then list what would be captured; capture nothing
visualice crawl --no-states # pages only, no UI states (fast; cached states are kept)

# after code changes (the routes file records the commit each crawl shot):
visualice changes # what changed since, and whether some pages or all need reshooting
visualice crawl --replay --only=/pricing,/blog/** # reshoot those; carry every other page over

# other commands:
visualice discover https://your.site # discovery only, no screenshots
visualice init https://your.site # scaffold the config without crawling
Expand Down Expand Up @@ -88,6 +92,18 @@ gitignored folder; once tracked, git keeps it) or restore it from a CI cache, th
`visualice crawl --replay --json --quiet --fail-on-error`. Without it, `--replay` falls
back to a full discovery and the explored states are missing.

### Update notice

An installed CLI checks npm for a newer visualice at most once a day, in the background,
and says so on stderr at the start of a later command (`ℹ visualice 0.3.0 is available
…`). It never delays a command for more than a moment, and a failed lookup is ignored.
It is off with `--quiet`, in CI (`CI` set), in a source checkout, and with
`VISUALICE_NO_UPDATE_CHECK=1` (or `NO_UPDATE_NOTIFIER=1`). The last answer is cached in
`~/.cache/visualice/update-check.json` (`$XDG_CACHE_HOME` when set).

`visualice serve` passes the same answer to the viewer, which shows it as a banner with
the update steps (the viewer never contacts npm itself; an export never shows it).

## Output

Output lands under the configured output directory (default `.visualice/`), one folder
Expand Down
11 changes: 11 additions & 0 deletions docs/viewer.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,17 @@ back to it. A card's trash button deletes the site and all its runs from disk af
confirmation; the site `serve` was started on can't be deleted (409) while that server
runs.

### Partial runs and comparing versions

A partial run (`crawl --only`, see [updating after code changes](../skills/visualice/references/update-mode.md))
shoots the pages that changed and carries the rest over. Its shots carry an **updated**
tag on the canvas; a carried shot's details panel says so, with the run and commit it
was really taken in. The details panel's footer shows the commit a shot came from.

**Compare with another version**, in the details panel, puts the same shot from another
run of the site beside this one (the previous version by default). A shot that was
carried over unchanged says so instead of looking like a coincidence.

## Share a run

```bash
Expand Down
18 changes: 18 additions & 0 deletions manifest.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -740,6 +740,24 @@
},
"error": {
"type": "string"
},
"carried": {
"description": "Copied from an earlier run by a partial crawl (`--only`), not shot by this one.",
"type": "object",
"properties": {
"runId": {
"type": "string"
},
"commit": {
"type": "string"
},
"capturedAt": {
"type": "string"
}
},
"required": [
"runId"
]
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions site/.vitepress/config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const PAGES: Record<string, string> = {
"site/guide/getting-started.md": "guide/getting-started.md",
"skills/visualice/references/explore-mode.md": "guide/explore.md",
"docs/crawling.md": "guide/crawling.md",
"skills/visualice/references/update-mode.md": "guide/updating.md",
"docs/configuration.md": "guide/configuration.md",
"skills/visualice/references/auth.md": "guide/auth.md",
"docs/viewer.md": "guide/viewer.md",
Expand Down Expand Up @@ -127,6 +128,7 @@ export default defineConfig({
text: "Guide",
items: [
{ text: "Crawling", link: "/guide/crawling" },
{ text: "Updating after code changes", link: "/guide/updating" },
{ text: "Configuration", link: "/guide/configuration" },
{ text: "Logging in", link: "/guide/auth" },
{ text: "The viewer", link: "/guide/viewer" },
Expand Down
19 changes: 17 additions & 2 deletions skills/visualice/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ from any directory, no repo checkout needed. In a source checkout of this repo i
use the npm scripts instead: `npm run vc -- <cmd>` for anything below, `npm run crawl --
<args>` for crawls. The commands below say `visualice`; substitute whichever applies.

If a command prints `ℹ visualice X is available (you have Y)…` on stderr, tell the user
once, with the update command it gives (`claude plugin update visualice@visualice`), and
carry on with the task: don't update anything yourself.

Before the first crawl in a project, run `visualice doctor` — an idempotent preflight
that checks Node/Playwright chromium/sharp/the viewer build and self-heals what it
safely can (installs chromium, builds the viewer; `--no-fix` to only report). This
Expand Down Expand Up @@ -88,10 +92,18 @@ rediscovery and loses any Explore-mode states authored into it.
hasn't been mapped: map it with a dry run, plan the page types with the user,
explore each type, then capture with `--replay`. Read
[`references/explore-mode.md`](references/explore-mode.md) and follow it.
2. **Replay or extend.** The site is mapped. To recapture, run
2. **Update after code changes.** The site is mapped and the project is a git repo
whose code changed since the last crawl. Run `visualice changes --json`: it diffs
against the commit the catalogue was shot from (recorded in the routes file) and
says whether nothing, some pages, or everything needs reshooting. Work out the
affected pages, ask the user whether to rerun just those or everything, then run
`visualice crawl --replay --only=<pages>`, which carries every other page over from
the last run. Read [`references/update-mode.md`](references/update-mode.md) and
follow it.
3. **Replay or extend.** The site is mapped. To recapture, run
`visualice crawl --replay --json --quiet`. For new pages, `wanted` lines, or a focus the user names, explore
just those page types first (explore-mode.md, "Later runs").
3. **Quick.** Only when the user asks for it ("quick", "just screenshot it", pages only)
4. **Quick.** Only when the user asks for it ("quick", "just screenshot it", pages only)
or you're scripting CI: `visualice crawl <url> --json --quiet` runs the heuristics
and captures in one go, with no exploring. Mention that exploring would find more.

Expand Down Expand Up @@ -161,3 +173,6 @@ Full flag reference: [`references/cli.md`](references/cli.md).
by default never publish, delete, pay, sign out or change account settings.
- The cached model makes re-runs cheap — once a site is mapped, default to `--replay`
and explore only what's new.
- After code changes, never reshoot part of a catalogue without asking: lay out what
`visualice changes` found and the pages you traced, and let the user choose between
those pages and a full run. When in doubt, recommend the full run.
41 changes: 22 additions & 19 deletions skills/visualice/references/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,26 @@ the dedicated script where one exists, e.g. `npm run crawl -- <args>`).

## Commands

| Command | Purpose |
| --------------------------- | ------------------------------------------------------------------------- |
| `init [url]` | Scaffold `visualice.config.json` (+ `.gitignore` entry) without crawling |
| `crawl [url]` | Discover routes + UI states, then capture across devices |
| `discover [url]` | Auto-discover routes + UI states only — no screenshots |
| `routes` | Regenerate `visualice.routes.md` from the cached site model |
| `validate` | Validate a crawl manifest / cached site model |
| `auth [--force]` | Run the configured login recipe, save storage state |
| `capture --manifest=<path>` | Replay a given manifest's recipes and capture screenshots |
| `demo` | Capture the bundled fixture from a hand-written manifest |
| `demo-crawl` | Full discover → capture run against the bundled fixture |
| `fixture` | Serve the bundled fixture blog so you can browse it |
| `doctor [--no-fix]` | Idempotent preflight: check Node/Playwright/sharp/viewer, self-heal |
| `serve` | Launch the zoomable results viewer |
| `export <dir>` | Write the viewer + a run as a static folder |
| `probe <path>` | JSON: the page's inventory, or (`--recipe`/`--state`) what a recipe does |
| `author [dir\|file]` | Merge explorer state files (default `.visualice/explore/`) into the cache |
| `--version` | Print the installed version |
| `help` | Print usage |
| Command | Purpose |
| --------------------------- | -------------------------------------------------------------------------- |
| `init [url]` | Scaffold `visualice.config.json` (+ `.gitignore` entry) without crawling |
| `crawl [url]` | Discover routes + UI states, then capture across devices |
| `discover [url]` | Auto-discover routes + UI states only — no screenshots |
| `routes` | Regenerate `visualice.routes.md` from the cached site model |
| `validate` | Validate a crawl manifest / cached site model |
| `auth [--force]` | Run the configured login recipe, save storage state |
| `capture --manifest=<path>` | Replay a given manifest's recipes and capture screenshots |
| `demo` | Capture the bundled fixture from a hand-written manifest |
| `demo-crawl` | Full discover → capture run against the bundled fixture |
| `fixture` | Serve the bundled fixture blog so you can browse it |
| `doctor [--no-fix]` | Idempotent preflight: check Node/Playwright/sharp/viewer, self-heal |
| `serve` | Launch the zoomable results viewer |
| `export <dir>` | Write the viewer + a run as a static folder |
| `probe <path>` | JSON: the page's inventory, or (`--recipe`/`--state`) what a recipe does |
| `author [dir\|file]` | Merge explorer state files (default `.visualice/explore/`) into the cache |
| `changes [--discover]` | JSON/text: what changed in git since the catalogue's commit, and a verdict |
| `--version` | Print the installed version |
| `help` | Print usage |

## Flags

Expand All @@ -43,6 +44,8 @@ command are accepted by it.
| `--manifest=<path>` | `capture`/`validate` | Input manifest path |
| `--replay` | `crawl`/`demo-crawl` | Reuse the cached site model, skip discovery |
| `--resume` | `crawl` | Continue the newest interrupted run, keeping its shots |
| `--only=<paths>` | `crawl` | Shoot only these pages (paths or globs, comma-separated); every other page's shots are carried over from the last run. With `--replay`, rediscovers their states |
| `--discover` | `changes` | Also map the site's pages (no states, nothing written) to list new and removed ones |
| `--json` | most | Print a machine-readable JSON summary to stdout |
| `--quiet` | most | Suppress progress output on stderr |
| `--fail-on-error` | capture cmds | Exit 3 if any capture failed |
Expand Down
Loading
Loading