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/docs/LIBRARY.md
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# Library API
|
|
2
|
+
|
|
3
|
+
Pixelkiln's public package entry point exposes the same provider-independent
|
|
4
|
+
primitives used by the CLI. Use these when a build tool, editor integration, or
|
|
5
|
+
game pipeline needs structured results instead of terminal output.
|
|
6
|
+
|
|
7
|
+
## Load, resolve, and plan
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import {
|
|
11
|
+
buildPlan,
|
|
12
|
+
loadLock,
|
|
13
|
+
loadManifest,
|
|
14
|
+
PixelLabProvider,
|
|
15
|
+
resolveSpecs,
|
|
16
|
+
summarize,
|
|
17
|
+
} from "pixelkiln"
|
|
18
|
+
|
|
19
|
+
const loaded = await loadManifest("pixelkiln.manifest.json")
|
|
20
|
+
const provider = PixelLabProvider.forOffline()
|
|
21
|
+
const specs = await resolveSpecs(loaded, { provider })
|
|
22
|
+
const lock = await loadLock("pixelkiln.lock.json")
|
|
23
|
+
const plan = await buildPlan(specs, lock)
|
|
24
|
+
|
|
25
|
+
console.log(summarize(plan))
|
|
26
|
+
if (plan.actionable.length) {
|
|
27
|
+
console.log(`${plan.cost} ${plan.costUnit} for ${plan.actionable.length} assets`)
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Planning performs no provider calls and spends nothing. Passing a provider lets
|
|
32
|
+
its synchronous `supports()` and `estimate()` methods determine cost unit and
|
|
33
|
+
candidate count; no credentials are required for those methods. A resolved
|
|
34
|
+
spec has the fully inherited style and asset settings plus its deterministic
|
|
35
|
+
spec hash.
|
|
36
|
+
|
|
37
|
+
## Audit and gate generated art
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
import { auditStyle, evaluateAudit } from "pixelkiln"
|
|
41
|
+
|
|
42
|
+
const audit = await auditStyle(loaded, specs, "neon", lock)
|
|
43
|
+
const result = evaluateAudit(audit, {
|
|
44
|
+
maxDistance: 35,
|
|
45
|
+
minTransparency: 0.1,
|
|
46
|
+
maxColors: 128,
|
|
47
|
+
sigma: 1.5,
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
if (!result.safe) console.error(result.violations)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Audits evaluate every structural output separately. Missing and unreadable
|
|
54
|
+
files make the result unsafe even when all measured assets pass. Standard
|
|
55
|
+
non-interlaced greyscale, indexed, RGB, greyscale-alpha, and RGBA PNGs are
|
|
56
|
+
normalized to RGBA before palette and transparency measurements.
|
|
57
|
+
|
|
58
|
+
## Build sprite sheets
|
|
59
|
+
|
|
60
|
+
Use `packStyle` for one lockfile style or `packSprites` for an explicit list:
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
import { packSprites, packStyle } from "pixelkiln"
|
|
64
|
+
|
|
65
|
+
const sheet = packStyle(lock, "ground", loaded.root, {
|
|
66
|
+
outputRoles: ["tile-00", "tile-01"],
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
const shared = packSprites([
|
|
70
|
+
{ id: "anvil", path: "/absolute/art/anvil.png" },
|
|
71
|
+
{ id: "hammer", path: "/absolute/art/hammer.png" },
|
|
72
|
+
])
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Both return PNG bytes, a deterministic JSON-compatible atlas, and details for
|
|
76
|
+
skipped files plus source hashes for provenance. Common non-interlaced PNG color
|
|
77
|
+
modes and bit depths are accepted as inputs; packed output is always RGBA.
|
|
78
|
+
Corrupt and interlaced inputs are skipped with a specific reason. `mountStyle`
|
|
79
|
+
and `mountSprites` provide declared-cell placement when existing atlas
|
|
80
|
+
coordinates must remain stable.
|
|
81
|
+
|
|
82
|
+
The CLI adds a `.pixelkiln.json` companion, stages the three members together,
|
|
83
|
+
restores the previous bundle after ordinary write failures, and leaves
|
|
84
|
+
byte-identical members untouched. Library consumers can apply the same behavior
|
|
85
|
+
with `writeManagedArtifactBundle()`, then use `verifyArtifactBundle()` to detect
|
|
86
|
+
changed sources, outputs, or metadata without rendering again. The managed
|
|
87
|
+
writer adopts pre-companion files only when byte-identical, refuses to replace
|
|
88
|
+
unowned or manually modified output, and accepts `{ force: true }` as an
|
|
89
|
+
explicit takeover. `writeArtifactBundle()` remains the lower-level transactional
|
|
90
|
+
primitive for callers with their own ownership policy.
|
|
91
|
+
|
|
92
|
+
Managed writes also keep a short-lived transaction journal beside the companion.
|
|
93
|
+
The next invocation rolls back an interrupted pre-commit promotion or completes
|
|
94
|
+
post-commit cleanup before checking ownership. Journal recovery is restricted to
|
|
95
|
+
the current bundle's exact destinations and same-directory PixelKiln temp names;
|
|
96
|
+
an unsafe journal or live concurrent writer is refused.
|
|
97
|
+
|
|
98
|
+
## Export generated tiles
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
import { exportTileset } from "pixelkiln"
|
|
102
|
+
|
|
103
|
+
const exported = exportTileset(lockEntry, spec, {
|
|
104
|
+
format: "tiled",
|
|
105
|
+
manifestDir: loaded.root,
|
|
106
|
+
imageName: "terrain.png",
|
|
107
|
+
columns: 8,
|
|
108
|
+
})
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
The generic format preserves the complete provider rule object. Tiled and
|
|
112
|
+
Godot exporters translate supported 4-edge and 4-corner rule sets and reject
|
|
113
|
+
unknown semantics rather than emitting plausible but incorrect adjacency.
|
|
114
|
+
See [TILES.md](./TILES.md) for file contracts and engine details.
|
|
115
|
+
|
|
116
|
+
## Provider integrations
|
|
117
|
+
|
|
118
|
+
`Provider` is the capability boundary. Generation pipelines accept that
|
|
119
|
+
interface rather than importing PixelLab directly; `FakeProvider` implements it
|
|
120
|
+
in memory for deterministic tests.
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
import { FakeProvider, fetchAssets, poll, submit } from "pixelkiln"
|
|
124
|
+
|
|
125
|
+
const provider = new FakeProvider({ candidates: 4 })
|
|
126
|
+
const lockPath = "pixelkiln.lock.json"
|
|
127
|
+
await submit(provider, loaded, plan.actionable, lock, lockPath)
|
|
128
|
+
await poll(provider, lock, lockPath, { specs })
|
|
129
|
+
await fetchAssets(provider, specs, lock, lockPath)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Provider-backed operations mutate the supplied lock object; persist at the
|
|
133
|
+
workflow boundary with `saveLock`. See [PROVIDERS.md](../PROVIDERS.md) before
|
|
134
|
+
implementing another backend, especially its optional capabilities and cost
|
|
135
|
+
units.
|
|
136
|
+
|
|
137
|
+
`submit` validates adapter estimates again at the spending boundary and returns
|
|
138
|
+
`{ spent, unit }` for successful submissions. Lock entries retain fractional
|
|
139
|
+
costs with their unit; use `spendByUnit(lock)` for history. Use
|
|
140
|
+
`measureBalanceChange(before, after)` when the provider exposes authoritative
|
|
141
|
+
balance readings and keep that observed delta distinct from the estimate.
|
|
142
|
+
|
|
143
|
+
## Stability and file paths
|
|
144
|
+
|
|
145
|
+
- Public imports come from `pixelkiln`; internal `src/` paths are not part of
|
|
146
|
+
the package contract.
|
|
147
|
+
- Manifest-relative outputs resolve from `loaded.root`, not the process's
|
|
148
|
+
current working directory.
|
|
149
|
+
- New lock outputs are portable manifest-relative paths. `resolveOutputPath`
|
|
150
|
+
resolves one for file I/O; `normalizeLockOutputPaths` rebases absolute paths
|
|
151
|
+
from earlier v2 locks and marks them for persistence on the next `saveLock`.
|
|
152
|
+
Spec-aware operations derive the current destination from the manifest, so a
|
|
153
|
+
stale lock path cannot redirect a restore.
|
|
154
|
+
- Lock keys use `styleId/assetId`. Structural members use stable output roles
|
|
155
|
+
such as `assetId/tile-03` in audits and atlases.
|
|
156
|
+
- The lockfile is a paid-work record. Use its exported load/save/upsert helpers
|
|
157
|
+
instead of rewriting it piecemeal.
|
package/docs/MANIFEST.md
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# Manifest reference
|
|
2
|
+
|
|
3
|
+
`pixelkiln.manifest.json` is the hand-authored, committed declaration of styles
|
|
4
|
+
and assets. Paths resolve relative to the manifest file, not the current shell
|
|
5
|
+
directory. The canonical machine-readable contract is
|
|
6
|
+
[`schema/manifest.schema.json`](../schema/manifest.schema.json).
|
|
7
|
+
|
|
8
|
+
```jsonc
|
|
9
|
+
{
|
|
10
|
+
"$schema": "./node_modules/pixelkiln/schema/manifest.schema.json",
|
|
11
|
+
"name": "my-game",
|
|
12
|
+
"styles": {
|
|
13
|
+
"base": {
|
|
14
|
+
"generator": "map",
|
|
15
|
+
"promptPrefix": "Pixel-art game prop: ",
|
|
16
|
+
"promptSuffix": ", isolated, transparent background",
|
|
17
|
+
"outDir": "assets/generated/base"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"assets": {
|
|
21
|
+
"anvil": { "prompt": "a compact blacksmith anvil" }
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Unknown properties are rejected at every level.
|
|
27
|
+
|
|
28
|
+
## Top level
|
|
29
|
+
|
|
30
|
+
| Field | Required | Meaning |
|
|
31
|
+
|---|---|---|
|
|
32
|
+
| `$schema` | no | Editor schema URL/path. It does not affect generation identity. |
|
|
33
|
+
| `name` | yes | Project/account tag namespace. |
|
|
34
|
+
| `styles` | yes | Map of style id to inherited generation/output settings. |
|
|
35
|
+
| `assets` | yes | Map of stable asset id to subject and per-asset overrides. |
|
|
36
|
+
|
|
37
|
+
A resolved unit of work is one `styleId/assetId`. Asset ids are stable lookup
|
|
38
|
+
keys, atlas frame ids, and default filenames; changing one is a data migration,
|
|
39
|
+
not merely a label edit.
|
|
40
|
+
|
|
41
|
+
## Style fields
|
|
42
|
+
|
|
43
|
+
| Field | Type/default | Meaning |
|
|
44
|
+
|---|---|---|
|
|
45
|
+
| `generator` | `map` | `map`, `1dir`, `pixflux`, or `tiles`. |
|
|
46
|
+
| `outDir` | string, required | Output directory relative to the manifest. |
|
|
47
|
+
| `promptPrefix` | `""` | Prepended to every participating asset prompt. |
|
|
48
|
+
| `promptSuffix` | `""` | Appended to every participating asset prompt. |
|
|
49
|
+
| `styleImages` | `[]` | `{ "path": "..." }` reference images. Paths are manifest-relative. |
|
|
50
|
+
| `size` | integer 32–256 | Square size for `1dir`; a style reference's dimensions take precedence when present. |
|
|
51
|
+
| `view` | string | Provider-facing view/direction description. |
|
|
52
|
+
| `outline` | string | PixelLab `map` outline setting. |
|
|
53
|
+
| `shading` | string | PixelLab shading setting. |
|
|
54
|
+
| `detail` | string | PixelLab detail setting. |
|
|
55
|
+
| `seed` | integer | Deterministic provider seed where supported. |
|
|
56
|
+
| `palette` | hex array, `[]` | Forced palette for `pixflux`; `#` is optional. |
|
|
57
|
+
| `noBackground` | boolean, `true` | `pixflux` background removal. Set false for scenes/backdrops. |
|
|
58
|
+
| `tileSize` | integer 16–256 | Edge length for `tiles` when no style reference supplies geometry. |
|
|
59
|
+
| `tileType` | enum | `hex`, `hex_pointy`, `isometric`, `oblique`, `octagon`, or `square_topdown`. |
|
|
60
|
+
| `tileView` | enum | `top-down`, `high top-down`, `low top-down`, or `side`. |
|
|
61
|
+
| `tileFeature` | enum | Connectable `roads`, `tileset`, or `building` structural set. |
|
|
62
|
+
| `outlineMode` | enum | `outline` or `segmentation`; segmentation avoids quilted ground seams. |
|
|
63
|
+
| `mount` | object | Stable-cell sheet placement; documented below. |
|
|
64
|
+
| `tags` | string array, `[]` | Tags inherited by every generated provider object in the style. |
|
|
65
|
+
|
|
66
|
+
Generator-specific fields are validated before planning. Important constraints:
|
|
67
|
+
|
|
68
|
+
- `1dir` is square; use style/asset `size` rather than width/height.
|
|
69
|
+
- When `size` and `styleImages` are both present, PixelLab derives size from
|
|
70
|
+
the largest reference image and the declared size is advisory.
|
|
71
|
+
- `map` supports arbitrary asset `width` and `height` but not forced palettes
|
|
72
|
+
or style images.
|
|
73
|
+
- `pixflux` accepts a forced `palette` and returns inline output; it has no
|
|
74
|
+
style-image support.
|
|
75
|
+
- `tiles` cannot combine `tileFeature` with `styleImages` because the provider
|
|
76
|
+
rejects connectable features in style-tile mode.
|
|
77
|
+
|
|
78
|
+
See [generator selection](./GENERATORS.md) for costs and trade-offs.
|
|
79
|
+
|
|
80
|
+
## Asset fields
|
|
81
|
+
|
|
82
|
+
| Field | Type/default | Meaning |
|
|
83
|
+
|---|---|---|
|
|
84
|
+
| `prompt` | string, required | Subject-specific prompt. It may be empty only during existing-art onboarding. |
|
|
85
|
+
| `category` | string | Human grouping metadata. |
|
|
86
|
+
| `width` | integer 16–400 | Per-asset width override for arbitrary-size generators. |
|
|
87
|
+
| `height` | integer 16–400 | Per-asset height override. |
|
|
88
|
+
| `size` | integer 32–256 | Per-asset square size override. |
|
|
89
|
+
| `file` | string | Filename/path override beneath the style output root. |
|
|
90
|
+
| `styles` | string array, `[]` | If non-empty, generate this asset only in the named styles. |
|
|
91
|
+
| `promptByStyle` | object, `{}` | Replace the asset prompt for specific style ids. |
|
|
92
|
+
| `tags` | string array, `[]` | Asset tags combined with style tags. |
|
|
93
|
+
| `cell` | `[column,row]` | Non-negative stable grid cell used by `mount`. |
|
|
94
|
+
| `source` | string | Manifest-relative post-processed/hand-drawn source used by `mount` instead of lock output. |
|
|
95
|
+
| `outputRole` | string | Select one member of a structural output set for mounting. |
|
|
96
|
+
|
|
97
|
+
## Prompt and override resolution
|
|
98
|
+
|
|
99
|
+
For each participating style/asset pair:
|
|
100
|
+
|
|
101
|
+
1. Choose `promptByStyle[styleId]` when present, otherwise `prompt`.
|
|
102
|
+
2. Apply the style prefix and suffix.
|
|
103
|
+
3. Apply generator dimensions and generator-specific settings.
|
|
104
|
+
4. Merge style and asset tags.
|
|
105
|
+
5. Derive a deterministic spec hash from every setting that changes generated
|
|
106
|
+
pixels, including style-image hashes.
|
|
107
|
+
|
|
108
|
+
Project root, output path, and tags are excluded from the pixel identity, so
|
|
109
|
+
moving a checkout or retagging does not buy new art. Prompt, size, palette,
|
|
110
|
+
seed, view, and reference-image bytes do change identity.
|
|
111
|
+
|
|
112
|
+
## Stable-cell mounting
|
|
113
|
+
|
|
114
|
+
```jsonc
|
|
115
|
+
{
|
|
116
|
+
"styles": {
|
|
117
|
+
"ground": {
|
|
118
|
+
"generator": "tiles",
|
|
119
|
+
"outDir": "assets/tiles/src",
|
|
120
|
+
"mount": {
|
|
121
|
+
"base": "assets/tiles/spritesheet.png",
|
|
122
|
+
"cellWidth": 32,
|
|
123
|
+
"cellHeight": 32,
|
|
124
|
+
"out": "assets/tiles/spritesheet.png"
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
"assets": {
|
|
129
|
+
"rough_grass": {
|
|
130
|
+
"prompt": "unmown dark grass",
|
|
131
|
+
"cell": [6, 2],
|
|
132
|
+
"outputRole": "tile-03"
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
`base` is optional; omission starts from transparency. `out` may equal `base`.
|
|
139
|
+
Assets without `cell` are not mounted. Two assets cannot own one cell. A
|
|
140
|
+
sprite larger than its cell is reported and skipped rather than cropped.
|
|
141
|
+
`source` lets a remapped or hand-edited committed file replace generated input
|
|
142
|
+
without losing the declarative placement.
|
|
143
|
+
|
|
144
|
+
## Filenames and output roles
|
|
145
|
+
|
|
146
|
+
The default output is `<outDir>/<category>/<assetId>.png` when `category` is
|
|
147
|
+
set, otherwise `<outDir>/<assetId>.png`; `file` overrides it. Structural sets
|
|
148
|
+
expand one asset into `outputs[]` with stable roles such as `tile-00` and
|
|
149
|
+
filenames such as `terrain-tile-00.png`. Consumers should use roles rather than
|
|
150
|
+
assuming array position. See [tiles](./TILES.md).
|
|
151
|
+
|
|
152
|
+
## Validation and editor setup
|
|
153
|
+
|
|
154
|
+
Regenerate the checked-in schema after changing the Zod manifest types:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
npm run schema
|
|
158
|
+
git diff -- schema/manifest.schema.json
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Run `pixelkiln doctor --dry-run` for local references and project-state checks,
|
|
162
|
+
then `pixelkiln plan` to see the resolved work and cost before spending.
|
package/docs/QUALITY.md
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Quality and automation gates
|
|
2
|
+
|
|
3
|
+
PixelKiln exposes local, deterministic checks separately from paid provider
|
|
4
|
+
work. Run them before generation and in CI.
|
|
5
|
+
|
|
6
|
+
## Plan gate
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
pixelkiln plan
|
|
10
|
+
pixelkiln plan --json --check
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Planning compares resolved specs with lock state and on-disk hashes. It calls no
|
|
14
|
+
provider and reports estimated spend before work starts. `--check` succeeds only
|
|
15
|
+
when every selected entry is current.
|
|
16
|
+
|
|
17
|
+
Plan states include:
|
|
18
|
+
|
|
19
|
+
| State | Meaning |
|
|
20
|
+
|---|---|
|
|
21
|
+
| `ok` | Current spec, lock, and output bytes agree. |
|
|
22
|
+
| `missing` | No satisfying generation is recorded. |
|
|
23
|
+
| `untracked` | Local art exists without known provider provenance. |
|
|
24
|
+
| `stale` | Generation identity changed. |
|
|
25
|
+
| `failed` | Provider generation failed. |
|
|
26
|
+
| `recoverable` | Paid output can be fetched/restored without regeneration. |
|
|
27
|
+
| `in-flight` | Submitted work has not settled. |
|
|
28
|
+
| `orphaned` | Recorded output exists but current bytes differ. |
|
|
29
|
+
|
|
30
|
+
## Doctor gate
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pixelkiln doctor
|
|
34
|
+
pixelkiln doctor --dry-run --json
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Doctor validates schema and references, output authority/writability, lock
|
|
38
|
+
recovery sources, stale jobs, plan state, API-key configuration, and live
|
|
39
|
+
connectivity. `--dry-run` skips only provider connectivity. It changes nothing
|
|
40
|
+
and exits nonzero for unsafe state.
|
|
41
|
+
|
|
42
|
+
## Visual consistency audit
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pixelkiln audit --style neon
|
|
46
|
+
pixelkiln audit --style neon --json --check \
|
|
47
|
+
--max-distance 35 \
|
|
48
|
+
--min-transparency 0.10 \
|
|
49
|
+
--max-colors 128 \
|
|
50
|
+
--sigma 1.5
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Audit measures:
|
|
54
|
+
|
|
55
|
+
- palette distance from style reference images (or the set average when no
|
|
56
|
+
references exist);
|
|
57
|
+
- transparent canvas share;
|
|
58
|
+
- distinct opaque color count;
|
|
59
|
+
- relative palette outliers by standard-deviation cutoff.
|
|
60
|
+
|
|
61
|
+
Missing and unreadable files are always unsafe. Structural output sets are
|
|
62
|
+
measured member-by-member with stable role-qualified ids. Standard
|
|
63
|
+
non-interlaced greyscale, indexed, RGB, greyscale-alpha, and RGBA PNGs are
|
|
64
|
+
normalized to RGBA before measurement.
|
|
65
|
+
|
|
66
|
+
## Cache integrity gate
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
pixelkiln cache --check
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
This validates both local caches, including complete PNG decoding. Add
|
|
73
|
+
`--prune` only in a maintenance workflow because it mutates disposable cache
|
|
74
|
+
state, though it never deletes provider objects or generated destinations.
|
|
75
|
+
|
|
76
|
+
## Recommended CI
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
npm ci
|
|
80
|
+
npm run typecheck
|
|
81
|
+
npm test
|
|
82
|
+
npm run test:docs
|
|
83
|
+
npm run build
|
|
84
|
+
npm run test:package
|
|
85
|
+
npm audit
|
|
86
|
+
|
|
87
|
+
pixelkiln doctor --dry-run
|
|
88
|
+
pixelkiln plan --json --check
|
|
89
|
+
pixelkiln audit --json --check --max-distance 35 --max-colors 128
|
|
90
|
+
pixelkiln cache --check
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Choose audit thresholds per project; do not copy a palette distance or color
|
|
94
|
+
ceiling without checking representative art. The repository's core test suite
|
|
95
|
+
uses `FakeProvider`, so money-spending stages are deterministic and offline.
|
|
96
|
+
|
|
97
|
+
## JSON and exit behavior
|
|
98
|
+
|
|
99
|
+
- JSON contracts are versioned/stable enough for automation where documented.
|
|
100
|
+
- Partial provider pipeline failures and timeouts exit nonzero.
|
|
101
|
+
- `salvage --dry-run --json` reserves stdout for JSON and sends diagnostics to
|
|
102
|
+
stderr.
|
|
103
|
+
- A failed CI job should distinguish provider/output drift from repository test
|
|
104
|
+
failures rather than regenerating automatically.
|
|
105
|
+
|
|
106
|
+
Generation should remain an explicit, budgeted human action; CI is for proving
|
|
107
|
+
that committed declarations, state, and artifacts still agree.
|
package/docs/README.md
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# PixelKiln documentation
|
|
2
|
+
|
|
3
|
+
PixelKiln is a manifest-driven pixel-art pipeline. Start with the workflow
|
|
4
|
+
guide, then use the references for the part of the pipeline you are changing.
|
|
5
|
+
This source also renders at
|
|
6
|
+
[pixelkiln.griffen.codes/docs](https://pixelkiln.griffen.codes/docs).
|
|
7
|
+
|
|
8
|
+
## Start here
|
|
9
|
+
|
|
10
|
+
| Guide | Use it for |
|
|
11
|
+
|---|---|
|
|
12
|
+
| [Getting started](./GETTING_STARTED.md) | Install from a checkout, create or adopt a project, run the everyday workflow, and decide what belongs in Git. |
|
|
13
|
+
| [CLI reference](./CLI.md) | Every command and flag, offline/provider requirements, JSON output, and exit behavior. |
|
|
14
|
+
| [Manifest reference](./MANIFEST.md) | Every style and asset field, inheritance, generator-specific constraints, mounting, and schema validation. |
|
|
15
|
+
| [Agent workflows](./AGENTS.md) | Install the official skill and pair agent guidance with the deterministic CLI. |
|
|
16
|
+
|
|
17
|
+
## Workflows
|
|
18
|
+
|
|
19
|
+
| Guide | Use it for |
|
|
20
|
+
|---|---|
|
|
21
|
+
| [Generators](./GENERATORS.md) | Choose between `map`, `1dir`, `pixflux`, and `tiles`; understand measured costs and capability trade-offs. |
|
|
22
|
+
| [Derived artifacts](./ARTIFACTS.md) | Pack, mount, and export; provenance companions; ownership; force takeover; transactional and crash recovery. |
|
|
23
|
+
| [Recovery and account safety](./RECOVERY.md) | Restore, caches, adopt, salvage, cross-project claims, tagging, and confirmed purge. |
|
|
24
|
+
| [Quality gates](./QUALITY.md) | Plan, doctor, audit, cache checks, JSON contracts, and CI usage. |
|
|
25
|
+
|
|
26
|
+
## Internals and extension
|
|
27
|
+
|
|
28
|
+
| Guide | Use it for |
|
|
29
|
+
|---|---|
|
|
30
|
+
| [Architecture](./ARCHITECTURE.md) | Manifest/lock state, provider boundary, output identity, concurrency, and durable writes. |
|
|
31
|
+
| [Library API](./LIBRARY.md) | Public TypeScript imports for planning, auditing, providers, packing, exporting, and managed artifact writes. |
|
|
32
|
+
| [Tiles and engine exports](./TILES.md) | Structural tile roles, provider rule preservation, generic JSON, Tiled Wang sets, and Godot terrain sets. |
|
|
33
|
+
| [Measured PixelLab endpoints](./ENDPOINTS.md) | Live-account cost and payload research, endpoint recipes, limits, and unresolved API behavior. |
|
|
34
|
+
| [Provider notes](../PROVIDERS.md) | Current provider seam and the next adapter work. |
|
|
35
|
+
|
|
36
|
+
## Project policies
|
|
37
|
+
|
|
38
|
+
- [Contributing](../CONTRIBUTING.md)
|
|
39
|
+
- [Security](../SECURITY.md)
|
|
40
|
+
- [Naming decision](../NAMING.md)
|
|
41
|
+
|
|
42
|
+
The Markdown in this directory is the canonical documentation and ships in the
|
|
43
|
+
npm package. The Next.js app in `website/` renders this source directly into
|
|
44
|
+
the public documentation routes rather than maintaining a second copy.
|
package/docs/RECOVERY.md
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# Recovery and account safety
|
|
2
|
+
|
|
3
|
+
PixelKiln separates local file recovery, account reconciliation, unclaimed-work
|
|
4
|
+
review, and irreversible deletion. A failed download never needs to become a
|
|
5
|
+
new paid generation, and salvage never deletes by implication.
|
|
6
|
+
|
|
7
|
+
## Restore missing output
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pixelkiln restore
|
|
11
|
+
pixelkiln restore --style neon --only anvil
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
`restore` repairs a missing lock output from validated content-cache bytes or
|
|
15
|
+
the provider URL. It does not submit generation and refuses to replace a file
|
|
16
|
+
whose current bytes differ from the recorded hash.
|
|
17
|
+
|
|
18
|
+
Generation and download failures are separate lock states. A CDN failure after
|
|
19
|
+
successful generation becomes `download-failed`; the next `fetch` or `restore`
|
|
20
|
+
retries at zero generation cost.
|
|
21
|
+
|
|
22
|
+
## Local caches
|
|
23
|
+
|
|
24
|
+
Two ignored caches accelerate recovery:
|
|
25
|
+
|
|
26
|
+
- `.pixelkiln/cache/<sha256>.png`: content-addressed generated PNG bytes;
|
|
27
|
+
- `pixelkiln.cache.json`: provider object id → remote image hash.
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pixelkiln cache
|
|
31
|
+
pixelkiln cache --check
|
|
32
|
+
pixelkiln cache --prune
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Cache checks verify filenames/hashes and fully decode PNG chunks, checksums,
|
|
36
|
+
palettes, scanlines, and decompressed size. Pruning removes corrupt/partial and
|
|
37
|
+
unreferenced content plus malformed object-hash entries. Caches are disposable
|
|
38
|
+
and should not be committed.
|
|
39
|
+
|
|
40
|
+
## Adopt existing art
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
pixelkiln init --from assets/sprites --generator map
|
|
44
|
+
pixelkiln adopt --write-prompts
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
`adopt` hashes local files and provider objects, then maps exact matches into
|
|
48
|
+
the lockfile. `--write-prompts` recovers the real upstream prompts. Retouched
|
|
49
|
+
files remain `untracked`: provenance is unknown, but the art is not overwritten
|
|
50
|
+
or automatically scheduled for paid regeneration.
|
|
51
|
+
|
|
52
|
+
The account object-hash cache avoids repeated full downloads. It is pruned for
|
|
53
|
+
deleted remote ids only after `adopt` has seen the provider's complete object
|
|
54
|
+
list.
|
|
55
|
+
|
|
56
|
+
## Salvage unclaimed work
|
|
57
|
+
|
|
58
|
+
An account can contain paid objects that no current project lockfile claims.
|
|
59
|
+
Inventory them before generating replacements:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
pixelkiln salvage --claims ../other-project/pixelkiln.lock.json --dry-run
|
|
63
|
+
pixelkiln salvage --claims ../other-project/pixelkiln.lock.json
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
On shared accounts, supply every other project lockfile with repeatable
|
|
67
|
+
`--claims`. Missing claim files are errors. PixelKiln loads sibling manifests
|
|
68
|
+
where available to recognize another project's style patterns; incomplete
|
|
69
|
+
claims could otherwise make shipped art look unowned.
|
|
70
|
+
|
|
71
|
+
Multi-style manifests group matching objects into one review session per style.
|
|
72
|
+
Unmatched objects are listed separately. `--style` deliberately overrides
|
|
73
|
+
grouping when a human wants to force one destination.
|
|
74
|
+
|
|
75
|
+
Review verdicts:
|
|
76
|
+
|
|
77
|
+
| Verdict | Effect |
|
|
78
|
+
|---|---|
|
|
79
|
+
| import | Download, add a manifest asset and lock entry, and recover its prompt. |
|
|
80
|
+
| keep | Add `pixelkiln:keep` upstream; no local change. |
|
|
81
|
+
| discard | Add `pixelkiln:discard`; does not delete. |
|
|
82
|
+
|
|
83
|
+
`--dry-run --all` lists the full inventory. `--dry-run --json` writes the JSON
|
|
84
|
+
array to stdout and human diagnostics to stderr for piping into `jq`.
|
|
85
|
+
|
|
86
|
+
Imported ids are derived from prompts and land under `_salvaged/`; review and
|
|
87
|
+
rename them before treating them as stable application ids.
|
|
88
|
+
|
|
89
|
+
## Confirmed purge
|
|
90
|
+
|
|
91
|
+
Deletion is a separate command:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
pixelkiln purge --dry-run
|
|
95
|
+
pixelkiln purge
|
|
96
|
+
pixelkiln purge --yes
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Only objects already tagged `pixelkiln:discard` are eligible. The command lists
|
|
100
|
+
targets, asks interactively, and refuses non-interactive deletion without
|
|
101
|
+
`--yes`. A shared account should be fully adopted/salvaged before purge.
|
|
102
|
+
|
|
103
|
+
## Accept intentional spec prose changes
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
pixelkiln accept --style base --only anvil
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
`accept` re-baselines an intact output against the current spec hash when prose
|
|
110
|
+
changed but the existing pixels are intentionally retained. It does not modify
|
|
111
|
+
art and skips missing or hash-mismatched files.
|
|
112
|
+
|
|
113
|
+
## Derived output recovery
|
|
114
|
+
|
|
115
|
+
Pack, mount, and export bundles have a separate ownership and crash-recovery
|
|
116
|
+
system based on `.pixelkiln.json` companions and transaction journals. See
|
|
117
|
+
[derived artifacts](./ARTIFACTS.md).
|
|
118
|
+
|
|
119
|
+
## What to commit
|
|
120
|
+
|
|
121
|
+
Commit manifests, lockfiles, generated art, derived output used by the
|
|
122
|
+
application, and its `.pixelkiln.json` companions. Do not commit credentials,
|
|
123
|
+
`.pixelkiln/`, `pixelkiln.cache.json`, or short-lived transaction/stage/backup
|
|
124
|
+
files.
|