Making content

There is still no CMS, and there will not be one. Photographs and words arrive through an agent — this instance can host one for you at /agent, or, if you would rather run your own, Fernscout Helper is a separate toolbox that gives it something to run.

git clone https://github.com/severinlindenmann/fernscout-helper
cd fernscout-helper
claude

MIT, no dependencies to install, and nothing it produces depends on it afterwards.

Three jobs, and every tool in it does one of them.

ExtractGet what already exists out of wherever it is stuck — a phone's photo library, a bank's CSV export
CreateAsk for what only a person knows — what happened that day, what the flights cost — and write it down without inventing the rest
FormatTurn all of it into this project's shape: one entry per day, sized galleries, costs, coordinates, status: draft

Extracting photographs

Say "help me export photos from iCloud on my Mac". What follows is five commands the agent runs for you, and one evening you spend in a browser.

  1. The tools are checkedosxphotos to read the Photos library, exiftool, and Node. Nothing is installed without asking. exiftool is the one that matters: Photos keeps location in its own database rather than in the files, and without it every exported picture arrives with no coordinates at all.
  2. You are asked four things: the dates, what to call the trip, whether there is an album, and whether to take everything or only the good ones. Photos scores its own pictures, so "every favourite plus the best-scoring rest, fifteen a day" is available and is a decent first pass.
  3. The selection is counted before it is fetched. How many photographs, how many gigabytes, roughly how many minutes — read back to you, because anything not already on the Mac comes down from iCloud.
  4. A page opens in your browser. Every photograph, grouped by day, with a Keep button and a note field, and a bigger box per day for what happened. You turn off what does not belong — the screenshots, the picture somebody sent you — and write a few words. It saves as you type.
  5. The content folder is written. One entry per day, galleries sized to 2000px, your photo notes as captions, coordinates in the frontmatter — and every trace of metadata stripped from the pictures themselves, which is the same rule lib/ingest follows here and for the same reason: a phone writes the coordinates of somebody's front door into a file.

Then the agent writes each day from your notes and from nothing else. Days you said nothing about get a question, not a paragraph.

Extracting costs

Say "import my Revolut statement". A consolidated statement is CSV — in the app, Accounts → the three-dot menu → Statement.

  • Transactions are read out per account currency, filtered to the trip's dates, and printed for you to look at first: by day, and by merchant with the biggest first. Twenty merchant names is a two-minute conversation; seventy payments is not.
  • Transfers, exchanges and money coming in are left out — moving your own money between your own pots is not a trip cost — and they are kept in the working file and marked, never silently dropped.
  • The exchange rate is computed from what the bank actually moved: the amount debited divided by the amount received, across every payment. That is the number trip.md's rates: block wants, and it is the one figure nobody can look up afterwards.
  • You sort the merchants into this project's seven categories. A statement says what was paid, never what it was for — the agent proposes, you correct, and a category this software does not know is refused rather than quietly turned into other.

Another bank is a different reader over the same middle: the file it produces is generic, and the half that writes into the journal is unchanged.

The costs a statement cannot see

Say "what did the trip cost". This one is an interview, because the biggest lines are the ones no card statement covering the trip dates will ever show: the flights booked in March, the hotel paid on arrival, the car on somebody else's card, the cash nobody has a receipt for.

The agent looks at what is already recorded, names what is missing — which categories have nothing, which days have nothing, whether flights and accommodation are absent entirely — and asks about those rather than about everything. Advance bookings land in costs.md; things paid during the trip land on the day. A budget can be set, and the costs page then draws real spending against it.

It will not estimate. An amount nobody remembers is not recorded, and the page reports an incomplete total rather than a confident wrong one. Costs somebody typed and costs read from a statement live in the same list, and only the imported ones are marked — so re-importing replaces those and never touches yours.

What comes out

content/<you>/trips/<trip>/
  trip.md                     the trip, its dates, its rates, its budget
  costs.md                    what was spent before leaving
  entries/2026-06-23-….md     one day: prose, gallery, costs
  media/…                     pictures, resized, metadata stripped

Point this software's CONTENT_DIR at that content/ folder and it is a site — see running-locally.md. Or hand the files to a hosted journal over the API, for which /agent.md is the guide.

Everything it writes is a draft. status: draft on every entry, filtered out of every reading path by lib/entries.ts. Publishing is a person's decision here exactly as it is everywhere else in this project.

It does not host, serve or render anything, it holds no account and no database, and it sends nothing anywhere — statements and photographs stay on the machine they were read from, and its import/, export/ and content/ folders are all gitignored. It is a separate repository with its own release cycle: this project does not depend on it, and it is not tested by this repository's suite.