pixelkiln 0.2.0 → 0.3.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/docs/AGENTS.md CHANGED
@@ -28,7 +28,7 @@ With the skill loaded, an agent should:
28
28
  5. Pass an explicit `--budget` within the amount the user authorized.
29
29
  6. Leave artwork selection in the local `pick` page unless the user gives a
30
30
  specific selection rule.
31
- 7. Commit the manifest, lockfile, generated output, and artifact companionsbut
31
+ 7. Commit the manifest, lockfile, generated output, and artifact companions, but
32
32
  never credentials or `.pixelkiln/` caches.
33
33
 
34
34
  The skill guides the workflow; PixelKiln remains the deterministic execution
@@ -41,7 +41,8 @@ are rebased in memory and rewritten portably on the next save. The current
41
41
  manifest remains destination authority; a stale lock path cannot redirect
42
42
  restore into an unrelated project file.
43
43
 
44
- Unlike cost units—`generations`, `usd`, and `free`—are never summed. Candidate
44
+ Cost units that differ are never summed. `generations`, `usd`, and `free`
45
+ stay separate. Candidate
45
46
  count also belongs to the provider estimate rather than being assumed globally.
46
47
 
47
48
  ## State machine
@@ -79,7 +80,8 @@ output or recovery cache data.
79
80
  Lock writes use a same-directory temporary file and rename. An advisory writer
80
81
  lock serializes separate processes. In-process saves queue per path, and
81
82
  field-level dirty patches merge separate snapshots so updates to different
82
- assetsor different fields of one assetdo not silently lose the earlier write.
83
+ assets, or to different fields of one asset, do not silently lose the earlier
84
+ write.
83
85
  Stale advisory locks are recoverable after their safety window.
84
86
 
85
87
  ## Derived artifact transactions
package/docs/CLI.md CHANGED
@@ -141,6 +141,50 @@ Show the provider's remaining balance and cost unit.
141
141
  Summarize lock entries by state and successful submission spend by cost unit.
142
142
  Supports `--json`; unlike units are never added together.
143
143
 
