Files
unique/.claude/skills/daily-finds/SKILL.md
T
rzen 9858abedc2 initial: four-collection content pipeline for unique.rzen.dev
A small Astro + MDX blog for delightful, daily-use finds. The architecture
separates capture from publication and supports reuse:

- find/    captured items, hidden from indexes
- finds/   editorial superposts referencing find slugs in a grid
- reviews/ full-length writeups; can graduate from a find via fromFind
- posts/   regular essays

Three project-local skills under .claude/skills/ drive the pipeline:
daily-finds (capture-only sweep across sources.json), build-finds (draft
a thematic superpost), build-review (graduate a find).

sources.json carries 47 curated feeds with per-source fetch strategy
(webfetch / curl / skip) so Cloudflare-blocked sites and Reddit JSON
endpoints are handled deterministically. /sources renders a 3-column
card stream with a "Recent finds" cross-reference per source.

Seeds: 17 reviews and one superpost referencing 5 finds.
2026-05-03 11:48:03 -04:00

107 lines
6.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: daily-finds
description: Capture-only daily sweep for unique.rzen.dev. Scans every source in sources.json, writes one find file per qualifying item to src/content/find/, and nominates 1-2 new sources to consider. Does NOT pick a winner, write a superpost, or address the user/audience. Picking happens via /build-finds and /build-review. Use when the user asks for "today's finds", "morning sweep", "capture", or runs /daily-finds.
disable-model-invocation: true
---
# daily-finds
Pure capture: every item that passes the bar becomes a `find` file. No daily cap, no theme detection, no audience-facing post. Whether any of these finds appears in a `finds` superpost or graduates to a review is a separate editorial decision.
Invoke from inside the `unique.rzen.dev` repo.
## Inputs
- `sources.json` at the project root — curated source list with per-source `fetch` strategy (`webfetch` / `curl` / `skip`) and optional `fetchUrl`.
- `daily-finds.log.md` — running log of every find slug ever written (used to skip duplicates).
- `src/content/find/*.mdx` — already-captured finds (every existing slug is a "do not re-suggest" item).
- `src/content/reviews/*.mdx` — already-reviewed items (do not re-suggest).
- `candidate-sources.md` — newly nominated sources awaiting user vetting.
## The bar
A find qualifies if and only if it is **(a)** delightful, unusual, or distinctive in a way the audience would care about *and* **(b)** usable daily (relax to "memorable for a visitor" for travel). Drop generic mass-market items, ad-copy listicles, speculative / not-yet-shipping products, self-promo, and anything not traceable to a real currently-buyable / currently-visitable thing.
Crucially: do **not** filter by "is it the best of the day." Capture broadly. Editorial selection happens later.
## Procedure
### 1. Scan every source
For each source in `sources.json`:
- **Default (`fetch: "webfetch"` or no field)**: WebFetch against `fetchUrl` if present, else `url`. Extract recently-featured items (name, link, one-line description).
- **`fetch: "curl"`**: shell out to `curl -sL -A "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15" --max-time 25 "<fetchUrl|url>"` and parse the HTML body. For Reddit JSON endpoints, pipe through `python3 -c '…'` to extract titles, links, and selftext. Treat HTTP 403 with a non-empty HTML body as a content response (Atlas Obscura quirk) — only treat empty bodies or Cloudflare challenge markers as blocked.
- **`fetch: "skip"`**: log the source as skipped (with `skipReason`) and move on. Do not retry.
Parallelize WebFetch in batches of ~8 concurrent requests; finish all sources before proceeding.
For each source record: items extracted, or `empty` / `blocked` / `skipped`.
### 2. Filter
For each extracted item, drop:
- Anything whose slug already exists in `src/content/find/`.
- Anything whose name appears anywhere in `daily-finds.log.md`.
- Anything reviewed in `src/content/reviews/` (compare by `name` field).
- Items that fail the bar above.
### 3. Write find files
For every survivor, write one file at `src/content/find/<slug>.mdx`:
- Slug: kebab-case form of the name (lowercase, ASCII, no leading numbers).
- Frontmatter: `name`, `subtitle` (optional, one-liner), `date` (today), `link` (external URL — required), `linkText` (optional), `source` (the source name from sources.json — required, exact match), `topics` (copied from the source's `topics`), `tags` (free editorial tags inferred from the item — keep to 2-4), `description` (optional meta override).
- Body: 2-3 sentence note. Concrete, name a *specific* virtue. Bad: "great design". Good: "the silicone bumper means it survives drops onto concrete; the lanyard hole is positioned where your thumb naturally rests".
- No daily cap — write every survivor.
If `link` for a Reddit-discovered item points at a v.redd.it / i.redd.it URL, fetch the post's selftext or comments to find the actual product URL before writing the file.
### 4. Nominate 12 new sources
Spend a small slice of the run on source discovery:
- During scans, when another publication / blog / shop / newsletter is referenced in a way that suggests it'd fit the brief, capture it.
- Or run one targeted `WebSearch` for `"best <topic> newsletter"` or `"<topic> curator blog"`.
- Append nominees to `candidate-sources.md` (create if missing) under today's date heading. For each: name, URL, a one-line case for adding, and which existing source surfaced it (or "WebSearch").
- Don't auto-add to `sources.json` — that's a user decision.
### 5. Update the log
Append to `daily-finds.log.md`:
```
## YYYY-MM-DD — capture run
Sources scanned: <N> total — <hits> hits, <empty> empty, <blocked> blocked, <skipped> skipped.
Productive sources: <comma-separated list of sources that produced at least one written find>.
Captured finds:
- <slug> — <name> — source: <source>
- <slug> — <name> — source: <source>
- ...
New source nominees: <count> (see candidate-sources.md).
```
### 6. Report to the user
Short summary in chat:
```
Captured <N> finds across <M> productive sources today.
Blocked: <K> sources. New source nominees: <count>.
Run /build-finds to draft a superpost from the recent pool, or /build-review <slug> to graduate one to a review.
```
That's it. No theme, no candidates list, no "pick a winner."
## Notes
- "Why it fits" / find descriptions should name a *specific* virtue. Bad: "great design". Good: "magnetic connector means it never strains the cable when a foot catches it".
- Travel destinations relax the daily-use criterion — a place qualifies if a visitor would remember it years later.
- If a source's homepage is too noisy, prefer adding a `fetchUrl` to `sources.json` rather than working around it inside the skill.
- Never invent slugs that collide with existing finds or reviews. If a name would produce a colliding slug, append a year or distinguishing word.
- Source attribution must be exact — the `source` field in each find file must match a `name` in `sources.json` so the `/sources` page cross-reference works.