{"slug":"shopify-room-mockup","total":4,"limit":100,"offset":0,"since":null,"commits":[{"hash":"e6427c0","date":"2026-09-26 09:22:42 -0700","author":"Steve Abrams","subject":"TK-12096: double-run guard — refuse push when ledger has a live upload for product+ticket (--force overrides) + negative test; ledger records the 5 duplicate deletions","body":"Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VqJiAb5GBhYitB8Fr17eGx"},{"hash":"3a3e31e","date":"2026-09-24 07:59:28 -0700","author":"Steve Abrams","subject":"TK-12090 Fix 1: ledger the media id upload_media() already returns","body":"productCreateMedia's response already carries the MediaImage gid\n(media{id status}), but the success branch only ever printed the\nproduct title -- the id reached no ledger, so a documented undo\n(productDeleteMedia for \"the ids the mutation returns\") was\nunexecutable, because those ids existed nowhere after the run.\n\nAdds --ledger (JSONL, default out/room-mockup-ledger.jsonl) and\n--ticket. Every successful upload writes {ts, ticket, product_gid,\nmedia_id, undo_cmd} BEFORE printing the success line, so a crash\nbetween write and print can't lose the id. A response missing a\nusable id, or a ledger-write failure, is now a loud refusal to\nreport success (stderr + counted failed) instead of a silent green\nline with nothing recorded.\n\nAdds --delete-media/--product as a small undo-utility mode so the\nledger's undo_cmd is a directly runnable invocation of this same\nscript, not a hand-assembled GraphQL call.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01KXUyzc9vybUz39rhnNJdwY"},{"hash":"37d416c","date":"2026-09-23 14:43:11 -0700","author":"Steve Abrams","subject":"Repoint room render off the dead Kamatera :3075 service to room-engines' local $0 compositor (TK-12096)","body":":3075 is confirmed dead — the port is now bound by tailscaled and the real\nroom-setting-app pm2 process moved to :3076 and is crash-looping (50\nrestarts/2h). render_room() now shells out locally to room-engines'\ncompose_real.py (the $0 patch-quilt \"real-swatch\" engine, one of the\nengines room-engines' own judge/apply_winners pipeline already picks\nper-SKU), bootstrapping its expected /tmp scratch from the viewer's\npermanently-preserved bakeoff-assets/. CLI surface kept identical\n(--box now a deprecated no-op); this tool's distinct value — generic\n--ids/--query/--collection Shopify-side selection pulling a product's own\nlive featured image — is preserved and not duplicated by room-engines,\nwhich is wired to a single book's local catalog table + manifest. Verified\nlocally against 3 different swatches (bamboo/grasscloth/silk), all render\nvalid 1024x1024 PNGs in <1s, $0.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01KXUyzc9vybUz39rhnNJdwY"},{"hash":"f470b56","date":"2026-05-29 14:43:08 -0700","author":"Steve","subject":"shopify-room-mockup: reusable tool to add photoreal room mockups to Shopify products (select by ids/query/collection, render via :3075 over SSH, staged-upload + productCreateMedia, --skip-existing idempotency, --dry-run). Built from the Crowley's Crocodile batch","body":""}]}