144
+ ### `workspace`
145
+
146
+ Register sibling projects in a schema-versioned catalog file, outside any one
147
+ manifest, so a shared provider account's complete claim set no longer depends
148
+ on remembering every `--claims` path. Offline throughout.
149
+
150
+ ```bash
151
+ pixelkiln workspace add ../other-game/pixelkiln.manifest.json
152
+ pixelkiln workspace add ../another-game/pixelkiln.manifest.json --name another
153
+ pixelkiln workspace list
154
+ pixelkiln workspace status --json
155
+ pixelkiln workspace claims
156
+ pixelkiln workspace remove another
157
+ ```
158
+
159
+ Subcommands:
160
+
161
+ | Subcommand | Effect |
162
+ |---|---|
163
+ | `add <manifest>` | Registers a project. Id defaults to the manifest's `name`; `--name` overrides it. Lock defaults to `pixelkiln.lock.json` beside the manifest; `--lock` overrides it. `--provider` sets the provider id (default `pixellab`); `--account` sets a free-form account label. Refuses a duplicate id or a lockfile already registered under another id. Warns, but does not refuse, when the lock does not exist yet. |
164
+ | `remove <id-or-manifest>` | Drops a registration by project id or by manifest path. Touches no art, no lock, no provider account. |
165
+ | `list` | Lists registered projects and catalog diagnostics. Refuses if the catalog file does not exist. |
166
+ | `status` | Aggregate provider, spend-by-unit, plan state, and claim count, offline. Provider cost units are never summed across each other. Refuses if the catalog file does not exist. |
167
+ | `claims` | Validates the catalog and emits the exact union of `objectId`/`reviewObjectId`/`jobId` across every registered lock. Refuses — rather than silently omitting a project — when any registered lock is missing, unreadable, or the catalog itself has a duplicate id or duplicate lock path. |
168
+
169
+ `--workspace <path>` selects the catalog file; it defaults to
170
+ `pixelkiln.workspace.json` in the current directory. Stored paths are relative
171
+ to the catalog file's own directory, so a catalog survives a clone or move.
172
+ `list`/`status` support `--json` and `--check` (nonzero exit on any error-level
173
+ diagnostic); both treat a nonexistent catalog file as a hard error rather than
174
+ an empty, vacuously-safe one — the same hazard class as an incomplete claim
175
+ set. In `--json` output, the `workspace` key always names the catalog *file*;
176
+ `status` additionally reports `dir`, the catalog's own directory that
177
+ registered paths resolve against.
178
+
179
+ Passing `--workspace <path>` to `salvage` derives its claim set, and its
180
+ sibling-manifest style signal, from every project the catalog registers;
181
+ `--claims` still works and unions with both — the combined lockfile claim set
182
+ and the combined sibling-manifest list. A missing or unreadable registered
183
+ lock is a hard error there too — never silently skipped — because it is
184
+ precisely the account-wide claim completeness this catalog exists to
185
+ guarantee. See
186
+ [Recovery and account safety](./RECOVERY.md#shared-workspace-catalog).
187
+
144
188
  ## Local quality and derived output
145
189
 
146
190
  ### `audit`
@@ -217,6 +261,9 @@ Print the package version. `-v` is an alias.
217
261
  | `--no-open` | pick/salvage | Do not automatically open the browser. |
218
262
  | `--tag` | fetch/adopt | Also push tags after the command's primary work. |
219
263
  | `--claims <paths>` | salvage | Other project lockfiles; repeatable and comma-separated. |
264
+ | `--workspace <path>` | workspace/salvage | Workspace catalog path; defaults to `pixelkiln.workspace.json`. On salvage, derives the claim set instead of repeated `--claims`. |
265
+ | `--provider <id>` | workspace add | Provider id to register the project under; defaults to `pixellab`. |
266
+ | `--account <label>` | workspace add | Free-form account label, e.g. distinguishing sandboxes. |
220
267
  | `--all` | salvage dry run | List every unclaimed object rather than the first 30. |
221
268
  | `--from <dir>` | init | Existing source tree to scan. |
222
269
  | `--exclude <names>` | init | Directory/name fragments to exclude; repeatable. |
package/docs/ENDPOINTS.md CHANGED
@@ -1,4 +1,4 @@
1
- # PixelLab API — measured reference
1
+ # Measured PixelLab API reference
2
2
 
3
3
  Every cost here was **measured against a live Tier 2 account**, not read from
4
4
  documentation. Where a figure came from docs rather than a meter, it says so.
@@ -10,7 +10,7 @@ Auth is one long-term key for everything: `Authorization: Bearer $PIXELLAB_API_K
10
10
 
11
11
  ---
12
12
 
13
- ## The API surface
13
+ ## Endpoint families
14
14
 
15
15
  | Family | Paths | What it covers |
16
16
  |---|---|---|
@@ -27,7 +27,7 @@ listed so it is obvious what exists.
27
27
 
28
28
  ---
29
29
 
30
- ## Single-image generators measured
30
+ ## Single-image generators, measured
31
31
 
32
32
  The endpoints that produce one standalone image. This is the decision that
33
33
  matters most for icon and prop work.
@@ -50,12 +50,12 @@ regardless of size.
50
50
 
51
51
  **`pixflux` is the workhorse.** 1 generation, returns the PNG inline, and its
52
52
  `color_image` parameter is a genuine constraint. A two-colour palette produced
53
- 130 badges containing **only** `#000000` and `#ffffff` verified 65/65 in each
53
+ 130 badges containing **only** `#000000` and `#ffffff`, verified 65/65 in each
54
54
  of two sets. Prose asking for the same thing gave a yellow star and a brown
55
55
  chocolate bar.
56
56
 
57
57
  **`bitforge` disappoints.** It is the only single-image endpoint with palette
58
- *and* style reference *and* synchronous delivery, all for 1 generation which
58
+ *and* style reference *and* synchronous delivery, all for 1 generation, which
59
59
  should make it ideal. In practice it returned unrecognisable blobs for a simple
60
60
  "blacksmith anvil" prompt at `style_strength` 0, 10, 25 and 50. The first
61
61
  failure looked like the style reference overwhelming the prompt; sweeping the
@@ -63,7 +63,7 @@ strength proved otherwise. Possibly tuned for a different kind of subject (docs
63
63
  call it "Create S-M image", max area 200×200). **Do not reach for it on this
64
64
  evidence alone.**
65
65
 
66
- **`pixen` gave the best unconstrained detail** of anything at 1 generation a
66
+ **`pixen` gave the best unconstrained detail** of anything at 1 generation, a
67
67
  properly rendered anvil with sparks where others produced flat shapes. It has no
68
68
  palette parameter, so it suits styles carried entirely by the prompt.
69
69
 
@@ -96,15 +96,15 @@ A palette swatch must also be **chunky**: a 4×1 image was rejected outright wit
96
96
 
97
97
  ---
98
98
 
99
- ## Post-processing utilities measured
99
+ ## Post-processing utilities, measured
100
100
 
101
101
  Five endpoints take an image in and give one back. All are **synchronous**, all
102
- return `{usage, image}` inline, and all cost **1 generation** including the
102
+ return `{usage, image}` inline, and all cost **1 generation**, including the
103
103
  ones that sound like pure image manipulation.
104
104
 
105
105
  | Endpoint | Cost | Palette survives? | What it actually does |
106
106
  |---|---|---|---|
107
- | `remove-background` | 1 | **yes** | Genuine cleanup the only safe one |
107
+ | `remove-background` | 1 | **yes** | Genuine cleanup, the only safe one |
108
108
  | `rotate` | 1 | no | Re-renders from a new angle |
109
109
  | `resize` | 1 | no | **Re-generates**, does not resample |
110
110
  | `image-to-pixelart` | 1 | no | Destroys alpha too |
@@ -115,7 +115,7 @@ Measured on one 64×64 riso badge with an exact 4-colour palette
115
115
 
116
116
  | | colours out | transparency | result |
117
117
  |---|---|---|---|
118
- | source | 4 | 0.57 | |
118
+ | source | 4 | 0.57 | n/a |
119
119
  | `remove-background` | **3** | 0.60 | dropped a stray fringe, kept the rest |
120
120
  | `rotate` | 30 | 0.58 | anti-aliased new angle |
121
121
  | `resize` → 32px | 38 | 0.57 | cream+rust came back **gold** |
@@ -123,7 +123,7 @@ Measured on one 64×64 riso badge with an exact 4-colour palette
123
123
 
124
124
  **`remove-background` is a de-fringe pass, not just a matte.** It removed the
125
125
  scattered sage-green speckles around the badge outline and left the three real
126
- inks untouched colour count went *down*, transparency went *up*. It is the one
126
+ inks untouched. Colour count went *down*, transparency went *up*. It is the one
127
127
  utility safe to run on palette-locked art.
128
128
 
129
129
  **`resize` is generative, not a resampler.** The name is misleading: it takes a
@@ -131,7 +131,7 @@ utility safe to run on palette-locked art.
131
131
  badge came back as 38 colours of gold.
132
132
 
133
133
  **`color_image` does not rescue it.** `resize` accepts the parameter in its
134
- schema; passing the exact same swatch that `pixflux` honours changed nothing
134
+ schema; passing the exact same swatch that `pixflux` honours changed nothing.
135
135
  56 colours, still gold. The forced palette works on **`pixflux` and `bitforge`
136
136
  only**, and being in another endpoint's schema is not evidence it is wired up.
137
137
 
@@ -146,7 +146,7 @@ prevent that.
146
146
 
147
147
  ---
148
148
 
149
- ## Tilesets schema only, not yet measured
149
+ ## Tilesets: schema only, not yet measured
150
150
 
151
151
  Called out separately because these are the most capable endpoints for level art
152
152
  and they are relevant to the disc-golf game. **Costs below are unmeasured.**
@@ -155,17 +155,17 @@ and they are relevant to the disc-golf game. **Costs below are unmeasured.**
155
155
  versions; `/create-tileset*` are the older aliases with identical schemas.
156
156
 
157
157
  They take `lower_description` + `upper_description` (+ optional
158
- `transition_description`) you describe two terrains and the transition between
158
+ `transition_description`). You describe two terrains and the transition between
159
159
  them, and get a tileset that blends them. Distinctively, they accept **both**
