rzen 622d9d63fd pipeline: autonomous operation — shortlist stage, auto modes, daily-pipeline orchestrator
- daily-finds: feed-first fetch strategy (fetch: feed + feedUrl), cadence-aware
  scanning, new score-and-shortlist stage (shortlist: true, up to 12/day, top
  1-3 flagged as review candidates), Amazon affiliate lookup for shortlisted
  physical products, and authority to apply mechanical sources.json maintenance
  (skip dead sources, demote dormant ones, record working fetch paths) instead
  of logging recommendations nobody executes.
- build-bundle: auto mode (no confirmation gate when unattended) and a 'weekly'
  date-based catch mode so shortlisted finds never sit invisible for weeks.
- cluster-bundles: auto mode.
- build-review: hero.ts registration step removed (heroes auto-discovered from
  hero.<ext>); mandatory fact-check against the product's own site in auto
  mode; amazonLink carry-through; auto mode publishes and logs instead of
  pausing twice for approval.
- New daily-pipeline skill: capture → bundle → reviews → pick of the day →
  build → commit → push → digest, with granular per-stage commits. This is the
  entrypoint for scheduled runs.
- Project CLAUDE.md documenting the pipeline and its foot-gun conventions.
2026-07-03 15:21:27 -04:00
2026-05-06 21:51:26 -04:00

Unique

A small blog about delightful, unique things — products, apps, phenomena, oddities.

Built with Astro + MDX.

Key features

  • Four-collection pipeline: find (captured items, hidden from indexes), bundles (editorial roundups that reference find slugs in a grid), reviews (full-length, sometimes graduated from a find), posts (generic essays)
  • Daily capture skills under .claude/skills/: daily-finds (sweeps every source in sources.json, writes one find file per qualifying item — capture-only, no editorial selection); build-bundle (drafts a thematic bundle from the find pool); cluster-bundles (batch-clusters the entire find pool into multiple bundles); build-review (graduates a find to a full review, linking the two via fromFind / promotedTo)
  • Sources catalog at sources.json with per-source fetch strategy (webfetch / curl / skip) and the /sources page rendering a 3-column card stream with a "Recent finds" sub-list per card
  • Strict find visibility: find items are reachable only via the bundles that reference them, the /sources cross-reference, or direct URL — they don't crowd the home feed, tag pages, or category pages
  • Backlinks computed at build time: each find page lists every bundle that references it; promoted finds show a forward link to the review; reviews show a "← First surfaced…" backlink to their originating find
  • Newspaper-style masthead on every page: live entry-count + last-updated stats on the left, large serif "Unique" wordmark centered between thin rules, About/Blog nav on the right; per-page italic subheader ("A small log of delightful things.") with last-updated date on listing pages
  • Pinterest-style home page: hero card for the latest review plus a 3-column masonry grid of remaining reviews with a "Load more" reveal; old plain-list home preserved at /index3/
  • Unified chronological feed at /index3/ across reviews + bundles + posts
  • SEO-friendly site footer with Browse / Collections (live counts) / About link columns and a centered legal line; consistent 76rem page width across the entire site (article prose constrained to a comfortable reading measure inside the wider layout)
  • Reviews render as two-line index entries: bold name + muted subtitle (Cotypist / Autocomplete that lives everywhere on your Mac)
  • Auto-generated /categories/<name>/ and /tags/<name>/ listing pages — finds excluded by design
  • Amazon affiliate handling in src/lib/affiliate.ts: outbound links to Amazon (amazon.com, amzn.to, a.co, smile.amazon.com) get the configured tracking ID appended automatically; the link gets rel="sponsored", an "Affiliate" badge appears next to it, and a one-line disclosure is shown beneath. Add additional marketplace IDs (e.g. amazon.co.uk) to the AMAZON_TAGS map when needed
  • SEO surface: single <SEO> component owning canonical, Open Graph, Twitter Card, and JSON-LD; per-page structured data (Review, BlogPosting, Product, Article, CollectionPage, ItemList, BreadcrumbList, WebSite, Organization); auto-generated sitemap-index.xml (excludes /grid/ and /index3/); RSS feed at /rss.xml; robots.txt; static OG image fallbacks under /public/og/; promoted finds canonical to their review
  • Custom 404 page with recent-reviews and navigation fallback
  • Light/dark mode via prefers-color-scheme
  • Cloudflare Web Analytics beacon in BaseLayout.astro for cookieless, privacy-preserving page-view + referrer + Core Web Vitals tracking scoped to unique.rzen.dev
  • Otherwise no client-side framework — only the inline theme bootstrap and the analytics beacon
  • Static build, deployable anywhere

