SimpMusic Icons

SkillMedia

Lets your agent add or change app icons in SimpMusic using generated code-based icon vectors.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the SimpMusic Icons skill

About this capability

Add or change an icon in SimpMusic. Every icon is a generated Material Symbols ImageVector under ui/icon, addressed as SimpIcons.<Name> — there is no material-icons dependency and no XML icon drawable. Use when adding a new icon, replacing one, or hitting ImageVector/Painter type errors.

What this skill tells your AI

The instructions your AI receives, as published by maxrave-dev/simpmusic in .claude/skills/simpmusic-icons/SKILL.md and read by ahel’s review.

Icons live in composeApp/src/commonMain/kotlin/com/maxrave/simpmusic/ui/icon/, one file per icon, each declaring val SimpIcons.<Name>: ImageVector.

Two things are deliberately absent and must not come back:

  • the material-icons-core / material-icons-extended dependency (Icons.Rounded.*)
  • XML icon drawables in composeResources/drawable used through painterResource(...)

Adding an icon

Google's font service generates the Compose file directly — no conversion tool needed:

curl -sfL --compressed \
  "https://fonts.gstatic.com/render/v1/Material+Symbols+Rounded/24dp/<symbol_name>.kt?var=opsz,wght,FILL,GRAD,ROND@24,400,1,0,50" \
  -o <PascalName>.kt

Keep these axes identical for every icon, or the set stops looking like one set: Rounded, opsz 24, wght 400, GRAD 0, ROND 50, FILL=1.

Use FILL=0 only for the "off" half of a state pair — FavoriteBorder, AddCircleOutline, DownloadForOfflineOutlined. At FILL=1 the off state renders identically to the on state and the distinction is lost.

Then edit the downloaded file:

  1. package com.example.testpackage com.maxrave.simpmusic.ui.icon
  2. public val <symbol_name>: ImageVectorval SimpIcons.<PascalName>: ImageVector
  3. Rename the backing field _<symbol_name>_<PascalName>, and name = "<symbol_name>""<PascalName>"
  4. If the glyph must flip in RTL, add autoMirror = true, inside ImageVector.Builder(...) (currently: ArrowForwardIos, QueueMusic, Sort, TrendingUp, VolumeOff, VolumeUp)

Using an icon

import com.maxrave.simpmusic.ui.icon.PlayArrow   // per-icon import, required
import com.maxrave.simpmusic.ui.icon.SimpIcons

Icon(SimpIcons.PlayArrow, contentDescription = null)

The project's own icon buttons take an ImageVector: RippleIconButton(imageVector = …), LiquidGlassIconButton(imageVector = …), ActionButton(icon = …).

Traps

Every icon needs its own import. val SimpIcons.X is an extension property; importing the SimpIcons object alone leaves it unresolved. This is the same mechanism that lets R8 strip unused icons, so never "simplify" the set into a map or a when — that would ship all of them.

ImageVector is not a Painter. Icon and Image have overloads for both, so those look fine. These do not, and need rememberVectorPainter(SimpIcons.X):

  • AsyncImage(placeholder = …, error = …)
  • anything drawn inside a DrawScope (with(painter) { draw(...) })
  • custom composables whose parameter is typed Painter

Do not text-replace blindly. A regex swap of Res.drawable.XSimpIcons.X produced 40 compile errors in one pass: it also hit Painter parameters, and it landed inside multi-line painterResource(\n Res.drawable.X,\n) calls, leaving the syntactically valid but wrong painterResource(SimpIcons.X).

Do not replace an icon whose colour carries meaning. These stay as resources:

FileWhy
baseline_downloaded.xml#FF00A0CB — the blue is the "downloaded" state
baseline_favorite_24.xml#D10000 — the red is the "liked" state
mono.xml, monochrome.xmlSimpMusic logos (#0AEAF8 / black)
app_icon.png, circle_app_icon.png, holder*.pngbitmaps, not icons

If a state needs that colour with a shared symbol, pass it explicitly — e.g. ActionButton's iconColor = Color(0xFF00A0CB) for the downloaded state.

Verify the symbol name exists before assuming a mapping, against google/material-design-iconsvariablefont/MaterialSymbolsRounded[FILL,GRAD,opsz,wght].codepoints. Legacy names such as favorite_border, add_circle_outline and thumb_up_alt do still exist; person_add_alt_1 does not (use person_add).

The response is gzipped even when the request asks for identitycurl --compressed, or decompress by magic bytes (\x1f\x8b) when fetching from a script.

Signals

GitHub stars
11k
Forks
584
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
simpmusic-icons
Source
github.com/maxrave-dev/simpmusic