Skip to content

v1.9.0

Latest

Choose a tag to compare

@github-actions github-actions released this 10 Oct 09:48
362a10a

Important

Re-download your Compose file, not only the image. The API memory limit rises from 768 MB to 1024 MB in both Compose files, because screenshot captions are now read on your machine. This release also runs nine database migrations, three of which repair stored App Store data and untrack keywords that were only a category name. Everything is covered in Upgrade notes below.

AsoBeast 1.9.0 makes the listing as multi market as keyword tracking already was. It captures the listing of every storefront you track keywords in, plus the native localization of English default storefronts such as Poland and Türkiye. It also reads the caption text printed on App Store screenshots, imports keywords from a CSV file, and lets an agent make changes over MCP when you allow it. A long run of extraction fixes keeps word fragments, function words and category names out of auto tracked keywords.

curl -fsSLO https://raw.githubusercontent.com/AsoBeast/asobeast/v1.9.0/docker-compose.pull.yml
docker compose -f docker-compose.pull.yml pull
docker compose -f docker-compose.pull.yml up -d --wait

🌟 Highlights

Every market gets its own listing

A German keyword used to be judged against the US title, and a competitor's Japanese listing change was never seen. AsoBeast now captures the listing of every market the primary app tracks keywords in, for the app and for each competitor. Capture runs in the daily run, on demand, and as soon as the first keyword lands in a new market. (#272)

  • A Listing market switcher on the metadata, overview and changes pages (?market=de). The header refresh follows it: "Refresh Germany listing".
  • Keyword coverage and relevance judge each keyword against the listing of its own market. Until that market has a listing, they fall back to the home listing.
  • Market changes are recorded on the changes timeline and are not alerted.
  • GET /apps/:id?country=, GET /apps/:id/listing-markets, GET /apps/:id/changes?country= and GET /apps/:id/metadata/audit?country=. The MCP tools get_app, metadata_audit and changes_timeline accept country.