Local development

npm install
npm run dev      # local dev server
npm run build    # type-check + static build to ./dist
npm run preview  # serve the built site

Adding a review

Each review is a folder with index.mdx plus its media. The folder name is the slug:

src/content/reviews/cotypist/
├── index.mdx                # the article + frontmatter
├── hero.mp4                 # web-ready variants live here, alongside the article
├── screenshot.png
└── source/                  # heavy originals (archival; never bundled)
    └── hero.gif

index.mdx frontmatter:

---
name: "Cotypist"
subtitle: "Autocomplete that lives everywhere on your Mac"
date: 2026-05-03
category: writing
tags: [macos, productivity]
link: https://cotypist.app/        # optional product URL
linkText: "Visit in App Store"     # optional; defaults to the link's hostname (sans `www.`)
description: "Optional <meta> override; defaults to subtitle."
---

Body in markdown / MDX. You can import and use components here.

The folder name becomes the URL at /reviews/<slug>/. Media is referenced relatively:

![alt](./screenshot.png)

import demo from './hero.mp4';
<video src={demo} autoplay loop muted playsinline preload="metadata" />

If the review needs a hero on the home/grid pages, add it to src/lib/hero.ts.

Media

Prefer real screenshots, GIFs, or short clips from the app's own site (downloaded locally — don't hotlink). Pair with a short italic caption that names what's being shown. Visuals should illustrate the virtue of the product, not decorate the page.

Source vs published media. Heavy originals live in <slug>/source/; web-ready variants live at <slug>/<file> and are what the site actually ships. Files inside source/ aren't imported anywhere, so Astro doesn't bundle them into dist/. To add or replace a video:

# 1. drop the original into source/
mv ~/Downloads/demo.mp4 src/content/reviews/<slug>/source/

# 2. encode a smaller web variant alongside (h264 CRF 28, ≤1280px, no audio)
ffmpeg -i src/content/reviews/<slug>/source/demo.mp4 \
  -c:v libx264 -preset slow -crf 28 \
  -movflags +faststart -pix_fmt yuv420p \
  -vf "scale='min(1280,iw)':-2,crop=trunc(iw/2)*2:trunc(ih/2)*2" \
  -an src/content/reviews/<slug>/demo.mp4

# 3. reference ./demo.mp4 from index.mdx or src/lib/hero.ts

For animated GIFs, use the same recipe with crf 26 and source .gif — the resulting MP4 is typically 515× smaller.

Adding a post (essay)

Create a folder + index.mdx under src/content/posts/<slug>/:

---
title: "Some essay title"
date: 2026-05-10
category: writing
tags: [meta, opinion]
description: "Optional <meta> tag override."
---

Body in markdown / MDX.

The folder name becomes the URL at /posts/<slug>/. Drop any media (images, screenshots) next to index.mdx and reference them as ./image.png. Same convention applies to the find/ and bundles/ collections — each entry is a folder with index.mdx and any sibling media.

Project layout

src/
  content.config.ts          # collection schemas (reviews, posts, find, bundles)
  content/
    reviews/<slug>/
      index.mdx              # article + frontmatter
      <media files>          # web-ready variants (hero, screenshots, demos)
      source/                # archival originals (not bundled)
    find/<year>/<month>/<slug>/
      index.mdx                # find folders are bucketed by capture date
      hero.{jpg,png,gif,webp}  # auto-resolved by src/lib/find-hero.ts; URLs stay flat at /find/<slug>/
    bundles/<slug>/index.mdx # editorial roundups (text intro + grid)
    posts/<slug>/index.mdx   # essays
  lib/
    entries.ts               # getAllEntries() — unified feed across collections
  components/
    EntryList.astro          # shared two-shape entry list
  layouts/
    BaseLayout.astro
  pages/
    index.astro              # Pinterest-style home (hero + masonry)
    index3.astro             # plain chronological list view
    about.astro              # About page
    blog.astro               # /posts index (essays)
    grid.astro               # full grid of every review
    sources.astro            # source catalog
    reviews/[...slug].astro
    posts/[...slug].astro
    categories/[category].astro
    tags/[tag].astro
public/
  favicon.svg

Adding a new content type

  1. Define the collection in src/content.config.ts.
  2. Extend the Entry union and getAllEntries() in src/lib/entries.ts so the new type joins the merged feed.
  3. Add a detail route at src/pages/<type>/[...slug].astro.

Listing pages (index, categories, tags) need no changes — they consume getAllEntries().

S
Description
No description provided
Readme
591 MiB
Languages
MDX 88.6%
Astro 8.7%
TypeScript 1.5%
JavaScript 1%
XSLT 0.2%