StoreScribe 用 Gemma 4 為 App Store 和 Google Play 生成符合欄位限制的上架文案
StoreScribe: an open model writes your App Store listing, inside every limit
開發者 Souvik Biswas 建立 StoreScribe,使用 Gemma 4 為 App Store 和 Google Play 生成符合各欄位限制的上架文案。工具可分析截圖、搜尋同類應用,並生成最多六種語言的文案;CLI 會讀取專案資料並將結果寫入 fastlane/metadata。CLI 的 --local 模式透過 Ollama 在本機執行 Gemma 4,無需網絡連線。
This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle
What I Built
StoreScribe writes your App Store and Google Play listings, researched against the apps you're competing with, inside every character limit, in up to six languages.
I build mobile apps, and the part I always put off is the store listing. The code is done, the screenshots are done, and then App Store Connect asks for:
- an app name in 30 characters
- a subtitle in 30 characters
- a keywords field of 100 bytes. Bytes, not characters, so Japanese gets about a third of the room
- promotional text and a description
Then Google Play wants its own title, short description and full description. Then you do all of it again for every language you want to sell in.
There are tools for this (App Store optimization, or ASO, is a whole industry), but they're built and priced for studios and agencies. An indie developer shipping one app a quarter isn't going to pay for that. They'd pay $6 a month for something that gets the listing right in two minutes.
Who pays: indie app developers and small studios. The free tier covers one app in three languages. The paid plan covers more apps, all 14 languages, competitor research and daily rank tracking.
What it does:
- Reads your screenshots with Gemma's vision, so the listing describes what the app actually does.
- Researches the category: pulls the top App Store and Google Play results for your search terms and finds the words they all use.
- Writes every field for both stores with Gemma 4.
- Enforces the rules in code, not in the prompt. Every limit is checked, Apple's keyword field is measured in bytes, banned words in Play titles are caught, and so is keyword stuffing and a short field that repeats a word ("Track planes & planes near you" got caught by this, and rewritten). Anything that doesn't fit goes back to the model to be tightened.
- Packs the keywords field: most valuable terms first, nothing already in the name or subtitle (Apple indexes those anyway), no competitor brand names, no wasted spaces.
- Localizes for each market, with the keywords people there actually type, not translations of the English ones.
- Lets you edit with live counters, keeps every version, exports straight to fastlane, and tracks your rank for each keyword, day by day, once you're live.
And a CLI that reads your repo
Filling in a form felt wrong for developers, so there's also a CLI. Run it inside your app's repo:
npx github:sbis04/storescribe --langs ja-JP,de-DE
It reads the project itself: the app name and bundle id from Info.plist, pubspec.yaml or app.json, the README, the names of the screens in your code, your current fastlane listing and any screenshots it can find. Then it writes the finished listing into fastlane/metadata, ready for fastlane deliver. It works with Flutter, React Native, Expo, Swift and Kotlin projects.
Add --local and Gemma runs on your own machine through Ollama. No web searches, no server, nothing leaves your laptop.
Demo
Try it: storescribe.souvikbiswas.com (no sign-up)
Code
sbis04
/
storescribe
App Store and Google Play listings that fit every limit, use the words your category searches with, and read like a person wrote them.
StoreScribe
App Store and Google Play listings that fit every limit, use the words your category searches with, and read like a person wrote them.
In English and up to five more languages. Written by Gemma 4, an open-weight model
Try it: storescribe.souvikbiswas.com · Demo video · CLI
Why
Your app is done. Now the App Store wants a 30-character name, a 30-character subtitle, a keywords field of exactly 100 bytes, promotional text and a description, and Google Play wants its own set. Then the same again in every language you sell in. Japanese gets about a third of the keyword room, because Apple counts bytes, not characters.
StoreScribe studies the apps you're up against, then writes both listings inside every limit, in about two minutes.
Screenshots
Your listing, inside every limit. A live App Store preview with your screenshots, and a counter on every field.
Each language…
MIT licensed. Everything in the demo is in the repo, including the deploy scripts.
How I Built It
The model is Gemma 4. On the live site it's gemma-4-31B-it on DigitalOcean's serverless inference. Locally, and in the CLI's --local mode, it's gemma4 through Ollama. The same code talks to both: one setting switches between Ollama's API and any OpenAI-compatible endpoint.
The model writes, the code decides. This was the most important design choice. Language models are bad at counting characters, and worse at counting UTF-8 bytes. So I never ask Gemma to "stay under 30 characters" and hope. Each draft goes through limits.js, which measures every field the way the store does (grapheme clusters for names, bytes for Apple's keywords), lints it against store policy, and sends anything over the limit back to Gemma with the exact count. If two rewrites still don't fit, it trims cleanly at a word boundary. In the demo you can see this happen live: "Subtitle is 34/30, tightening it".
Keywords are packed by code, too. Gemma suggests 20 candidate terms in priority order. Code then builds the 100-byte field: it drops anything already in the name or subtitle, plurals of words already used, and competitor brand names (taken from the research), and stops before the byte limit. In Japanese that's only about 33 characters; AeroTail's Japanese keywords use 91 of the 100 bytes.
Research comes from SerpApi. The App Store and Google Play engines return the top apps for each search term. StoreScribe shows them, works out the words that recur across them (the category's search vocabulary) and gives that to Gemma as context. The page then shows which of those words made it into your listing. Searches are cached for a day, because the free plan is 250 searches a month.
Tiger Data holds everything that changes over time. It's TimescaleDB on Tiger Cloud:
-
listing_versions: every draft and every hand edit, per store and language, so you can go back to any version. -
keyword_ranks: one row per keyword per daily check. The rank chart reads atime_bucketover this. -
usage: every model call and search, with its cost. Ausage_dailycontinuous aggregate powers the "this month" meter, and it's what a subscription would be billed from.
All three are hypertables.
DigitalOcean runs it. A $6 Droplet with Caddy (automatic HTTPS) and the Node app, created and deployed by one script (deploy/up.sh). Gemma runs on DigitalOcean's serverless inference, so the Droplet needs no GPU.
The front end is plain HTML, CSS and JavaScript. I tested it at wide desktop, laptop, tablet and phone sizes, in light and dark. On a phone, once a listing exists, the listing comes first and the form folds away.
The CLI (src/repo.js) is a scanner, not a model: it reads files and finds bundle ids, display names, feature folders, screen files, README sections and screenshots (portrait images first, so it picks real screens over marketing art). Only then does Gemma turn that into a brief.
Why Does Open Innovation Matter?
Because the business only works if a listing costs almost nothing to write. A full listing for both stores in six languages is about 13,000 tokens in and 10,000 out. At DigitalOcean's Gemma 4 price ($0.18 per million input tokens, $0.50 per million output), that's less than one cent. A listing isn't written once: you rewrite it for every update, every season and every new market. At under a cent each, a $6 subscription has plenty of margin even for heavy users. On a frontier closed API the same job costs many times more, and the price is set by someone else.
Because developers don't want their unreleased app on someone else's server. Screenshots of an app that isn't out yet are sensitive. StoreScribe never stores them, and with --local Gemma runs on your own laptop: no API key, no account, no network. The same model that powers the hosted version runs offline, which is only possible because the weights are open.
Because the model is one setting. I developed and tested everything against Gemma on my Mac, for free, and deployed against Gemma on DigitalOcean without changing a line of the writing pipeline. If a better open model comes out, it's an environment variable. If I collect listings that convert well, I can fine-tune on them. None of that depends on one vendor's roadmap or pricing.
Where open didn't win: small local models are weaker at hitting exact lengths and at not repeating themselves. That's why the rules live in code, and why there are automatic rewrites. Once the code owns the rules, an open model is more than good enough for the writing.
My Agent Session
I built StoreScribe with Claude Code in one evening. Here's the session, from reading the challenge and picking the idea, through the CLI and the UI passes, to recording the demo video:
You
ok fine keep it offline
now, a new week hackathon is happening: https://dev.to/challenges/hacktoberfest-week2-2026-10-12
let's participate in this with a competely new project
read all the details from tje webpage
I think the prizes and the categories are the same
let me know what ideas are you thinking of?
Agent
You
Tool loaded.
Agent
I read the full details through DEV's challenge API. First, the timing:
Week 2 closes tonight at 11:59 PM PDT (06:59 UTC Oct 19). Assuming you're on India time, that's about 17 hours from now. It's doable, but only with a tight, small project. Week 3 starts tomorrow (Oct 19, 16:00 UTC) and gives a full week, but its theme isn't announced yet.
Week 2 in short. The theme is Side Hustle: build something with open-weight models or open-source AI that someone would actually pay for. The open part has to be what makes it work. The post should explain why open matters here: cost, privacy, fine-tuning for a niche, or avoiding lock-in. There are bonus points for landing a first user and telling them whether that person paid, would pay, or what they asked for next.
- Judging: writing counts most, then fit with the theme, creativity, technical execution, and use of a partner's tech.
- Prizes: the same as last week. $250 overall, six featured categories at $200 (Gemma, DigitalOcean, Render, TabPFN, Tinker, Arduino), and eleven partner categories at $100, now including a .tech domain. One win per person per challenge.
- To enter: use the Side Hustle submission temp …
You
her's the post template:
<pasted_content id="dd41">
This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle
What I Built
<!-- What does it do, and who would pay for it? What problem does it solve for them? -->
Demo
<!-- Share a deployed link or a video demo. -->
Code
<!-- Show us the code! You can embed a GitHub repo directly into your post. -->
How I Built It
<!-- Which open-source AI did you use (open-weight models, agent harnesses, frameworks, local inference), and how is your project built around it? -->
Why Does Open Innovation Matter?
<!-- Why does open innovation matter for what you built? What did it make possible that a closed API wouldn't? -->
My Agent Session
<!-- Optional, but judges love it. Save your session with DevRelay and embed it with the agent_s …
Agent
Going with the shoot culler, and you'll be the first user. I'll check the local setup first.
I'll build it as Keeper, a local app you start with a folder of photos. Everything runs on the laptop with Gemma 4 through Ollama.
You
The user sent a new message while you were working:
what categories would this qualify in>
This is how Claude Code surfaces messages the user sends mid-turn — within the running turn, often alongside the next tool result, rather than as a separate conversation turn. Address the message above as you continue this turn.
[Request interrupted by user]
first allow do an assessment of which categories would be the easiest to win based on all th submission yet and from the last few weeks ones
based on that we might decide to change the prject idea
The user sent a new message while you were working:
what categories would this qualify in>
This is how Claude Code surfaces messages the user sends mid-turn — within the running turn, often alongside the next tool result, rather than as a separate conversation turn. Address the message above as you continue this turn.
[Request interrupted by user]
first allow do an assessment of which categories would be the easiest to win based on all th submission yet and from the last few weeks ones
based on that we might decide to change the prject idea
Agent
You
Tool loaded.
Agent
You
[Request interrupted by user for tool use]
have youn stared the assessment yet??
[Request interrupted by user for tool use]
have youn stared the assessment yet??
Agent
I counted mentions of each partner in the tags, titles and summaries of all 2,904 #hf26challenge posts:
| Category (prize) | Weekend | Week 1 | Week 2 so far |
|---|---|---|---|
| Gemma ($200) | 107 | 194 | 151 |
| TabPFN ($200) | 9 | 16 | 19 |
| GitHub Copilot ($100) | 6 | 2 | 18 |
| Render ($200) | 4 | 5 | 10 |
| Sentry ($100) | 2 | 0 | 6 |
| ElevenLabs, Entire ($100) | 6 / 2 | 4 / 4 | 4 / 4 |
| Tinker ($200) | 1 | 2 | 3 |
| DigitalOcean ($200) | 0 | 1 | 2 |
| Tiger Data ($100) | 0 | 0 | 2 |
| Temporal, MongoDB, SerpApi, .tech ($100) | 1 / 3 / 0 / 0 | 5 / 3 / 1 / 0 | 2 / 2 / 2 / 2 |
| Arduino ($200) | 0 | 1 | 1 |
Week 2 has 852 posts so far, against 1,210 for Week 1.
Caveat: this undercounts, because most people list categories only in the post body, which I didn't download. The proportions are what matter, and they're very lopsided.
What this means:
- Gemma is crowded. About one in six posts mentions it, so it's the hardest category to win despite paying $200.
- DigitalOcean, Tinker and Arduino pay $200 and have almost no competition. Last week you won DigitalOcean against probably one or two other entries, likely inc …
You
prioritize the ones those qualify for this week first
Agent
Here are the Week 2 categories ranked by how winnable they are tonight. That weighs how many entries mention each so far, the prize, and whether we can use it properly in about 16 hours.
| # | Category | Prize | Week 2 entries so far | Can we do it tonight? |
|---|---|---|---|---|
| 1 | DigitalOcean | $200 | 2 | ✅ Yes. Same setup as your win: Gemma on DigitalOcean's inference plus a Droplet |
| 2 | Tiger Data | $100 | 2 | ✅ Yes. Reuse the Leaf Peep account and setup |
| 3 | .tech domain | $100 | 2 | ⚠️ Possibly. It needs a .tech domain, which may come free through hacktoberfest.com/my. Worth checking |
| 4 | SerpApi | $100 | 2 | ⚠️ Only if search fits the idea. A listing writer could use it to look up competing apps' keywords |
| 5 | Arduino | $200 | 1 | ❌ Only if you have a board at home |
| 6 | Tinker | $200 | 3 | ❌ Fine-tuning takes too long for tonight |
| 7 | Temporal / MongoDB / Mastra / Backboard | $100 | 1–2 each | ⚠️ Possible, but each adds new setup work |
| 8 | ElevenLabs / Entire | $100 | 4 each | ⚠️ Moderate competition |
| 9 | Sentry / Render | $100 / $200 | 6 / 10 | ⚠️ More crowded |
| 10 | GitHub Copilot / TabPFN | $100 / $200 | 18 / 19 | ❌ … |
You
can you actually check all the project body for the category they are participating for the ones those qualify for this week>
Agent
I'll download the full text of the 852 Week 2 posts, fairly slowly so DEV doesn't block us. Then I'll read each post's "Prize Categories" section.
You
[Request interrupted by user for tool use]
also I do have an ardunoi UNO q board at home
and what about these?
[Request interrupted by user for tool use]
also I do have an ardunoi UNO q board at home
and what about these?
Agent
You stopped the download, so I'll use only what's already on disk: 476 Week 2 posts whose full text was saved by the earlier attempt. No more requests to DEV.
I worked only from posts already saved on disk, with no new downloads. That gave 207 posts, of which 163 are Week 2 submissions and 80 list prize categories:
| Category | Prize | Entries in sample | Estimated across all Week 2 (×5) |
|---|---|---|---|
| DigitalOcean | $200 | 0 | ~0–5 |
| MongoDB, SerpApi | $100 | 0 | ~0–5 |
| Arduino | $200 | 1 | ~5 |
| Tiger Data, Sentry, Temporal, Mastra, Backboard | $100 | 1 each | ~5 |
| ElevenLabs, Entire | $100 | 2–3 | ~10–15 |
| .tech domain | $100 | 4 | ~20 |
| TabPFN | $200 | 5 | ~25 |
| Tinker | $200 | 5 | ~25 |
| GitHub Copilot | $100 | 5 | ~25 |
| Render | $200 | 7 | ~35 |
| Gemma | $200 | 36 | ~190 |
Arduino UNO Q is your best shot. It's a $200 featured category with almost no competition, and you have the board. Hardware also makes the post and demo memorable, which helps with writing quality and creativity, the criteria judges weight most. The UNO Q runs Linux next to its microcontroller, so it can run a small open model on the board itself. That's a strong "why open" story: no cloud, no monthly fee and private by default, which is exactly what this week's prompt asks about.
The othe …
You
let's just start with withoit wasting time:
The idea that fits these best: the App Store listing writer. It's a hosted subscription tool, so DigitalOcean is central rather than bolted on. Tiger Data keeps each app's listing history, SerpApi pulls competing apps' keywords, and it could live on a .tech domain. The culler is mainly a laptop app, so it only meaningfully uses Gemma, the crowded category.
let's just start with withoit wasting time:
The idea that fits these best: the App Store listing writer. It's a hosted subscription tool, so DigitalOcean is central rather than bolted on. Tiger Data keeps each app's listing history, SerpApi pulls competing apps' keywords, and it could live on a .tech domain. The culler is mainly a laptop app, so it only meaningfully uses Gemma, the crowded category.
Agent
Starting the build. It's called StoreScribe for now, and we can rename it later. I'll reuse the parts of Leaf Peep that worked: Gemma through DigitalOcean (with Ollama locally), Tiger Cloud and the deploy scripts.
I have what I need. Writing the backend now.
You
The user sent a new message while you were working:
what quick ideas do you have for Ardunio Q which you think might win?
This is how Claude Code surfaces messages the user sends mid-turn — within the running turn, often alongside the next tool result, rather than as a separate conversation turn. Address the message above as you continue this turn.
Agent
I've paused StoreScribe. The setup is done but no app code is written yet, so switching now costs nothing.
The UNO Q is an Arduino and a small Linux computer in one: it has an 8×13 LED matrix, runs Debian and can run a small open model (Gemma 3 1B or 270M) on the board itself. Here are ideas that only need the board, plus your laptop or phone for setup:
-
Billable hours box for freelancers (my pick). A little desk clock for side-hustlers who bill by the hour.
- You pick a client in a tiny web page served from the board and start a timer. The LED matrix shows the client and running time, so you don't need another browser tab.
- When you stop, you jot a quick note like "fixed login bug, call with Priya". The open model on the board turns the notes into clean invoice lines, then makes the week's invoice as a PDF or CSV.
- Who pays: freelancers already pay $9–12/month for tools like Toggl and Harvest. This is a one-off device with no subscription.
- Why open: client names and rates never leave the desk, and it keeps working with the Wi-Fi off. That's an exact match for the prompt's "keep your customers' data private" and "avoid lock-in".
- **Feasibilit …
You
I think doing a hardware project in limited time qwould be a hazzle, continue with the one we started
Agent
Continuing with StoreScribe. I'll write the model layer first: one wrapper that works with both Ollama locally and DigitalOcean's inference in production.
Next are the store rules: character limits, Apple's 100-byte keywords field, and Play policy words. Code will enforce these instead of trusting the model.
The schema is live on Tiger Cloud: three hypertables (listing_versions, keyword_ranks, usage) and a continuous aggregate for the usage meter. Next is the writing pipeline.
Let me test the pipeline with local Gemma before building the server around it:
Backend committed (under your name only). Now the front end, starting with the page structure:
Now the styling, with light and dark themes:
You
The user sent a new message while you were working:
make sure to creat a lanbdinbg page fo the app a well
and do end to end testing of the project
This is how Claude Code surfaces messages the user sends mid-turn — within the running turn, often alongside the next tool result, rather than as a separate conversation turn. Address the message above as you continue this turn.
Agent
Noted: I'll add a landing page at / and move the tool to /app, then test the whole thing end to end. First the app's logic:
Now the landing page at /. The tool moves to /app:
You
The user sent a new message while you were working:
Instead of we habing to give the following:
<pasted_content id="dd41">
What you give it
In a single form:
- App name (required, 30 characters max)
- One-line pitch (required), e.g. "Split bills with roommates and settle up without awkward reminders"
- Details (optional): features, what makes it different, tone of voice
- Who it's for and category (optional)
- Search terms (optional): up to 3, like "split bills, rent tracker". If you leave this empty, Gemma suggests 3 itself.
- Screenshots (optional, up to 5). Gemma reads them to list what the app actually does. They're shrunk for the model and never saved to disk or the database.
- Stores: App Store, Google Play, or both
- Languages: English plus up to 5 more (Japanese, German, Spanish, Hindi and others)
</pasted_content id="dd41">
what if there's also a cli version of this tool t …
Agent
All routes are up. Now a real test in Chrome:
You
Tool loaded.
Agent
Now the app itself: filling the form and running a real generation in the browser.
The listing came back after about 3 minutes on the local model. Checking the rest of the page and the Japanese version:
You
The user sent a new message while you were working:
make sure you pay attensiton to the ui and ux of the app so that it's optimized for wide desktop and tablet and mobile screen sizes and do several passes until ebverything looks perfect
This is how Claude Code surfaces messages the user sends mid-turn — within the running turn, often alongside the next tool result, rather than as a separate conversation turn. Address the message above as you continue this turn.
Agent
Noted. Once the CLI is wired up, I'll do several UI passes at wide desktop, tablet and phone widths. Next, the server accepts repo context from the CLI:
Testing the CLI on a real app repo from your machine:
That's a good brief from AeroTail, your plane-spotting app. Running the CLI fully offline on it:
Now the UI passes. I'll restart the server in watch mode so changes show up immediately, then check desktop, tablet and phone widths.
The hidden checkboxes inside the language and store chips aren't anchored to their chip, so they stick out and cause the sideways scroll. Fixing that:
You
The user sent a new message while you were working:
once the ui passes are done for consistency, make sure to take screenshots and screenrecording and create a nice video with proper elevenlabs voiceover and review it as well
This is how Claude Code surfaces messages the user sends mid-turn — within the running turn, often alongside the next tool result, rather than as a separate conversation turn. Address the message above as you continue this turn.
Agent
The CSS fix didn't show because the browser cached the stylesheet for 7 days, and the cache-busting value only changes when the server restarts. I'll turn caching off in development:
No more sideways scroll. But reloading should reopen the last app (Pawlog), and it's showing the empty state, so I'll check the console:
You
The user sent a new message while you were working:
can you open the dir in vs code
This is how Claude Code surfaces messages the user sends mid-turn — within the running turn, often alongside the next tool result, rather than as a separate conversation turn. Address the message above as you continue this turn.
The user sent a new message while you were working:
also keep commit the chages as you go
This is how Claude Code surfaces messages the user sends mid-turn — within the running turn, often alongside the next tool result, rather than as a separate conversation turn. Address the message above as you continue this turn.
Agent
Opened storescribe in a new VS Code window, and I'm committing as I go (4 commits so far, all under your name). Now reviewing the screenshots:
Opened storescribe in a new VS Code window, and I'm committing as I go (4 commits so far, all under your name). Now reviewing the screenshots:
You
The user sent a new message while you were working:
and puysh to this new github repo: https://github.com/sbis04/storescribe.git
This is how Claude Code surfaces messages the user sends mid-turn — within the running turn, often alongside the next tool result, rather than as a separate conversation turn. Address the message above as you continue this turn.
Agent
No overflow at any size now. Before pushing to GitHub, I'll add the MIT licence and a basic README, and confirm no secrets are tracked:
Pushed to https://github.com/sbis04/storescribe. No .env or secrets are in the repo. Reviewing the second pass:
The UI passes are in good shape at all four sizes, in both themes. To deploy and use the research features, I need two things from you:
Before creating the Droplet, a single test of Gemma 4 31B on DigitalOcean's inference from here (a fraction of a cent):
You
The user sent a new message while you were working:
can we keep it free?
This is how Claude Code surfaces messages the user sends mid-turn — within the running turn, often alongside the next tool result, rather than as a separate conversation turn. Address the message above as you continue this turn.
Agent
The test against DigitalOcean's Gemma returned empty fields, so I'll look at the raw reply. I'll come back to your "keep it free" question right after.
The API works. The listing call must be returning a different JSON shape, so I'll print what the draft step gets back:
The DigitalOcean run now works: App Store and Google Play in English and German in 33 seconds, with no issues, for about $0.0014 in model cost. Committing, then your question about keeping it free.
Going with the Droplet. Creating it now:
You
The user sent a new message while you were working:
added the search api key
This is how Claude Code surfaces messages the user sends mid-turn — within the running turn, often alongside the next tool result, rather than as a separate conversation turn. Address the message above as you continue this turn.
The user sent a new message while you were working:
while we run for the testing or video etc, always use the locla gemma one instead of the digitial ocean one to save money, I really don't want to spend any mnoney on digitial ocean (only the very minimum absolutely requried)
This is how Claude Code surfaces messages the user sends mid-turn — within the running turn, often alongside the next tool result, rather than as a separate conversation turn. Address the message above as you continue this turn.
Agent
Noted: all testing and the video will use local Gemma, and DigitalOcean only serves real visitors on the live site. I'll save that as a standing preference, then push the SerpApi key to the server:
Noted: all testing and the video will use local Gemma, and DigitalOcean only serves real visitors on the live site. I'll save that as a standing preference, then push the SerpApi key to the server:
SerpApi rejects the key (401). I'll check its format without displaying it:
SearchApi.io returns the same shape as SerpApi, so supporting both is a small change:
Research now works with your current key: 13 App Store and 15 Google Play results, plus the shared category vocabulary. I'll filter a few more filler words ("keep", "their", "helps"), then commit.
AeroTail-iOS has a website, onboarding screens and hero images, which is a richer test. Scanning it:
Checking those images actually show the app:
You
The user sent a new message while you were working:
added the cporrect serpapi key npw
This is how Claude Code surfaces messages the user sends mid-turn — within the running turn, often alongside the next tool result, rather than as a separate conversation turn. Address the message above as you continue this turn.
The user sent a new message while you were working:
you can also use the aerotial projecy for the demo, but make sure no changes in that project
This is how Claude Code surfaces messages the user sends mid-turn — within the running turn, often alongside the next tool result, rather than as a separate conversation turn. Address the message above as you continue this turn.
Agent
SerpApi works: Free Plan with 246 searches left, and both stores return full results. AeroTail-iOS has 0 changed files. Restarting the local server and redeploying the Droplet with the new key:
Now opening the CLI's handoff link in Chrome, to check the AeroTail listing and the competitor section in the web app:
That's the old page: changing only the # part of the URL doesn't reload it. Forcing a reload:
Writing the browser recording script. It uses a visible cursor, real typing and real local generation, and logs timestamps so I can cut the scenes precisely.
While that records, the narration. Each line is a separate ElevenLabs clip, so each scene can be timed to its own line:
While Ollama is busy with the recording, I'll write the landing-page recording, which needs no model:
Puppeteer recorded at 1536×864 rather than device pixels, so upscaling to 1080p would look soft. Checking a frame:
The cards look clean. Before I narrate "less than a cent", I need DigitalOcean's real price for Gemma 4 31B, because my cost meter currently uses placeholder rates:
You
Tool loaded.
Agent
While the app recording finishes, I'll prepare the terminal replay. It plays back the real CLI output line by line, with long model waits shortened and labelled "sped up":
Running straight from GitHub works. I'll update the usage text, landing page and README to use that command, push, then record the real CLI run on the AeroTail copy with that exact command:
No more stuffing warnings, but the subtitle came out as "Track planes & planes near you". I'll add a check that catches a repeated word in a short field and has it rewritten:
The replay lost its lines: the terminal body was a flex container, so each span became its own row, and the overflow trimming deleted everything. Switching it to normal text flow:
The blank last frame is a seeking problem: the WebM has no duration index, so -sseof landed at the start. Checking a frame near the end instead:
The replay looks right. Two small fixes: short_description isn't dimmed like the other labels, and the "!" warning should be amber. Re-recording (18 seconds):
The clips and cards are ready. I'll check whether the new ElevenLabs key has arrived:
I'll re-record the app walkthrough in the background so the video shows this fix too. Then I need two things from you:
StoreScribe is built, pushed to GitHub and deployed on DigitalOcean. Two things from you will unblock the rest:
-
DNS: in Cloudflare, add an A record named
storescribepointing to[REDACTED], set to DNS only (grey cloud). Tell me once it's in and I'll switch the site over; Caddy then gets the HTTPS certificate on its own. -
ElevenLabs: the key in Leaf Peep's
.envis now rejected as invalid, so I can't generate the voiceover. Put a new key in~/MobileDev/storescribe/.envas `ELEVENLABS_API_KEY=<redacted> Hacktoberfest participants can also claim free ElevenLabs credits at hacktoberfest.com/my.
Where things stand (about 16 hours to the 11:59 PM PDT deadline, which is 12:29 PM tomorrow India time):
- Repo: https://github.com/sbis04/storescribe, MIT licence, 20+ commits all under your name only.
- Live site: https://[REDACTED].sslip.io for now. It runs Gemma 4 31B through DigitalOcean, with Tiger Data and SerpApi. I haven't triggered a single paid generation on it; all testing used local Gemma.
- Web app: I tested it end to end in Chrome:
- competitor research found the real rivals (Flightradar24, FlightAware, Flighty and others); …
The re-recording is done and the keywords fix shows. The keyword box is now one clean line with the chips underneath, and the preview has the real AeroTail screenshots. This run wrote "AeroTail: Plane Spotting Radar" (30/30) and "Live Flight Tracking & Alerts" (29/30), and generation took about 2 minutes on local Gemma.
Everything for the video is recorded. I'm waiting on the two items from my last message:
1. ElevenLabs key in ~/MobileDev/storescribe/.env as ELEVENLABS_API_KEY=<redacted> The voiceover is the only thing blocking the video.storescribe
2. **Cloudflare A record:**→[REDACTED]`, set to DNS only.
Once you've added them, send me a quick message and I'll generate the narration, assemble and review the video, then point the domain at the server.
You
can you guide me for the eleven labs key and rthe cloudflare thing?
for eleven labs can't we use digital ocaen, what did we use last timea?
can you guide me for the eleven labs key and rthe cloudflare thing?
for eleven labs can't we use digital ocaen, what did we use last timea?
Agent
What we used last time: Leaf Peep's final video (v3) used ElevenLabs with the voice "Eric", and the key sat in leaf-peep/.env. That key is now rejected (maybe deleted or regenerated). The first Leaf Peep video used Kokoro, a free open voice model that runs on the Mac.
Can DigitalOcean do it? Yes, technically. I just checked its model list, and it has one text-to-speech model (qwen3-tts-voicedesign). But it's billed per use, I haven't heard how it sounds, and you asked to keep DigitalOcean spend to the minimum. I wouldn't use it for this.
My recommendation is a new ElevenLabs key. It's the best quality and the same voice as your winning video. The free plan has 10,000 characters a month, and this narration is about 2,200, so it costs nothing. If you'd rather skip ElevenLabs, I can use Kokoro locally for free; it just sounds a little more robotic.
ElevenLabs key (2 minutes)
- Go to elevenlabs.io and sign in.
- In the left sidebar, open Developers → API Keys. On some accounts it's under your profile menu at the bottom left, then API Keys.
- Click Create API Key and name it
storescribe. If it offers permissions, turn on **Text to Spee …
You
doen both
Agent
Both are in place: the key is set and DNS already resolves to the Droplet. Switching the server to the domain, and generating the voiceover at the same time:
Live at https://storescribe.souvikbiswas.com with HTTPS, and the sslip.io address now redirects there. Now the video assembly script:
This ffmpeg build doesn't have the text filter, so I'll render the "SPED UP" labels as small transparent images and overlay those instead:
The first cut is 1:44. Reviewing it with a contact sheet, one frame every 3.5 seconds:
You
The user sent a new message while you were working:
once the video is done, revire it propertly and let me know when to uupload
make sure to incldue the live url in the video and the submissin
also make sure the github redame is nice has the screenshots and url as well
This is how Claude Code surfaces messages the user sends mid-turn — within the running turn, often alongside the next tool result, rather than as a separate conversation turn. Address the message above as you continue this turn.
Agent
I'll also add the live URL to the title card, so it appears near the start as well as in the browser frame and the outro. First, re-checking the cards and audio levels:
Loudness is now −16 LUFS, the standard for YouTube and X. Last review pass: one frame from the middle of each scene, checked against its narration line:
The result appears at about 150 s, roughly 2 seconds after the done event. Shifting scene 5 to start on the finished listing, and letting the sped-up scene end on "Done in 123 s":
The thumbnail works. Now the README: live link, video, screenshots table, CLI, how it works, stack and credits:
I wrote "Pixabay" for the music credit without checking, so I'll confirm the real source before committing:
I've reviewed the video and it's ready for you to upload.
File: ~/MobileDev/storescribe/docs/storescribe-demo.mp4 (1:44, 1080p, 10 MB)
Thumbnail: ~/MobileDev/storescribe/docs/img/thumbnail.jpg
Review checks:
- Narration: all 13 lines fit inside their scenes, with no overlaps or cut-offs.
- Sync: each scene shows what its line describes. I fixed one scene that showed the progress list instead of the finished listing.
- Loudness: −15.7 LUFS, the standard level for YouTube and X. The music ducks under the voice.
- Live URL: on screen in the browser frame for most of the video, on the title card (0:11) and on the outro. It isn't read aloud.
- Honesty: sped-up parts are labelled ("Sped up", "Sped up 11×", and in the terminal). Everything shown is a real run on local Gemma, with no paid inference.
- Music credit: I switched the track to "Autumn Acoustic Guitar" by YuraSoop (Pixabay), because I couldn't confirm where the other track came from.
For YouTube:
- Title: StoreScribe: App Store listings written by an open model (Gemma 4)
- Description:
```
Your app is done. Now write the store listing.
StoreScribe studies the app …
You
openn the video inn finder
Agent
I've opened Finder with storescribe-demo.mp4 selected, in ~/MobileDev/storescribe/docs/. The thumbnail is in the img folder next to it.
Agent
Thank you! I'll add the YouTube link to the README and landing page, then draft the DEV post.
The demo link sits neatly next to the main button. Now the DEV post. I'll write it to a local draft file first:
You
The user sent a new message while you were working:
the screnshots are not qwuite easily visible on github
This is how Claude Code surfaces messages the user sends mid-turn — within the running turn, often alongside the next tool result, rather than as a separate conversation turn. Address the message above as you continue this turn.
Agent
Cropping by coordinates cuts through the research card. I'll capture exact page elements instead: the preview with its fields, and the whole research card. Each comes out complete and sharp.
Checking how the README looks on GitHub now:
You
Tool loaded.
Agent
The DEV draft is staged, unpublished: open it in the DEV editor
It follows the Side Hustle template and has the tag #hf26challenge. It includes the live URL, the YouTube embed, the GitHub embed, the screenshots, the "Why open" argument and four prize categories (DigitalOcean, Gemma, Tiger Data, SerpApi). There are no em dashes, and the cover is the thumbnail.
Please don't publish yet. Three things are needed first:
-
Make the repo public. It's still Private, so the GitHub embed and every screenshot in the post (served from GitHub) won't load for judges. Can I run
gh repo edit sbis04/storescribe --visibility public --accept-visibility-change-consequences? Or you can flip it under Settings → Danger Zone. - Your first-user words. The "My First User" section has the facts from your AeroTail run, plus a placeholder for 1 to 3 sentences in your own words: did the listing beat what you'd have written, would you pay $6/month, and what do you want next? That section earns the bonus points, so it should be your real reaction, not mine.
- ** …
You
have made the repo public now!
Agent
The repo is public and the post's images now load (HTTP 200 from GitHub). Updating the DEV draft with the two corrected lines:
The repo is public and the post's screenshots load. I've updated the DEV draft with the two corrected lines, and it's still unpublished: open it in the DEV editor
- Price claim: the line about ASO tools now says they're "built and priced for studios and agencies", with no dollar figure I couldn't verify.
- Japanese keywords: the text now says 91 of 100 bytes, matching the screenshot.
Two things left before you publish:
-
Your first-user words. In "My First User", replace the
[[SOUVIK: ...]]line with 1 to 3 sentences in your own words: did the AeroTail listing beat what you'd have written, would you pay $6/month, and what do you want next? You can edit it in the DEV editor, or tell me here and I'll put it in. - Agent session. Do you want me to save this session to DEV and embed it in "My Agent Session"? If not, I'll remove that empty section.
Once both are done, the post is ready for you to publish. The deadline is 11:59 PM PDT tonight, which is 12:29 PM tomorrow India time.
You
can ypou open the dev draft link
Agent
The DEV draft editor is open in your default browser. Your quote goes in "My First User": replace the [[SOUVIK: ...]] line.
My First User
The first user is me, with AeroTail, the plane-spotting iOS app I'm building.
I ran the CLI inside a copy of the AeroTail repo. It found the display name and bundle id in the Xcode project, read the feature list in the README, picked up 21 screens from the Swift code (capture flight, collection, flight search, watch map and more) and the onboarding screenshots, all without me typing a word. Two minutes later, on my laptop with no internet calls, it had written 24 fastlane files: App Store and Google Play listings in English, Japanese and German. In the web app, the research found exactly the apps I'm up against: Flightradar24, FlightAware, Flighty and Plane Finder.
Did it beat the listing I'd have written myself? Yes, definitely. Would I pay $6 a month for it? Yes, it's definitely worth it.
Prize Categories
-
Best Use of DigitalOcean: the app runs on a Droplet, deployed by
deploy/up.sh, and every listing on the live site is written by Gemma 4 on DigitalOcean serverless inference. - Best Use of Gemma: Gemma 4 does all the writing, plus vision on the screenshots, the repo brief and localization. It runs on DigitalOcean in production and locally through Ollama in the CLI.
- Best Use of Tiger Data: versions, daily keyword ranks and usage are hypertables, and the usage meter is a continuous aggregate.
- Best Use of SerpApi: competitor research and rank tracking use SerpApi's App Store and Google Play engines.
來源:DEV Community · dev.to



