← back to Wallco Ai
Add style-aware-sample.js — PG-palette-derived chinoiserie SAMPLE prompts onto canonical generator
bc99681ea2400f3ad492cdaa1296aa0d611b60a2 · 2026-05-26 14:35:36 -0700 · Steve
Files touched
A scripts/style-aware-sample.js
Diff
commit bc99681ea2400f3ad492cdaa1296aa0d611b60a2
Author: Steve <steve@designerwallcoverings.com>
Date: Tue May 26 14:35:36 2026 -0700
Add style-aware-sample.js — PG-palette-derived chinoiserie SAMPLE prompts onto canonical generator
---
scripts/style-aware-sample.js | 147 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 147 insertions(+)
diff --git a/scripts/style-aware-sample.js b/scripts/style-aware-sample.js
new file mode 100644
index 0000000..0b75c4f
--- /dev/null
+++ b/scripts/style-aware-sample.js
@@ -0,0 +1,147 @@
+#!/usr/bin/env node
+/**
+ * style-aware-sample.js — SAMPLE-GATE prover for the style-aware design idea.
+ *
+ * Proves the style-aware pipeline (idea-loop survivor #1, YOLO task 13) by
+ * DERIVING on-style prompts for ONE aesthetic bucket from the real PG colorway
+ * palettes + motif vocabulary already living in dw_unified.spoon_all_designs,
+ * then handing them to the canonical scripts/generate_designs.js --prompts path
+ * so every wallco gate (tone-on-tone suffix, ghost / seamless / frame-overlay,
+ * watermark, make_seamless) runs unchanged. No new generation code — this only
+ * builds the prompts.
+ *
+ * DTD verdict 2026-05-26 (3/3 unanimous): bucket = chinoiserie, because it is
+ * the only bucket with enough reference data to derive a genuinely style-aware
+ * prompt. chinoiserie is in TILE_CATEGORIES so generate_designs.js auto-forces
+ * GEN_BACKEND=comfy (Mac1, free) + SeamlessTile + MakeCircularVAE.
+ *
+ * Authority: SAMPLE ONLY. is_published stays FALSE (generate_designs.js inserts
+ * FALSE). Does NOT publish, deploy, or push to Shopify. Does NOT mass-generate.
+ *
+ * Usage:
+ * node scripts/style-aware-sample.js --bucket chinoiserie --n 6
+ * node scripts/style-aware-sample.js --bucket chinoiserie --n 6 --dry-run # print prompts only
+ */
+const { spawnSync } = require('child_process');
+const path = require('path');
+
+function args() {
+ const a = process.argv.slice(2);
+ const o = { bucket: 'chinoiserie', n: 6, dryRun: false };
+ for (let i = 0; i < a.length; i++) {
+ switch (a[i]) {
+ case '--bucket': o.bucket = a[++i]; break;
+ case '--n': o.n = parseInt(a[++i], 10); break;
+ case '--dry-run': o.dryRun = true; break;
+ }
+ }
+ return o;
+}
+
+function psql(sql) {
+ const r = spawnSync('psql', ['dw_unified', '-At', '-q', '-F', '\t'], { input: sql, encoding: 'utf8' });
+ if (r.status !== 0) throw new Error(r.stderr || r.stdout || 'psql failed');
+ return r.stdout.trim();
+}
+
+// Pull real named-colorway grounds for the bucket (style-aware: the palette
+// comes from the catalog, not from a hardcoded list).
+function pullColorways(bucket) {
+ const rows = psql(`
+ SELECT DISTINCT ON (category)
+ regexp_replace(category, '^.* · ', '') AS colorway,
+ dominant_hex
+ FROM spoon_all_designs
+ WHERE category LIKE '${bucket} ·%'
+ AND dominant_hex IS NOT NULL
+ AND prompt LIKE '%colorway%'
+ ORDER BY category, id DESC;
+ `);
+ return rows.split('\n').filter(Boolean).map(l => {
+ const [colorway, hex] = l.split('\t');
+ return { colorway, hex };
+ });
+}
+
+// Pull the real motif vocabulary the bucket has actually used.
+function pullMotifs(bucket) {
+ const rows = psql(`
+ SELECT DISTINCT substring(prompt from 'Motif: (.*?), arranged')
+ FROM spoon_all_designs
+ WHERE category LIKE '${bucket}%' AND prompt LIKE '%Motif:%'
+ AND substring(prompt from 'Motif: (.*?), arranged') IS NOT NULL;
+ `);
+ return rows.split('\n').filter(Boolean);
+}
+
+// The battle-tested chinoiserie body, verbatim from the catalog's own prompts
+// (minus the per-design Ground/Figure/Motif header, which we fill from PG).
+const BODY = `British-archival Mandarin / Ming-dynasty woodblock register. KEEP IT SIMPLE — sparse, refined, lavishly negative-space-driven. At LEAST 75-85% of the tile area is solid clean ground tone with NOTHING in it. Motifs are FEW (2-4 per tile maximum), well-spaced, never edge-to-edge, never cluttered. The empty ground IS the design — motifs are punctuation, not pattern-fill. Default is 2-tone unless the subject demands a small accent color. Never more than 4 distinct ink tones. ABSOLUTELY NO bleed between layers — bleed looks cheap and is FORBIDDEN. Single-layer screen-print only. NO ghost layer, NO faded background, NO atmospheric depth, NO secondary motifs behind the main figures. The ground is one completely uniform flat solid color from edge to edge. High-end designer wallcovering register, hand-blocked scenic archival aesthetic. Subtle. Sparse. Refined. Negative-space-driven. Single-pass silkscreen with two ink screens. Hard clean razor-sharp edges. No half-tones, no gradient, no watercolor, no crosshatch shading. Every figure region is one flat color. Square aspect ratio, seamless tile repeat (edges meet cleanly), flat-paper rendering, no watermark, no signature, no text, no logos.`;
+
+const FIGURE_LIGHT = '#F2EADB'; // bone-ivory — figure for dark/mid grounds (catalog default)
+const FIGURE_DARK = '#2A2118'; // deep-cocoa — figure for light grounds, so it stays legible
+
+// Pick a figure ink that actually contrasts the ground (relative luminance).
+function figureFor(groundHex) {
+ const h = groundHex.replace('#', '');
+ const r = parseInt(h.slice(0, 2), 16), g = parseInt(h.slice(2, 4), 16), b = parseInt(h.slice(4, 6), 16);
+ const lum = 0.2126 * r + 0.7152 * g + 0.0722 * b; // 0..255
+ return lum > 150 ? FIGURE_DARK : FIGURE_LIGHT;
+}
+
+function buildPrompts(bucket, n) {
+ const colorways = pullColorways(bucket);
+ const motifs = pullMotifs(bucket);
+ if (!colorways.length) throw new Error(`No PG colorway palettes for bucket "${bucket}"`);
+ if (!motifs.length) throw new Error(`No PG motif vocabulary for bucket "${bucket}"`);
+
+ // Heterogeneous pairing (Steve's rule): walk colorways and motifs on coprime
+ // strides so the sample spans distinct grounds AND distinct motifs, not a
+ // monotone block. Shuffle colorways deterministically by hex for spread.
+ const cw = [...colorways].sort((a, b) => a.hex.localeCompare(b.hex));
+ const prompts = [];
+ for (let i = 0; i < n; i++) {
+ const ground = cw[(i * 5) % cw.length]; // stride 5 across grounds
+ const motif = motifs[i % motifs.length]; // cycle the 4 motif archetypes
+ const colorwayLabel = ground.colorway
+ .replace(/-/g, ' ')
+ .replace(/\b\w/g, c => c.toUpperCase());
+ const figHex = figureFor(ground.hex);
+ const figName = figHex === FIGURE_DARK ? 'deep-cocoa' : 'bone-ivory';
+ const p = `Chinoiserie wallpaper — ${colorwayLabel} colorway. Ground: solid ${colorwayLabel.toLowerCase()} (${ground.hex.toUpperCase()}). Figure: ${figName} (${figHex}) single-ink. Motif: ${motif}, arranged in a tessellated seamless repeat. ${BODY}`;
+ prompts.push({ colorway: colorwayLabel, ground: ground.hex.toUpperCase(), figure: figHex, motif, prompt: p });
+ }
+ return prompts;
+}
+
+function main() {
+ const o = args();
+ const prompts = buildPrompts(o.bucket, o.n);
+
+ console.log(`\n=== style-aware SAMPLE prompts · bucket=${o.bucket} · n=${prompts.length} ===\n`);
+ prompts.forEach((p, i) => {
+ console.log(`[${i + 1}] colorway=${p.colorway} ground=${p.ground} figure=${p.figure}`);
+ console.log(` motif: ${p.motif}`);
+ });
+
+ if (o.dryRun) {
+ console.log('\n[dry-run] not generating. Prompts derived from PG only.');
+ return;
+ }
+
+ // Hand off to the canonical generator. The --prompts path appends the
+ // tone-on-tone suffix and runs every gate. category=chinoiserie forces
+ // comfy backend + SeamlessTile (TILE_CATEGORIES).
+ const joined = prompts.map(p => p.prompt).join('|');
+ console.log(`\n=== handing ${prompts.length} prompts to generate_designs.js (category=${o.bucket}) ===\n`);
+ const r = spawnSync('node', [
+ path.join(__dirname, 'generate_designs.js'),
+ '--kind', 'seamless_tile',
+ '--category', o.bucket,
+ '--n', String(prompts.length),
+ '--prompts', joined,
+ ], { stdio: 'inherit', encoding: 'utf8' });
+ process.exit(r.status || 0);
+}
+
+main();
← 3646071 TODO: record 157-catalog incident + fix, fliepaper publish +
·
back to Wallco Ai
·
dogs collection generator — 11 breeds (DTD verdict) × 20 des 03497c0 →