Releases: AsoBeast/asobeast
Release list
v1.4.0
1.4.0 (2026-09-18)
Features
- actions: carry failing audit checks into fix factor evidence (cb1b644)
- api: classify openai failures and control image detail (a4ec900)
- api: classify openai failures and control image detail (1a6a462)
- api: default the ai model to gpt-5.6-luna (88b4a41)
- api: store developer replies on google play reviews (0db796f)
- api: store developer replies on google play reviews (0bef860)
- audit: analyze creative with ai observations on a queue (c863d96)
- audit: benchmark rating volume and recent reviews (1eb2ec4)
- audit: compare the listing with competitor benchmarks (7cd3c62)
- audit: expose creative analysis runs over http (06cbaa9)
- audit: expose creative analysis runs over http (0def8e3)
- audit: name the keywords behind title, subtitle and field checks (520f7be)
- audit: observe icon and screenshots instead of asking for scores (289c883)
- audit: observe icon and screenshots instead of asking for scores (263cefb)
- audit: rank recommendations by score lift and effort (882f36f)
- audit: run the creative analysis on a queue with persisted state (74253a5)
- audit: run the creative analysis on a queue with persisted state (6f43728)
- audit: score google play short description and visual assets (e072130)
- audit: score keyword placement in google play descriptions (e26b67a)
- audit: score listings with a deterministic v2 rubric (3ef6ae7)
- audit: score rankings from visibility and competitor gaps (be7ef52)
- audit: score the review response rate on google play (988c959)
- audit: score the review response rate on google play (8b05c61)
- audit: score update freshness, release notes and localizations (d8f8223)
- audit: separate unmeasurable checks from checks awaiting input (4c201ec)
- audit: weight checks and report confidence, grade and groups (a311b59)
- db: store audit rubric version, confidence and ai run state (39a4a07)
- mcp: describe grades and recommendations in the audit tool (8414cef)
- shared: add optional audit v2 fields to the audit contract (4919feb)
- shared: flag store policy terms in titles and short descriptions (98784c2)
- web: choose the agent the connect snippets are written for (754856f)
- web: compare the listing with competitors on the audit page (27cddd5)
- web: copy the audit as a markdown report (c7bf1e0)
- web: describe the endpoint for any other mcp client (e7369c2)
- web: lead the audit page with score, grade and confidence (345f918)
- web: rebuild the audit page around score, confidence and plan (098e077)
- web: run the creative analysis with live progress (d5adeb2)
- web: show factor checks with evidence, sources and unlocks (402da99)
- web: show icon and screenshot observations from the analysis (67a966a)
- web: show the audit action plan with lift, effort and fix links (19ac870)
- web: write a cursor connect snippet (646aa1a)
- web: write a vs code connect snippet (5293781)
- web: write a windsurf connect snippet (00f25f2)
- web: write codex connect snippets (4e8ea85)
- web: write gemini cli connect snippets (c297072)
- web: write working connect snippets for every common mcp client (7995eea)
Bug Fixes
- actions: coalesce generation requests only while a run is pending (933131b)
- actions: let generation run again and wait for the first checks (31eac08)
- actions: record a generation run that opens no action (6d37441)
- actions: refuse a snooze date that is not on the calendar (ff4d5d2)
- analytics: refuse an impossible or reversed visibility window (c4853a4)
- api: answer get, head and delete on the mcp endpoint with 405 (01c1ca7)
- api: challenge every 401 with a bearer www-authenticate header (3b793d2)
- api: refuse a market that is not a storefront of the app's store (4b9ba1c)
- api: refuse an impossible or reversed category rank window (02d9ff8)
- api: retry openai failures only on transient statuses (f7468f8)
- api: retry openai failures only on transient statuses (bc9aff8)
- apps: backfill a subtitle the import could not read (c6a5e7e)
- apps: backfill a subtitle the import could not read (c2ff1b8)
- apps: generate the first action run after the first rank checks (f7c1a73)
- apps: keep the history of an app that is already tracked (7e33885)
- apps: keep the last known subtitle when a refresh cannot read it ([848f110](https://github.com/AsoBeast/asobeast...
v1.3.0
1.3.0 (2026-09-13)
Features
- api: reconcile a workspace before refusing its checkout (0a39ee3)
- shared: carry the recovery a billing conflict needs (8c3a7a5)
- web: reconcile the workspace when a checkout returns (9118c2e)
- web: show the release version in the sidebar footer (972fb3f)
- web: show the release version in the sidebar footer (f4e25f4)
Bug Fixes
- actions: answer 404 for an unknown app in the action route (6bfc29c)
- actions: answer 404 for an unknown app in the action route (3359ec8)
- api: adopt the subscription stripe already links to the workspace (17e45e3)
- api: close the gaps a review found in the recovery path (75f2529)
- api: recover a workspace whose subscription no webhook recorded (08225c3)
- api: revoke only a workspace that claims a subscription (b45f542)
- api: stop a dead subscription shadowing the recovery (470668d)
- api: tell a stalled subscription what it is missing (e47677e)
- auth: count password characters by code point (6b5c585)
- auth: refuse a password that is only whitespace (145c469)
- auth: refuse a password that is only whitespace (b5e468f)
- ci: build workspace packages before linting (996c368)
- keywords: insert new keyword rows in one order so saves cannot deadlock (ba38a0e)
- keywords: insert new keyword rows in text order so writes cannot deadlock (ab3ab7b)
- keywords: make keyword inserts deadlock free and keep the field in saved order (0b70e22)
- keywords: read the keyword field in the order it was saved (bcd801f)
- keywords: record keyword field membership apart from the keyword source (d4f5cf4)
- keywords: record keyword field membership apart from the keyword source (b4392c6)
- keywords: refuse a keyword field over the 100 character limit (09ab7b9)
- keywords: serialize concurrent keyword field saves per app (c47a0b9)
- keywords: serialize the keyword field write per app (13fd4e3)
- repo: close the advisories the dependency tree carries (f842557)
- repo: keep generated env files private and node recoverable (5d42222)
- repo: let prisma fetch the schema engine at install (9263f52)
- shared: lowercase a capital dotted I without splitting the word (367125a)
- shared: lowercase a capital dotted I without splitting the word (e2faffa)
- shared: lowercase a dotted I written with a combining dot as one letter (3da7b9c)
- web: check the whole password rule and link its error to the field (ca5d5b2)
- web: clamp displayed keyword scores to their 0 to 100 scale (e9831a1)
- web: clamp the comparison matrix scores to their 0 to 100 scale (c42bf17)
- web: clamp the displayed difficulty to its 0 to 100 scale (968af05)
- web: fall back to the letter placeholder when a store icon fails (3f85494)
- web: fall back to the letter placeholder when an icon fails (377a7d5)
- web: keep the app icon decorative whether it loads or not (dd595b8)
- web: offer the recovery a held subscription needs (be2e369)
- web: read the dashboard action summary as the page prefetches it (5f860db)
- web: read the ratings histogram as its page prefetches it (2004584)
- web: render relative times from one instant (55fefbd)
- web: render the dashboard and its relative times from one server state (44b8991)
- web: retry an icon whose url comes back after a failure (3f44e3c)
- web: state the password rule beside the password field (4ecabcc)
Performance
- keywords: leave inactive phrases alone when a keyword field save deactivates (83eadc5)
Refactoring
- api: give a subscription status one table and three outcomes (01319e4)
- api: pick a held subscription by one rule (9dc36e7)
- api: write a workspace from one subscription projection (68bc73d)
- shared: keep the score display maximum private (5c99263)
- shared: share the password rule predicate with the web app (6c24708)
- web: move the comparison matrix score label into its own module (0b9ad37)
- web: share the route cookie seeding between specs (b27d717)
Documentation
- api: document the not found answer on the app action route (071c166)
- docs: correct the stored scale for difficulty (902cde8)
- docs: list the normalized keyword field limit (ed98198)
- docs: record how a stalled subscription recovers (12f5fb8)
- docs: record the password rule and what it does not change (656008b)
- docs: say the keyword field keeps the order of the latest save (0c7ed15)
- docs: scope the uniform sign in answer to the length limit ([53df47d](https://gi...
v1.2.0
1.2.0 (2026-08-29)
Features
- api: alert and meter a broken store parser (8cd3008)
- api: report errors through the sentry sdk (17ee38c)
- apps: generate the action queue when an app is imported (ffb134d)
- apps: schedule the first rank pass at import (a0fffa4)
- apps: schedule the first rank pass at import (c8a3ce0)
- jobs: merge the published store status into store health (0685245)
- jobs: report exhausted queue failures (f987df0)
- jobs: report first run readiness for one app (4096de0)
- jobs: report whether each store still parses (eec6967)
- jobs: resolve the next firing of a weekly cron (50c2081)
- providers: classify a canary failure as broken, unreachable or missing (2bb0e5f)
- providers: make a broken store parser a detected product state (ca81ab8)
- providers: parse a published store status document (27f6683)
- providers: poll a published store status when one is configured (832dceb)
- providers: probe each store on a schedule and record the verdict (a4396a8)
- report hosted errors to sentry from the api and the web app (654ad7b)
- shared: add the first run status contract (0f7bd97)
- shared: add the store health contract (09da195)
- web: choose one system notice from run and store health (9cd4e7d)
- web: map the first run status to timeline rows (c9b7deb)
- web: read the first run status for an app (73a7cf4)
- web: report browser and server errors to sentry (4bcf3de)
- web: show a store parser break above everything (e49370f)
- web: show what a newly imported app is still waiting for (53c72e6)
Bug Fixes
- api: name the store a request asked for that this version cannot serve (43959ff)
- api: stop the sdk reporting every failed job attempt (6e6a3b6)
- apps: keep an import when its first pass cannot be scheduled (a26aeeb)
- apps: name the app in the first run check identifier (95693a9)
- db: untrack the keywords a competitor snapshot auto tracked (42fabc9)
- distinguish unchecked keywords, bound keyword writes, answer 404 for a missing app (6dcb210)
- docker: load the web env file so the browser can report errors (d53c2c7)
- jobs: close the first run report once its window has passed (d3d4034)
- jobs: keep egress failure text off the store health route (37e49c2)
- jobs: stop expecting a review backfill that has had its window (fcbffa1)
- keywords: cap the keywords one bulk add request may carry (f05e97b)
- keywords: hold the keyword field to the same caps and quota as a bulk add (47fe18f)
- keywords: refuse a keyword phrase no store search box would accept (417bd3b)
- keywords: stop auto tracking keywords for a competitor app (8dd9c4d)
- providers: answer 404 for an app the store does not have (2e69cde)
- providers: keep a missing app out of endpoint health (5b2cef2)
- providers: keep retrying a missing app, which can be a soft block (ec22261)
- providers: reject a published timestamp with no utc offset (9c1fd31)
- providers: release the status response body on every early return (a7ba9ec)
- providers: report an unreadable status body for what it was (ba00a78)
- providers: require every asserted parser field to be a string (5b5fc46)
- providers: take each store's own signal for a missing app (1fcc15b)
- providers: treat every egress transport failure as unreachable (328c45b)
- repo: bound the nanoid and esbuild overrides to tested majors (b081e69)
- repo: bump the captured openapi version with the release (efe1348)
- repo: keep the captured openapi version in step with the release (e8f3d04)
- web: initialize reporting before capturing a browser error (0f1e284)
- web: keep sentry out of the first load and mask the nextjs path (09adb42)
- web: leave a day a keyword was not checked blank on the rankings chart (26960c9)
- web: name the app's own store in the suggestions hint (64dc492)
- web: offer a wider rankings window only when history exists outside it (22fe80b)
- web: take the retry prop next actually passes to an error boundary (fbe854e)
- web: take the retry prop next actually passes to an error boundary (7c415fe)
- web: tell a never checked keyword apart from one beyond depth (b704b7c)
Performance
- web: stop polling first run status once only history is left (df62404)
Refactoring
v1.1.0
1.1.0 (2026-08-26)
Features
- api: serve the stored App Store keyword field (babe18d)
- competitors: name the store on the discovery panel (923faa1)
Bug Fixes
- alerts: keep a pressed toggle still under the pointer (9948994)
- alerts: keep a pressed toggle still under the pointer (ac2185f)
- api: forgive an empty review feed for an app with no recent reviews (0f550fd)
- auth: give the sign in and create account pages a page heading (e299cac)
- competitors: match the add competitor example to the app store in view (7f0cc0e)
- competitors: track a discovered app on the store it came from (c6b9470)
- competitors: track a discovered app on the store it came from (d08f940)
- forgive quiet review feeds, give the auth pages a heading, hide play subtitle coverage (f179c81)
- jobs: stop retrying a plausibility rejection (56e954f)
- keywords: auto track a snapshot without racing a concurrent sync (cfa0853)
- keywords: write a keyword and its tracking without racing another request (0b9f639)
- keywords: write a keyword and its tracking without racing another request (5089d15)
- shared: raise the per minute request budgets above the dashboard cost (45ed8a1)
- web: blame the plan budget only when the plan refused the request (c3b0dfc)
- web: hide subtitle coverage for google play apps (d98b328)
- web: keep a server render from retrying a failed query (cc0c2f1)
- web: let an emptied keyword field be saved (69e1940)
- web: restore the App Store keyword field after a reload (eaea8bd)
- web: restore the keyword field editor from the stored value (260728b)
- web: show the plan rate limit reason instead of the generic error (efd6133)
- web: stop retrying a refused request before Retry-After elapses (aa3e5b9)
- web: stop the dashboard exhausting the trial read budget (2353723)
Performance
- web: prefetch app detail on intent instead of on sight (2808efa)
Refactoring
- alerts: expose the event toggles as a labelled group (7547527)
- api: move the implausible result rule beside the store providers (f9003e9)
- api: name the plausibility input for both of its callers (4fafe31)
Documentation
v1.0.0
1.0.0 (2026-08-24)
The first public release.
Highlights
- Tenancy is enforced by the database. Every tenant-owned table carries a
tenant_isolationrow level security policy readingapp.workspace_id, and every Prisma operation runs in a transaction that enters the workspace and drops to the non-ownerasobeast_approle. A query with no workspace in scope returns nothing rather than everything. Work that genuinely spans tenants goes through a singleCrossTenantAccessescape hatch that demands a written justification, and a dedicated isolation suite (pnpm --filter api test:isolation) proves it on every pull request. - Plans, quotas and billing. Plans and their limits are typed data in
@asobeast/shared; entitlement lives onWorkspacerather thanUser, because a workspace has one plan whatever the size of the team. Stripe delivers checkout, the customer portal, idempotent subscription webhooks, daily reconciliation, period-end downgrades and cancellations, card-free trials and payment-failure notices.BILLING_ENABLED=falsekeeps a self-hosted install single-workspace and entirely free of it. - A proxy pool for store requests.
PROXY_PROVIDER=websharereconciles a pool against the provider, spreads store requests across endpoints under a per-endpoint budget, classifies failures, tracks endpoint health and exposes it to operators. A residential fallback is available behind a hard monthly cost ceiling that refuses every request at0.PROXY_PROVIDER=nonekeeps every request on the host address, exactly as before. - The daily pipeline fans out per workspace. Runs interleave across workspaces, degrade in a defined order under capacity pressure, and report per-workspace budget and projected completion. A keyword two workspaces track is still one search.
- Rate limits everywhere. Every endpoint is classified by cost and limited per workspace from Redis-backed counters, answering with standard rate limit headers and typed limit errors. Sustained abuse is flagged, and an operator can suspend a workspace by hand.
- A remote MCP endpoint.
POST /mcpserves the same read-only tool catalog as the stdio binary from one shared definition in@asobeast/mcp-tools, authenticated by anasob_token, entitlement-checked and rate limited per workspace. Both surfaces now run@modelcontextprotocol/server@2.0.0and serve protocol2026-07-28alongside the 2025 revisions. - Operations you can run. Structured logging with tenant and correlation context, per-workspace operational metrics, capacity and anomaly alerting, optional cloud-only error tracking with scrubbing, owner-only support tooling, and in-app delay notices for affected customers.
- Account and data rights. Password recovery from the login card with single-use tokens that reset every other session, workspace member invitations, personal API tokens with expiry and a read-only scope, and complete workspace export and deletion.
- Packaging.
docker-compose.pull.ymlruns the published GHCR images without a clone or a build, completing the pinned-image path promised for this release.
Install notes
-
Migrations are additive and forward only. The API applies them on boot. Take a database backup before any upgrade regardless; see Backups and Restore.
-
Row level security changes who may run migrations. Migrations and the seed must run as a role that bypasses the policies, which is the superuser the images already use. A deployment that runs migrations as a restricted role needs to change that before upgrading.
-
A self-hosted install needs no configuration change.
BILLING_ENABLEDdefaults tofalse,PROXY_PROVIDERdefaults tonone, and every new variable has a working default. Nothing about billing, proxies, capacity gating or error tracking activates until it is switched on deliberately. -
WEBHOOK_ALLOW_PRIVATE_TARGETSdefaults tofalse. Alert webhooks are now refused against loopback, private, carrier-grade NAT, link-local and cloud metadata targets, at registration and again when the connection is made. If you deliver alerts to your own LAN from a self-hosted instance, set it totrue. It refuses to boot alongsideBILLING_ENABLED=true.
Compatibility promise
From this release, the HTTP contract, the @asobeast/shared contract types and the MCP tool surface stay compatible throughout the 1.x line. Breaking any of them requires 2.0.0. Environment variables, the database schema and internal modules are outside that promise, and every schema change ships as a forward Prisma migration.