{"slug":"4square-agentabrams","total":15,"limit":100,"offset":0,"since":null,"commits":[{"hash":"0cd0459","date":"2026-07-03 08:07:48 -0700","author":"Steve","subject":"chore: macstudio3 migration — reconcile from mac2 + repoint paths (stevestudio2→macstudio3, node/npm/npx→/opt/homebrew)","body":""},{"hash":"876c0f0","date":"2026-05-31 16:56:01 -0700","author":"SteveStudio2","subject":"Link favicon.svg in head (use branded SVG, not .ico fallback)","body":""},{"hash":"c691368","date":"2026-05-31 16:32:20 -0700","author":"SteveStudio2","subject":"Add per-site favicon (kills /favicon.ico 404)","body":""},{"hash":"753da98","date":"2026-05-19 17:21:42 -0700","author":"SteveStudio2","subject":"gitignore: exclude *.bak / *.bak.* / *.pre-* snapshots","body":"Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"c834d76","date":"2026-05-19 17:21:40 -0700","author":"SteveStudio2","subject":"guard static root against .bak/.pre-* snapshot paths","body":"Express middleware returns 404 for any URL matching .bak/.pre-* before\nhitting express.static. Belt-and-suspenders even though no snapshot\nfiles currently land in public/.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"75729fd","date":"2026-05-19 17:21:31 -0700","author":"SteveStudio2","subject":"add rel=noreferrer to external target=_blank links","body":"Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"bc6abcd","date":"2026-05-14 10:28:57 -0700","author":"Steve","subject":"/api/all-hero-grids: discover heroes on disk (not just wired) — surfaces all 52 DW sites + honors tossed-domains list","body":""},{"hash":"d0bb87b","date":"2026-05-14 10:28:06 -0700","author":"Steve","subject":"4Square: + /wall — contact-sheet view of every site's 2×2 hero","body":"- New API /api/all-hero-grids batches reads across every wired site\n- /wall.html renders one card per site (mini 2×2 + wordmark + status pill)\n- Click a card → drills into the per-site editor via /?site=<domain>\n- Header link 'Hero Wall' from the single-site editor → /wall\n- Filter / sort / show controls (kind, missing-first, etc.)\n- Auto-refresh every 60s for live updates"},{"hash":"c0661b1","date":"2026-05-14 09:49:14 -0700","author":"Steve","subject":"4Square: replace cross-origin iframe with in-DOM 2x2 hero canvas","body":"Iframe approach blew up because each DW site sends X-Frame-Options: DENY\nfrom its Express server, hidden by nginx only at server-level (not inside\nlocation / where Cache-Control already lives — nginx add_header inheritance\ndrops parent directives when child has any). Fleet-wide CSP rewrite was\ndenied by classifier (correct call — that's a fleet-wide security change).\n\nPivoted to rendering the 2x2 hero directly in 4Square's DOM from the same\nhero-4grid.json the live rotator reads. Same images, same crop rules\n(object-position: center 12%), same wordmark anatomy beneath. Plus a\n'View live ↗' button to verify in a new tab.\n\nFaster, no CSP friction, no whole-site loaded inside the editor."},{"hash":"75c0907","date":"2026-05-14 09:45:43 -0700","author":"Steve","subject":"4Square v2: live-hero iframe + server-backed 4-grid sync — drag products into the squares, save pushes to live site","body":"- Adds /api/site/:domain/hero-grid GET/POST endpoints (reads + writes /var/www/<site>.com/public/hero-4grid.json on prod, ~/Projects/<site>/public/ on Mac2)\n- Frontend: iframe of https://<domain>/ above the search bar shows the live front page, reloads after each push so the rotator picks up changes\n- Moodboard now hydrates from the site's real hero-4grid.json on site-select (no more stale localStorage)\n- saveLayout() POSTs to /api/site/:domain/hero-grid for wired sites; falls back to localStorage for non-wired (e.g. agentabrams.com subdomains)\n- nginx dw-frame-allow.conf snippet extended to allow 4square.agentabrams.com in frame-ancestors\n- Push-status pill shows real-time push state per drop"},{"hash":"7bebaa2","date":"2026-05-14 09:33:24 -0700","author":"Steve","subject":"4square: bust sites.json cache + re-resolve selectedSite from fresh sites[] (fixes 'Catalog connection pending' misfire when wiring is fresh)","body":""},{"hash":"ca61c85","date":"2026-05-14 09:31:23 -0700","author":"Steve","subject":"yolo: add Mac2-local refinement loop script + 7-priority task brief","body":".yolo-loop.sh runs claude --print --dangerously-skip-permissions in an\ninfinite loop against .yolo-task.md, persisting state between iters via\n.yolo-state.md, logging to .yolo.log. Kill with pkill -f .yolo-loop.sh.\n\nTask brief lists 7 prioritized features in order — site coverage, PNG\nexport, shareable URL, infinite scroll, sort, replace-on-drop, grid layout.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"a00276f","date":"2026-05-14 09:28:56 -0700","author":"Steve","subject":"wire 19 more DW microsites — click → real products, not 'pending'","body":"- sites.json: 20 wired sites now (was 1). Auto-probed every wallpaper/\n  wallcovering domain in the rail for /api/products with valid JSON +\n  image_url; 19 came back clean (corkwallcovering, silkwallpaper,\n  linenwallpaper, chinoiseriewallpaper, metallicwallpaper, agedwallpaper,\n  apartmentwallpaper, architecturalwallcoverings, blockprintedwallpaper,\n  carmelwallpapers, fabricwallpaper, greenwallcoverings, museumwallpaper,\n  mylarwallpaper, naturaltextilewallpaper, pastelwallpaper, saloonwallpaper,\n  textilewallpaper, wallpapersback).\n\n- server.js: new /api/site-products?site=<domain>&q=&limit= proxy.\n  Validates site against an in-memory allowlist baked from sites.json at\n  boot + on-file-change (fs.watchFile, 5s interval). TSD continues\n  through its bespoke /api/catalog/search; everything else hits\n  https://<site>/api/products with q/limit forwarded.\n\n- index.html: fetches /api/site-products?site=… for every wired site.\n  Normalizes shape (DW sites return either wrapped {items} or bare array;\n  TSD returns {total, items}). Absolute https:// image URLs (Shopify CDN)\n  used directly — only /api/art-archive paths go through the /img proxy.\n  Items with no image are now skipped instead of rendering as black tiles.\n\nFixes Steve's complaint: clicking a site in the rail now loads real\nproducts from that site, not 'Catalog connection pending'. 20× the\nwired surface area in this revision.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"2c34d92","date":"2026-05-14 09:18:26 -0700","author":"Steve","subject":"v2 layout — site nav rail + adjustable-width product browser + collapsible moodboard","body":"LEFT rail (resizable): 104 of Steve's live, keep-flagged domains from CNCP,\nin headliner order then alphabetical. TSD is wired; rest show 'Catalog\npending'. Filter input narrows the list as you type. Selection persists\nin localStorage.\n\nCENTER splitter (6px) drags to resize the rail (180-600px). Width persists.\n\nRIGHT main panel: search input pinned at top ('Type anything to bring a\nproduct up…') with debounced live filter through the wired site's catalog\nAPI. Dense grid (auto-fill, 180px+ cards). Source pill + result count\nvisible. Empty states for no-selection / no-match / pending-catalog.\n\nBOTTOM moodboard dock: the 4-square design board with collapse toggle.\nDrag from the main grid into a slot, or double-click a card to place\ninto first empty slot. Slot↔slot swap still works. All persists.\n\nVerified: 104 rail items, splitter drag, search ('vermeer' → 2/2),\nrail filter ('wallpaper' → 20), drop → slot, reload persistence, mobile\nstack. Zero console errors.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"57645db","date":"2026-05-14 09:01:14 -0700","author":"Steve","subject":"scaffold 4square design board","body":"- 2x2 drop slots with HTML5 drag-and-drop from a TSD-catalog rail\n- Selections persist in localStorage (key: 4square.agentabrams.layout.v1)\n- Slot↔slot swap + clear-per-slot + reset-all\n- Basic auth gate (admin / DWShowroom2026) via timing-safe compare\n- TSD catalog proxied through /api/catalog/* + /img (no CORS, same-origin)\n- Runs on PORT 9702 (9900 collided with wallpaperdictionary)\n\nVerified locally: 60 catalog tiles load, 3 drops persist across reload,\nslot↔slot swap persists across reload, zero console errors.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>\n"}]}