Inspiration

I'm just starting out as a freelance developer. My clients are small, local businesses: a guesthouse, a clinic, a dental practice. When something breaks on their site, I get the same message every time: "it doesn't work", plus a screenshot, on WhatsApp. No page, no steps, no idea what they clicked. I end up spending more time asking what happened than fixing it.

I didn't want a ticketing system. My clients would never fill in a form. I wanted the screenshot and the one sentence they already send me to arrive as a ticket I can act on, and I wanted the AI part to be honest about what it actually knows.

What it does

Each client gets a private link. On it they add a screenshot and one sentence. No account, no form. Their reports stay on that page with a status (Received, In progress, Done), and they can add a follow-up later.

On my side, every client is a chat. Claude reads the screenshot in the background, and a ticket card appears under the client's message: a title, where it happened, what's wrong, tags, severity and a confidence score.

The core idea is the split between what the screenshot shows and what the model inferred. Expected result and steps to reproduce are inferred fields: each one either carries a "Based on:" evidence line or stays empty with "Not enough in the screenshot to tell". If the sentence is vague and confidence is low, the ticket gets an Ask client flag instead of a guess. If the model can't read the image at all, the card says so and offers a retry.

I can fix any field in place (edited fields are marked, with the model's original on hover), and one key copies the ticket as Markdown, ready to paste into a GitHub issue.

Who it's for

Right now: me and my own clients, a closed environment. Longer term: freelancers and small agencies who maintain apps for non-technical clients and are tired of being the human parser between "it doesn't work" and a bug report.

How I built it

With Claude Code and the Devpost Learn skill pack, start to finish. Scope first, then a PRD, then a technical spec, then a build checklist. All of it is in the repo under devpost/. The build went in small, tested slices: extraction and its eval first, then the client page, then the dashboard and ticket detail, then a demo seed and a review pass against a list of things hackathon judges actually look for.

Stack: Next.js 16, TypeScript, Tailwind v4, shadcn/ui, Postgres with Drizzle. Extraction runs on Claude Sonnet with a Zod-validated structured output; the report is saved first and extracted second, so a model failure never loses a client's message. It runs locally with Docker Compose and in production on Vercel with Supabase for Postgres and screenshot storage. 407 tests, typecheck and lint pass.

Challenges

  • Keeping the model honest. The first prompts invented plausible reproduction steps. The fix was structural: observed and inferred fields live in separate parts of the schema, every inferred field must cite evidence or be null, and the eval treats any invented inferred field as a failure of the whole run.
  • A client page that doesn't feel like a form. The version that stuck is a feed: the client's own reports as a chat, with the composer at the bottom, like the apps they already use.
  • Demo data that looks real without being real. All screenshots in the demo and the eval are synthetic captures from my own apps with fictional data. They aren't in the repo at all, so nothing from a real client can leak.
  • Going serverless the night before. The app stored screenshots on disk and kept the login limiter in memory, neither of which survives on Vercel. Screenshots moved behind a storage interface (local disk for Compose, a private Supabase bucket in production), every rate limit moved into the database, and extractions that outlive a function instance are cleaned up instead of failing reports another instance is still reading.
  • Small things judges hit first: a hydration mismatch from server and client timezones, an auth wall with no demo code, screenshots not served from the container volume. Each found in the review pass and fixed before recording.

What I learned

An AI feature earns trust by showing what it doesn't know. The empty field with "Not enough in the screenshot to tell" turned out to be the most convincing part of the demo.

Spec before code works even for a one-person project. The deploy rewrite went smoothly because the storage and rate-limit boundaries were already written down.

And the honest limit: the eval set is 21 synthetic screenshots, and only the first case has its real client sentence and reference ticket so far, so I don't publish an acceptance number yet. The pipeline is there; the data collection is the next job.

What's next

Fill the eval set with sentences from real non-technical people role-playing clients and publish the numbers. Then the things my own clients will ask for first: more than one screenshot per report, a reply channel back to the client, and GitHub issue creation instead of Markdown copy. After that, multi-user, so it can grow into a tool for small agencies.

Try it

Voiceover in the video was generated with ElevenLabs text-to-speech from a script I wrote.

Built With

Share this project:

Updates

Submission history