160
160
  `color_image` *and* per-layer reference images (`lower_reference_image`,
161
- `upper_reference_image`, `transition_reference_image`) the only family that
162
- combines palette forcing with style anchoring.
161
+ `upper_reference_image`, `transition_reference_image`). They are the only
162
+ family that combines palette forcing with style anchoring.
163
163
 
164
164
  Useful knobs: `tile_size`, `tileset_adherence` / `tileset_adherence_freedom`
165
165
  (how strictly tiles must fit together), `raggedness` and `slope_size` for edge
166
166
  character, plus the usual `outline` / `shading` / `detail`.
167
167
 
168
- `create-tiles-pro` is a different shape a single `description` plus
168
+ `create-tiles-pro` is a different shape, a single `description` plus
169
169
  `style_images`, `tile_view`, `building_*` fields for structures.
170
170
 
171
171
  Its `style_images` is a **fourth** convention, and not the one two lines up:
@@ -178,14 +178,14 @@ Its `style_images` is a **fourth** convention, and not the one two lines up:
178
178
 
179
179
  Sending `generate-with-style-v2`'s nested `{image: {...}}` here is rejected as
180
180
  an extra field. Passing style images at all makes the endpoint ignore
181
- `tile_type` and `tile_view` and copy the reference's tile geometry instead
182
- which is the only way to land new art on an existing sheet's ground plane.
181
+ `tile_type` and `tile_view` and copy the reference's tile geometry instead.
182
+ That is the only way to land new art on an existing sheet's ground plane.
183
183
 
