{"slug":"gmc-viewer","total":11,"limit":100,"offset":0,"since":null,"commits":[{"hash":"828b20f","date":"2026-09-24 23:08:40 -0700","author":"Steve Abrams","subject":"gmc-viewer: migrate refresh to Merchant API v1, fail-closed cache write (TK-12036)","body":"Content API v2.1 410s mid-pagination (sunset); old pull() wrote the partial\nresult as the catalog then crashed on undefined summary. Now: merchantapi\nproducts/v1, overwrite cache only after a complete error-free walk.\nVerified: 61,659 offers refreshed.\n\nCo-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_014RPYSiFdzmd1W1zPngeHTy"},{"hash":"05df51e","date":"2026-09-10 08:04:37 -0700","author":"Steve Abrams","subject":"reassign default port 9971->9972 to resolve collision with adsense-manager (TK-11375)","body":""},{"hash":"9a84d83","date":"2026-08-25 10:48:56 -0700","author":"Steve","subject":"creds-safe fetch guard: resolve relative fetch vs credential-free location (creds-in-URL trap)","body":"Fleet inoculation — opening this basic-auth app with credentials in the URL\npoisoned document.baseURI and made relative fetch('/api/…') throw. Guard resolves\nnon-absolute request URLs against location instead. Ref: creds-in-url-fetch-guard-fleet-pattern.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"0493c14","date":"2026-08-20 08:14:33 -0700","author":"Steve Abrams","subject":"nav-agent: sync v1.3 (host left-sidebar collapse on load)","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"2678a19","date":"2026-08-19 14:31:00 -0700","author":"Steve","subject":"nav-agent: List data full-width tight columns (grid) — layout fix","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"63f6867","date":"2026-08-19 14:05:21 -0700","author":"Steve","subject":"Refresh nav-agent to v1.2 (adds kv-list compact List view, default-off)","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"5341e5a","date":"2026-08-13 09:27:27 -0700","author":"Steve Abrams","subject":"nav-agent: universal grid-controls drop-in on internal dashboard/command-center pages (STRONG-only)","body":""},{"hash":"8669671","date":"2026-07-31 17:46:56 -0700","author":"Steve Abrams","subject":"gmc-viewer: href-drill — status badge is a filter-link + URL-addressable state","body":"Each card's Merchant status badge (approved/disapproved/pending — the statuses the\n/api/products filter supports) is now an <a href=\"?filter=<status>\"> to its filtered\nview (href-drill HARD rule); the chip filter + search are URL-addressable too. Click\nfilters in place + reflects into the URL, cmd/ctrl-click opens the shareable href,\nback-button + deep-link restore via popstate/readURL. Brand/country left as text — the\nAPI can't filter them, and gaming the detector without a real drill is not the fix.\n\nVerified (Playwright + basic auth, live :9971): click an approved badge -> ?filter=approved\n+ every card now approved; deep-link restores; back-button restores; canary FLAT->DONE;\n0 pageerrors. href-drill backlog grid 5/92. TK-10089."},{"hash":"a07e983","date":"2026-07-09 14:10:55 -0700","author":"Steve Abrams","subject":"auto-save: 2026-07-09T14:10:49 (1 files) — dw-ga4-custom-pixel.js","body":""},{"hash":"3da85f7","date":"2026-07-09 08:32:07 -0700","author":"steve","subject":"fix: MC status value is 'approved' not 'active' (approved count was 0); summary recomputes live from cache","body":""},{"hash":"7e32dc7","date":"2026-07-09 08:17:08 -0700","author":"steve","subject":"gmc-viewer: local read-only viewer of live Google Merchant catalog (grid, status/price filters, search)","body":""}]}