pixelkiln 0.89.1 → 0.89.2
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/dist/cli.js +61 -2
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +65 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +459 -1
- package/dist/index.d.ts +459 -1
- package/dist/index.js +63 -2
- package/dist/index.js.map +1 -1
- package/docs/ARCHITECTURE.md +8 -0
- package/docs/MANIFEST.md +1 -1
- package/package.json +1 -1
- package/skills/pixelkiln/references/pixellab-roadmap.md +10 -5
- package/skills/pixelkiln/references/pixellab.md +10 -0
package/dist/cli.js
CHANGED
|
@@ -772,8 +772,9 @@ function specHash(spec, styleImageHashes, providerOptionIdentity = spec.provider
|
|
|
772
772
|
uiColorPalette: spec.uiColorPalette,
|
|
773
773
|
// The older terrain knobs (terrainMode, terrainTransitionSize, and the
|
|
774
774
|
// rest) were never part of this hash, and adding them now would make
|
|
775
|
-
// every existing terrain entry stale
|
|
776
|
-
//
|
|
775
|
+
// every existing terrain entry stale; terrainSettings below records
|
|
776
|
+
// them per entry instead. The Pro shape controls added after them are
|
|
777
|
+
// identity, each only when set.
|
|
777
778
|
terrainRoundness: spec.terrainRoundness,
|
|
778
779
|
terrainBoundaryAmplitude: spec.terrainBoundaryAmplitude,
|
|
779
780
|
terrainBoundarySeed: spec.terrainBoundarySeed,
|
|
@@ -899,6 +900,22 @@ function specHash(spec, styleImageHashes, providerOptionIdentity = spec.provider
|
|
|
899
900
|
})
|
|
900
901
|
);
|
|
901
902
|
}
|
|
903
|
+
function terrainSettings(spec) {
|
|
904
|
+
if (spec.generator !== "terrain") return void 0;
|
|
905
|
+
const settings = {
|
|
906
|
+
terrainMode: spec.terrainMode,
|
|
907
|
+
terrainShapeStyle: spec.terrainShapeStyle,
|
|
908
|
+
terrainSpreadX: spec.terrainSpreadX,
|
|
909
|
+
terrainSlopeSize: spec.terrainSlopeSize,
|
|
910
|
+
terrainRaggedness: spec.terrainRaggedness,
|
|
911
|
+
terrainTransitionSize: spec.terrainTransitionSize,
|
|
912
|
+
terrainView: spec.terrainView,
|
|
913
|
+
terrainLowerDescription: spec.terrainLowerDescription,
|
|
914
|
+
terrainUpperDescription: spec.terrainUpperDescription,
|
|
915
|
+
terrainTransitionDescription: spec.terrainTransitionDescription
|
|
916
|
+
};
|
|
917
|
+
return Object.fromEntries(Object.entries(settings).filter(([, value]) => value !== void 0));
|
|
918
|
+
}
|
|
902
919
|
|
|
903
920
|
// src/pipeline/mirror.ts
|
|
904
921
|
import { mkdir as mkdir2, readFile as readFile2, rename as rename2, writeFile as writeFile2 } from "fs/promises";
|
|
@@ -2224,6 +2241,18 @@ var LockTerrainConnectSchema = z.record(
|
|
|
2224
2241
|
TerrainSideSchema,
|
|
2225
2242
|
z.object({ sourceAssetId: z.string().min(1), sourceObjectId: z.string().min(1) }).strict()
|
|
2226
2243
|
);
|
|
2244
|
+
var LockTerrainSettingsSchema = z.object({
|
|
2245
|
+
terrainMode: z.string().optional(),
|
|
2246
|
+
terrainShapeStyle: z.string().optional(),
|
|
2247
|
+
terrainSpreadX: z.number().optional(),
|
|
2248
|
+
terrainSlopeSize: z.number().optional(),
|
|
2249
|
+
terrainRaggedness: z.number().optional(),
|
|
2250
|
+
terrainTransitionSize: z.number().optional(),
|
|
2251
|
+
terrainView: z.string().optional(),
|
|
2252
|
+
terrainLowerDescription: z.string().optional(),
|
|
2253
|
+
terrainUpperDescription: z.string().optional(),
|
|
2254
|
+
terrainTransitionDescription: z.string().optional()
|
|
2255
|
+
});
|
|
2227
2256
|
var LockHistoryEntrySchema = z.object({
|
|
2228
2257
|
specHash: z.string(),
|
|
2229
2258
|
generator: GeneratorSchema,
|
|
@@ -2248,6 +2277,8 @@ var LockHistoryEntrySchema = z.object({
|
|
|
2248
2277
|
postprocess: PostprocessSchema.optional(),
|
|
2249
2278
|
/** A connected terrain set's other sets; see LockEntrySchema.terrainConnect. */
|
|
2250
2279
|
terrainConnect: LockTerrainConnectSchema.optional(),
|
|
2280
|
+
/** A terrain set's settings outside specHash; see LockEntrySchema.terrainSettings. */
|
|
2281
|
+
terrainSettings: LockTerrainSettingsSchema.optional(),
|
|
2251
2282
|
/** When the replacement was submitted. */
|
|
2252
2283
|
retiredAt: z.string()
|
|
2253
2284
|
});
|
|
@@ -2322,6 +2353,14 @@ var LockEntrySchema = z.object({
|
|
|
2322
2353
|
* Absent (not null) otherwise, so other entries do not grow the key.
|
|
2323
2354
|
*/
|
|
2324
2355
|
terrainConnect: LockTerrainConnectSchema.optional(),
|
|
2356
|
+
/**
|
|
2357
|
+
* For a terrain set: the settings it was submitted with that `specHash`
|
|
2358
|
+
* leaves out (see LockTerrainSettingsSchema). The plan marks the entry
|
|
2359
|
+
* stale when the manifest's differ. Absent on entries submitted before
|
|
2360
|
+
* it was recorded, which are taken as current, and on every other
|
|
2361
|
+
* generator's entries.
|
|
2362
|
+
*/
|
|
2363
|
+
terrainSettings: LockTerrainSettingsSchema.optional(),
|
|
2325
2364
|
/**
|
|
2326
2365
|
* Output hashes owned by the previous generation while its replacement is
|
|
2327
2366
|
* pending. They authorize replacing only unchanged PixelKiln-owned files.
|
|
@@ -4905,6 +4944,15 @@ function changedTerrainConnection(spec, entry, lock) {
|
|
|
4905
4944
|
}
|
|
4906
4945
|
return null;
|
|
4907
4946
|
}
|
|
4947
|
+
function changedTerrainSettings(spec, entry) {
|
|
4948
|
+
const recorded = entry.terrainSettings;
|
|
4949
|
+
const current = terrainSettings(spec);
|
|
4950
|
+
if (!recorded || !current) return null;
|
|
4951
|
+
const show = (value) => value === void 0 ? "unset" : JSON.stringify(value);
|
|
4952
|
+
const fields = /* @__PURE__ */ new Set([...Object.keys(recorded), ...Object.keys(current)]);
|
|
4953
|
+
const changes = [...fields].filter((field) => recorded[field] !== current[field]).map((field) => `${field} changed from ${show(recorded[field])} to ${show(current[field])}`);
|
|
4954
|
+
return changes.length ? changes.join("; ") : null;
|
|
4955
|
+
}
|
|
4908
4956
|
function resumeCommandForStatus(status) {
|
|
4909
4957
|
if (status === "pending" || status === "processing") return "poll";
|
|
4910
4958
|
if (status === "review") return "pick";
|
|
@@ -4937,6 +4985,7 @@ async function buildPlan(specs, lock, opts = {}) {
|
|
|
4937
4985
|
let state;
|
|
4938
4986
|
let reason;
|
|
4939
4987
|
const changedConnection = entry ? changedTerrainConnection(spec, entry, lock) : null;
|
|
4988
|
+
const changedSettings = entry ? changedTerrainSettings(spec, entry) : null;
|
|
4940
4989
|
const revision = await inspectRevisionReadiness(spec, lock);
|
|
4941
4990
|
if (revision && !revision.ready) {
|
|
4942
4991
|
state = "blocked";
|
|
@@ -4975,6 +5024,9 @@ async function buildPlan(specs, lock, opts = {}) {
|
|
|
4975
5024
|
} else if (changedConnection) {
|
|
4976
5025
|
state = "stale";
|
|
4977
5026
|
reason = `connected set ${changedConnection} was regenerated; draw this set from its new terrain`;
|
|
5027
|
+
} else if (changedSettings) {
|
|
5028
|
+
state = "stale";
|
|
5029
|
+
reason = changedSettings;
|
|
4978
5030
|
} else if (entry.status === "download-failed") {
|
|
4979
5031
|
state = "recoverable";
|
|
4980
5032
|
const force = entry.error?.includes("pass --force") ? " --force" : "";
|
|
@@ -17394,6 +17446,7 @@ function retireGeneration(entry, retiredAt) {
|
|
|
17394
17446
|
provider: entry.provider,
|
|
17395
17447
|
postprocess: entry.postprocess,
|
|
17396
17448
|
...entry.terrainConnect ? { terrainConnect: entry.terrainConnect } : {},
|
|
17449
|
+
...entry.terrainSettings ? { terrainSettings: entry.terrainSettings } : {},
|
|
17397
17450
|
retiredAt
|
|
17398
17451
|
};
|
|
17399
17452
|
}
|
|
@@ -17488,6 +17541,9 @@ async function revertGeneration(provider, spec, lock, lockPath, opts) {
|
|
|
17488
17541
|
// A connected set comes back with the connection it was drawn from, so
|
|
17489
17542
|
// the plan compares the restored generation, not the one it replaced.
|
|
17490
17543
|
terrainConnect: generation.terrainConnect,
|
|
17544
|
+
// Likewise its settings; a generation from before they were recorded
|
|
17545
|
+
// comes back with none and is taken as current.
|
|
17546
|
+
terrainSettings: generation.terrainSettings,
|
|
17491
17547
|
history
|
|
17492
17548
|
});
|
|
17493
17549
|
await saveLock(lockPath, lock);
|
|
@@ -18889,6 +18945,9 @@ async function submit(provider, loaded, items, lock, lockPath, opts = {}) {
|
|
|
18889
18945
|
referenceSha256: spec.character.outfit.reference.sha256
|
|
18890
18946
|
} : null,
|
|
18891
18947
|
terrainConnect: spec.terrainConnect ? terrainConnect : void 0,
|
|
18948
|
+
// The terrain knobs specHash leaves out, so the plan can tell a
|
|
18949
|
+
// changed one; undefined (no key) for every other generator.
|
|
18950
|
+
terrainSettings: terrainSettings(spec),
|
|
18892
18951
|
status: "pending",
|
|
18893
18952
|
jobId: previousJobId ?? null,
|
|
18894
18953
|
...previousJobId ? { submissionComplete: false } : { submissionComplete: void 0 },
|