184
184
  `GET /tiles-pro/{id}` carries no `status` field. It answers **423 while the set
185
185
  is still drawing** and 200 with `storage_urls` when it is done, so the HTTP code
186
186
  is the status. Cost is reported at submit time and lands on the same 20/25/40
187
187
  canvas tiers as `1dir`, but the canvas is tile size x variation count, not one
188
- sprite a small tile in a large set still reaches the top tier.
188
+ sprite. A small tile in a large set still reaches the top tier.
189
189
 
190
190
  All response shapes used by the client are validated at runtime. The TypeScript
191
191
  interfaces alone are not trusted at the HTTP boundary: missing ids, invalid
@@ -195,18 +195,19 @@ produce an `Invalid PixelLab response` error before pipeline state is updated.
195
195
  `outline_mode` defaults to `outline`, which draws a dark border around every
196
196
  tile. For ground tiles that is wrong: laid on a grid the borders read as
197
197
  quilting, with a seam at every cell edge. `segmentation` omits them and the
198
- same set tiles seamlessly measured on a fairway-to-rough terrain set, where
198
+ same set tiles seamlessly, measured on a fairway-to-rough terrain set, where
199
199
  it was the difference between usable and unusable.
200
200
 
201
- `tile_feature` and `style_images` are **mutually exclusive** "Connectable
202
- features (roads/tileset/building) cannot be combined with style tiles". So the
201
+ `tile_feature` and `style_images` are **mutually exclusive**. The API says
202
+ "Connectable features (roads/tileset/building) cannot be combined with style
203
+ tiles". So the
203
204
  geometry-anchoring trick above is unavailable for a connectable set, and its
