
app-entry-creator
Create Navidrome client app catalog entries from a URL. This skill should be used when the user prov
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:
cd 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:
npm run convert:images <app-name>
Step 7: Create the App Entry
-
Create the folder using kebab-case:
mkdir -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 nameurl: Official website or GitHub URLplatforms: At least one platformapi: One ofOpenSubsonic,Subsonic,Navidromedescription: 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 freescreenshots.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:
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 |