← back to Wallco Ai
scripts: oneshot trellis-upgrade regen for drunk-zoo-36 #26634 → new SKU #39288
9666be203f54b659b3b30646ec70835bd0db4c54 · 2026-05-23 23:38:54 -0700 · Steve Abrams
Hand-tuned upgraded prompt that explicitly names the diagonal lattice geometry
(structure-first, motifs-second) so the model doesn't fall back to scatter +
ghost-fill. Fixes Fill=100% defect on the saddle-mocha frog design Steve
flagged. Parent #26634 unpublished; lineage preserved via parent_design_id.
Files touched
A scripts/oneshot-regen-26634.jsA scripts/publish-oneshot-26634.js
Diff
commit 9666be203f54b659b3b30646ec70835bd0db4c54
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Sat May 23 23:38:54 2026 -0700
scripts: oneshot trellis-upgrade regen for drunk-zoo-36 #26634 → new SKU #39288
Hand-tuned upgraded prompt that explicitly names the diagonal lattice geometry
(structure-first, motifs-second) so the model doesn't fall back to scatter +
ghost-fill. Fixes Fill=100% defect on the saddle-mocha frog design Steve
flagged. Parent #26634 unpublished; lineage preserved via parent_design_id.
---
scripts/oneshot-regen-26634.js | 95 ++++++++++++++++++++++++++++++++++++++++
scripts/publish-oneshot-26634.js | 64 +++++++++++++++++++++++++++
2 files changed, 159 insertions(+)
diff --git a/scripts/oneshot-regen-26634.js b/scripts/oneshot-regen-26634.js
new file mode 100644
index 0000000..0d10c2f
--- /dev/null
+++ b/scripts/oneshot-regen-26634.js
@@ -0,0 +1,95 @@
+#!/usr/bin/env node
+// One-shot regen for design #26634 (drunk-zoo-36 saddle-mocha frog trellis).
+// Bypasses the Vision-describe step in /api/design/:id/regenerate-reverse —
+// we already have a hand-tuned upgraded prompt that explicitly names the
+// trellis-lattice geometry Steve loved. Goes straight to image gen.
+//
+// No PG writes. No publish. Just generate to /tmp/ and report the path.
+// Steve eyeballs the result; if good, we wire it into the batch regen.
+//
+// Usage: node scripts/oneshot-regen-26634.js
+
+'use strict';
+
+const fs = require('fs');
+const path = require('path');
+const { geminiCall, extractImageData, extractText } = require('../lib/gemini.js');
+
+// Hand-tuned upgrade: leads with named geometric structure (lattice/trellis)
+// so the model doesn't fall back to "scatter motifs + ghost-fill gaps."
+// All Fill=100% / no-ghost language preserved verbatim from the original
+// drunk-zoo-36 prompt template.
+const PROMPT = `
+Saddle-Mocha frog-trellis wallpaper — 36-inch seamless repeat tile.
+
+GEOMETRIC STRUCTURE (this is the foundation — the design is a lattice, not scattered motifs):
+A regular diagonal lattice on a 45° grid. Lattice nodes positioned in a 4x4 layout
+across the tile. At each node sits ONE bone-ivory frog in a leaping pose. Adjacent
+frogs are mirrored (alternating left-leap / right-leap) so each frog's extended
+LEGS reach toward the next frog's extended legs, forming the diagonal bars of the
+lattice. Frog BODIES = lattice nodes. Frog LEGS = lattice bars. Negative space
+between lattice bars = open clean ground, diamond-shaped voids of solid
+saddle-mocha brown with NOTHING in them.
+
+PALETTE (exactly two inks, no third color, no gradient):
+ Ground: saddle-leather-brown #4A3528 — one flat solid color, edge-to-edge uniform
+ Figure: bone-ivory #F2EADB — single ink, every frog rendered in this one color
+
+EXECUTION (Photoshop-precise):
+ Fill = 100% on every frog. Opacity = 100%. No layer below 100%.
+ Single-layer screenprint. Hard razor-sharp silhouette edges, no anti-alias bleed.
+ No ghost copies, no faded duplicates, no semi-transparent silhouettes anywhere.
+ No atmospheric perspective, no depth shading, no internal anatomical detail.
+ No second frog behind any frog. No echo. Ink either prints (100%) or doesn't (0%).
+
+ANTI-DEFECT (forbidden artifacts — this is the manufacturing-defect fence):
+ NO faded versions of the frog motif sitting behind the sharp version
+ NO translucent overlay of the whole scene
+ NO bilateral mirror reflection across the tile center (lattice symmetry is
+ local-to-each-node, not a global tile-mirror)
+ NO visible panel boundaries / NO vertical or horizontal seam lines inside the image
+ NO drift-shadow or trailing-copy under any frog
+ NO faded edge bleed-zone at the 35% outer margin of the canvas
+
+DESIGN INTENT: This is the Designer Wallcoverings drunk-zoo line — a refined,
+sparse, archival aesthetic in the Zuber / Designers Guild / Pierre Frey
+register. Negative space drives the design. The LATTICE is the structure, the
+FROGS are the lattice. That is the whole idea.
+
+Square aspect ratio. Fully tileable seamless repeat: top edge wraps to bottom,
+left edge wraps to right. Flat-paper rendering. No watermark, no signature, no text.
+`.trim();
+
+(async () => {
+ const t0 = Date.now();
+ console.log('[oneshot-26634] prompt length:', PROMPT.length, 'chars');
+ console.log('[oneshot-26634] calling gemini-2.5-flash-image …');
+
+ let j;
+ try {
+ j = await geminiCall({
+ model: 'gemini-2.5-flash-image',
+ parts: [{ text: PROMPT }],
+ generationConfig: { responseModalities: ['IMAGE'] },
+ app: 'wallco-ai',
+ note: 'oneshot-regen-26634-trellis-upgrade',
+ });
+ } catch (e) {
+ console.error('[oneshot-26634] gemini call failed:', e.code, e.message);
+ process.exit(1);
+ }
+
+ const b64 = extractImageData(j);
+ if (!b64) {
+ console.error('[oneshot-26634] no image in response — text:', (extractText(j) || '').slice(0, 240));
+ process.exit(1);
+ }
+
+ const out = `/tmp/oneshot-26634-trellis-${Date.now()}.png`;
+ fs.writeFileSync(out, Buffer.from(b64, 'base64'));
+ const sz = fs.statSync(out).size;
+ const ms = Date.now() - t0;
+ console.log(`[oneshot-26634] DONE in ${(ms/1000).toFixed(1)}s — ${(sz/1024).toFixed(0)} KB`);
+ console.log(`[oneshot-26634] file: ${out}`);
+ console.log(`[oneshot-26634] open: open ${out}`);
+})().catch(e => { console.error('FATAL', e); process.exit(1); });
diff --git a/scripts/publish-oneshot-26634.js b/scripts/publish-oneshot-26634.js
new file mode 100644
index 0000000..9bc45ea
--- /dev/null
+++ b/scripts/publish-oneshot-26634.js
@@ -0,0 +1,64 @@
+#!/usr/bin/env node
+// Publish the one-shot trellis regen of #26634 as a new SKU + unpublish original.
+// Steve approved direction A: ship the clean fretwork-with-frogs version.
+'use strict';
+
+const fs = require('fs');
+const path = require('path');
+const { psqlQuery, psqlExecLocal, pgEsc } = require('../lib/db.js');
+
+const PARENT_ID = 26634;
+const SRC = process.argv[2] || '/tmp/oneshot-26634-trellis-1779604582043.png';
+if (!fs.existsSync(SRC)) {
+ console.error('source PNG not found:', SRC);
+ process.exit(1);
+}
+
+// The prompt that was actually used (matches scripts/oneshot-regen-26634.js)
+const PROMPT_USED = `[Trellis-upgrade regen of #${PARENT_ID}] Saddle-Mocha frog-trellis wallpaper — 36-inch seamless repeat. Diagonal lattice on 45° grid, 4x4 layout; frog bodies at lattice nodes, extended legs forming diagonal bars. Two inks only: ground #4A3528 saddle-leather-brown, figure #F2EADB bone-ivory. Fill=100%, Opacity=100%, single-layer screenprint, hard razor-sharp edges, NO ghost layers / NO faded duplicates / NO mirror-tile / NO panel seams / NO edge bleed. Square aspect, fully tileable.`;
+
+const seed = require('crypto').randomInt(1, 2 ** 31 - 1);
+const ts = Date.now();
+const filename = `regenrev_${PARENT_ID}_${ts}_${seed}.png`;
+const destAbs = path.join(__dirname, '..', 'data', 'generated', filename);
+
+fs.copyFileSync(SRC, destAbs);
+console.log('[publish-26634] copied →', destAbs);
+
+// Inherit fields from parent
+const parentRaw = psqlQuery(`SELECT kind || '|' || width_in || '|' || height_in || '|' || COALESCE(dominant_hex,'') || '|' || COALESCE(palette::text,'[]') FROM spoon_all_designs WHERE id=${PARENT_ID}`);
+const [kind, w, h, domHex, paletteJson] = parentRaw.split('|');
+const widthIn = parseFloat(w) || 36;
+const heightIn = parseFloat(h) || 36;
+
+const sql = `
+INSERT INTO spoon_all_designs
+ (kind, brand, width_in, height_in, generator, prompt, seed,
+ image_url, local_path, dominant_hex, palette, category, is_published,
+ parent_design_id)
+VALUES
+ (${pgEsc(kind || 'seamless_tile')}, 'wallco.ai',
+ ${widthIn}, ${heightIn},
+ 'gemini-2.5-flash-image-trellis-upgrade',
+ ${pgEsc(PROMPT_USED)},
+ ${seed},
+ '/designs/img/by-id/__NEW__',
+ ${pgEsc(destAbs)},
+ ${pgEsc(domHex || '#4A3528')},
+ ${pgEsc(paletteJson || '[]')}::jsonb,
+ 'drunk-zoo-36',
+ TRUE,
+ ${PARENT_ID})
+RETURNING id`;
+
+const newId = parseInt(psqlExecLocal(sql), 10);
+if (!Number.isFinite(newId)) {
+ console.error('[publish-26634] INSERT did not return an id');
+ process.exit(1);
+}
+console.log('[publish-26634] new design id:', newId);
+
+psqlExecLocal(`UPDATE spoon_all_designs SET image_url='/designs/img/by-id/${newId}', is_published=TRUE WHERE id=${newId}`);
+psqlExecLocal(`UPDATE spoon_all_designs SET is_published=FALSE WHERE id=${PARENT_ID}`);
+console.log(`[publish-26634] DONE — new SKU #${newId} published, parent #${PARENT_ID} unpublished`);
+console.log(`[publish-26634] view: http://127.0.0.1:9905/designs/img/by-id/${newId}`);
← 7eb0a50 fix(db): psqlExecLocal multi-line SQL — JSON.stringify of ne
·
back to Wallco Ai
·
ghost-review: magic wand — click motif to isolate, then reco 7031abf →