204
205
  tiles land on whatever ground plane the view angle implies (measured: 32x24
205
206
  with the diamond midline at y=7, against a 32x32 sheet wanting y=15).
206
207
 
207
208
  `tile_feature` turns it from independent variations into a connectable set:
208
209
  `roads` (18-configuration path set), `tileset` (16-tile Wang corner set for a
209
- terrain transition describe it as the transition, not one terrain), and
210
+ terrain transition; describe it as the transition, not one terrain), and
210
211
  `building` (floor/wall/doorway kit). These are sliced by index, so the returned
211
212
  order is load-bearing. They are structural multi-output results, not candidates
212
213
  to choose between: PixelKiln persists every URL in numeric order and labels the
@@ -230,12 +231,12 @@ committing to a set**.
230
231
  ## Recipes
231
232
 
232
233
  **Lock a palette.** Use `pixflux` with a `color_image` swatch. Build the swatch
233
- with `paletteSwatch()` 64×64 blocks, one band per colour. It is a real
234
+ with `paletteSwatch()`: 64×64 blocks, one band per colour. It is a real
234
235
  constraint, not a hint: 130 badges across two sets came back containing *only*
235
236
  the requested colours.
236
237
 
237
238
  **Re-roll one bad asset.** 1 generation. `gen --only <id> --force`. Cheaper than
238
- asking for more candidates a `1dir` call that yields 16 candidates costs 20–40.
239
+ asking for more candidates. A `1dir` call that yields 16 candidates costs 20–40.
239
240
 
240
241
  **Clean up fringing.** `remove-background` at 1 generation, and it will not
241
242
  disturb the palette.
@@ -245,7 +246,7 @@ size. Do not use `resize`.
245
246
 
246
247
  **Anchor to an existing look rather than a palette.** `generate-with-style-v2`
247
248
  (20) or `generate-image-v2` (40). `bitforge` claims to do this for 1, but see
248
- above. `map` has no style anchoring at all a 1-bit set generated through it
249
+ above. `map` has no style anchoring at all. A 1-bit set generated through it
249
250
  came back with a yellow star and a brown chocolate bar.
250
251
 
251
252
  **Write prompts for a monochrome style.** Strip colour words from the prompt
@@ -263,7 +264,7 @@ whole set. Put the medium in the *suffix*, after the subject.
263
264
  ## Candidates
264
265
 
265
266
  Only `create-1-direction-object` returns multiple candidates, and the count is
266
- derived from size it cannot be requested:
267
+ derived from size, and cannot be requested:
267
268
 
268
269
  | size | candidates |
269
270
  |---|---|
@@ -285,8 +286,8 @@ once a 1-generation re-roll exists: forty re-rolls cost one `1dir` call.
285
286
  **image survives**: a March 2026 sprite still resolved from `/v2/objects` four
286
287
  months on while `/v2/map-objects/{id}` returned 404. pixelkiln's `poll` checks
287
288
  the objects collection on a 404 rather than writing the work off.
288
- - `pixflux`/`pixen`/`bitforge` results are **not account objects** at all
289
- bytes come back inline and are never listed. `adopt` and `salvage` cannot see
289
+ - `pixflux`/`pixen`/`bitforge` results are **not account objects** at all.
290
+ Bytes come back inline and are never listed. `adopt` and `salvage` cannot see
290
291
  them, and they cannot be tagged.
291
292
 
292
293
  ---
@@ -309,15 +310,15 @@ once a 1-generation re-roll exists: forty re-rolls cost one `1dir` call.
309
310
 
310
311
  Listed so the gaps are known rather than assumed away:
311
312
 
312
- - `inpaint`, `inpaint-v3`, `edit-image`, `edit-images-v2` targeted edits.
313
+ - `inpaint`, `inpaint-v3`, `edit-image`, `edit-images-v2`, for targeted edits.
313
314
  Both `inpaint` and `edit-image` accept `color_image`, but given that `resize`
