gallery
Open a local, read-only gallery of everything the project has generated. Each lock entry is shown at integer zoom on a transparency checkerboard, grouped by style, with its provenance one click away: the prompt actually sent, provider and generator, dimensions, recorded cost, lock status and plan state, submit and download times, job and object ids, every output with its path, SHA-256, size, and on-disk status, revision lineage, a character's parent and the states and loops that hang off it, the quality record (palette, native-grid detection, audit, named approval), the manifest asset as declared, and raw provider metadata.
pixelkiln gallery
pixelkiln gallery --style environment --port 4180 --no-open
pixelkiln gallery --json > generations.json
What it shows
The gallery is lock-first. A lock entry the manifest no longer declares still
appears, marked undeclared, so paid work is never hidden; a declared asset
with no entry appears as a placeholder so the page also shows what has not
been made. Search matches asset ids, prompts, job and object ids, hashes, and
paths; chips filter by plan state, provider, and generator. Filters and sort
live in the URL query (?state=failed,orphaned&group=none) and the open record
in the hash (#style/asset), so a link lands on the same view. A render shows
up to 600 cards before offering the rest, which keeps very large projects
responsive. Refresh re-reads the manifest, lockfile, and disk, so the page
can stay open while gen runs in another terminal. The server binds to
localhost, serves only the files the current snapshot names, never contacts a
provider, and never writes anything. Stop it with Ctrl+C. See the
Getting started guide for a
screenshot.
--json: the snapshot as data
--json prints the same snapshot to stdout without starting a server. It is
the offline, machine-readable answer to "what has this project generated?" for
scripts and agents; --style and --only narrow it the same way.
--edit: change prompts and style fields
--edit lets the page change intent: an asset's prompt (for every style or
only the one being viewed), width, height, size, category, and tags; a style's
prompt prefix, prompt suffix, palette, whether downloaded art is snapped to
it, view, and background removal; and a form under each style to add a new
asset. The palette rule is the one style field that changes no request:
saving it makes the style's generated entries recoverable, and the next
fetch re-applies it for free. A style edit shows its blast
radius before you save:
how many assets it changes the request for, including assets in styles that
extends this one and do not override the field themselves, and what
regenerating all of them would cost (noBackground counts only styles that
send it: pixflux, and non-PixelLab providers). Editing a child style sets a
value on the child only; clearing a field there makes it inherit again. Saving rewrites the manifest and
nothing else, the same edit you would make in an editor, so plan and the
page immediately report the asset stale or missing with its estimate, and
generation still goes through pixelkiln gen with its budget and confirmation.
The write is refused when the manifest changed on disk since the page loaded,
and a result the manifest loader would reject never lands. Edits are accepted
only from the page itself: the request must come from the gallery's own origin
and carry a session token minted when the server started. Without --edit
the gallery has no write route at all.
pixelkiln gallery --edit
pixelkiln gallery --edit --workspace pixelkiln.workspace.json
Restore and regenerate from a record
An orphaned record, one whose file is gone or changed after download, offers
Restore (the recorded bytes back from the cache or the provider, no cost)
and, for a changed file, Regenerate; both replacements say what they
discard and ask first, and the way to keep the change is Edit by hand or
Edit in browser, which copies it beside the record. An untracked file
can be replaced by a generation the same way.
A record's Previous generations lists what its regenerations replaced,
each with a thumbnail from the local cache, its date and cost, the prompt when
it differed, and a link to the object. Restore this one brings one back at
no cost, the page's form of restore --generation. Any --budget
enables it, 0 included, and the current generation moves into the list so
the restore can be undone.
--budget: generate from the page
--budget <n|provider=n> enables generation from the page under that session
ceiling. It is the same --budget gen takes: one unkeyed amount when a run
involves a single provider, or one keyed amount per provider for a mixed run,
and nothing is queued without it. Each asset record and each style header
gains Generate (for missing, stale, and failed work), Regenerate
(for up-to-date work, as gen --force), and Resume (poll, review, and
fetch existing provider work at no cost). Before anything is submitted a
dialog lists every asset with its candidate count and estimate, the total per
provider, and what the session budget still allows. It is the page's version of
gen's "Spend … on N asset(s)?" question. A run is then the same submit,
poll, and fetch library calls gen makes, writing the same lockfile, so a
terminal plan in another window agrees at every step. Progress appears in a
job strip under the filters; each job keeps the log lines the CLI would have
printed. Candidate sets stop in review: Review slides the pick sheet
out over the gallery, Apply selections writes the lockfile and downloads
the chosen art, and unchosen rows stay in review exactly as with pick. A
regeneration's sheet shows the current art beside the candidates.
Compare records side by side
Compare puts two to four records side by side at one shared zoom with
their fields in rows (provider, generator, candidates, size, cost, prompt,
dates, quality, hashes) and tints every row whose values differ. Shift-click
cards (or use Compare + in a record) to build the set; the tray at the
bottom opens it. The set lives in the URL (?compare=a,b), so a comparison
can be linked like any other view. It works in the read-only gallery too.
Two ceilings guard spend. The session budget is charged with each job's
estimate up front, so two quick clicks cannot both fit under the same
remainder, and each submission also carries the remaining ceiling as its own
budget, so a provider estimate that grows between plan and submit is refused
rather than paid. The balance preflight is the same as gen's. Provider
credentials are loaded from the project's own .env files and never reach the
page; in a workspace whose projects name the same credential with different
values, the gallery refuses to generate for the second project rather than run
it on the first project's account. Start a separate gallery for it.
"How many candidates" is a style setting, because it is part of the request
identity: Retro Diffusion, ComfyUI, and Scenario expose it as a provider option
(numImages/numOutputs), which each style header shows and, with --edit,
lets you change. Every asset in the style then becomes stale, and the header
says how many. PixelLab's count follows the generator and size (map and
pixflux return one image; a 1dir style returns 4–64), so the header
explains that instead of offering a number.
Hand edits, in your editor or the browser
With --edit, a record also gains Edit by hand, the page's form of
pixelkiln edit: it creates the edit file, declares it, and opens
it in PIXELKILN_EDITOR or the OS default. The record then shows the generated
art and the edit side by side with its status (an unchanged copy, edited, or
based on an older generation because the art was regenerated since), plus
Open in editor and Detach edit. A card whose edit differs from the
generated art shows the edit, since that is what ships, with a ✎ mark.
--edit also offers Edit in browser: a pinned build of
Pixelorama that the gallery serves itself, opened in
a slide-out sheet with the sprite and the style's palette loaded. See
tools for what is fetched, where it lives, and how it is verified;
the header shows whether it is installed and, if not, an Install editor
button that fetches it once with a progress bar. Nothing is downloaded without
that click or tools install editor. Save to project (or ⌘S / Ctrl+S in
the editor) hands the flattened image back to the page, which writes the same
edits/ file pixelkiln edit would and declares it; the sheet stays open for
the next change, Save & close does both, and closing with unsaved changes
asks first. Opening an existing edit also lays the generated art on a locked
Generated (PixelKiln reference) layer at 50%, an onion skin for seeing
what changed. The sheet's show generated box hides and shows it, and
a save never flattens it in. A set opens as one Pixelorama project with a
frame per member, an animation at its fps or a tile set as one frame per tile,
and saving writes every member back under its role; a set that comes back with
a different number of frames is refused rather than guessed at. A browser save also keeps Pixelorama's layered .pxo
beside the edit. The next Edit in browser hands it back, so layers and
frames come back as they were; the flattened PNG is used only if the file
cannot be read, and the sheet says which. The save also writes <edit>.edit.json
recording the editor, the time, and the hash of the generation each file was
based on, so regenerated-since is decided by hash rather than file times for
those edits. Edit status compares pixels, not bytes: an edit that was opened
and saved without a change stays same, whatever its editor did to the PNG. The record shows the
editor and the layer file; Open in desktop editor and Detach edit work
on the same file. The editor page runs same-origin under its own
content-security policy and never sees the gallery's session token; the page
does the write. --no-editor hides all of it and serves none of its routes.
Pull changes made in PixelLab's editor
A PixelLab map or 1dir record also links to its account object (Open in
pixellab ↗), where PixelLab's own editor can change it; with --budget
(any amount; --budget 0 allows provider contact and no spend) the record
and its style header offer Pull upstream changes, the page's form of
fetch --refresh, which re-downloads the object and replaces the local file
only if it changed upstream.
pixelkiln gallery --edit --budget 80
pixelkiln gallery --budget pixellab=40 --budget retrodiffusion=1.25 --workspace pixelkiln.workspace.json
--workspace: every project in one gallery
--workspace <catalog> shows every project the catalog registers in one
gallery, the way workspace status reads them: no manifest is needed in the
current directory, each project gets its own section and filter chip, and a
project whose manifest or lock cannot be read is listed with its error instead
of hiding the rest. Lock keys repeat across projects, so records are identified
as project:style/asset in links and search. --style and --only apply per
project; a project without the named ids shows nothing. --json prints
the combined snapshot with a workspace.projects summary.
pixelkiln gallery --workspace pixelkiln.workspace.json
pixelkiln gallery --workspace pixelkiln.workspace.json --style base --json