Task Gremlin
An LLM-backed app that breaks overwhelming tasks into small next steps, live on the web and the iOS App Store. Built and run solo.
The product
Task Gremlin takes a task that feels too big to start and turns it into small, concrete next steps. It runs at taskgremlin.app and on the iOS App Store, and I built all of it myself: 164 commits and 16 merged pull requests in the first 46 days.
What I built
- A self-hosted LLM gateway (Hono and SQLite) between the app and the model providers, so no API key ever reaches a client. Seven AI tools run behind it.
- Structured output in JSON mode, with parse guards that accept responses wrapped in code fences or preambles instead of failing on them.
- Two billing rails. Stripe over raw REST on the web, with hand-verified webhook signatures and an idempotent checkout flow. RevenueCat in-app purchases on iOS, because App Store rules forbid Stripe inside the app.
- Self-hosted sign-in with Google and Apple. The OAuth state is HMAC-signed so the flow survives Safari’s tracking prevention dropping the cross-site cookie on Apple’s callback, and native sign-in is verified against Apple’s and Google’s JWKS.
Decisions worth keeping
Reserve, then refund. Each prompt slot is reserved in a database transaction before the model is called, so two concurrent requests can’t both slip under the limit. Every failure path refunds the slot. That includes truncated JSON, which is detected and refunded rather than served, since cut-off JSON never parses on the client.
Meter networks, not browsers. Clearing browser storage used to reset the free tier. Anonymous usage is now metered per network, with IPv6 collapsed to its /64, and the proxy overwrites X-Forwarded-For instead of appending to it, so a caller can’t forge their way into a fresh bucket.
Limits live in the database. Every quota and the model ID are runtime configuration. Cost controls change without a redeploy and without an app update.