pixelkiln 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTING.md +92 -0
- package/LICENSE +21 -0
- package/NAMING.md +87 -0
- package/PROVIDERS.md +96 -0
- package/README.md +333 -0
- package/SECURITY.md +38 -0
- package/bin/pixelkiln.js +2 -0
- package/dist/cli.d.ts +47 -0
- package/dist/cli.js +5889 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.cjs +5129 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +2679 -0
- package/dist/index.d.ts +2679 -0
- package/dist/index.js +4990 -0
- package/dist/index.js.map +1 -0
- package/docs/AGENTS.md +64 -0
- package/docs/ARCHITECTURE.md +120 -0
- package/docs/ARTIFACTS.md +162 -0
- package/docs/CLI.md +248 -0
- package/docs/ENDPOINTS.md +344 -0
- package/docs/GENERATORS.md +170 -0
- package/docs/GETTING_STARTED.md +170 -0
- package/docs/LIBRARY.md +157 -0
- package/docs/MANIFEST.md +162 -0
- package/docs/QUALITY.md +107 -0
- package/docs/README.md +44 -0
- package/docs/RECOVERY.md +124 -0
- package/docs/TILES.md +118 -0
- package/examples/minimal/README.md +26 -0
- package/examples/minimal/pixelkiln.manifest.json +21 -0
- package/package.json +100 -0
- package/schema/manifest.schema.json +255 -0
- package/skills/pixelkiln/SKILL.md +51 -0
- package/skills/pixelkiln/agents/openai.yaml +5 -0
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Thanks for improving pixelkiln. The project is deliberately conservative around
|
|
4
|
+
paid generation, file ownership, and provider state: a convenient failure must
|
|
5
|
+
never widen a paid run, overwrite hand-edited art, or lose the identity of work
|
|
6
|
+
that already cost money.
|
|
7
|
+
|
|
8
|
+
## Development setup
|
|
9
|
+
|
|
10
|
+
Requires Node.js 20 or newer.
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm ci
|
|
14
|
+
npm run typecheck
|
|
15
|
+
npm run test:docs
|
|
16
|
+
npm test
|
|
17
|
+
npm run build
|
|
18
|
+
npm run test:package
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
The Next.js marketing/documentation site is isolated in `website/`:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm ci --prefix website
|
|
25
|
+
npm run website:check
|
|
26
|
+
npm run website:lint
|
|
27
|
+
npm run website:build
|
|
28
|
+
npm run website:dev
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The site reads canonical Markdown from `docs/` and the root policy files at
|
|
32
|
+
build time. Do not create a second documentation copy under `website/`.
|
|
33
|
+
|
|
34
|
+
Website sprites are generated from `website/art/pixelkiln.manifest.json`.
|
|
35
|
+
Treat those requests as paid work: run `plan` and `audit` first, use an explicit
|
|
36
|
+
hard budget, and commit the manifest, lockfile, and reviewed outputs together.
|
|
37
|
+
The Review UI showcase should be captured at 1280×720 only after every asset
|
|
38
|
+
loads. Give a replacement capture a new public filename and update the page
|
|
39
|
+
reference so deployed image caches cannot retain the old version.
|
|
40
|
+
|
|
41
|
+
Run the source CLI without a global install:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npm run pixelkiln -- help
|
|
45
|
+
npm run pixelkiln -- plan --manifest examples/minimal/pixelkiln.manifest.json
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Tests must not require a live provider account or API key. Use `FakeProvider`
|
|
49
|
+
for pipeline behavior and mocked HTTP responses for PixelLab wire contracts.
|
|
50
|
+
|
|
51
|
+
## Change guidelines
|
|
52
|
+
|
|
53
|
+
- Start from `main` and keep one coherent change per pull request.
|
|
54
|
+
- Use conventional commit subjects (`feat:`, `fix:`, `docs:`, `refactor:`,
|
|
55
|
+
`test:`, `chore:`). Semantic Release derives versions from them.
|
|
56
|
+
- Add regression coverage for bug fixes and behavior coverage for new public
|
|
57
|
+
options or exports.
|
|
58
|
+
- Update README/help text and focused docs in the same change as user-facing
|
|
59
|
+
behavior.
|
|
60
|
+
- Keep README as the concise product landing page. Put durable reference and
|
|
61
|
+
workflow detail in `docs/`, and link every guide from `docs/README.md`.
|
|
62
|
+
- Run `npm run test:docs` after changing Markdown or the CLI command/flag
|
|
63
|
+
surface. It checks local links, the docs index, README size, and CLI coverage.
|
|
64
|
+
- Run the website lint and build checks when changing `website/` or the
|
|
65
|
+
canonical Markdown it renders.
|
|
66
|
+
- Run the package smoke test when changing exports, build configuration, the
|
|
67
|
+
executable, package metadata, or the `files` allowlist.
|
|
68
|
+
|
|
69
|
+
## Architectural boundaries
|
|
70
|
+
|
|
71
|
+
- Provider-specific URLs, authentication, response schemas, and quirks belong
|
|
72
|
+
below `Provider`.
|
|
73
|
+
- Planning stays offline. Provider `supports()` and `estimate()` must perform no
|
|
74
|
+
I/O and estimates must carry their cost unit.
|
|
75
|
+
- Provider responses are untrusted input and need runtime validation before
|
|
76
|
+
entering the lockfile.
|
|
77
|
+
- Lockfile writes must remain atomic and resumable. Additive defaults should
|
|
78
|
+
preserve valid v2 files when extending lock entries.
|
|
79
|
+
- Unknown flags and ambiguous output selection are errors. Silent widening is
|
|
80
|
+
especially dangerous when a command can spend provider quota.
|
|
81
|
+
- Never overwrite a generated file whose current bytes differ from its recorded
|
|
82
|
+
hash, and never make deletion an implicit side effect of recovery/triage.
|
|
83
|
+
|
|
84
|
+
## Pull requests
|
|
85
|
+
|
|
86
|
+
Describe the user-visible outcome, any compatibility impact, and the exact
|
|
87
|
+
checks run. Keep generated `dist/` files out of commits; packaging builds them
|
|
88
|
+
from source. If hosted CI is unavailable, include the local Node version and
|
|
89
|
+
full check results in the PR description.
|
|
90
|
+
|
|
91
|
+
Security-sensitive findings should follow [SECURITY.md](./SECURITY.md), not a
|
|
92
|
+
public issue with exploit details.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 gfargo
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/NAMING.md
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Naming — resolved: `pixelkiln`
|
|
2
|
+
|
|
3
|
+
**The name is settled.** The project ships as `pixelkiln`. `package.json` is
|
|
4
|
+
no longer `private`.
|
|
5
|
+
|
|
6
|
+
## The original blocker was a factual error
|
|
7
|
+
|
|
8
|
+
The prior version of this file claimed `pixelkiln` "is an established npm
|
|
9
|
+
package (v3.5.1, the CSS spritesheet builder) and `pixelsmith` is its
|
|
10
|
+
engine," and blocked the name on that basis. Re-verified directly against
|
|
11
|
+
the npm registry (2026-08-18):
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
GET https://registry.npmjs.org/pixelkiln → 404 "Not found"
|
|
15
|
+
GET https://registry.npmjs.org/spritesmith → 200, latest 3.5.1, "Utility that
|
|
16
|
+
takes images and creates a
|
|
17
|
+
spritesheet with JSON sprite data"
|
|
18
|
+
GET https://registry.npmjs.org/pixelsmith → 200, latest 2.6.0, "Node based
|
|
19
|
+
engine for spritesmith"
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
`pixelkiln` was never published. The "v3.5.1 CSS spritesheet builder" is
|
|
23
|
+
**`spritesmith`**, a real and long-established package — `pixelsmith` really
|
|
24
|
+
is its engine, exactly as claimed, but neither of them is `pixelkiln`. The
|
|
25
|
+
original research conflated the two real packages into a collision that
|
|
26
|
+
didn't exist. (`pixelsmith` also appears, separately and correctly, in the
|
|
27
|
+
rejected-candidates list below — a real name in a different, adjacent
|
|
28
|
+
project — which should have been the tell.)
|
|
29
|
+
|
|
30
|
+
A GitHub search for `pixelkiln` returns nothing but this repository, and a
|
|
31
|
+
general web search turns up no product, tool, or project by that name
|
|
32
|
+
anywhere. Nothing else needs to change: `bin/pixelkiln.js`, `package.json`'s
|
|
33
|
+
`name`/`bin`, the README, `scripts/gen-schema.ts`'s schema title, and
|
|
34
|
+
heybud-admin's `package.json` badge scripts already all say `pixelkiln` —
|
|
35
|
+
there is no rename to do, only the `private: true` flag to drop, which is
|
|
36
|
+
done.
|
|
37
|
+
|
|
38
|
+
## What the space already looks like
|
|
39
|
+
|
|
40
|
+
The "manifest-driven AI asset generation CLI" idea is not novel. Prior art found:
|
|
41
|
+
|
|
42
|
+
| Project | Overlap | Backend |
|
|
43
|
+
|---|---|---|
|
|
44
|
+
| [pickbitsai/sprite-generator](https://github.com/pickbitsai/sprite-generator) | Closest. JSON manifest, `assets[]` with id/category/description, `defaultStyle`, `--dry-run`, `--category`, `--concurrency` | OpenAI `gpt-image-1` |
|
|
45
|
+
| [mcp-tool-shop-org/sprite-foundry](https://github.com/mcp-tool-shop-org/sprite-foundry) | SQLite lifecycle tracking, review/accept/reject, provenance, deterministic export with manifest + checksums | ComfyUI (local GPU) |
|
|
46
|
+
| [lx-0/restyle-sprites](https://github.com/lx-0/restyle-sprites) | Restyle a whole pack from source + style reference | Gemini / OpenAI |
|
|
47
|
+
| [trebeljahr/sprite-tools](https://github.com/trebeljahr/sprite-tools) | Post-processing toolkit — atlas, collision, palette | n/a |
|
|
48
|
+
| [dt-pirate/openrender](https://github.com/dt-pirate/openrender) | Installs generated assets into engines, manifests, rollback | n/a |
|
|
49
|
+
| [freema/pixelforge-mcp](https://github.com/freema/pixelforge-mcp) | MCP server for pixel art | Gemini |
|
|
50
|
+
| [ralphy](https://ralphy.mintlify.app/advanced/asset-manifest) | `asset-manifest.json` slot pointers + `generations.jsonl` audit log | multi |
|
|
51
|
+
|
|
52
|
+
**Implication for naming:** the `sprite-*` namespace is crowded — `sprite-generator`,
|
|
53
|
+
`sprite-foundry`, `sprite-tools`, `restyle-sprites` all exist. Avoid it.
|
|
54
|
+
|
|
55
|
+
## What is actually differentiated here
|
|
56
|
+
|
|
57
|
+
Worth knowing, because the name should point at it:
|
|
58
|
+
|
|
59
|
+
1. **PixelLab-native.** Everything above wraps a general image model and
|
|
60
|
+
downscales. PixelLab generates on a real pixel grid. Nothing found targets it.
|
|
61
|
+
2. **Exploits the candidate economics.** Cost is fixed per call while candidates
|
|
62
|
+
returned scale inversely with canvas size. Nothing found treats "generate
|
|
63
|
+
small, pick from 16" as the core loop.
|
|
64
|
+
3. **`adopt`.** Retroactively reconciling an existing account and repo by image
|
|
65
|
+
hash. Not found anywhere.
|
|
66
|
+
4. **A true lockfile.** `sprite-foundry` uses SQLite, `ralphy` uses a pointer
|
|
67
|
+
table plus a log. A committed, sorted, hash-on-both-sides lockfile in the npm
|
|
68
|
+
sense was not found.
|
|
69
|
+
|
|
70
|
+
## Shortlist (historical — kept for context, decision is above)
|
|
71
|
+
|
|
72
|
+
All verified free on npm, zero GitHub repos by that name, no web presence
|
|
73
|
+
(checked 2026-07-29 for the alternates; `pixelkiln` itself re-verified
|
|
74
|
+
2026-08-18 per the resolution above).
|
|
75
|
+
|
|
76
|
+
| Candidate | Note |
|
|
77
|
+
|---|---|
|
|
78
|
+
| **pixelkiln** ✅ **chosen** | Firing/baking metaphor fits pixel art, avoids the crowded `sprite-*` space. The npm collision this was shelved for turned out not to exist — see Resolution. |
|
|
79
|
+
| pixelquarry | Extraction metaphor — you quarry many candidates and keep the good ones. Still free, not needed. |
|
|
80
|
+
| pixelcrate | Packaging/inventory feel; leans toward the lockfile idea. Still free, not needed. |
|
|
81
|
+
| dithermill | Most pixel-art-native word available; "mill" carries batch production. Still free, not needed. |
|
|
82
|
+
| spriteledger | Points hardest at provenance, but inherits the crowded `sprite-` prefix. Still free, not needed. |
|
|
83
|
+
|
|
84
|
+
Rejected after checking: `pixelwright` (three live businesses use it — an AI app
|
|
85
|
+
builder, an iOS audit firm, a UI developer's brand), `spritefoundry` (taken by a
|
|
86
|
+
real project), `pixelsmith` (real package, `spritesmith`'s engine — see
|
|
87
|
+
Resolution), `spritemill`, `pixelloom`, `bitforge`, `spritelab`.
|
package/PROVIDERS.md
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Multi-provider — status and notes
|
|
2
|
+
|
|
3
|
+
**The seam is built.** `src/provider.ts` defines the interface;
|
|
4
|
+
`src/providers/pixellab.ts` is the reference implementation and
|
|
5
|
+
`src/providers/fake.ts` is the in-memory test double. Nothing above the
|
|
6
|
+
interface knows about PixelLab.
|
|
7
|
+
|
|
8
|
+
That is an architectural guarantee, not a compatibility claim: PixelLab is the
|
|
9
|
+
only production adapter and the only backend exercised against a live account
|
|
10
|
+
today. `FakeProvider` verifies the contract without network access. Until a
|
|
11
|
+
second production adapter ships, describe PixelKiln as **provider-neutral by
|
|
12
|
+
design and proven with PixelLab**, not as already multi-provider.
|
|
13
|
+
|
|
14
|
+
Both concerns this file previously flagged as blockers are resolved:
|
|
15
|
+
|
|
16
|
+
- **Cost is no longer assumed to be "generations."** `CostEstimate` carries a
|
|
17
|
+
`unit` of `generations | usd | free`, `plan` prints it, and `--budget` is
|
|
18
|
+
interpreted in it. `resolveSpecs(..., { provider })` asks the adapter for its
|
|
19
|
+
offline estimate, submission validates it again, and lock/status accounting
|
|
20
|
+
keeps fractional values separated by unit.
|
|
21
|
+
- **Free multi-candidate returns are no longer assumed universal.**
|
|
22
|
+
`estimate().candidates` is a provider property; `candidateCount()` moved
|
|
23
|
+
behind the interface.
|
|
24
|
+
|
|
25
|
+
What remains is writing a second adapter. This file records which one and why.
|
|
26
|
+
|
|
27
|
+
## Midjourney is the wrong first target
|
|
28
|
+
|
|
29
|
+
Verified 2026-07-29: **Midjourney has no public developer API.** API keys are
|
|
30
|
+
restricted to the Enterprise dashboard and require applying for access. Every
|
|
31
|
+
third-party "Midjourney API" works by automating the Discord or web interface,
|
|
32
|
+
which violates Midjourney's terms of service and risks the underlying account
|
|
33
|
+
being banned.
|
|
34
|
+
|
|
35
|
+
Building that adapter would mean shipping something fragile, unsupported, and
|
|
36
|
+
capable of getting a user's account terminated. Not worth it.
|
|
37
|
+
|
|
38
|
+
## The right first target: Retro Diffusion
|
|
39
|
+
|
|
40
|
+
[Retro Diffusion](https://retrodiffusion.ai/) is PixelLab's closest competitor
|
|
41
|
+
and the natural second provider:
|
|
42
|
+
|
|
43
|
+
- A real, documented developer API, with
|
|
44
|
+
[published examples](https://github.com/Retro-Diffusion/api-examples).
|
|
45
|
+
- Purpose-built for pixel art — grid-aligned output, no blur or anti-aliasing —
|
|
46
|
+
so it shares this tool's domain model rather than needing a downscale and
|
|
47
|
+
quantize pass bolted on.
|
|
48
|
+
- Supports seamless tiles, sprite-sheet animation, and free cost estimates,
|
|
49
|
+
which map onto `plan` almost directly.
|
|
50
|
+
|
|
51
|
+
Other candidates, in rough order of fit:
|
|
52
|
+
|
|
53
|
+
| Provider | API | Pixel-native | Notes |
|
|
54
|
+
|---|---|---|---|
|
|
55
|
+
| Retro Diffusion | yes | yes | Recommended first adapter |
|
|
56
|
+
| [Scenario](https://www.scenario.com/) | yes | partly | Game-asset focused, hosts Retro Diffusion models |
|
|
57
|
+
| OpenAI `gpt-image-1` | yes | no | Raster; needs downscale + palette quantization |
|
|
58
|
+
| Google Gemini image | yes | no | Same caveat |
|
|
59
|
+
| Local ComfyUI + pixel LoRA | n/a | yes | No per-call cost, but a GPU dependency |
|
|
60
|
+
| Midjourney | **no** | no | See above |
|
|
61
|
+
|
|
62
|
+
## Resolved: the two economic assumptions
|
|
63
|
+
|
|
64
|
+
Both were global assumptions baked into `plan`; both are now provider-owned.
|
|
65
|
+
Kept here as the rationale, since a second adapter has to honour them.
|
|
66
|
+
|
|
67
|
+
1. **Cost is not universally "generations".** `Plan.cost` used to be a bare
|
|
68
|
+
number meaning PixelLab subscription generations. It now carries a unit —
|
|
69
|
+
USD for OpenAI, generations for PixelLab, free for local — so `plan` prints
|
|
70
|
+
an honest figure and `--budget` means something in every backend.
|
|
71
|
+
|
|
72
|
+
2. **Free candidates were a PixelLab quirk.** The core loop — generate small,
|
|
73
|
+
get 16 candidates for one fixed price, pick the best — works because
|
|
74
|
+
PixelLab charges per *call* and scales candidates inversely with canvas
|
|
75
|
+
size. OpenAI charges per *image*, so 16 candidates costs 16×. The picker
|
|
76
|
+
still works either way, but the strategy advice in the README does not
|
|
77
|
+
generalise, which is why `candidateCount()` moved behind the interface.
|
|
78
|
+
|
|
79
|
+
See `src/provider.ts` for the shipped interface. Lock entries carry a
|
|
80
|
+
`provider` field plus `costUnit`, defaulted to `pixellab` and `generations` so
|
|
81
|
+
pre-provider/pre-unit v2 lockfiles stay readable. The CLI reports both the
|
|
82
|
+
successful-submission estimate and the provider balance delta observed across
|
|
83
|
+
the run; those are deliberately separate because provider balances may settle
|
|
84
|
+
asynchronously.
|
|
85
|
+
|
|
86
|
+
## Done: the integration tests it unblocked
|
|
87
|
+
|
|
88
|
+
`FakeProvider` turned out to be exactly the better test double predicted here.
|
|
89
|
+
17 integration tests now cover `submit → poll → fetch`, `pushTags` and `adopt`
|
|
90
|
+
— the stages that spend money and previously had zero coverage, where four of
|
|
91
|
+
the five real bugs in this project lived. Verified non-vacuous by mutation:
|
|
92
|
+
breaking the output hashes, the budget check, or the v1 lock rejection each
|
|
93
|
+
fails tests.
|
|
94
|
+
|
|
95
|
+
The contact-sheet request paths are covered through the picker and salvage
|
|
96
|
+
integration tests as well as their HTML unit tests.
|
package/README.md
ADDED
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
# pixelkiln
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
[Website](https://pixelkiln.griffen.codes) ·
|
|
6
|
+
[Documentation](https://pixelkiln.griffen.codes/docs) ·
|
|
7
|
+
[GitHub](https://github.com/gfargo/pixelkiln)
|
|
8
|
+
|
|
9
|
+
Manifest-driven pixel-art generation, review, recovery, quality control, and
|
|
10
|
+
game-ready asset packaging.
|
|
11
|
+
|
|
12
|
+
PixelKiln treats generated art like a build pipeline: declare assets once,
|
|
13
|
+
preview cost and drift, generate only the missing work, review candidates in a
|
|
14
|
+
local contact sheet, and commit exact provenance beside the files. No LLM is in
|
|
15
|
+
the orchestration loop; provider calls, polling, hashing, downloads, and filing
|
|
16
|
+
are deterministic software mechanics.
|
|
17
|
+
|
|
18
|
+
The orchestration layer is provider-neutral by design. PixelLab is currently
|
|
19
|
+
the only production adapter and the only live-tested generation backend;
|
|
20
|
+
`FakeProvider` exercises the same contract deterministically in tests. A second
|
|
21
|
+
production adapter is roadmap work, not current compatibility.
|
|
22
|
+
|
|
23
|
+
> **Release status:** the package is pre-1.0 and the first npm publication is
|
|
24
|
+
> tracked in [issue #1](https://github.com/gfargo/pixelkiln/issues/1). Until it
|
|
25
|
+
> is live, use a repository checkout.
|
|
26
|
+
|
|
27
|
+
## Why PixelKiln
|
|
28
|
+
|
|
29
|
+
A typical image-generation account becomes two unrelated piles: remote objects
|
|
30
|
+
that cost money and local files with no durable explanation of where they came
|
|
31
|
+
from. Handwritten prompts drift, failed downloads look like failed generations,
|
|
32
|
+
and regenerating a whole set is easier than determining what is actually stale.
|
|
33
|
+
|
|
34
|
+
PixelKiln supplies the missing project model:
|
|
35
|
+
|
|
36
|
+
- a committed manifest defines assets, styles, generators, budgets, and output;
|
|
37
|
+
- a committed lockfile maps each style/asset to paid provider work and exact
|
|
38
|
+
output hashes;
|
|
39
|
+
- planning distinguishes missing, stale, recoverable, in-flight, untracked, and
|
|
40
|
+
manually changed files before money is spent;
|
|
41
|
+
- local review keeps human judgment where it matters—choosing artwork;
|
|
42
|
+
- content-addressed recovery prevents a transient URL failure from buying the
|
|
43
|
+
same image twice;
|
|
44
|
+
- derived artifact bundles retain source provenance and recover across ordinary
|
|
45
|
+
write failures or abrupt process termination.
|
|
46
|
+
|
|
47
|
+
## Capabilities
|
|
48
|
+
|
|
49
|
+
| Workflow | What PixelKiln provides |
|
|
50
|
+
|---|---|
|
|
51
|
+
| Plan and budget | Offline manifest/lock/disk diff, provider-unit estimates, hard `--budget` ceiling, JSON/CI gate. |
|
|
52
|
+
| Generate and review | Resumable submit/poll/pick/fetch pipeline with a fast local candidate sheet. |
|
|
53
|
+
| Existing-art onboarding | Manifest scaffolding, exact-hash account adoption, and prompt recovery. |
|
|
54
|
+
| Recovery | Validated local content cache, provider URL restore, account object-hash cache, and resumable jobs. |
|
|
55
|
+
| Shared-account safety | Cross-project claim files, sibling-style exclusion, reviewed salvage, keep/discard tags, separate confirmed purge. |
|
|
56
|
+
| Quality control | Palette distance, transparency, color-count, relative outlier, cache-integrity, and doctor gates. |
|
|
57
|
+
| Sprite packaging | Deterministic RGBA packing, stable-cell mounting, explicit external input lists, structural output roles. |
|
|
58
|
+
| Engine export | Lossless generic tile contract, Tiled Wang sets, and Godot 4 terrain sets. |
|
|
59
|
+
| Artifact integrity | Portable source/output hashes, canonical fingerprints, manual-edit protection, transactional promotion, crash journal recovery. |
|
|
60
|
+
| Library/extension | Public TypeScript primitives, provider capability interface, and deterministic `FakeProvider`. |
|
|
61
|
+
|
|
62
|
+
### Human review, kept local
|
|
63
|
+
|
|
64
|
+
`pixelkiln pick` opens an actual local candidate sheet; the orchestration layer
|
|
65
|
+
never asks a model to choose artwork for you.
|
|
66
|
+
|
|
67
|
+

|
|
68
|
+
|
|
69
|
+
Use Left/Right to inspect alternatives, Enter or 1–9 to select, and 0 to leave
|
|
70
|
+
a row unresolved. Nothing is applied when the window is closed without using
|
|
71
|
+
**Apply selections**. See the [CLI reference](docs/CLI.md#pick) for the complete
|
|
72
|
+
review workflow.
|
|
73
|
+
|
|
74
|
+
## Install from a checkout
|
|
75
|
+
|
|
76
|
+
Requires Node.js 20 or newer.
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
git clone https://github.com/gfargo/pixelkiln.git
|
|
80
|
+
cd pixelkiln
|
|
81
|
+
npm ci
|
|
82
|
+
npm run pixelkiln -- help
|
|
83
|
+
npm test
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
`npm run pixelkiln -- …` executes the TypeScript source. `npm run build`
|
|
87
|
+
creates the ESM, CommonJS, declarations, and CLI distribution used by the
|
|
88
|
+
published package.
|
|
89
|
+
|
|
90
|
+
## Five-minute start
|
|
91
|
+
|
|
92
|
+
Copy the minimal example into a project and edit its output path and prompts:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
cp examples/minimal/pixelkiln.manifest.json ../my-game/pixelkiln.manifest.json
|
|
96
|
+
cd ../my-game
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Put the provider credential in `.env.local` beside the manifest:
|
|
100
|
+
|
|
101
|
+
```dotenv
|
|
102
|
+
PIXELLAB_API_KEY=...
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Validate locally, inspect exact work/cost, then generate with a hard ceiling:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
/path/to/pixelkiln/node_modules/.bin/tsx /path/to/pixelkiln/src/cli.ts doctor --dry-run
|
|
109
|
+
/path/to/pixelkiln/node_modules/.bin/tsx /path/to/pixelkiln/src/cli.ts plan
|
|
110
|
+
/path/to/pixelkiln/node_modules/.bin/tsx /path/to/pixelkiln/src/cli.ts gen --budget 120
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Once installed from npm, those commands become `pixelkiln doctor`,
|
|
114
|
+
`pixelkiln plan`, and `pixelkiln gen`.
|
|
115
|
+
|
|
116
|
+
`gen` submits, polls, opens the candidate-review sheet when necessary,
|
|
117
|
+
downloads validated output, populates the recovery cache, and updates
|
|
118
|
+
`pixelkiln.lock.json`. Commit the manifest, lockfile, generated art, and any
|
|
119
|
+
derived artifact companions. Do not commit credentials or `.pixelkiln/`.
|
|
120
|
+
|
|
121
|
+
For an existing art tree:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
pixelkiln init --from assets/sprites --exclude characters,gifs --generator map
|
|
125
|
+
pixelkiln adopt --write-prompts
|
|
126
|
+
pixelkiln plan
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
See [Getting started](./docs/GETTING_STARTED.md) for new and existing projects.
|
|
130
|
+
|
|
131
|
+
## Agent skill
|
|
132
|
+
|
|
133
|
+
Install the official PixelKiln skill so Codex, Claude Code, Cursor, and other
|
|
134
|
+
compatible agents know the safe plan → budget → generate → review → recover
|
|
135
|
+
workflow:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
npx skills add gfargo/pixelkiln@pixelkiln
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
The skill guides an agent around PixelKiln; it does not replace a generation
|
|
142
|
+
provider. PixelLab's MCP server is a complementary direct-generation surface,
|
|
143
|
+
while PixelKiln remains the project state, budget, provenance, review, and
|
|
144
|
+
packaging layer.
|
|
145
|
+
|
|
146
|
+
## Manifest
|
|
147
|
+
|
|
148
|
+
```jsonc
|
|
149
|
+
{
|
|
150
|
+
"$schema": "./node_modules/pixelkiln/schema/manifest.schema.json",
|
|
151
|
+
"name": "my-game",
|
|
152
|
+
"styles": {
|
|
153
|
+
"base": {
|
|
154
|
+
"generator": "map",
|
|
155
|
+
"promptPrefix": "Pixel-art game prop: ",
|
|
156
|
+
"promptSuffix": ", isolated, transparent background",
|
|
157
|
+
"outDir": "assets/generated/base",
|
|
158
|
+
"tags": ["my-game"]
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
"assets": {
|
|
162
|
+
"anvil": { "prompt": "a compact blacksmith anvil" },
|
|
163
|
+
"hammer": { "prompt": "a worn forging hammer" }
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Styles are namespaces. Adding a second style re-derives the same asset ids into
|
|
169
|
+
a separate output directory and separate lock keys without clobbering the first
|
|
170
|
+
set. Generator choice, reference-image bytes, dimensions, palette, seed, and
|
|
171
|
+
prompt settings participate in deterministic spec identity.
|
|
172
|
+
|
|
173
|
+
The schema rejects unknown fields and invalid generator combinations before
|
|
174
|
+
planning. See the [Manifest reference](./docs/MANIFEST.md).
|
|
175
|
+
|
|
176
|
+
## Everyday workflow
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
# Free: validate and inspect drift, recovery, and estimated spend.
|
|
180
|
+
pixelkiln doctor --dry-run
|
|
181
|
+
pixelkiln plan
|
|
182
|
+
|
|
183
|
+
# Generate only an intended slice with a provider-unit ceiling.
|
|
184
|
+
pixelkiln gen --style base --only anvil,hammer --budget 80
|
|
185
|
+
|
|
186
|
+
# Repair paid output without regenerating.
|
|
187
|
+
pixelkiln restore
|
|
188
|
+
|
|
189
|
+
# Optional local gates.
|
|
190
|
+
pixelkiln audit --check --max-distance 35 --min-transparency 0.1
|
|
191
|
+
pixelkiln cache --check
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Repeated `--style`, `--only`, `--claims`, and `--output-role` filters
|
|
195
|
+
accumulate; comma-separated values also work. Unknown flags are hard errors, so
|
|
196
|
+
a typo cannot silently widen paid work.
|
|
197
|
+
|
|
198
|
+
## Choose the right generator
|
|
199
|
+
|
|
200
|
+
Measured PixelLab economics vary by 40×:
|
|
201
|
+
|
|
202
|
+
| Need | Generator | Measured cost |
|
|
203
|
+
|---|---|---:|
|
|
204
|
+
| Standalone arbitrary-size prop/icon | `map` (default) | 1 generation |
|
|
205
|
+
| Exact closed palette | `pixflux` | 1 generation |
|
|
206
|
+
| Candidate variety/reference anchoring/future animation | `1dir` | 20–40 generations |
|
|
207
|
+
| Independent or connectable ground tiles | `tiles` | 20–40 generations |
|
|
208
|
+
|
|
209
|
+
Start with the required capability, not the most expensive endpoint. Forty
|
|
210
|
+
`map` re-rolls cost the same as one 64×64 `1dir` call; conversely, `map` cannot
|
|
211
|
+
replace a hard palette or reference-image constraint. See
|
|
212
|
+
[Generator selection](./docs/GENERATORS.md) and the
|
|
213
|
+
[measured endpoint reference](./docs/ENDPOINTS.md).
|
|
214
|
+
|
|
215
|
+
## Derived artifacts
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
# Deterministic sheet + atlas + provenance.
|
|
219
|
+
pixelkiln pack --style base
|
|
220
|
+
|
|
221
|
+
# Stable declared cells in an existing sheet.
|
|
222
|
+
pixelkiln mount --style ground
|
|
223
|
+
|
|
224
|
+
# Structural atlas + engine metadata + provenance.
|
|
225
|
+
pixelkiln export --style ground --only terrain --format tiled
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Pack, mount, and export write managed bundles. A `.pixelkiln.json` companion
|
|
229
|
+
records portable source paths/hashes, layout/export options, output hashes, and
|
|
230
|
+
a canonical fingerprint. Existing unowned output is adopted only when already
|
|
231
|
+
byte-identical; manual edits stop the whole write unless `--force` explicitly
|
|
232
|
+
takes ownership.
|
|
233
|
+
|
|
234
|
+
All changing members stage before promotion. Ordinary failures roll back.
|
|
235
|
+
Abrupt termination leaves a validated transaction journal: the next invocation
|
|
236
|
+
restores an incomplete old bundle or finishes cleanup for a committed new one.
|
|
237
|
+
See [Derived artifacts](./docs/ARTIFACTS.md) and
|
|
238
|
+
[Tiles and engine exports](./docs/TILES.md).
|
|
239
|
+
|
|
240
|
+
## Recovery and shared accounts
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
# Reconcile existing files with account objects.
|
|
244
|
+
pixelkiln adopt --write-prompts
|
|
245
|
+
|
|
246
|
+
# Review paid account objects no known project claims.
|
|
247
|
+
pixelkiln salvage --claims ../other-game/pixelkiln.lock.json --dry-run
|
|
248
|
+
pixelkiln salvage --claims ../other-game/pixelkiln.lock.json
|
|
249
|
+
|
|
250
|
+
# Deletion is deliberately separate and confirmed.
|
|
251
|
+
pixelkiln purge --dry-run
|
|
252
|
+
pixelkiln purge
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
Salvage imports, keeps, or tags discard; it never deletes. On shared accounts,
|
|
256
|
+
pass every other project lockfile via `--claims` so shipped art cannot appear
|
|
257
|
+
unowned. Purge only targets objects already tagged discard and requires an
|
|
258
|
+
explicit confirmation. See [Recovery and account safety](./docs/RECOVERY.md).
|
|
259
|
+
|
|
260
|
+
## Automation
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
pixelkiln doctor --dry-run --json
|
|
264
|
+
pixelkiln plan --json --check
|
|
265
|
+
pixelkiln audit --json --check --max-distance 35 --max-colors 128
|
|
266
|
+
pixelkiln cache --check
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
Pipeline stages exit nonzero after partial failures or timeouts. JSON modes
|
|
270
|
+
separate machine output from human diagnostics where necessary. Generation
|
|
271
|
+
should remain an explicit budgeted action; CI should prove committed state and
|
|
272
|
+
artifacts agree rather than regenerate them. See
|
|
273
|
+
[Quality and automation gates](./docs/QUALITY.md).
|
|
274
|
+
|
|
275
|
+
## TypeScript library
|
|
276
|
+
|
|
277
|
+
```ts
|
|
278
|
+
import {
|
|
279
|
+
buildPlan,
|
|
280
|
+
loadLock,
|
|
281
|
+
loadManifest,
|
|
282
|
+
PixelLabProvider,
|
|
283
|
+
resolveSpecs,
|
|
284
|
+
} from "pixelkiln"
|
|
285
|
+
|
|
286
|
+
const loaded = await loadManifest("pixelkiln.manifest.json")
|
|
287
|
+
const provider = PixelLabProvider.forOffline()
|
|
288
|
+
const specs = await resolveSpecs(loaded, { provider })
|
|
289
|
+
const plan = await buildPlan(specs, await loadLock("pixelkiln.lock.json"))
|
|
290
|
+
|
|
291
|
+
console.log(plan.cost, plan.costUnit, plan.actionable.length)
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
The package also exports audit gates, lock/output helpers, provider contracts,
|
|
295
|
+
pipeline stages, sprite packing/mounting, tile exporters, managed artifact
|
|
296
|
+
writes, and offline provenance verification. See [Library API](./docs/LIBRARY.md).
|
|
297
|
+
|
|
298
|
+
## Documentation
|
|
299
|
+
|
|
300
|
+
| Guide | Covers |
|
|
301
|
+
|---|---|
|
|
302
|
+
| [Documentation index](./docs/README.md) | All user, workflow, reference, and architecture guides. |
|
|
303
|
+
| [Getting started](./docs/GETTING_STARTED.md) | First project, existing-art onboarding, everyday workflow, and what to commit. |
|
|
304
|
+
| [CLI reference](./docs/CLI.md) | Every command, flag, JSON mode, and exit contract. |
|
|
305
|
+
| [Manifest reference](./docs/MANIFEST.md) | Every style/asset field and generator constraint. |
|
|
306
|
+
| [Agent workflows](./docs/AGENTS.md) | Official skill install, operating model, and PixelLab MCP pairing. |
|
|
307
|
+
| [Generators](./docs/GENERATORS.md) | Capability choice, measured costs, palettes, style references, and tiles. |
|
|
308
|
+
| [Derived artifacts](./docs/ARTIFACTS.md) | Pack, mount, export, provenance, ownership, transactions, and recovery. |
|
|
309
|
+
| [Recovery](./docs/RECOVERY.md) | Restore, caches, adopt, salvage, claims, and purge safety. |
|
|
310
|
+
| [Quality gates](./docs/QUALITY.md) | Plan, doctor, audit, cache, JSON, and CI. |
|
|
311
|
+
| [Architecture](./docs/ARCHITECTURE.md) | State model, lockfile, providers, concurrency, and output identity. |
|
|
312
|
+
| [Library API](./docs/LIBRARY.md) | Public TypeScript contracts and examples. |
|
|
313
|
+
| [Tiles](./docs/TILES.md) | Structural outputs and generic/Tiled/Godot formats. |
|
|
314
|
+
| [Endpoint research](./docs/ENDPOINTS.md) | Measured PixelLab API behavior and recipes. |
|
|
315
|
+
|
|
316
|
+
The [public documentation site](https://pixelkiln.griffen.codes/docs) is built by
|
|
317
|
+
the application in [`website/`](./website/README.md). It reads these Markdown
|
|
318
|
+
files directly at build time, so the website and published package share one
|
|
319
|
+
documentation source.
|
|
320
|
+
|
|
321
|
+
Project policies: [Contributing](./CONTRIBUTING.md),
|
|
322
|
+
[Security](./SECURITY.md), and [provider notes](./PROVIDERS.md).
|
|
323
|
+
|
|
324
|
+
## Scope
|
|
325
|
+
|
|
326
|
+
Animated eight-direction characters and their ZIP/engine-resource export are not
|
|
327
|
+
currently implemented. See the open
|
|
328
|
+
[roadmap issues](https://github.com/gfargo/pixelkiln/issues) for provider and
|
|
329
|
+
workspace-catalog work.
|
|
330
|
+
|
|
331
|
+
## License
|
|
332
|
+
|
|
333
|
+
[MIT](./LICENSE)
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Security policy
|
|
2
|
+
|
|
3
|
+
## Supported versions
|
|
4
|
+
|
|
5
|
+
Until the first npm release, security fixes are applied to `main`. After
|
|
6
|
+
publication, the latest released line and `main` are supported; older versions
|
|
7
|
+
may be asked to upgrade before a fix is backported.
|
|
8
|
+
|
|
9
|
+
## Reporting a vulnerability
|
|
10
|
+
|
|
11
|
+
Please use GitHub's private vulnerability report for this repository when it is
|
|
12
|
+
available under the **Security** tab. If that option is unavailable, open a
|
|
13
|
+
minimal issue asking for a private contact channel and do not include exploit
|
|
14
|
+
steps, credentials, private URLs, or affected user data in the issue.
|
|
15
|
+
|
|
16
|
+
Useful reports include:
|
|
17
|
+
|
|
18
|
+
- the affected version or commit;
|
|
19
|
+
- the smallest safe reproduction;
|
|
20
|
+
- expected and observed behavior;
|
|
21
|
+
- impact and whether provider quota, local files, credentials, or account
|
|
22
|
+
objects are at risk;
|
|
23
|
+
- suggested mitigation, if known.
|
|
24
|
+
|
|
25
|
+
Please allow the maintainer time to reproduce and coordinate a fix before
|
|
26
|
+
public disclosure. Credit and disclosure timing will be coordinated with the
|
|
27
|
+
reporter.
|
|
28
|
+
|
|
29
|
+
## Sensitive areas
|
|
30
|
+
|
|
31
|
+
Pixelkiln handles provider credentials, paid API actions, remote object deletion,
|
|
32
|
+
local output paths, a localhost review server, and generated HTML containing
|
|
33
|
+
provider data. Reports involving authentication leakage, path traversal,
|
|
34
|
+
cross-origin review actions, HTML/script injection, unsafe overwrite/delete
|
|
35
|
+
behavior, lockfile corruption, or budget bypass are security relevant.
|
|
36
|
+
|
|
37
|
+
Never attach a real `PIXELLAB_API_KEY`, `.env` file, private provider URL, or
|
|
38
|
+
unredacted lockfile from a confidential project to a public report.
|
package/bin/pixelkiln.js
ADDED