pixelkiln 0.19.0 → 0.20.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/README.md +4 -3
- package/dist/cli.js +93 -6
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +99 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1855 -157
- package/dist/index.d.ts +1855 -157
- package/dist/index.js +96 -6
- package/dist/index.js.map +1 -1
- package/docs/ARCHITECTURE.md +14 -8
- package/docs/GETTING_STARTED.md +5 -0
- package/docs/LIBRARY.md +5 -0
- package/docs/MANIFEST.md +52 -0
- package/package.json +1 -1
- package/schema/manifest.schema.json +395 -176
- package/skills/pixelkiln/SKILL.md +3 -0
package/README.md
CHANGED
|
@@ -183,9 +183,10 @@ packaging layer.
|
|
|
183
183
|
}
|
|
184
184
|
```
|
|
185
185
|
|
|
186
|
-
Styles are namespaces.
|
|
187
|
-
|
|
188
|
-
|
|
186
|
+
Styles are namespaces. A variant can `extend` a base style while keeping its own
|
|
187
|
+
output directory, so later parent fixes reach every child without copied config.
|
|
188
|
+
Each style re-derives the same asset ids into separate lock keys. Generator
|
|
189
|
+
choice, reference-image bytes, dimensions, palette, seed, and
|
|
189
190
|
prompt settings participate in deterministic spec identity. A manifest may
|
|
190
191
|
select another provider and pass namespaced `providerOptions`; see
|
|
191
192
|
[Set up PixelLab](./docs/PIXELLAB.md),
|
package/dist/cli.js
CHANGED
|
@@ -1836,7 +1836,7 @@ var StyleImageSchema = z2.object({
|
|
|
1836
1836
|
path: z2.string()
|
|
1837
1837
|
});
|
|
1838
1838
|
var HexColorSchema = z2.string().regex(/^#?[0-9a-f]{6}$/i, "expected a six-digit hex colour");
|
|
1839
|
-
var
|
|
1839
|
+
var QualityProfileObjectSchema = z2.object({
|
|
1840
1840
|
/** Output root for approved refined art, relative to the manifest. */
|
|
1841
1841
|
outDir: z2.string().min(1),
|
|
1842
1842
|
/** Closed final palette applied after native-grid recovery, without dithering. */
|
|
@@ -1851,7 +1851,8 @@ var QualityProfileSchema = z2.object({
|
|
|
1851
1851
|
fixerPython: z2.string().min(1).optional(),
|
|
1852
1852
|
/** Playback rate recorded for an ordered frame set. */
|
|
1853
1853
|
fps: z2.number().int().min(1).max(60).optional()
|
|
1854
|
-
}).strict()
|
|
1854
|
+
}).strict();
|
|
1855
|
+
var QualityProfileSchema = QualityProfileObjectSchema.refine(
|
|
1855
1856
|
(profile) => new Set(profile.palette.map((color) => color.replace(/^#/, "").toLowerCase())).size === profile.palette.length,
|
|
1856
1857
|
{ message: "quality palette colors must be unique", path: ["palette"] }
|
|
1857
1858
|
);
|
|
@@ -1880,7 +1881,7 @@ var RevisionSchema = z2.object({
|
|
|
1880
1881
|
});
|
|
1881
1882
|
}
|
|
1882
1883
|
});
|
|
1883
|
-
var
|
|
1884
|
+
var StyleObjectSchema = z2.object({
|
|
1884
1885
|
/** Generation backend for this style. Omit to inherit the manifest default. */
|
|
1885
1886
|
provider: z2.string().min(1).optional(),
|
|
1886
1887
|
// `map` is the default because it is 20-40x cheaper and correct for any
|
|
@@ -1995,7 +1996,8 @@ var StyleSchema = z2.object({
|
|
|
1995
1996
|
tags: z2.array(z2.string()).default([]),
|
|
1996
1997
|
/** Adapter-owned settings, keyed by provider id. */
|
|
1997
1998
|
providerOptions: z2.record(z2.record(z2.unknown())).default({})
|
|
1998
|
-
}).strict()
|
|
1999
|
+
}).strict();
|
|
2000
|
+
var StyleSchema = StyleObjectSchema.refine((s) => !(s.tileFeature && s.styleImages.length), {
|
|
1999
2001
|
message: "tileFeature and styleImages cannot be combined \u2014 a connectable set derives its own tile geometry, so remove one or the other",
|
|
2000
2002
|
path: ["tileFeature"]
|
|
2001
2003
|
}).superRefine((style, ctx) => {
|
|
@@ -2007,6 +2009,14 @@ var StyleSchema = z2.object({
|
|
|
2007
2009
|
});
|
|
2008
2010
|
}
|
|
2009
2011
|
});
|
|
2012
|
+
var InheritedStyleSchema = StyleObjectSchema.partial().extend({
|
|
2013
|
+
extends: z2.string().min(1),
|
|
2014
|
+
/** Children own their destination; sharing a parent's output is never implicit. */
|
|
2015
|
+
outDir: z2.string(),
|
|
2016
|
+
/** A child may override only part of the inherited final-art policy. */
|
|
2017
|
+
quality: QualityProfileObjectSchema.partial().optional()
|
|
2018
|
+
}).strict();
|
|
2019
|
+
var StyleInputSchema = z2.union([StyleSchema, InheritedStyleSchema]);
|
|
2010
2020
|
var AssetSchema = z2.object({
|
|
2011
2021
|
/** The subject. Style wrapping comes from the style's prefix/suffix. */
|
|
2012
2022
|
prompt: z2.string(),
|
|
@@ -2095,6 +2105,13 @@ var ManifestSchema = z2.object({
|
|
|
2095
2105
|
styles: z2.record(StyleSchema),
|
|
2096
2106
|
assets: z2.record(AssetSchema)
|
|
2097
2107
|
}).strict();
|
|
2108
|
+
var ManifestInputSchema = z2.object({
|
|
2109
|
+
$schema: z2.string().optional(),
|
|
2110
|
+
name: z2.string(),
|
|
2111
|
+
provider: z2.string().min(1).default("pixellab"),
|
|
2112
|
+
styles: z2.record(StyleInputSchema),
|
|
2113
|
+
assets: z2.record(AssetSchema)
|
|
2114
|
+
}).strict();
|
|
2098
2115
|
var LockEntrySchema = z2.object({
|
|
2099
2116
|
styleId: z2.string(),
|
|
2100
2117
|
assetId: z2.string(),
|
|
@@ -3670,9 +3687,24 @@ function resolveSpecOutputs(spec, lock, manifestDir) {
|
|
|
3670
3687
|
async function loadManifest(manifestPath) {
|
|
3671
3688
|
const abs = path6.resolve(manifestPath);
|
|
3672
3689
|
if (!existsSync4(abs)) throw new Error(`No manifest at ${abs}`);
|
|
3673
|
-
const
|
|
3690
|
+
const input = ManifestInputSchema.safeParse(JSON.parse(await readFile3(abs, "utf8")));
|
|
3691
|
+
if (!input.success) {
|
|
3692
|
+
const issues = formatManifestIssues(input.error.issues);
|
|
3693
|
+
throw new Error(`Manifest at ${abs} is invalid:
|
|
3694
|
+
${issues}`);
|
|
3695
|
+
}
|
|
3696
|
+
let styles;
|
|
3697
|
+
try {
|
|
3698
|
+
styles = resolveStyleInheritance(input.data.styles);
|
|
3699
|
+
} catch (error) {
|
|
3700
|
+
throw new Error(
|
|
3701
|
+
`Manifest at ${abs} is invalid:
|
|
3702
|
+
${error instanceof Error ? error.message : String(error)}`
|
|
3703
|
+
);
|
|
3704
|
+
}
|
|
3705
|
+
const parsed = ManifestSchema.safeParse({ ...input.data, styles });
|
|
3674
3706
|
if (!parsed.success) {
|
|
3675
|
-
const issues = parsed.error.issues
|
|
3707
|
+
const issues = formatManifestIssues(parsed.error.issues);
|
|
3676
3708
|
throw new Error(`Manifest at ${abs} is invalid:
|
|
3677
3709
|
${issues}`);
|
|
3678
3710
|
}
|
|
@@ -3723,6 +3755,61 @@ ${unknownReferences.map((i) => ` ${i}`).join("\n")}`);
|
|
|
3723
3755
|
}
|
|
3724
3756
|
return { manifest: parsed.data, root: path6.dirname(abs), path: abs };
|
|
3725
3757
|
}
|
|
3758
|
+
function formatManifestIssues(issues) {
|
|
3759
|
+
return issues.flatMap((issue) => {
|
|
3760
|
+
if (issue.code === "invalid_union") {
|
|
3761
|
+
return issue.unionErrors.flatMap((error) => formatManifestIssues(error.issues).split("\n"));
|
|
3762
|
+
}
|
|
3763
|
+
return [` ${issue.path.join(".")}: ${issue.message}`];
|
|
3764
|
+
}).join("\n");
|
|
3765
|
+
}
|
|
3766
|
+
function resolveStyleInheritance(styles) {
|
|
3767
|
+
const resolved = /* @__PURE__ */ new Map();
|
|
3768
|
+
const visit = (styleId, chain) => {
|
|
3769
|
+
const cached = resolved.get(styleId);
|
|
3770
|
+
if (cached) return cached;
|
|
3771
|
+
const cycleStart = chain.indexOf(styleId);
|
|
3772
|
+
if (cycleStart >= 0) {
|
|
3773
|
+
throw new Error(
|
|
3774
|
+
`styles.${styleId}.extends: inheritance cycle ${[...chain.slice(cycleStart), styleId].join(" -> ")}`
|
|
3775
|
+
);
|
|
3776
|
+
}
|
|
3777
|
+
const style = styles[styleId];
|
|
3778
|
+
if (!style) throw new Error(`styles.${styleId}: unknown style`);
|
|
3779
|
+
if (!("extends" in style)) {
|
|
3780
|
+
resolved.set(styleId, style);
|
|
3781
|
+
return style;
|
|
3782
|
+
}
|
|
3783
|
+
const parentId = style.extends;
|
|
3784
|
+
if (!Object.hasOwn(styles, parentId)) {
|
|
3785
|
+
throw new Error(`styles.${styleId}.extends: unknown style "${parentId}"`);
|
|
3786
|
+
}
|
|
3787
|
+
const parent = visit(parentId, [...chain, styleId]);
|
|
3788
|
+
const { extends: _parent, ...child } = style;
|
|
3789
|
+
const merged = {
|
|
3790
|
+
...parent,
|
|
3791
|
+
...child,
|
|
3792
|
+
quality: child.quality == null ? parent.quality : { ...parent.quality ?? {}, ...child.quality },
|
|
3793
|
+
providerOptions: mergeProviderOptions(parent.providerOptions, child.providerOptions)
|
|
3794
|
+
};
|
|
3795
|
+
const parsed = StyleSchema.safeParse(merged);
|
|
3796
|
+
if (!parsed.success) {
|
|
3797
|
+
const issues = parsed.error.issues.map((issue) => `styles.${styleId}.${issue.path.join(".")}: ${issue.message}`).join("; ");
|
|
3798
|
+
throw new Error(issues);
|
|
3799
|
+
}
|
|
3800
|
+
resolved.set(styleId, parsed.data);
|
|
3801
|
+
return parsed.data;
|
|
3802
|
+
};
|
|
3803
|
+
return Object.fromEntries(Object.keys(styles).map((styleId) => [styleId, visit(styleId, [])]));
|
|
3804
|
+
}
|
|
3805
|
+
function mergeProviderOptions(parent, child) {
|
|
3806
|
+
if (!child) return parent;
|
|
3807
|
+
const merged = { ...parent };
|
|
3808
|
+
for (const [provider, options] of Object.entries(child)) {
|
|
3809
|
+
merged[provider] = { ...parent[provider] ?? {}, ...options };
|
|
3810
|
+
}
|
|
3811
|
+
return merged;
|
|
3812
|
+
}
|
|
3726
3813
|
async function resolveSpecs(loaded, filter) {
|
|
3727
3814
|
const { manifest, root } = loaded;
|
|
3728
3815
|
const providerOverride = filter?.provider;
|