314
315
  accepts and ignores it, assume nothing until measured.
315
- - `image-to-pixelart-pro` takes only `image` + `description`, no size fields.
316
+ - `image-to-pixelart-pro` takes only `image` + `description`, no size fields.
316
317
  The non-Pro version is characterised above.
317
- - the tileset family schema documented above, costs unmeasured
318
- - `create-isometric-tile`, `create-ui-asset`, `generate-font-pro` job-based,
319
- response shapes not in the simple `{usage, image}` form
320
- - the character family (23 paths) out of pixelkiln's scope by design
318
+ - the tileset family, with schema documented above and costs unmeasured
319
+ - `create-isometric-tile`, `create-ui-asset`, `generate-font-pro`, all job-based,
320
+ with response shapes not in the simple `{usage, image}` form
321
+ - the character family (23 paths), out of pixelkiln's scope by design
321
322
 
322
323
  ---
323
324
 
@@ -328,7 +329,7 @@ curl -s -H "Authorization: Bearer $PIXELLAB_API_KEY" \
328
329
  https://api.pixellab.ai/v2/balance
329
330
  ```
330
331
 
331
- The count lives at **`subscription.generations`**, not at the top level — a
332
+ The count lives at **`subscription.generations`**, not at the top level. A
332
333
  probe reading `.generations` gets `undefined` and silently reports every cost as
333
334
  `NaN` rather than failing:
334
335
 
@@ -340,5 +341,5 @@ probe reading `.generations` gets `undefined` and silently reports every cost as
340
341
  ```
341
342
 
342
343
  Take a balance reading, make one call, wait a few seconds, read again. Prefer
343
- the response's `usage` field where present it is inline, exact, and immune to
344
+ the response's `usage` field where present. It is inline, exact, and immune to
344
345
  the billing lag.
@@ -114,7 +114,7 @@ instead creates a structural set in provider order:
114
114
  | `tileset` | 16-tile Wang-corner terrain transition. |
115
115
  | `building` | Floor/wall/doorway/pillar/stair construction kit. |
116
116
 
117
- Describe a `tileset` asset as the transition—“fairway grass to rough meadow”—
117
+ Describe a `tileset` asset as the transition, "fairway grass to rough meadow",
118
118
  rather than one terrain. Every returned member is required, so PixelKiln
119
119
  records numerical roles such as `tile-00` rather than treating them as choices.
120
120
 
package/docs/RECOVERY.md CHANGED
@@ -86,6 +86,50 @@ array to stdout and human diagnostics to stderr for piping into `jq`.
86
86
  Imported ids are derived from prompts and land under `_salvaged/`; review and
87
87
  rename them before treating them as stable application ids.
88
88
 
