Component Matcher Skill
Analyze a UI screenshot to identify which MEGA core-ui Compose library components can be used for the visible UI elements. Uses a two-phase approach: text-based narrowing with llms.txt, then visual comparison with component screenshots extracted from the sources.jar.
Usage
/component-matcher ./designs/home-screen.png
/component-matcher /tmp/screenshot.png --categories button,toolbar,list
/component-matcher https://figma.com/design/abc123/MyApp?node-id=42-1337
/component-matcher https://figma.com/design/abc123/branch/def456/MyApp --categories button,toolbar
Arguments
| Argument |
Description |
Example |
| Image source |
Path to a local screenshot or a Figma URL to capture (required, first positional arg) |
./designs/home.png or https://figma.com/design/abc123/MyApp?node-id=42-1337 |
--categories <list> |
Comma-separated category filter to limit matching scope (optional) |
--categories button,toolbar |
Execution Steps
Step 0 — Resolve the core-ui sources.jar
Read the core-ui version from the version catalog:
Grep: pattern "mega-core-ui = " in gradle/catalogs/lib.versions.toml
Extract the version string from the [versions] section (format: mega-core-ui = "X.Y.Z").
Locate the sources.jar in the Gradle cache:
find ~/.gradle/caches/modules-2/files-2.1/mega.android.core/ui/{version}/ -name "*-sources.jar" 2>/dev/null
The jar lives inside a hash-named subdirectory, so find is necessary.
Store the resolved path as SOURCES_JAR for subsequent steps.
If not found, output this message and stop:
The core-ui sources.jar for version {version} was not found in the Gradle cache.
Please run: ./gradlew :app:dependencies --configuration debugCompileClasspath
Then retry /component-matcher.
Step 1 — Acquire the user's input image
1a. Determine the input type:
Inspect the first positional argument:
- If it starts with
http and contains figma.com/design/, treat it as a Figma URL → go to 1b.
- Otherwise, treat it as a local file path → go to 1c.
1b. Figma URL — fetch screenshot via MCP:
Parse the URL to extract fileKey and nodeId:
- Standard URL:
figma.com/design/:fileKey/:fileName?node-id=:nodeId
fileKey = the path segment after /design/
nodeId = the node-id query parameter, with - converted to : (e.g., 42-1337 → 42:1337)
- Branch URL:
figma.com/design/:fileKey/branch/:branchKey/:fileName
- Use
:branchKey as the fileKey
nodeId = the node-id query parameter (same - to : conversion)
Validate that both fileKey and nodeId were extracted. If nodeId is missing (no node-id query parameter in the URL), inform the user:
The Figma URL must include a node-id parameter (e.g., ?node-id=42-1337).
Please select a specific frame or component in Figma, copy its link, and retry.
Stop execution.
Call the Figma MCP tool to capture the screenshot:
mcp__plugin_figma_figma__get_screenshot(fileKey: "<extracted>", nodeId: "<extracted>")
The tool returns the screenshot rendered visually in the conversation, the same as a Read on a local PNG.
If the MCP call fails (e.g., tool not available, auth error, invalid file/node), output:
Failed to fetch screenshot from Figma. Possible causes:
- The Figma MCP server is not connected (run /plugin to connect it)
- The fileKey or nodeId is invalid
- You do not have access to this Figma file
You can alternatively export the frame as a PNG and use a local file path:
/component-matcher ./exported-frame.png
Stop execution.
Store the original Figma URL as IMAGE_SOURCE for the report.
1c. Local file path — read from disk:
- Use the
Read tool to view the image at the provided path. Claude Code's multimodal capability will render the image visually.
- Store the file path as
IMAGE_SOURCE for the report.
1d. Visual inventory (applies to both input types):
Perform an initial visual analysis and produce a numbered inventory of all distinct UI elements visible in the screenshot. For example:
1. Top app bar with back arrow and title "Settings"
2. Toggle list items (3 rows with title, subtitle, trailing toggle)
3. Divider between sections
4. Primary filled button at bottom ("Save")
5. Inline warning banner below the toggle section
Present this inventory to the user before proceeding. This ensures alignment on what elements are being matched.
Step 2 — Text-based category narrowing with llms.txt
Extract the compact component catalog from the jar:
unzip -p "$SOURCES_JAR" META-INF/mega.android.core.ui/llms.txt
Read the full llms.txt content (~311 lines). It is organized by category with one-line component summaries including parameter names and descriptions.
For each UI element identified in Step 1, select 1-5 candidate components based on:
- Component name and description matching the visual element
- Parameter signatures (e.g., does it accept
title, subtitle, leadingElement, trailingElement?)
- Category relevance
If --categories was specified, restrict candidates to only those categories.
Build a candidate shortlist. This typically reduces 124 possible screenshots down to 5-15 relevant candidates.
Available categories in llms.txt:
badge, banner, button, card, card/plans, checkbox, chip, dialogs, divider, dropdown, empty, fab, general, image, indicators, inputfields, label, list, navigation, profile, prompt, scrollbar, scrollbar/fastscroll, settings, sheets, slider, snackbar, state, surface, tabs, text, thumbnail, toggle, toolbar, tooltip/component, tooltip/popup/interactive, tooltip/popup/simple
Step 3 — Visual comparison with candidate screenshots
For each candidate component that has a screenshot in the library:
Determine the screenshot path inside the jar. The naming convention is:
META-INF/mega.android.core.ui/screenshots/mega/android/core/ui/screenshots/{Category}ScreenshotsKt/{ComponentName}_Screenshot_748aa731_0.png
Category-to-screenshot-directory mapping:
| llms.txt category |
Screenshot directory |
| banner |
BannerScreenshotsKt |
| button |
ButtonScreenshotsKt |
| card |
CardScreenshotsKt |
| card/plans |
CardPlansScreenshotsKt |
| checkbox |
CheckboxScreenshotsKt |
| chip |
ChipScreenshotsKt |
| dialogs |
DialogsScreenshotsKt |
| divider |
DividerScreenshotsKt |
| fab |
FabScreenshotsKt |
| general |
GeneralScreenshotsKt |
| indicators |
IndicatorsScreenshotsKt |
| inputfields |
InputfieldsScreenshotsKt |
| list |
ListScreenshotsKt |
| navigation |
NavigationScreenshotsKt |
| profile |
ProfileScreenshotsKt |
| prompt |
PromptScreenshotsKt |
| scrollbar/fastscroll |
ScrollbarFastscrollScreenshotsKt |
| sheets |
SheetsScreenshotsKt |
| slider |
SliderScreenshotsKt |
| snackbar |
SnackbarScreenshotsKt |
| state |
StateScreenshotsKt |
| surface |
SurfaceScreenshotsKt |
| tabs |
TabsScreenshotsKt |
| text |
TextScreenshotsKt |
| thumbnail |
ThumbnailScreenshotsKt |
| toggle |
ToggleScreenshotsKt |
| toolbar |
ToolbarScreenshotsKt |
Categories with NO screenshots (text-only matching): badge, dropdown, empty, image, label, scrollbar (non-fastscroll), settings, tooltip/component, tooltip/popup/interactive, tooltip/popup/simple
Extract only the candidate screenshot PNGs to a temp directory:
mkdir -p /tmp/core-ui-match
unzip -j "$SOURCES_JAR" "META-INF/mega.android.core.ui/screenshots/mega/android/core/ui/screenshots/{Category}ScreenshotsKt/{ComponentName}_Screenshot_748aa731_0.png" -d /tmp/core-ui-match/
Repeat for each candidate. Only extract screenshots for the shortlisted candidates (typically 5-15), never all 124.
Use the Read tool to view each extracted candidate screenshot PNG.
Compare each candidate screenshot against the corresponding region in the user's input image. Assess:
- Visual similarity: layout, shape, spacing, element arrangement
- Component type accuracy: is it actually a button, or a card that looks like one?
- Configuration match: which variant/overload best fits?
Assign a confidence level to each match:
- High: near-identical visual match, clearly the right component
- Medium: correct component type but different configuration or styling
- Low: plausible match but uncertain, could be custom
For categories without screenshots, matching is text-only. Note this in the output: "No library screenshot available for visual comparison."
Step 4 — Fetch full signatures for confirmed matches
For each high or medium confidence match:
Extract the detailed component reference:
unzip -p "$SOURCES_JAR" META-INF/mega.android.core.ui/llms-full.txt
Locate the ### {ComponentName} section in llms-full.txt for the matched component.
Extract the full @Composable fun signature with all parameters and default values, plus any usage example.
Step 5 — Generate structured report
Output the report directly to the user in this format:
# Component Matching Report
**Input:** {IMAGE_SOURCE}
**core-ui Version:** {version}
## Summary
| # | UI Element | Matched Component | Category | Confidence |
|---|-----------|-------------------|----------|------------|
| 1 | Top app bar | MegaTopAppBar | toolbar | High |
| 2 | Toggle list items | SettingsToggleItem | settings | Medium |
| 3 | Divider | SubtleDivider | divider | High |
| 4 | Primary button | PrimaryFilledButton | button | High |
| 5 | Warning banner | InlineWarningBanner | banner | High |
| 6 | Custom header | No match | - | - |
## Detailed Matches
### 1. Top app bar -> MegaTopAppBar (toolbar) -- HIGH
[Show the library screenshot via Read tool output]
**Function Signature:**
[Full @Composable fun signature from llms-full.txt]
**Notes:** The top bar shows a back arrow and title, matching `AppBarNavigationType.Back`.
---
### 6. Custom header -> No Match
**Notes:** This header layout with a custom illustration does not correspond to any existing core-ui component. You will need a custom composable.
---
## Unmatched Elements (Custom Components Needed)
- Custom header with illustration — consider using `MegaScaffold` as the container
For composite elements (e.g., a list item with a toggle), identify each contributing component separately:
### 2. Toggle list items -> SettingsToggleItem (settings) -- MEDIUM
**Notes:** SettingsToggleItem provides title + subtitle + toggle in a single component.
Alternatively, this could be composed from `TwoLineListItem` (list) + `Toggle` (toggle)
if more layout control is needed.
Step 6 — Cleanup
Remove temporary screenshot files:
rm -rf /tmp/core-ui-match/
Guidelines
- Two-phase matching is mandatory — always narrow with
llms.txt text descriptions first, then extract only candidate screenshots for visual comparison. Never extract all 124 screenshots.
- Dynamic version resolution — always read the version from
gradle/catalogs/lib.versions.toml at runtime. Never hardcode the version or jar path.
- Composite patterns — when a UI element appears to combine multiple core-ui components (e.g., a list item with a toggle trailing element), identify each contributing component separately and note the composition.
- No match is a valid answer — not every UI element will have a core-ui equivalent. Explicitly call out elements that need custom composables, and suggest which core-ui components might serve as building blocks.
- Confidence transparency — always state the confidence level and explain why. High = near-identical visual match; Medium = correct component type, different configuration; Low = plausible but uncertain.
- Minimal temp files — extract only candidate PNGs (5-15), not all. Clean up
/tmp/core-ui-match/ when done.
- Overload awareness — many components have multiple overloads (e.g.,
BasicDialog has 5, MegaIcon has 9). Recommend the specific overload whose parameters best match what is visible in the screenshot.
- Standard Compose vs core-ui — recognize standard Android/Compose components (
Column, LazyColumn, Scaffold, Text) and note they are platform primitives, not core-ui components.
- Figma MCP fallback — when a Figma URL is provided but the MCP tool is unavailable or fails, always suggest the local-file-path alternative. Never silently skip the image acquisition step.
1---2name: component-matcher3description: Analyze a UI screenshot and identify which MEGA core-ui library components match the visible elements. Extracts component metadata from the sources.jar and performs text + visual matching against component screenshots.4---56# Component Matcher Skill78Analyze a UI screenshot to identify which MEGA core-ui Compose library components can be used for the visible UI elements. Uses a two-phase approach: text-based narrowing with `llms.txt`, then visual comparison with component screenshots extracted from the `sources.jar`.910## Usage1112```13/component-matcher ./designs/home-screen.png14/component-matcher /tmp/screenshot.png --categories button,toolbar,list15/component-matcher https://figma.com/design/abc123/MyApp?node-id=42-133716/component-matcher https://figma.com/design/abc123/branch/def456/MyApp --categories button,toolbar17```1819## Arguments2021| Argument | Description | Example |22|----------|-------------|---------|23| Image source | Path to a local screenshot **or** a Figma URL to capture (required, first positional arg) | `./designs/home.png` or `https://figma.com/design/abc123/MyApp?node-id=42-1337` |24| `--categories <list>` | Comma-separated category filter to limit matching scope (optional) | `--categories button,toolbar` |2526---2728## Execution Steps2930### Step 0 — Resolve the core-ui sources.jar31321. Read the core-ui version from the version catalog:33 ```34 Grep: pattern "mega-core-ui = " in gradle/catalogs/lib.versions.toml35 ```36 Extract the version string from the `[versions]` section (format: `mega-core-ui = "X.Y.Z"`).37382. Locate the sources.jar in the Gradle cache:39 ```bash40 find ~/.gradle/caches/modules-2/files-2.1/mega.android.core/ui/{version}/ -name "*-sources.jar" 2>/dev/null41 ```42 The jar lives inside a hash-named subdirectory, so `find` is necessary.43443. Store the resolved path as `SOURCES_JAR` for subsequent steps.45464. **If not found**, output this message and **stop**:47 ```48 The core-ui sources.jar for version {version} was not found in the Gradle cache.49 Please run: ./gradlew :app:dependencies --configuration debugCompileClasspath50 Then retry /component-matcher.51 ```5253### Step 1 — Acquire the user's input image5455**1a. Determine the input type:**5657Inspect the first positional argument:58- If it starts with `http` and contains `figma.com/design/`, treat it as a **Figma URL** → go to **1b**.59- Otherwise, treat it as a **local file path** → go to **1c**.6061**1b. Figma URL — fetch screenshot via MCP:**62631. Parse the URL to extract `fileKey` and `nodeId`:64 - Standard URL: `figma.com/design/:fileKey/:fileName?node-id=:nodeId`65 - `fileKey` = the path segment after `/design/`66 - `nodeId` = the `node-id` query parameter, with `-` converted to `:` (e.g., `42-1337` → `42:1337`)67 - Branch URL: `figma.com/design/:fileKey/branch/:branchKey/:fileName`68 - Use `:branchKey` as the `fileKey`69 - `nodeId` = the `node-id` query parameter (same `-` to `:` conversion)70712. **Validate** that both `fileKey` and `nodeId` were extracted. If `nodeId` is missing (no `node-id` query parameter in the URL), inform the user:72 ```73 The Figma URL must include a node-id parameter (e.g., ?node-id=42-1337).74 Please select a specific frame or component in Figma, copy its link, and retry.75 ```76 **Stop execution.**77783. Call the Figma MCP tool to capture the screenshot:79 ```80 mcp__plugin_figma_figma__get_screenshot(fileKey: "<extracted>", nodeId: "<extracted>")81 ```82 The tool returns the screenshot rendered visually in the conversation, the same as a `Read` on a local PNG.83844. **If the MCP call fails** (e.g., tool not available, auth error, invalid file/node), output:85 ```86 Failed to fetch screenshot from Figma. Possible causes:87 - The Figma MCP server is not connected (run /plugin to connect it)88 - The fileKey or nodeId is invalid89 - You do not have access to this Figma file9091 You can alternatively export the frame as a PNG and use a local file path:92 /component-matcher ./exported-frame.png93 ```94 **Stop execution.**95965. Store the original Figma URL as `IMAGE_SOURCE` for the report.9798**1c. Local file path — read from disk:**991001. Use the `Read` tool to view the image at the provided path. Claude Code's multimodal capability will render the image visually.1012. Store the file path as `IMAGE_SOURCE` for the report.102103**1d. Visual inventory (applies to both input types):**1041051. Perform an initial visual analysis and produce a **numbered inventory** of all distinct UI elements visible in the screenshot. For example:106 ```107 1. Top app bar with back arrow and title "Settings"108 2. Toggle list items (3 rows with title, subtitle, trailing toggle)109 3. Divider between sections110 4. Primary filled button at bottom ("Save")111 5. Inline warning banner below the toggle section112 ```1131142. Present this inventory to the user before proceeding. This ensures alignment on what elements are being matched.115116### Step 2 — Text-based category narrowing with llms.txt1171181. Extract the compact component catalog from the jar:119 ```bash120 unzip -p "$SOURCES_JAR" META-INF/mega.android.core.ui/llms.txt121 ```1221232. Read the full `llms.txt` content (~311 lines). It is organized by category with one-line component summaries including parameter names and descriptions.1241253. For each UI element identified in Step 1, select **1-5 candidate components** based on:126 - Component name and description matching the visual element127 - Parameter signatures (e.g., does it accept `title`, `subtitle`, `leadingElement`, `trailingElement`?)128 - Category relevance1291304. If `--categories` was specified, restrict candidates to only those categories.1311325. Build a candidate shortlist. This typically reduces 124 possible screenshots down to 5-15 relevant candidates.133134**Available categories in llms.txt:**135badge, banner, button, card, card/plans, checkbox, chip, dialogs, divider, dropdown, empty, fab, general, image, indicators, inputfields, label, list, navigation, profile, prompt, scrollbar, scrollbar/fastscroll, settings, sheets, slider, snackbar, state, surface, tabs, text, thumbnail, toggle, toolbar, tooltip/component, tooltip/popup/interactive, tooltip/popup/simple136137### Step 3 — Visual comparison with candidate screenshots138139For each candidate component that has a screenshot in the library:1401411. Determine the screenshot path inside the jar. The naming convention is:142 ```143 META-INF/mega.android.core.ui/screenshots/mega/android/core/ui/screenshots/{Category}ScreenshotsKt/{ComponentName}_Screenshot_748aa731_0.png144 ```145146 **Category-to-screenshot-directory mapping:**147148 | llms.txt category | Screenshot directory |149 |-------------------|---------------------|150 | banner | BannerScreenshotsKt |151 | button | ButtonScreenshotsKt |152 | card | CardScreenshotsKt |153 | card/plans | CardPlansScreenshotsKt |154 | checkbox | CheckboxScreenshotsKt |155 | chip | ChipScreenshotsKt |156 | dialogs | DialogsScreenshotsKt |157 | divider | DividerScreenshotsKt |158 | fab | FabScreenshotsKt |159 | general | GeneralScreenshotsKt |160 | indicators | IndicatorsScreenshotsKt |161 | inputfields | InputfieldsScreenshotsKt |162 | list | ListScreenshotsKt |163 | navigation | NavigationScreenshotsKt |164 | profile | ProfileScreenshotsKt |165 | prompt | PromptScreenshotsKt |166 | scrollbar/fastscroll | ScrollbarFastscrollScreenshotsKt |167 | sheets | SheetsScreenshotsKt |168 | slider | SliderScreenshotsKt |169 | snackbar | SnackbarScreenshotsKt |170 | state | StateScreenshotsKt |171 | surface | SurfaceScreenshotsKt |172 | tabs | TabsScreenshotsKt |173 | text | TextScreenshotsKt |174 | thumbnail | ThumbnailScreenshotsKt |175 | toggle | ToggleScreenshotsKt |176 | toolbar | ToolbarScreenshotsKt |177178 **Categories with NO screenshots** (text-only matching): badge, dropdown, empty, image, label, scrollbar (non-fastscroll), settings, tooltip/component, tooltip/popup/interactive, tooltip/popup/simple1791802. Extract only the candidate screenshot PNGs to a temp directory:181 ```bash182 mkdir -p /tmp/core-ui-match183 unzip -j "$SOURCES_JAR" "META-INF/mega.android.core.ui/screenshots/mega/android/core/ui/screenshots/{Category}ScreenshotsKt/{ComponentName}_Screenshot_748aa731_0.png" -d /tmp/core-ui-match/184 ```185 Repeat for each candidate. Only extract screenshots for the shortlisted candidates (typically 5-15), **never all 124**.1861873. Use the `Read` tool to view each extracted candidate screenshot PNG.1881894. Compare each candidate screenshot against the corresponding region in the user's input image. Assess:190 - **Visual similarity**: layout, shape, spacing, element arrangement191 - **Component type accuracy**: is it actually a button, or a card that looks like one?192 - **Configuration match**: which variant/overload best fits?1931945. Assign a confidence level to each match:195 - **High**: near-identical visual match, clearly the right component196 - **Medium**: correct component type but different configuration or styling197 - **Low**: plausible match but uncertain, could be custom1981996. For categories without screenshots, matching is text-only. Note this in the output: "No library screenshot available for visual comparison."200201### Step 4 — Fetch full signatures for confirmed matches202203For each high or medium confidence match:2042051. Extract the detailed component reference:206 ```bash207 unzip -p "$SOURCES_JAR" META-INF/mega.android.core.ui/llms-full.txt208 ```2092102. Locate the `### {ComponentName}` section in `llms-full.txt` for the matched component.2112123. Extract the full `@Composable fun` signature with all parameters and default values, plus any usage example.213214### Step 5 — Generate structured report215216Output the report directly to the user in this format:217218```markdown219# Component Matching Report220221**Input:** {IMAGE_SOURCE}222**core-ui Version:** {version}223224## Summary225226| # | UI Element | Matched Component | Category | Confidence |227|---|-----------|-------------------|----------|------------|228| 1 | Top app bar | MegaTopAppBar | toolbar | High |229| 2 | Toggle list items | SettingsToggleItem | settings | Medium |230| 3 | Divider | SubtleDivider | divider | High |231| 4 | Primary button | PrimaryFilledButton | button | High |232| 5 | Warning banner | InlineWarningBanner | banner | High |233| 6 | Custom header | No match | - | - |234235## Detailed Matches236237### 1. Top app bar -> MegaTopAppBar (toolbar) -- HIGH238239[Show the library screenshot via Read tool output]240241**Function Signature:**242[Full @Composable fun signature from llms-full.txt]243244**Notes:** The top bar shows a back arrow and title, matching `AppBarNavigationType.Back`.245246---247248### 6. Custom header -> No Match249250**Notes:** This header layout with a custom illustration does not correspond to any existing core-ui component. You will need a custom composable.251252---253254## Unmatched Elements (Custom Components Needed)255256- Custom header with illustration — consider using `MegaScaffold` as the container257```258259For composite elements (e.g., a list item with a toggle), identify each contributing component separately:260```261### 2. Toggle list items -> SettingsToggleItem (settings) -- MEDIUM262263**Notes:** SettingsToggleItem provides title + subtitle + toggle in a single component.264Alternatively, this could be composed from `TwoLineListItem` (list) + `Toggle` (toggle)265if more layout control is needed.266```267268### Step 6 — Cleanup269270Remove temporary screenshot files:271```bash272rm -rf /tmp/core-ui-match/273```274275---276277## Guidelines2782791. **Two-phase matching is mandatory** — always narrow with `llms.txt` text descriptions first, then extract only candidate screenshots for visual comparison. Never extract all 124 screenshots.2802. **Dynamic version resolution** — always read the version from `gradle/catalogs/lib.versions.toml` at runtime. Never hardcode the version or jar path.2813. **Composite patterns** — when a UI element appears to combine multiple core-ui components (e.g., a list item with a toggle trailing element), identify each contributing component separately and note the composition.2824. **No match is a valid answer** — not every UI element will have a core-ui equivalent. Explicitly call out elements that need custom composables, and suggest which core-ui components might serve as building blocks.2835. **Confidence transparency** — always state the confidence level and explain why. High = near-identical visual match; Medium = correct component type, different configuration; Low = plausible but uncertain.2846. **Minimal temp files** — extract only candidate PNGs (5-15), not all. Clean up `/tmp/core-ui-match/` when done.2857. **Overload awareness** — many components have multiple overloads (e.g., `BasicDialog` has 5, `MegaIcon` has 9). Recommend the specific overload whose parameters best match what is visible in the screenshot.2868. **Standard Compose vs core-ui** — recognize standard Android/Compose components (`Column`, `LazyColumn`, `Scaffold`, `Text`) and note they are platform primitives, not core-ui components.2879. **Figma MCP fallback** — when a Figma URL is provided but the MCP tool is unavailable or fails, always suggest the local-file-path alternative. Never silently skip the image acquisition step.