Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "compose-expert",
"version": "2.3.0",
"version": "2.3.1",
"description": "Compose and Compose Multiplatform expert skill — state, animations, navigation, performance, design-to-code, PR review mode, M3 motion.",
"author": {
"name": "Adit Lal",
Expand Down
2 changes: 1 addition & 1 deletion .copilot/plugin.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: compose-expert
version: 2.3.0
version: 2.3.1
description: >
Compose and Compose Multiplatform expert skill — state, animations, navigation,
performance, design-to-code, PR review mode, M3 motion.
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ jobs:
- name: Validate plugin manifest schema
run: bash scripts/validate-plugin-manifest.sh

- name: Check SKILL.md description length (Codex/Copilot 1024-char cap)
run: bash scripts/check-description-length.sh

- name: Run manifest schema tests
run: bats scripts/validate-plugin-manifest.bats

Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ jobs:
- name: Validate plugin manifest schema
run: bash scripts/validate-plugin-manifest.sh

- name: Check SKILL.md description length (Codex/Copilot 1024-char cap)
run: bash scripts/check-description-length.sh

- name: Assert version consistency
run: bash scripts/check-versions.sh "${GITHUB_REF_NAME}"

Expand Down
27 changes: 27 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,33 @@

All notable changes to this project will be documented in this file.

## [2.3.1] - 2026-05-03

### Fixed

- **`SKILL.md` `description:` frontmatter no longer exceeds Codex / Copilot
CLI's 1024-character cap** (issue #12). Both hosts rejected the manifest
with `invalid description: exceeds maximum length of 1024 characters`. The
field is now 843 chars; Claude Code continues to load it identically.

### Changed

- Long trigger-keyword surface previously packed into the `description:`
field (TV phrases, casual phrasings, Compose Multiplatform symbol lists,
Review Mode triggers) is preserved in a new **`## When this skill applies`**
section in the SKILL.md body. Body content is not subject to the 1024-char
cap, so the keyword surface remains available to Claude after the skill
loads.

### Added

- **`scripts/check-description-length.sh`** — a regression check that
asserts the SKILL.md frontmatter `description:` is ≤ 1024 chars.
- Wired the new check into both `.github/workflows/ci.yml` (every PR) and
`.github/workflows/release.yml` (every tag push) so a future regression
fails CI loudly instead of shipping green on Claude Code and breaking
Codex / Copilot installs.

## [2.3.0] - 2026-05-03

### Added
Expand Down
41 changes: 41 additions & 0 deletions scripts/check-description-length.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/usr/bin/env bash
set -euo pipefail

# Asserts the SKILL.md frontmatter `description:` field is <= 1024 characters.
# Codex CLI and Copilot CLI both reject the manifest when this field exceeds
# 1024 characters (see issue #12). Claude Code does not enforce the cap, so
# without this check a regression ships green on Claude and breaks downstream.

SKILL_FILE="${1:-skills/compose-expert/SKILL.md}"
LIMIT=1024

if [[ ! -f "$SKILL_FILE" ]]; then
echo "FAIL: $SKILL_FILE not found"
exit 1
fi

# Extract the description: block from the frontmatter (between first two `---`).
# Handles both inline (`description: ...`) and folded (`description: >\n ...`)
# YAML forms. Stops at the next top-level frontmatter key.
desc=$(awk '
/^---$/ { c++; next }
c == 1 && /^description:/ {
flag = 1
sub(/^description: */, "")
print
next
}
c == 1 && flag && /^[a-zA-Z_]+:/ { exit }
c == 1 && flag { print }
' "$SKILL_FILE")

len=${#desc}

if (( len > LIMIT )); then
echo "FAIL: description is $len chars, exceeds $LIMIT-char Codex/Copilot limit"
echo " file: $SKILL_FILE"
echo " issue: https://github.com/aldefy/compose-skill/issues/12"
exit 1
fi

echo "OK: description is $len chars (limit $LIMIT)"
13 changes: 8 additions & 5 deletions scripts/check-versions.bats
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,31 @@ setup() {
TEST_DIR=$(mktemp -d)
cp -R "$BATS_TEST_DIRNAME/.." "$TEST_DIR/repo"
cd "$TEST_DIR/repo"
# Read the current version from plugin.json so the test does not rot at
# every release. Tests verify the script's logic, not a fixed version.
CURRENT=$(jq -r .version .claude-plugin/plugin.json)
}

teardown() {
rm -rf "$TEST_DIR"
}

@test "passes when all five versions match (tag passed as arg)" {
run bash scripts/check-versions.sh v2.1.2
run bash scripts/check-versions.sh "v${CURRENT}"
[ "$status" -eq 0 ]
[[ "$output" == *"versions aligned"* ]]
}

@test "fails when plugin.json version diverges" {
sed -i.bak 's/"version": "2.1.2"/"version": "2.0.1"/' .claude-plugin/plugin.json
run bash scripts/check-versions.sh v2.1.2
sed -i.bak "s/\"version\": \"${CURRENT}\"/\"version\": \"0.0.1\"/" .claude-plugin/plugin.json
run bash scripts/check-versions.sh "v${CURRENT}"
[ "$status" -ne 0 ]
[[ "$output" == *"plugin.json"* ]]
}

@test "fails when SKILL.md frontmatter version diverges" {
sed -i.bak 's/^version: 2.1.2$/version: 2.0.1/' skills/compose-expert/SKILL.md
run bash scripts/check-versions.sh v2.1.2
sed -i.bak "s/^version: ${CURRENT}$/version: 0.0.1/" skills/compose-expert/SKILL.md
run bash scripts/check-versions.sh "v${CURRENT}"
[ "$status" -ne 0 ]
[[ "$output" == *"SKILL.md"* ]]
}
Expand Down
84 changes: 63 additions & 21 deletions skills/compose-expert/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,18 @@
---
name: compose-expert
description: >
Compose and Compose Multiplatform expert skill for UI development across Android, Desktop,
iOS, and Web. Guides state management, view composition, animations, navigation, performance,
design-to-code workflows, and production crash patterns. Backed by actual source code analysis
from both androidx/androidx and JetBrains/compose-multiplatform-core.
Use this skill whenever the user mentions Compose, @Composable, remember, LaunchedEffect,
Scaffold, NavHost, MaterialTheme, LazyColumn, Modifier, recomposition, Style, styleable,
MutableStyleState, Compose Multiplatform, CMP, KMP, commonMain, expect, actual,
ComposeUIViewController, Window composable, UIKitView, ComposeViewport, Res.drawable,
Res.string, or any Compose API. Also trigger when the user says "Android UI", "Kotlin UI",
"compose layout", "compose navigation", "compose animation", "material3", "compose styles",
"compose multiplatform", "desktop compose", "iOS compose", "compose web", "design to compose",
"build this UI", "implement this design", "Android TV", "Google TV", "tv-material",
"tv-foundation", "Carousel", "NavigationDrawer", "D-pad", "focus indication",
"10-foot UI", "living room", "tv compose", "review this PR", "review this code",
"check this diff", or any GitHub PR URL (github.com/.*/pull/),
"design system", "component library", "atomic", "reusable component",
"design tokens", "atoms", "molecules", or asks about modern
Kotlin UI development patterns. Even casual mentions like "my compose screen is slow"
or "how do I pass data between screens" or "how do I build a TV app" should trigger this skill.
Also trigger on session_start to auto-detect Compose projects — see references/auto-init.md.
version: 2.3.0
Compose and Compose Multiplatform expert for UI development across Android, Desktop,
iOS, and Web. Use whenever the user mentions Compose APIs (@Composable, remember,
LaunchedEffect, NavHost, MaterialTheme, LazyColumn, Modifier, recomposition),
Compose Multiplatform (commonMain, expect/actual, Res.*, ComposeUIViewController,
UIKitView, ComposeViewport), Android TV (tv-material, D-pad, focus, Carousel),
Material 3 motion, atomic design systems, design-to-code workflows, Paging 3, or
navigation. Activates Review Mode on GitHub PR URLs and review phrases ("review
this PR", "what's wrong with this"). Auto-detects Compose projects on
session_start. Backed by actual androidx/androidx and JetBrains/compose-multiplatform-core
source receipts. See "## When this skill applies" in SKILL.md for the full trigger
surface.
version: 2.3.1
---

> **Installation notice:** This skill is now distributed as a plugin.
Expand All @@ -34,6 +25,57 @@ version: 2.3.0
> See [MIGRATION.md](../docs/MIGRATION.md) for Codex and Copilot CLI instructions.
> This banner will remain through v2.x and escalate in v3.0.

## When this skill applies

The frontmatter `description:` is intentionally short to satisfy Codex / Copilot
CLI's 1024-character cap on that field (see issue #12). The full trigger surface
lives here so it stays available to Claude after the skill loads.

### Compose API mentions
`@Composable`, `remember`, `mutableStateOf`, `derivedStateOf`, `rememberSaveable`,
`LaunchedEffect`, `DisposableEffect`, `SideEffect`, `rememberCoroutineScope`,
`Scaffold`, `NavHost`, `NavController`, `MaterialTheme`, `ColorScheme`,
`Typography`, `LazyColumn`, `LazyRow`, `LazyVerticalGrid`, `HorizontalPager`,
`Modifier`, `Modifier.Node`, `recomposition`, `CompositionLocal`, `Style`,
`styleable`, `MutableStyleState`.

### Compose Multiplatform / KMP
`Compose Multiplatform`, `CMP`, `KMP`, `commonMain`, `expect`, `actual`,
`ComposeUIViewController`, `Window` composable, `UIKitView`, `ComposeViewport`,
`Res.drawable`, `Res.string`, `SkikoMain`.

### Android TV
`tv-material`, `tv-foundation`, `Carousel`, `NavigationDrawer` (TV),
`D-pad`, `focus indication`, `FocusRequester` on TV, `10-foot UI`,
`living room`, `tv compose`, `Android TV`, `Google TV`, `leanback migration`.

### Paging 3
`PagingSource`, `Pager`, `PagingConfig`, `PagingData`, `LazyPagingItems`,
`collectAsLazyPagingItems`, `RemoteMediator`, `LoadState`,
`asSnapshot`, `TestPager`, `cachedIn`.

### Design system / design-to-code
`atomic design`, `atoms`, `molecules`, `organisms`, `templates`,
`design tokens`, `design system`, `component library`, `reusable component`,
`Figma to Compose`, `design to compose`, `build this UI`, `implement this design`,
`spec to code`, `redline`.

### Casual phrasing
"my compose screen is slow", "my recomposition is broken",
"how do I pass data between screens", "how do I build a TV app",
"Android UI", "Kotlin UI", "compose layout", "compose navigation",
"compose animation", "compose styles", "desktop compose", "iOS compose",
"compose web".

### Review Mode triggers
Any GitHub PR URL matching `github.com/.*/pull/\d+`, or phrases:
"review this PR", "review this diff", "review this code",
"check this code", "check this diff", "what's wrong with this".
On match, follow `references/pr-review.md` exclusively.

### Session start
Auto-detect Compose projects on `session_start` — see `references/auto-init.md`.

## Quick Routing

Use this table first. Match the user's signal to one reference file and read it before
Expand Down
Loading