App Entry Creator
This skill creates complete app entries for the Navidrome Compatible Client Apps catalog by analyzing a provided URL and discovering all relevant information automatically.
When to Use
Use this skill when:
- •User provides a URL and wants to create a new app entry
- •User mentions adding an app to the catalog
- •User wants to create an entry in
assets/apps/
Workflow
Step 1: Analyze the Provided URL
Determine the URL type and extract initial information:
| URL Type | What to Extract |
|---|---|
| GitHub repo | Name, description, README content, releases, screenshots from README |
| App website | Name, description, screenshots, links to stores |
| Play Store | App name, description, screenshots, developer website |
| App Store | App name, description, screenshots, developer website |
| Docker Hub | Image name, description, GitHub link |
Step 2: Discover Related URLs
From the initial URL, find all related resources:
- •
From GitHub repos: Look for:
- •Website URL (in repo description or README)
- •App store links (Play Store, App Store) in README
- •Docker images (in README or packages)
- •Screenshots in README or
/screenshots,/images,/docsfolders
- •
From app websites: Look for:
- •GitHub/source repository link
- •App store badges/links
- •Docker installation instructions
- •
From app stores: Look for:
- •Developer website
- •GitHub link in description
Step 3: Determine Open Source Status
If the app has a GitHub/GitLab repository, determine if it's truly open source:
| Check | Result |
|---|---|
Repository has source code (.java, .swift, .ts, .py, etc.) | Likely open source |
| Repository only has releases, issues, or documentation | NOT open source - set isOpenSource: false |
| Repository has a LICENSE file with OSI-approved license | Open source |
| Repository marked as "Source available" but restrictive license | NOT open source - set isOpenSource: false |
| Repository is empty or only contains binaries | NOT open source - set isOpenSource: false |
How to check:
- •Visit the repository URL
- •Look at the file list - are there actual source code files?
- •Check for a LICENSE file - is it an open source license (MIT, GPL, Apache, etc.)?
- •If the repo only has Releases with no source, it's a releases-only repo
Default behavior:
- •If
repoUrlis set andisOpenSourceis omitted → treated as open source - •Only add
isOpenSource: falsewhen you've confirmed the source is NOT publicly available
Step 4: Determine API Support
Check documentation/README for mentions of:
- •"OpenSubsonic" →
api: OpenSubsonic - •"Subsonic API" or just "Subsonic" →
api: Subsonic - •"Navidrome API" or Navidrome-specific features →
api: Navidrome
Default to Subsonic if unclear but the app claims Subsonic compatibility.
Step 5: Identify Platforms
Map discovered information to platforms:
| Evidence | Platform Config |
|---|---|
| Play Store URL | android: { store: <url> } |
| App Store URL (iPhone/iPad) | ios: { store: <url> } |
| Mac App Store URL | macos: { store: <url> } |
| macOS downloads/releases | macos: true |
| Windows downloads/releases | windows: true |
| Linux downloads/releases | linux: true |
| Web demo/hosted version | web: { url: <url> } or web: true |
| Docker image | docker: { store: <url> } or docker: true |
| CLI tool | other: true |
Step 6: Download Screenshots
- •
Find screenshot sources (in priority order):
- •App store listings (highest quality)
- •README screenshots
- •
/screenshotsor/imagesfolder in repo - •App website gallery
- •
Download images using terminal commands:
bashcd assets/apps/<app-name> curl -L -o thumbnail.png "<image-url>" curl -L -o screen1.png "<image-url>"
- •
Skip these image types:
- •Small icons/logos (< 200px)
- •Badges (build status, download counts)
- •Diagrams/flowcharts
- •Social media preview images
- •
Run the conversion script:
bashnpm run convert:images <app-name>
Step 7: Create the App Entry
- •
Create the folder using kebab-case:
bashmkdir -p assets/apps/<app-name>
- •
Generate
index.yamlwith all discovered information following the schema inreferences/app-schema.json - •
Required fields (must have values):
- •
name: Display name - •
url: Official website or GitHub URL - •
platforms: At least one platform - •
api: One ofOpenSubsonic,Subsonic,Navidrome - •
description: 1-2 sentences (max 500 chars) - •
screenshots.thumbnail: Filename of downloaded thumbnail
- •
- •
Optional fields (include if found):
- •
repoUrl: Repository URL (for release date tracking) - •
isOpenSource: Set tofalseif repo exists but source is not public (see Step 3) - •
isFree: Set totrueif app is free - •
screenshots.gallery: Array of screenshot filenames (max 5) - •
keywords: Search terms not in name/description (max 6)
- •
Step 8: Validate the Entry
Run validation to ensure correctness:
npm run validate:app <app-name>
Fix any errors before presenting to user.
Example Workflow
Given URL: https://github.com/jeffvli/feishin
- •Fetch GitHub page → Extract: name "Feishin", description, README
- •Parse README → Find: screenshots, Docker image, web demo URL
- •Discover URLs:
- •Website: https://feishin.vercel.app/ (from README)
- •Docker: ghcr.io/jeffvli/feishin (from README)
- •Check open source status: Repo has TypeScript source code and MIT license → open source (no need to set
isOpenSource) - •Determine API: README mentions "Navidrome" →
api: Navidrome - •Identify platforms: Windows, macOS, Linux (releases), Docker, Web
- •Download screenshots from README images
- •Create entry:
code
assets/apps/feishin/ index.yaml thumbnail.webp screen1.webp screen2.webp
- •Validate:
npm run validate:app feishin
Output Format
After completion, present:
- •Summary of discovered information
- •The generated
index.yamlcontent - •List of downloaded images
- •Validation results
- •Any manual steps needed (if images couldn't be found)
References
- •Schema:
apps/app-schema.json- JSON Schema for validation - •Template:
apps/_template/index.yaml- Example index.yaml structure - •Documentation: Adding Client Apps
Error Handling
| Issue | Action |
|---|---|
| No screenshots found | Warn user, create entry without gallery, thumbnail required |
| URL unreachable | Report error, ask for alternative URL |
| API type unclear | Default to Subsonic, note uncertainty |
| Multiple possible names | Use the most prominent/official name |