For the 65 App Store storefronts whose default is English other than English (U.S.), AsoBeast also reads the native localization: Polish in Poland, Turkish in Türkiye, eleven languages in India. Each one is stored as its own snapshot when the store actually serves it, has its own Localization switcher on the metadata page, and is judged in coverage as in Title (Polish). (#282)

Read What is a market listing? and Which localizations does a storefront read?

Screenshot captions, read on your machine

ASO practitioners report that Apple reads the text on App Store screenshots. AsoBeast now reads it too, locally, with tesseract.js and bundled language packs. Nothing is sent to OpenAI, no language pack is fetched from a CDN, and no store request budget is spent. (#273, #281)

  • A Screenshot captions card on the metadata page, and a Screenshot text column in keyword coverage. Captions are labelled a weak signal and never count a keyword as covered.
  • New change events: screenshotImages when a screenshot is replaced or reordered at the same count, and screenshotCaptions when the caption text changes. A competitor can no longer swap every screenshot without leaving a trace.
  • The audit check Keywords in captions answers from the read text when no AI analysis exists.
  • Fourteen bundled languages, Polish included. Reading takes about 1 to 2 seconds per screenshot.
Measured on 42 captions from 9 apps (#281) Before After
Usable caption about 1 in 3 35 of 42
Exact caption not measured 30 of 42
Mean character error rate not measured 0.076

Google Play screenshots are recorded and diffed but not read. SCREENSHOT_OCR=false turns off every download and read and keeps the image change detection. See Screenshot captions.

Import keywords from a CSV file

Import CSV on the keyword monitor takes up to 500 rows across any number of markets, with tags and notes. Pick a file, check the columns, review every row and import. (#271)

  • Reads what spreadsheets actually export: UTF-8 with or without a byte order mark, UTF-16 (Excel's Unicode Text), a Windows-1252 fallback, and comma, semicolon, tab or pipe delimiters.
  • The server checks every row and names its status: new, resume, tracked, duplicate, invalid or overQuota. Rows over the plan limit are skipped, not failed. A keyword you already track keeps its tags and note.
  • The dialog shows how many daily store requests the import adds before you commit.
  • The keyword CSV export gains a final country column, so an export reads straight back in.
keyword,country,tags,note
habit tracker,us,core; brand,Launch keyword
streak counter,pl,testing,

Two new endpoints, POST /apps/{id}/keywords/import/preview (writes nothing, allowed for a read token) and POST /apps/{id}/keywords/import. See Import keywords from a CSV file.

MCP agents can make changes, if you let them

An agent could read everything the dashboard shows but could not act on it. Five small, reversible write tools are now listed to a token with the write scope, on both the stdio server and POST /mcp. (#270)

Tool What it does Hints
track_keywords Track up to 50 phrases in a market idempotent, open world
untrack_keyword Stop tracking one keyword idempotent, destructive
add_competitor Add a competitor by store URL idempotent, open world
remove_competitor Remove a competitor idempotent, destructive
set_action_status Snooze, complete, reopen or dismiss an action idempotent

Connect an agent in Settings gains an Allow this agent to make changes checkbox, off by default. Existing tokens stay read only, and a read token still gets 403 from every write route even if it names a write tool. Four read tools fill gaps the dashboard already covered: list_competitors, competitor_analysis, keyword_comparison and category_ranks. See MCP tools.

AsoBeast orange

Primary actions use the landing page orange with dark text (8.67:1 contrast), and the product is written AsoBeast everywhere a person reads it. Each view now has one filled button per task, so the action you came for stands out. Every route then passed an axe colour contrast scan in both themes, which now runs on every pull request. (#263, #264)

⚠️ Upgrade notes

Use the 1.9.0 Compose file. It raises the API memory limit to 1024 MB, which caption reading needs (about 190 MB while reading). If you only change ASOBEAST_IMAGE_TAG, the API keeps the old 768 MB limit. Building from source? Run git pull and then docker compose up -d --build. (#273)

Stored App Store subtitles are cleaned up, and some keywords are untracked. When a listing has no subtitle, the App Store page prints a category there instead, so AsoBeast stored subtitles such as Finance or Action. The migrations clear those subtitles and the subtitle change events built on them. They also untrack the keywords auto tracked only from such a category, for example finance for an app whose subtitle was never Finance. A keyword is untracked only if it has no tags, no note, no relevance, is not in the iOS keyword field, is not paused and does not appear in any stored title or subtitle. Its ranking history is kept. Take a backup first, as always. (#284, #291)

Your daily store requests go up. Each tracked market now adds one listing read for the app and each competitor, and each native localization adds one more. The budget card in Settings and GET /jobs/budget count both (marketListings, localizations). Check them if you track many markets on one IP. (#272, #282)

Google Play in Taiwan and Hong Kong switches to Traditional Chinese. These storefronts used to read the Simplified listing. On the first run after the upgrade, expect a title change on each Play app there, one metadata.changed alert for apps whose home storefront is tw or hk, one step in position history, and possibly one negative review report as the Traditional review feed arrives. Simplified keywords that were auto tracked stay tracked. (#294)

Two new optional environment variables: SCREENSHOT_OCR (default true) and SCREENSHOT_OCR_LANGUAGES. The API refuses to boot on a language name that is not bundled. (#273)

Contributors: a development database that applied the 1.8.0 migrations needs pnpm --filter api db:deploy once before pnpm --filter api db:migrate works again. Production installs are unaffected, because the image runs migrate deploy. (#274)

✨ Features

  • apps: capture the listing of every tracked market for the app and its competitors, and switch markets on app detail (#272)
  • metadata: read App Store screenshot captions on the host into keyword coverage, change tracking and the audit (#273)
  • keywords: import up to 500 tracked keywords with markets, tags and notes from a CSV file, and add country to the export (#271)
  • mcp: five write tools for write scoped tokens, and the list_competitors, competitor_analysis, keyword_comparison and category_ranks read tools (#270)
  • web: the AsoBeast orange and name across the app (#263)

🐛 Fixes

Keywords

  • Function words: auto tracking and suggestions skip the function words of the listing language (de, la, para, och, voor and more in fifteen languages), as they already did for English (#293)
  • Word fragments: ve from you've, 10 and 000 from 10,000, and katakana stubs such as プリ no longer become keywords (#292)
  • Thai: listings are split with a 62,107 word list before extraction, so สนามบินล่วง and similar fragments stop taking keyword slots (#261)
  • Mixed scripts: a Latin word written directly against Japanese, Chinese or Thai text is now found by coverage, so ai in aiが3行要約 counts as covered (#260)
  • Seasonal suggestions: suggestions follow the year (goals 2028 in late 2027) and the storefront, so kr no longer gets Halloween. Mother's Day no longer drops out in years when it falls after 12 May (#295)

Store data

  • App Store: a category or subgenre printed in the subtitle slot is read as no subtitle (#284, #291)
  • App Store: English default storefronts also capture their native localization (#282)
  • Google Play: Taiwan and Hong Kong read the Traditional Chinese listing, search and reviews (#294)
  • Google Play: a review with a rating and no text is stored as empty text. Before this fix, one such review failed the whole review sync, and one app lost 380 reviews to a single 2014 rating (#296)
  • Captions: caption reading is reliable on real listings, including white text on a colour band and thin text over a bright device (#281)

App

  • Refresh: the refresh dialog lists every recorded change, including price, screenshots, icon and What's New, with the field names of the changes timeline (#280)
  • Sign in: a tab waking from sleep no longer loops between /login and / (676 navigations in 4 seconds in the regression test). After sign in you return to the page you were on (#276)
  • Security: the sign in next parameter refuses paths such as /.//evil.example that resolved off site (#276)
  • Contrast: every route meets WCAG AA text contrast in both themes. A paused keyword now has muted text instead of a faded row (#264)
  • Builds: IBM Plex is bundled with the web app, so builds no longer fetch Google Fonts and fail at random on an upstream Turbopack bug (#256)
  • Database: the 1.8.0 What's New migration replays into a shadow database, so prisma migrate dev works again (#274)
🧰 Maintenance
  • One-click deploy on Railway in the docs (#275)
  • The web app README describes this project instead of the Next.js boilerplate (#257)
  • @modelcontextprotocol/sdk 1.32.1, sharp 0.35.5 and handlebars 4.7.10 (#253, #259, #283)

Full Changelog: v1.8.0...v1.9.0