A tool died, and that’s how this one was born
Months ago there was a small community tool — I’ll call it “galadriel” here,
because its real name is redacted for obvious reasons — that let you search
and stream anime straight from a terminal. No browser, no ads, just a
prompt, a search box, and a media player getting handed a link. It scraped
a streaming site whose real name I’m also not going to use, so I’ll call it
ashigaru.tv.
Then ashigaru.tv changed, or got taken down, or just stopped answering the
way galadriel expected. It doesn’t really matter which. What matters is that
galadriel depended on being able to scrape one specific site in one specific
way, and the moment that site moved, the tool had nothing left to stand on.
The repository is still up. It just doesn’t work anymore, and probably
never will again.
I got to know about galadriel too late. It was long gone by the time I found it. The loss was still real. Instead of reviving it, I decided to build my own, and to build it so that a single site going away would be an inconvenience, not an extinction event.
Treat the provider as hostile, not just as a dependency
The first design decision for anime-ter had nothing to do with anime. It was about how much I trusted a website I do not control, whose HTML and JSON shapes can change without warning, and whose incentives are not mine.
The answer was: not at all. Every response coming back from the provider is treated as untrusted input, full stop. A few rules follow from that, and I kept every one of them non-negotiable:
- Never execute anything the site sends. No JavaScript engine, no headless browser, nothing capable of running a script the provider controls. If it can’t run, it can’t fingerprint me, track me, or exploit me.
- Never hand a URL to a subprocess or a parser without validating it first. Every stream link, subtitle link, and referer has to clear a strict scheme allowlist before anything downstream ever sees it. This is enforced by the type system, not by a comment reminding someone to remember.
- Never parse untrusted text with something loose. HTML and JSON both go through real, bounded parsers with hard limits on size and nesting depth, so a hostile or just poorly-formed page can’t blow up memory or CPU.
- Never shell out with a string. Every subprocess call uses an explicit argument list. No shell interpolation, anywhere, ever.
- Never phone home. Watch history and settings live in a local file. There is no telemetry and nothing leaves my machine except the requests to the provider itself.
None of this makes the provider trustworthy. It makes the blast radius of the provider doing something unexpected as small as I could get it, which is the only thing actually in my control.
Why this stays off GitHub
anime-ter is not going up as a public repository, and that was a deliberate call for three separate reasons, not one.
First, scraping a site that hasn’t given permission for it sits in a legal and ToS gray area no matter how carefully it’s built. Publishing the source would mean publishing exactly which site, exactly how, which is a much bigger invitation than I want to send.
Second, that site runs on ad revenue. I’m not interested in helping route traffic around the thing that pays for it to exist. Using it privately for myself is one thing; handing out a tool that scales that up is another.
Third, and honestly the most important one: publishing the exact scraping approach in the open is the fastest way to get it noticed and closed off, which is the exact fate that ended galadriel and its provider. I’m not eager to repeat that lesson with my own project and its provider.
This was built as a training exercise, for me and for the handful of close friends and family who already know about it. If you’re one of the people this reaches and you want in, email me. But honestly, I’d rather point you at the idea than the binary — building your own version will probably teach you more than using mine ever will, and the journey is the actual point.
The build: mostly Sonnet, always my call
I built this almost entirely through Claude, model Sonnet, and I want to be specific about that because there’s a narrative floating around that you need the biggest, most expensive model to get real engineering work out of an AI assistant. That has not been my experience here. What made this work wasn’t the model tier, it was the process wrapped around it.
I described what I wanted at each step, Sonnet proposed how to build it, and nothing got written until I’d actually read the plan and either approved it or sent it back with corrections. Security-sensitive pieces — the URL validation, the subprocess boundary, the parsing limits — got extra scrutiny before any code landed, because those are exactly the spots where a plausible-looking suggestion can quietly be wrong. The rest of it moved fast precisely because I wasn’t trying to review every line, only the decisions that actually mattered.
The lesson isn’t “Sonnet is secretly as good as anything bigger.” It’s that model tier matters less than I expected once you’re the one holding the plan, checking the output, and refusing to let momentum substitute for understanding. A bigger model doesn’t fix a hands-off process, and a careful process gets you a long way on a smaller one.
The part that actually got me
Here’s the thing I didn’t expect going in. I’ve had the idea for a tool like this and many others for a long time — genuinely years, on and off. I’ve forgotten more than I can remember. Most importantly, I always had the know-how. I could have built them by hand, eventually, on some weekend I never seemed to find.
I don’t have that weekend. What I have now is fifteen minutes here, an hour there, direction I can give from my phone between other things. Some of the screens in anime-ter’s TUI got designed and iterated on while I was skating outside — not writing code, just describing what I wanted the next screen to feel like, reading back what came out, and correcting course. The tool kept getting built. I kept living my day.
That’s the actual shift for me. It’s not that AI writes code I couldn’t write myself. It’s that the distance between having an idea fully formed in my head and having a working thing in front of me used to be measured in free weekends I didn’t have, and now it’s measured in attention I can spend in short bursts without stopping what I’m already doing. I used to close browser tabs of “software that does roughly this” because building my own version wasn’t a realistic use of the time I actually had. Now it is, and that changes what’s worth building for just one person: yourself.
Just a tiny footnote
A tiny gotcha in the AI driven world is that it is becoming a norm to make the models do better without us, and we design workflows and tools to make them more automated, more independent. A loop here, a memory there plus a model big enough and I will need to direct the AI a little less. There was an article where the term meat proxy was minted. I don’t believe in being a meat proxy. I believe that we are context windows for AIs. We remember what they can’t, we tell them what they can’t guess or see. We still hold the responsibility to connect the dots for them, because even after knowing a lot, all they can do is mix-and-match what they know from us. We still need to learn and know things, because only we can do deterministically what the AIs are trying to do probabilistically.