← back to 4square Agentabrams
yolo: add Mac2-local refinement loop script + 7-priority task brief
ca61c854d0ff8ac5b89f28c37cd537df9e324391 · 2026-05-14 09:31:23 -0700 · Steve
.yolo-loop.sh runs claude --print --dangerously-skip-permissions in an
infinite loop against .yolo-task.md, persisting state between iters via
.yolo-state.md, logging to .yolo.log. Kill with pkill -f .yolo-loop.sh.
Task brief lists 7 prioritized features in order — site coverage, PNG
export, shareable URL, infinite scroll, sort, replace-on-drop, grid layout.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Files touched
M .gitignoreA .yolo-loop.shA .yolo-task.md
Diff
commit ca61c854d0ff8ac5b89f28c37cd537df9e324391
Author: Steve <steve@designerwallcoverings.com>
Date: Thu May 14 09:31:23 2026 -0700
yolo: add Mac2-local refinement loop script + 7-priority task brief
.yolo-loop.sh runs claude --print --dangerously-skip-permissions in an
infinite loop against .yolo-task.md, persisting state between iters via
.yolo-state.md, logging to .yolo.log. Kill with pkill -f .yolo-loop.sh.
Task brief lists 7 prioritized features in order — site coverage, PNG
export, shareable URL, infinite scroll, sort, replace-on-drop, grid layout.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---
.gitignore | 5 ++++
.yolo-loop.sh | 31 +++++++++++++++++++++
.yolo-task.md | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 123 insertions(+)
diff --git a/.gitignore b/.gitignore
index 711f94e..b331388 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,8 @@ dist/
build/
.next/
tmp/
+
+# YOLO loop runtime
+.yolo.log
+.yolo-state.md
+.yolo-blocked.md
diff --git a/.yolo-loop.sh b/.yolo-loop.sh
new file mode 100755
index 0000000..a8d9572
--- /dev/null
+++ b/.yolo-loop.sh
@@ -0,0 +1,31 @@
+#!/usr/bin/env zsh
+# Mac2-local YOLO loop for 4square-agentabrams.
+# Loops claude --print against .yolo-task.md indefinitely until killed.
+# kill via: pkill -f '.yolo-loop.sh'
+
+set -u
+cd "$(dirname "$0")" || exit 2
+LOG="$PWD/.yolo.log"
+TASK="$PWD/.yolo-task.md"
+STATE="$PWD/.yolo-state.md"
+ITER=0
+
+print -- "$(date -u +%Y-%m-%dT%H:%M:%SZ) yolo-loop START — pid=$$ task=$TASK log=$LOG" >> "$LOG"
+
+while true; do
+ ITER=$((ITER+1))
+ print -- "$(date -u +%Y-%m-%dT%H:%M:%SZ) === iter $ITER START ===" >> "$LOG"
+
+ # Re-read the task each iter so Steve can edit it live.
+ PROMPT="$(cat "$TASK")"
+ if [[ -f "$STATE" ]]; then
+ PROMPT+="\n\n## State from previous iterations\n$(cat "$STATE")"
+ fi
+
+ echo "$PROMPT" | /usr/bin/claude --print --dangerously-skip-permissions --max-turns 80 >> "$LOG" 2>&1
+ EXIT=$?
+ print -- "$(date -u +%Y-%m-%dT%H:%M:%SZ) === iter $ITER END exit=$EXIT ===" >> "$LOG"
+
+ # Pause between iterations
+ sleep 30
+done
diff --git a/.yolo-task.md b/.yolo-task.md
new file mode 100644
index 0000000..02a0e23
--- /dev/null
+++ b/.yolo-task.md
@@ -0,0 +1,87 @@
+# 4Square YOLO — keep refining features
+
+You are working in `~/Projects/4square-agentabrams`. The app is live at
+https://4square.agentabrams.com (admin/DWShowroom2026), backed by pm2 process
+`4square-agentabrams` on port 9702 (local) and Kamatera (proxied via nginx).
+
+## Current state
+- Left rail: 104 of Steve's live domains from CNCP, in headliner order then
+ alphabetical. 20 of them are wired into `/api/site-products` proxy
+ (TSD catalog + 19 DW microsites).
+- Right panel: search input + dense product grid (120 items/load).
+- Moodboard: 4-square design board at the bottom, drag from grid to slot,
+ slot↔slot swap, localStorage persistence. All verified end-to-end.
+- Resizable left/main splitter, mobile stacks vertically, collapsible
+ moodboard.
+
+## Priorities (do in this order, ship each one independently)
+
+1. **Wire MORE sites — coverage.** Probe the remaining ~84 unwired domains
+ in `public/data/sites.json` for any product endpoint. Try in order:
+ - `/api/products` (already done — those are already wired)
+ - `/products.json` (Shopify storefront default)
+ - `/collections/all/products.json` (Shopify Section API)
+ - `/api/items`
+ - `/api/catalog`
+ - JSON-LD `<script type="application/ld+json">` embedded on the
+ homepage (parse + extract Product schemas)
+ Run probes in parallel (Promise.all batches of 10). For each domain
+ that returns valid JSON with at least one item carrying an image URL,
+ add it to `wiredSites` map in `server.js` AND add a `source` block in
+ `public/data/sites.json`. Don't break the existing 20 wired sites.
+
+2. **Export the moodboard as a PNG.** Add an "Export PNG" button next to
+ "Reset moodboard" in the header. Implementation: an offscreen 2048x2048
+ canvas, draw the 4 slots in a 2x2 grid with 32px padding + slot label
+ text overlay (Steve's site name + tile title). Save via
+ `canvas.toBlob` + `<a download>`. Skip slots that are empty.
+ Watermark "4Square · Agent Abrams" bottom-right small.
+
+3. **Shareable URL.** Encode the 4-slot layout as a compact URL hash
+ so Steve can send a moodboard link to a client. Hash format:
+ `#l=BASE64-encoded-JSON(layout)`. On page load, if `location.hash`
+ starts with `#l=`, decode and seed `layout` BEFORE rendering. Add a
+ "Share Link" button that copies the current URL+hash to clipboard
+ and flashes "copied ✓".
+
+4. **Infinite scroll** on the right panel. Replace the single 120-item
+ load with IntersectionObserver-based pagination. Track `offset` per
+ site. Append, don't replace.
+
+5. **Per-site sort options** for sites whose backend supports sort
+ params (most DW microsites accept `?sort=newest|price-asc|price-desc`).
+ Add a small Sort `<select>` next to the search bar — visible only
+ when the active site supports it (detect via probing `?sort=newest`
+ returns different first-item id than `?sort=price-asc`).
+
+6. **Swap slot image without clearing first.** When user drags a tile
+ onto a FILLED slot, instead of swapping with another slot, REPLACE
+ the slot's contents with the dragged tile. (Slot↔slot drags stay
+ swap.) Update the dnd handler to differentiate `kind: 'tile'` (replace)
+ vs `kind: 'slot'` (swap). Already partially in place — verify it works
+ and add a tiny "replaced" toast.
+
+7. **Slot grid layout options.** Add a small selector "Layout:" with
+ options 2x2 (default), 3x3 (9 slots), 1x4 (linear row), 4x1 (linear
+ column). Layout choice persists in localStorage. Storage key bumps
+ to `…layout.v2` to avoid stomping the v1 4-slot data.
+
+## Ground rules
+
+- Each priority is its own commit. Each commit gets its own deploy via
+ `bash ~/Projects/_shared/scripts/deploy.sh`. Verify with a curl smoke
+ test against https://4square.agentabrams.com after each deploy.
+- Use the same `admin/DWShowroom2026` credentials in curl tests.
+- Don't touch `~/Projects/thesetdecorator/` — it's a different project.
+- Don't modify DNS records, don't touch Cloudflare, don't send mail,
+ don't run pm2 `save` (that already happened).
+- After each feature lands, append a one-line entry to `.yolo-log.md`
+ in the project root: `[<ISO timestamp>] <commit-sha> <feature>`.
+- If you hit a blocker that needs Steve's input, write it to
+ `.yolo-blocked.md` and move to the next priority — don't loop on
+ the same problem.
+- Keep diffs small. Don't reformat unrelated files.
+- Run `pm2 restart 4square-agentabrams` locally after each Edit so the
+ Mac2 dev server reflects changes for verification.
+
+Start with priority #1 (wire more sites). Go.
← a00276f wire 19 more DW microsites — click → real products, not 'pen
·
back to 4square Agentabrams
·
4square: bust sites.json cache + re-resolve selectedSite fro 7bebaa2 →