Skip to content
All builds

DogearSmart Bookmarks

What it does for you

A bookmark manager that suggests tags with confidence scores, learns from every accept or reject, and can hand batches to Claude.

Dogear screenshot

Screenshots

Dogear screenshot 1

In more detail

Dogear is a bookmark manager that suggests tags for every link you save and learns from the ones you accept or reject. Bookmarks usually pile up untagged and never get found again. Dogear makes tagging a one-click yes or no, and it tries hard to reuse your tags instead of inventing new ones.

Honest limits

The live Claude batch call was never made during the build (no key used, by rule). Live /api/meta fetches against real sites were not tested either. The SSRF block path was checked once by hand (127.0.0.1 returns "blocked address (loopback)"), and the guard logic is covered in verify.mjs. Clicks were exercised through headless renders, not a manual pass. Storage is localStorage, which a big import could fill.

How I built it

Claude Code wrote the pure core, marks.js, and the 270-assertion verify.mjs first, then the UI as about a dozen small modules. I set the spec, the port, the "local first, Claude optional" rule, and the SSRF guard as non-negotiable.

Earlier runs wrote the core and the UI, then died on dropped API streams before screenshots or the case study were captured. The fix I pushed was the tiny-writes approach: no file over about 100 lines per call, one tool call per turn, many small modules. So the finishing run on September 23 (about 0.5 hours) only had to keep every good file, re-run verify, retake both screenshots, and write the docs.

The local tagger blends five signals into one confidence score: domain rules, URL path words, content type, TF-IDF keywords against your own library, and learned weights. It works with no key and no network. There is also an optional page-info endpoint on the local server, and since that is a classic SSRF surface, it checks the URL, pins every DNS answer, and rechecks the socket's remote address on every redirect hop.

What I learned

  • Showing a confidence percent with accept and reject turns every click into training data. Per-feature weights keep that learning transparent and exportable in the JSON backup.
  • Sending Claude the existing tag vocabulary, most used first, plus each link's rejected tags, is what stops tag sprawl. Parsing its JSON defensively matters more than the prompt wording.
  • SSRF is not one check. A URL filter alone loses to DNS rebinding and redirects, so the server checks the name, pins the resolved address, and rechecks the socket on every hop.
  • On a flaky connection, small files are a reliability tool, not just a style choice.

What carried forward

This is one of the stalled builds the #31 tiny-writes pilot rescued. The local-default, Claude-optional AI shape matches #33 Tidemark: a deterministic engine does the work, and the model is an add-on that has to go through a tested parser. The zero-dependency serve.mjs pattern goes back to the first days of the sprint in June; here it grew a guarded /api/meta route.

If I took it further

I would move storage to IndexedDB so large imports never hit the quota, and add a browser extension so saving a link does not mean switching tabs.

#035 Built with Claude Code September 23, 2026 270 automated checks

Want one like this?