TypeScript chat app that accepts an Apple App Store URL, confirms the correct listing, and runs a structured ASO audit powered by Mastra.
npm install
cp .env.example .env.local
# Set NVIDIA_API_KEY or OPENAI_API_KEY (see .env.example)
npm run devOpen http://localhost:3000, paste an App Store URL (e.g. Spotify), confirm the preview card, and wait for the audit report.
Optional: set FIRECRAWL_API_KEY for more reliable App Store page scraping.
| Layer | Role |
|---|---|
| Next.js | Chat UI, API routes, monorepo host |
| Mastra workflow | Parse URL → preview → human confirm → fetch data → audit |
| Mastra tools | URL parse, preview, competitors, listing, workflow start/confirm |
| Mastra agents | Chat assistant (tools) + structured ASO auditor (skill workspace) |
| Mastra skill | src/mastra/skills/aso-audit/SKILL.md — scoring rubric (YAML frontmatter) |
- Monorepo — Mastra runs in-process via
src/mastra; Next API routes call workflows directly (no separate Mastra server in dev). - Workflow steps call tools —
lookup-app,fetch-app-preview,fetch-competitors, andfetch-app-listingare invoked from workflow steps (not duplicated lib calls). - Skill via Workspace — Auditor agent uses
asoAuditWorkspaceso Mastra injects theaso-auditskill instructions. - Competitors — Top 3 free apps in the same iTunes genre + country (chart RSS), excluding the target app.
- Keyword field — Not public on the store page; auditor scores from visible copy with a required disclaimer on the keywords dimension.
- Data sources — iTunes Lookup API for stable metadata; HTML scrape (Firecrawl optional) for subtitle, reviews sample, in-app events signals.
- Human-in-the-loop —
confirm-appworkflow step uses Mastra suspend/resume before LLM audit spend. - Chat — URL submissions drive the workflow; other messages go to
aso-chatvia/api/chat/assist(Mastra agent with audit tools).
src/
app/ # Next.js pages & API
components/aso/ # Preview card, progress, report UI
lib/app-store/ # URL parse, iTunes, competitors, scrape
lib/aso/ # Score normalization
mastra/ # Agents, tools, workflows, skills, schemas, workspace
| Command | Description |
|---|---|
npm run dev |
Next.js dev server |
npm run build |
Production build |
npm run test |
Vitest (framework logic, no UI) |
npm run test:watch |
Vitest watch mode |
npm run mastra:dev |
Mastra Studio (optional debugging) |
npm testSuites cover URL parsing, scrape extraction, scoring normalization, Mastra tools, workflow orchestration (mocked), schema contracts, and UI/framework decoupling.
- Private GitHub repo — invite
@mikekhristo -
npm install && npm run dev -
.env.example - README with setup and decisions
- Screen recording of end-to-end demo
git init
git add .
git commit -m "ASO Audit Agent take-home"
# Create private repo on GitHub, then:
git remote add origin <your-repo-url>
git push -u origin main
# Invite @mikekhristo as collaboratorSee .env.example. For NVIDIA NIM, set NVIDIA_API_KEY (or OPENAI_API_KEY) and:
Mastra stores workflow runs in LibSQL. A local mastra.db file does not work on serverless (read-only filesystem).
Recommended: Turso (free tier):
- Create a database and copy
LIBSQL_URL+LIBSQL_AUTH_TOKEN. - Add both to your host’s environment variables (e.g. Vercel → Project → Settings → Environment Variables).
- Redeploy.
Without Turso, the app uses a temp file under /tmp, which can break when confirm/resume hits a different server instance.
OPENAI_BASE_URL=https://integrate.api.nvidia.com/v1
OPENAI_MODEL=nvidia/meta/llama-3.1-70b-instruct