89
+ ## Shared workspace catalog
90
+
91
+ For a single project, its own lockfile is the whole claim set. On a shared
92
+ account with several sibling projects, repeating `--claims` on every salvage
93
+ run is easy to get wrong — a forgotten lockfile makes another project's paid
94
+ art look unclaimed. `workspace` fixes that by registering every sibling once,
95
+ outside any one manifest:
96
+
97
+ ```bash
98
+ pixelkiln workspace add ../other-game/pixelkiln.manifest.json
99
+ pixelkiln workspace add ../another-game/pixelkiln.manifest.json --name another
100
+ pixelkiln workspace status
101
+ pixelkiln workspace claims
102
+ ```
103
+
104
+ `workspace status` reports aggregate provider, spend-by-unit, and plan state
105
+ per project, offline. `workspace claims` validates the catalog and emits the
106
+ exact union of `objectId`/`reviewObjectId`/`jobId` across every registered
107
+ lock — the same union rule `--claims` uses, so the two paths cannot drift.
108
+
109
+ A registered lockfile that is missing or unreadable is a hard error for
110
+ `claims`, never a silent skip: an incomplete claim set is precisely what makes
111
+ another project's shipped art look orphaned. `workspace add` still lets you
112
+ register a brand-new project before its first `gen` — it warns rather than
113
+ refusing, since the project genuinely has no lock yet — but `claims` and
114
+ `salvage --workspace` both refuse until every registered project has one.
115
+
116
+ Salvage accepts the catalog directly instead of a repeated `--claims` list:
117
+
118
+ ```bash
119
+ pixelkiln salvage --workspace pixelkiln.workspace.json --dry-run
120
+ pixelkiln salvage --workspace pixelkiln.workspace.json
121
+ ```
122
+
123
+ `--claims` still works and unions with a workspace's claim set — useful for a
124
+ one-off lockfile that isn't part of the catalog. Choose one workflow per
125
+ account: `--claims` for an occasional cross-project check, `workspace` once
126
+ sibling projects are a standing arrangement worth registering once.
127
+
128
+ The catalog stores paths and project identity, never a credential — each
129
+ project still loads its own provider key from its own `.env`. `workspace
130
+ remove` only edits the catalog file; it never touches art, a lock, or the
131
+ provider account.
132
+
89
133
  ## Confirmed purge
90
134
 
91
135
  Deletion is a separate command:
package/docs/TILES.md CHANGED
@@ -53,7 +53,7 @@ The companion record is engine-neutral: it stores portable source paths and
53
53
  SHA-256s, export options (including raw provider rules), output hashes, and a
54
54
  canonical fingerprint. `verifyArtifactBundle()` can detect changed inputs,
55
55
  edited/missing outputs, or altered provenance offline without rebuilding the
56
- atlas. The project manifest and lockfile are conservative inputs, ensuring that
56
+ atlas. The project manifest and lockfile are conservative inputs, so
57
57
  newly declared or recorded tiles also make an older export stale. The TSJ/TRES
58
58
  contracts therefore remain free of PixelKiln-only fields.
59
59
 
@@ -22,5 +22,5 @@ Add a second entry under `styles` with a different `outDir`, then:
22
22
  pixelkiln gen --style neon
23
23
  ```
24
24
 
25
- Every asset re-derives under the new style. The original files are untouched
26
- styles are separate namespaces in both the output tree and the lockfile.
25
+ Every asset re-derives under the new style. The original files are untouched.
26
+ Styles are separate namespaces in both the output tree and the lockfile.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pixelkiln",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Manifest-driven pixel-art generation, review, recovery, and packaging with deterministic provenance.",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -0,0 +1,54 @@
1
+ {
2
+ "$ref": "#/definitions/PixelkilnWorkspace",
3
+ "definitions": {
4
+ "PixelkilnWorkspace": {
5
+ "type": "object",
6
+ "properties": {
7
+ "version": {
8
+ "type": "number",
9
+ "const": 1
10
+ },
11
+ "projects": {
12
+ "type": "array",
13
+ "items": {
14
+ "type": "object",
15
+ "properties": {
16
+ "id": {
17
+ "type": "string",
18
+ "minLength": 1
19
+ },
20
+ "manifest": {
21
+ "type": "string",
22
+ "minLength": 1
23
+ },
24
+ "lock": {
25
+ "type": "string",
26
+ "minLength": 1
27
+ },
28
+ "provider": {
29
+ "type": "string",
30
+ "minLength": 1,
31
+ "default": "pixellab"
32
+ },
33
+ "account": {
34
+ "type": "string"
35
+ }
36
+ },
37
+ "required": [
38
+ "id",
39
+ "manifest",
40
+ "lock"
41
+ ],
42
+ "additionalProperties": false
43
+ },
44
+ "default": []
45
+ }
46
+ },
47
+ "required": [
48
+ "version"
49
+ ],
50
+ "additionalProperties": false
51
+ }
52
+ },
53
+ "$schema": "http://json-schema.org/draft-07/schema#"
54
+ }