compose-agent

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Compose Agent

Compose Agent

Review, write, or modify Jetpack Compose code for correctness, modern API usage, and adherence to the official AndroidX guidelines. Report only genuine problems — do not nitpick or invent issues.
Target track (unless the repo says otherwise):
  • Kotlin
    2.0.20+
    with Compose Compiler
    1.5.4+
    (Strong Skipping Mode on by default).
  • Jetpack Compose BOM current, Material 3,
    androidx.lifecycle
    with
    collectAsStateWithLifecycle()
    .
  • Navigation 3 (
    androidx.navigation3
    ) when the project can adopt it; otherwise Navigation 2.8+.
  • Coroutines + Flow as the async primitives. Do not reach for RxJava or blocking I/O.
If the repo pins older versions, match the repo — but call out what the modern path would look like in a one-line note.
用于审查、编写或修改Jetpack Compose代码,确保其正确性、符合现代API用法并遵循官方AndroidX规范。仅报告真实存在的问题——不要吹毛求疵或编造问题。
目标技术栈(除非仓库另有说明):
  • Kotlin
    2.0.20+
    及 Compose Compiler
    1.5.4+
    (默认启用Strong Skipping Mode)。
  • 最新版Jetpack Compose BOM、Material 3、搭配
    collectAsStateWithLifecycle()
    使用的
    androidx.lifecycle
    。
  • 项目支持时使用Navigation 3(
    androidx.navigation3
    );否则使用Navigation 2.8+。
  • 使用Coroutines + Flow作为异步原语。不要使用RxJava或阻塞式I/O。
如果仓库固定了旧版本,则与仓库保持一致——但请用一行注释说明现代实现方式是什么样的。

Review Process

审查流程

  1. Check for deprecated or soft-deprecated API using
    references/api.md
    .
  2. Validate state and data flow using
    references/state.md
    .
  3. Validate side-effect choice (
    LaunchedEffect
    ,
    DisposableEffect
    ,
    produceState
    ,
    snapshotFlow
    ,
    rememberUpdatedState
    ) using
    references/effects.md
    .
  4. Review composable performance — stability, lambda modifiers, lazy list keys, deferred reads, cross-phase back-writes — using
    references/performance.md
    .
  5. Review modifier usage — ordering, lambda-form,
    Modifier.Node
    over
    composed { }
    — using
    references/modifiers.md
    .
  6. Review navigation using
    references/navigation.md
    — start from its decision table (Nav3 vs Nav2 type-safe vs plain state) before touching call sites.
  7. Review coroutines and lifecycle collection using
    references/concurrency.md
    .
  8. Review Flow operators and StateFlow / SharedFlow shape (
    stateIn
    ,
    shareIn
    ,
    flatMap
    variants,
    combine
    , error handling, backpressure,
    asStateFlow()
    ) using
    references/flows.md
    .
  9. Review composable API shape (parameter order, slots, naming, defaults) using
    references/component-api.md
    .
  10. Review UI testing patterns using
    references/testing.md
    when tests, semantics, screenshots, previews, or fake UI dependencies are in scope.
  11. Review focus and keyboard / D-pad navigation using
    references/focus.md
    when the UI uses focus APIs, keyboard input, TV, desktop, ChromeOS, or accessibility focus behavior.
  12. Review Compose Multiplatform / KMP boundaries using
    references/kmp.md
    when common code,
    expect
    /
    actual
    , platform services, native views, or shared UI targets are in scope.
  13. Review animation API choice and lifecycle — declarative vs imperative,
    remember
    ed
    Animatable
    , target-driven launches,
    spring
    over
    tween
    , deferred animated reads,
    AnimatedContent
    keys — using
    references/animation.md
    when any
    animate*
    ,
    Animatable
    ,
    Transition
    ,
    AnimatedVisibility
    ,
    AnimatedContent
    , or infinite-transition API is in scope.
  14. Review Paging 3 in Compose —
    collectAsLazyPagingItems
    (the paging differ — not
    collectAsStateWithLifecycle
    , which does not apply to
    PagingData
    ), stable
    itemKey
    ,
    LoadState
    branches, user-driven
    refresh()
    /
    retry()
    — using
    references/paging.md
    when
    LazyPagingItems
    ,
    PagingData
    , or
    collectAsLazyPagingItems
    is in scope.
  15. Final Kotlin style pass using
    references/kotlin.md
    .
If doing a partial review, load only the relevant reference files — each references file is designed to be read in isolation.
  1. 使用
    references/api.md
    检查已弃用或软弃用的API。
  2. 使用
    references/state.md
    验证状态和数据流。
  3. 使用
    references/effects.md
    验证副作用选择(
    LaunchedEffect
    、
    DisposableEffect
    、
    produceState
    、
    snapshotFlow
    、
    rememberUpdatedState
    )。
  4. 使用
    references/performance.md
    审查可组合函数性能——稳定性、lambda形式的Modifier、懒加载列表key、延迟读取、跨阶段回写。
  5. 使用
    references/modifiers.md
    审查Modifier使用——顺序、lambda形式、优先使用
    Modifier.Node
    而非
    composed { }
    。
  6. 使用
    references/navigation.md
    审查导航——在修改调用点之前,先从其决策表(Nav3 vs Nav2类型安全 vs 纯状态)开始分析。
  7. 使用
    references/concurrency.md
    审查协程与生命周期收集。
  8. 使用
    references/flows.md
    审查Flow运算符及StateFlow / SharedFlow形态(
    stateIn
    、
    shareIn
    、
    flatMap
    变体、
    combine
    、错误处理、背压、
    asStateFlow()
    )。
  9. 使用
    references/component-api.md
    审查可组合API形态(参数顺序、插槽、命名、默认值)。
  10. 当测试、语义、截图、预览或模拟UI依赖在范围内时,使用
    references/testing.md
    审查UI测试模式。
  11. 当UI使用焦点API、键盘输入、TV、桌面、ChromeOS或无障碍焦点行为时,使用
    references/focus.md
    审查焦点与键盘/D-pad导航。
  12. 当公共代码、
    expect
    /
    actual
    、平台服务、原生视图或共享UI目标在范围内时,使用
    references/kmp.md
    审查Compose Multiplatform / KMP边界。
  13. 当任何
    animate*
    、
    Animatable
    、
    Transition
    、
    AnimatedVisibility
    、
    AnimatedContent
    或无限过渡API在范围内时,使用
    references/animation.md
    审查动画API选择与生命周期——声明式 vs 命令式、
    remember
    存储的
    Animatable
    、目标驱动的启动、优先使用
    spring
    而非
    tween
    、延迟动画读取、
    AnimatedContent
    的key。
  14. 当
    LazyPagingItems
    、
    PagingData
    或
    collectAsLazyPagingItems
    在范围内时,使用
    references/paging.md
    审查Compose中的Paging 3——
    collectAsLazyPagingItems
    (分页差异器——不是
    collectAsStateWithLifecycle
    ,后者不适用于
    PagingData
    )、稳定的
    itemKey
    、
    LoadState
    分支、用户驱动的
    refresh()
    /
    retry()
    。
  15. 使用
    references/kotlin.md
    进行最终的Kotlin风格检查。
如果进行部分审查,仅加载相关的参考文件——每个参考文件都设计为可独立阅读。

Core Instructions

核心指令

  • Keep composables side-effect free in composition. All I/O, state mutation outside remembered objects, analytics, etc. belong in
    LaunchedEffect
    ,
    DisposableEffect
    ,
    produceState
    , the ViewModel, or — for event/gesture-driven work only —
    rememberCoroutineScope().launch
    inside a handler. Target-driven animation belongs in
    LaunchedEffect
    or declarative
    animate*AsState
    /
    updateTransition
    , not in
    scope.launch
    from the composition body. See
    references/animation.md
    and
    references/effects.md
    .
  • Every composable that takes a
    Modifier
    names the parameter
    modifier
    , types it
    Modifier = Modifier
    , and applies it to the outermost layout only. Never create a
    modifier
    parameter you do not forward.
  • Parameter order for a component: required data →
    modifier: Modifier = Modifier
    → other optional parameters with defaults → trailing
    content: @Composable () -> Unit
    slots last. One
    modifier
    parameter per component.
  • For stateful APIs, expose a stateless overload plus a stateful convenience that hoists
    remember
    . See
    references/component-api.md
    .
  • Collect Flows with
    collectAsStateWithLifecycle()
    in UI code. Plain
    collectAsState()
    keeps collecting when the screen is not visible and burns battery and bandwidth. Exception:
    Flow<PagingData<T>>
    is collected with
    collectAsLazyPagingItems()
    , never
    collectAsStateWithLifecycle()
    — see
    references/paging.md
    .
  • Prefer
    rememberSaveable
    over
    remember
    for UI state that should survive configuration change or process death, unless the value is unserializable or derivable.
  • Use the typed state factories (
    mutableIntStateOf
    ,
    mutableLongStateOf
    ,
    mutableFloatStateOf
    ,
    mutableDoubleStateOf
    ) for primitive state. Raw
    mutableStateOf<Int>(...)
    boxes.
  • Never write state a phase has already read. A layout callback (
    onSizeChanged
    /
    onGloballyPositioned
    /
    onPlaced
    ) must not write state a sibling reads in composition (a cross-phase back-write, a measure → recompose loop), and never mutate a
    mutableStateListOf
    /
    mutableStateMapOf
    inside a composable body that also reads it (composition-phase self-invalidation, a mutate → recompose loop). Consume measured values in layout/draw, or mutate snapshot state from an event /
    LaunchedEffect
    / state holder. See
    references/performance.md
    .
  • Don't ship no-op "optimizations":
    remember(index)
    on a pure function, or
    remember
    -ing an already-auto-memoized callback under Strong Skipping (SSM memoizes lambdas even with unstable captures). Prove a recomposition win with Layout Inspector counts or compiler reports, not the presence of a pattern. See
    references/performance.md
    .
  • Never put a lambda in a
    CompositionLocal
    . Use explicit parameters.
  • Do not introduce third-party libraries without asking first. The Accompanist libraries covering pager, swipe-refresh, flow layout, and system UI controller are deprecated — the functionality is in AndroidX now (
    HorizontalPager
    ,
    PullToRefreshBox
    ,
    FlowRow
    /
    FlowColumn
    ,
    enableEdgeToEdge()
    ).
  • When an element's background reads from
    MaterialTheme.colorScheme.*
    (directly or via a blend), its text and icon colors must read from the same theming source. Hard-coded
    Color.Black
    /
    Color.White
    / raw ARGB literals over theme-driven backgrounds are dark-mode regressions. See
    references/component-api.md
    .
  • Animate declaratively first. Use
    animate*AsState
    for single state-driven values and
    updateTransition
    for synchronized ones; reach for
    Animatable
    only when you need imperative control (gesture, fling, sequence). Always
    remember
    an
    Animatable
    , launch target-driven animations from
    LaunchedEffect
    (never
    scope.launch
    in composition to react to state), prefer
    spring()
    over
    tween
    for interruptible motion, and read animated values in the layout/draw phase (lambda modifiers /
    graphicsLayer
    ) so the animation does not recompose every frame. See
    references/animation.md
    .
  • For paged feeds, use
    collectAsLazyPagingItems()
    , render with
    items(count = …, key = …)
    and stable domain ids, branch on
    loadState
    for loading/empty/error/append, and keep
    refresh()
    /
    retry()
    on user actions — not in the composition body. See
    references/paging.md
    .
  • 确保组合过程中的可组合函数无副作用。所有I/O操作、remember存储对象之外的状态变更、埋点统计等都应放在
    LaunchedEffect
    、
    DisposableEffect
    、
    produceState
    、ViewModel中,或者——仅适用于事件/手势驱动的任务——放在处理器内的
    rememberCoroutineScope().launch
    中。目标驱动的动画应放在
    LaunchedEffect
    或声明式的
    animate*AsState
    /
    updateTransition
    中,而不是放在组合体的
    scope.launch
    里。参见
    references/animation.md
    和
    references/effects.md
    。
  • 每个接收
    Modifier
    的可组合函数都应将参数命名为
    modifier
    ,类型为
    Modifier = Modifier
    ,并且仅将其应用于最外层布局。永远不要创建一个不向下传递的
    modifier
    参数。
  • 组件的参数顺序:必填数据 →
    modifier: Modifier = Modifier
    → 其他带默认值的可选参数 → 最后是尾随的
    content: @Composable () -> Unit
    插槽。每个组件只能有一个
    modifier
    参数。
  • 对于有状态的API,提供一个无状态的重载,加上一个提升了
    remember
    的有状态便捷重载。参见
    references/component-api.md
    。
  • 在UI代码中使用
    collectAsStateWithLifecycle()
    收集Flow。普通的
    collectAsState()
    会在屏幕不可见时继续收集,消耗电量和带宽。例外:
    Flow<PagingData<T>>
    使用
    collectAsLazyPagingItems()
    收集,绝对不能用
    collectAsStateWithLifecycle()
    ——参见
    references/paging.md
    。
  • 对于需要在配置变更或进程死亡后保留的UI状态,优先使用
    rememberSaveable
    而非
    remember
    ,除非值无法序列化或可通过其他方式推导。
  • 对于基础类型状态,使用类型化状态工厂(
    mutableIntStateOf
    、
    mutableLongStateOf
    、
    mutableFloatStateOf
    、
    mutableDoubleStateOf
    )。原始的
    mutableStateOf<Int>(...)
    会进行装箱。
  • 永远不要写入某个阶段已经读取过的状态。布局回调(
    onSizeChanged
    /
    onGloballyPositioned
    /
    onPlaced
    )不能写入兄弟节点在组合中读取的状态(跨阶段回写,会导致测量→重组循环),也永远不要在同时读取
    mutableStateListOf
    /
    mutableStateMapOf
    的可组合函数体内修改它们(组合阶段自失效,会导致修改→重组循环)。应在布局/绘制阶段消费测量值,或者从事件/
    LaunchedEffect
    /状态持有者中修改快照状态。参见
    references/performance.md
    。
  • 不要交付无操作的“优化”:纯函数上的
    remember(index)
    ,或者在Strong Skipping模式下对已经自动记忆的回调使用
    remember
    (SSM会记忆即使带有不稳定捕获的lambda)。要用Layout Inspector计数或编译器报告证明重组优化的效果,而不是靠某种模式的存在。参见
    references/performance.md
    。
  • 永远不要在
    CompositionLocal
    中放入lambda。使用显式参数。
  • 未经询问不要引入第三方库。覆盖分页器、下拉刷新、流式布局、系统UI控制器的Accompanist库已经弃用——这些功能现在已经在AndroidX中了(
    HorizontalPager
    、
    PullToRefreshBox
    、
    FlowRow
    /
    FlowColumn
    、
    enableEdgeToEdge()
    )。
  • 当一个元素的背景从
    MaterialTheme.colorScheme.*
    读取颜色时(直接或通过混合),其文本和图标颜色必须从同一主题源读取。在主题驱动的背景上使用硬编码的
    Color.Black
    /
    Color.White
    / 原始ARGB字面量会导致深色模式回归问题。参见
    references/component-api.md
    。
  • 优先使用声明式动画。对于单状态驱动的值使用
    animate*AsState
    ,对于同步动画使用
    updateTransition
    ;仅当需要命令式控制(手势、抛掷、序列动画)时才使用
    Animatable
    。始终用
    remember
    存储
    Animatable
    ,从
    LaunchedEffect
    中启动目标驱动的动画(永远不要在组合中使用
    scope.launch
    来响应状态),优先使用
    spring()
    而非
    tween
    以实现可中断的动效,并在布局/绘制阶段(lambda形式的Modifier /
    graphicsLayer
    )读取动画值,这样动画不会每帧都触发重组。参见
    references/animation.md
    。
  • 对于分页信息流,使用
    collectAsLazyPagingItems()
    ,通过
    items(count = …, key = …)
    和稳定的业务ID进行渲染,根据
    loadState
    分支处理加载/空状态/错误/加载更多,并且将
    refresh()
    /
    retry()
    放在用户操作中——而不是放在组合体里。参见
    references/paging.md
    。

Output Format (review mode)

输出格式(审查模式)

Organize findings by file. For each issue:
  1. State the file and relevant line(s).
  2. Name the rule being violated (e.g., "Use
    collectAsStateWithLifecycle()
    instead of
    collectAsState()
    ").
  3. Show a brief before/after code fix.
  4. Link the official source (
    developer.android.com/...
    or AndroidX component guidelines).
Skip files with no issues. End with a prioritized summary — three items max, highest impact first.
按文件组织发现的问题。对于每个问题:
  1. 说明文件及相关行号。
  2. 指出违反的规则(例如:“使用
    collectAsStateWithLifecycle()
    代替
    collectAsState()
    ”)。
  3. 展示简短的修复前后代码对比。
  4. 链接官方来源(
    developer.android.com/...
    或AndroidX组件规范)。
跳过没有问题的文件。最后附上优先级总结——最多三项,影响最高的排在前面。

Example Output

输出示例

feature/profile/ProfileScreen.kt

feature/profile/ProfileScreen.kt

Line 34: Use
collectAsStateWithLifecycle()
— UI Flows must stop collecting when the screen is not STARTED.
kotlin
// Before
val user by viewModel.user.collectAsState()

// After
val user by viewModel.user.collectAsStateWithLifecycle()
Line 58: Pass
modifier
to the outermost layout, not to inner content.
kotlin
// Before
@Composable
fun UserCard(user: User, modifier: Modifier = Modifier) {
    Column {
        Text(user.name, modifier = modifier) // modifier swallowed here
        Text(user.email)
    }
}

// After
@Composable
fun UserCard(user: User, modifier: Modifier = Modifier) {
    Column(modifier = modifier) {
        Text(user.name)
        Text(user.email)
    }
}
Line 72: Defer the animated
offset
read to the layout phase using the lambda form.
kotlin
// Before
val dx by animateDpAsState(targetValue = if (expanded) 0.dp else (-200).dp, label = "drawerOffset")
Box(modifier = Modifier.offset(x = dx))

// After — layout-phase read, skips recomposition on every frame
val dx by animateDpAsState(targetValue = if (expanded) 0.dp else (-200).dp, label = "drawerOffset")
Box(modifier = Modifier.offset { IntOffset(dx.roundToPx(), 0) })
第34行:使用
collectAsStateWithLifecycle()
——UI Flow在屏幕未处于STARTED状态时必须停止收集。
kotlin
// Before
val user by viewModel.user.collectAsState()

// After
val user by viewModel.user.collectAsStateWithLifecycle()
第58行:将
modifier
传递给最外层布局,而不是内部内容。
kotlin
// Before
@Composable
fun UserCard(user: User, modifier: Modifier = Modifier) {
    Column {
        Text(user.name, modifier = modifier) // modifier swallowed here
        Text(user.email)
    }
}

// After
@Composable
fun UserCard(user: User, modifier: Modifier = Modifier) {
    Column(modifier = modifier) {
        Text(user.name)
        Text(user.email)
    }
}
第72行:使用lambda形式将动画
offset
的读取延迟到布局阶段。
kotlin
// Before
val dx by animateDpAsState(targetValue = if (expanded) 0.dp else (-200).dp, label = "drawerOffset")
Box(modifier = Modifier.offset(x = dx))

// After — layout-phase read, skips recomposition on every frame
val dx by animateDpAsState(targetValue = if (expanded) 0.dp else (-200).dp, label = "drawerOffset")
Box(modifier = Modifier.offset { IntOffset(dx.roundToPx(), 0) })

Summary

总结

  1. Performance (high): Non-deferred animated reads on
    ProfileScreen.kt:72
    ,
    HomeScreen.kt:110
    ,
    DetailScreen.kt:88
    recompose every frame. Switch to lambda-form modifiers.
  2. Lifecycle (high): Three screens use
    collectAsState()
    — replace with
    collectAsStateWithLifecycle()
    to avoid collecting in the background.
  3. API shape (medium):
    UserCard
    swallows its
    modifier
    parameter. Forward it to the outermost layout.
End of example.
  1. 性能(高优先级):
    ProfileScreen.kt:72
    、
    HomeScreen.kt:110
    、
    DetailScreen.kt:88
    上的非延迟动画读取会导致每帧重组。请切换为lambda形式的Modifier。
  2. 生命周期(高优先级): 三个屏幕使用了
    collectAsState()
    ——请替换为
    collectAsStateWithLifecycle()
    以避免在后台收集。
  3. API形态(中优先级):
    UserCard
    未传递其
    modifier
    参数。请将其转发给最外层布局。
示例结束。

Authoring Mode

编写模式

When the agent is writing new code rather than reviewing, the same rules apply as guardrails. Before generating a composable, silently check:
  • Does it take
    modifier: Modifier = Modifier
    ?
  • Is state hoisted, or is there a clear reason to own it here?
  • If it renders a list, does it use a stable
    key =
    ?
  • If it launches work, is that work in a
    LaunchedEffect
    ,
    produceState
    , or the ViewModel — not in the composition body?
  • If it collects a Flow, is it
    collectAsStateWithLifecycle()
    ? (A
    Flow<PagingData<T>>
    is the exception — it uses
    collectAsLazyPagingItems()
    .)
  • Is the parameter order: data → modifier → other → content slot last?
  • If it animates, is the API declarative first, remembered where needed, lifecycle-aware, and phase-correct?
  • Does any layout callback or snapshot-collection mutation write state read back in composition (a cross-phase / self-invalidation loop)?
  • If it pages, are keys stable,
    LoadState
    handled, and refresh/retry user-driven?
  • If it needs focus, testing, or platform-specific behavior, did you load the focused reference before judging?
If any answer is no and there is no deliberate reason, fix it before returning the code.
当Agent编写新代码而非审查时,同样的规则作为防护栏适用。在生成可组合函数之前,请静默检查:
  • 是否接收了
    modifier: Modifier = Modifier
    ?
  • 状态是否被提升,或者是否有明确的理由在此处拥有状态?
  • 如果渲染列表,是否使用了稳定的
    key =
    ?
  • 如果启动了任务,该任务是否在
    LaunchedEffect
    、
    produceState
    或ViewModel中——而不是在组合体里?
  • 如果收集Flow,是否使用了
    collectAsStateWithLifecycle()
    ?(
    Flow<PagingData<T>>
    是例外——它使用
    collectAsLazyPagingItems()
    。)
  • 参数顺序是否为:数据 → modifier → 其他 → 最后是content插槽?
  • 如果有动画,是否优先使用声明式API、在需要时remember、具有生命周期感知且阶段正确?
  • 是否存在布局回调或快照收集修改了组合中会回读的状态(跨阶段/自失效循环)?
  • 如果是分页,key是否稳定、
    LoadState
    是否被处理、刷新/重试是否由用户驱动?
  • 如果需要焦点、测试或平台特定行为,是否在判断前加载了相关参考文档?
如果任何答案为“否”且没有刻意的理由,请在返回代码前修复。

What This Skill Does Not Cover

本技能不覆盖的内容

Out of scope in v1 — delegate elsewhere or scope down explicitly:
  • Material 3 compliance, theming, and design tokens — use the
    material-3
    skill.
  • Scoring an existing codebase with numeric grades — use the sibling
    jetpack-compose-audit
    skill in the same repo.
  • Wear OS / TV / Auto / Glance deep platform review — this skill now covers focus and keyboard/D-pad basics, but not full platform certification.
  • Accessibility deep review — we flag obvious gaps (missing
    contentDescription
    , icon-only buttons without labels, touch targets under 48dp) but do not grade.
If the user needs any of the above, narrow the scope and say so.
v1版本范围外的内容——请委托给其他技能或明确缩小范围:
  • Material 3合规性、主题和设计令牌——使用
    material-3
    技能。
  • 用数字等级对现有代码库进行评分——使用同一仓库中的姊妹技能
    jetpack-compose-audit
    。
  • Wear OS / TV / Auto / Glance深度平台审查——本技能目前覆盖焦点和键盘/D-pad基础,但不包括完整的平台认证。
  • 无障碍深度审查——我们会标记明显的缺陷(缺少
    contentDescription
    、无标签的纯图标按钮、触摸目标小于48dp),但不进行评分。
如果用户需要以上任何内容,请缩小范围并说明。

References

参考文献

  • references/api.md
    — deprecated and soft-deprecated Compose APIs and their modern replacements.
  • references/state.md
    — hoisting,
    remember
    vs
    rememberSaveable
    , ViewModel boundaries,
    derivedStateOf
    .
  • references/effects.md
    —
    LaunchedEffect
    ,
    DisposableEffect
    ,
    SideEffect
    ,
    produceState
    ,
    snapshotFlow
    ,
    rememberUpdatedState
    .
  • references/performance.md
    — stability, Strong Skipping Mode, lambda modifiers, lazy keys, typed state factories, deferred reads.
  • references/modifiers.md
    — modifier ordering, lambda form,
    Modifier.Node
    over
    composed { }
    .
  • references/navigation.md
    — decision table (Nav3 vs Nav2 type-safe vs plain state), Navigation 3, and what to replace from Navigation 2.
  • references/concurrency.md
    — coroutines, Flow,
    collectAsStateWithLifecycle
    ,
    repeatOnLifecycle
    , scope choice.
  • references/flows.md
    — operator selection:
    StateFlow
    vs
    SharedFlow
    vs cold
    Flow
    ,
    stateIn(WhileSubscribed)
    ,
    shareIn
    ,
    flatMap
    variants,
    combine
    /
    merge
    /
    zip
    , error handling, backpressure,
    asStateFlow()
    exposure.
  • references/component-api.md
    — composable API guidelines: parameter order, slots, naming, defaults, state hoisting shape.
  • references/testing.md
    — Compose UI tests, semantics assertions, screenshot tests, fake image/platform services, previews.
  • references/focus.md
    —
    FocusRequester
    , focus restoration, keyboard / D-pad input, key handlers, and focus tests.
  • references/kmp.md
    — Kotlin Multiplatform and Compose Multiplatform boundaries,
    expect
    /
    actual
    , interfaces, platform leaf composables.
  • references/animation.md
    — animation API selection (
    animate*AsState
    vs
    updateTransition
    vs
    Animatable
    ),
    remember
    ed animation state, target-driven launches, gesture-driven
    snapTo
    /
    animateDecay
    ,
    spring
    /
    tween
    /
    keyframes
    , reduced motion, deferred animated reads,
    AnimatedContent
    /
    AnimatedVisibility
    ,
    animateItem()
    , off-screen infinite transitions.
  • references/paging.md
    — Paging 3 in Compose: when to page vs plain lists,
    collectAsLazyPagingItems
    , stable
    itemKey
    ,
    LoadState
    UI, pull-to-refresh, anti-patterns for paginated lazy lists.
  • references/kotlin.md
    — Kotlin coding conventions and Android Kotlin style the LLM keeps missing.
  • references/api.md
    — 已弃用和软弃用的Compose API及其现代替代方案。
  • references/state.md
    — 状态提升、
    remember
    vs
    rememberSaveable
    、ViewModel边界、
    derivedStateOf
    。
  • references/effects.md
    —
    LaunchedEffect
    、
    DisposableEffect
    、
    SideEffect
    、
    produceState
    、
    snapshotFlow
    、
    rememberUpdatedState
    。
  • references/performance.md
    — 稳定性、Strong Skipping Mode、lambda形式的Modifier、懒加载key、类型化状态工厂、延迟读取。
  • references/modifiers.md
    — Modifier顺序、lambda形式、优先使用
    Modifier.Node
    而非
    composed { }
    。
  • references/navigation.md
    — 决策表(Nav3 vs Nav2类型安全 vs 纯状态)、Navigation 3,以及Navigation 2中需要替换的内容。
  • references/concurrency.md
    — 协程、Flow、
    collectAsStateWithLifecycle
    、
    repeatOnLifecycle
    、作用域选择。
  • references/flows.md
    — 运算符选择:
    StateFlow
    vs
    SharedFlow
    vs 冷
    Flow
    、
    stateIn(WhileSubscribed)
    、
    shareIn
    、
    flatMap
    变体、
    combine
    /
    merge
    /
    zip
    、错误处理、背压、
    asStateFlow()
    暴露。
  • references/component-api.md
    — 可组合API规范:参数顺序、插槽、命名、默认值、状态提升形态。
  • references/testing.md
    — Compose UI测试、语义断言、截图测试、模拟图片/平台服务、预览。
  • references/focus.md
    —
    FocusRequester
    、焦点恢复、键盘/D-pad输入、按键处理器、焦点测试。
  • references/kmp.md
    — Kotlin Multiplatform与Compose Multiplatform边界、
    expect
    /
    actual
    、接口、平台叶子可组合函数。
  • references/animation.md
    — 动画API选择(
    animate*AsState
    vs
    updateTransition
    vs
    Animatable
    )、
    remember
    存储的动画状态、目标驱动启动、手势驱动的
    snapTo
    /
    animateDecay
    、
    spring
    /
    tween
    /
    keyframes
    、减少动效、延迟动画读取、
    AnimatedContent
    /
    AnimatedVisibility
    、
    animateItem()
    、屏幕外无限过渡。
  • references/paging.md
    — Compose中的Paging 3:何时使用分页 vs 普通列表、
    collectAsLazyPagingItems
    、稳定的
    itemKey
    、
    LoadState
    UI、下拉刷新、分页懒加载列表的反模式。
  • references/kotlin.md
    — LLM经常遗漏的Kotlin编码约定和Android Kotlin风格。

Acceptance Evals

验收评估

evals/evals.json
holds write-mode acceptance cases — prompts that ask this skill to write Compose, plus the expectations the produced code must satisfy. Cases 0–2 mirror the
jetpack-compose-audit
scoring rules 1:1 (cross-phase back-writes, Strong Skipping false leads, snapshot self-invalidation) —
bin/ci
keeps them in lockstep so the authoring path can't drift from the audit path; cases 3–4 add foundational phase-correct reads and lifecycle-aware Flow collection. Run a model with this skill loaded against each prompt and check every expectation.
evals/evals.json
包含编写模式的验收用例——要求本技能编写Compose代码的提示,以及生成的代码必须满足的期望。用例0–2与
jetpack-compose-audit
评分规则1:1对应(跨阶段回写、Strong Skipping错误引导、快照自失效)——
bin/ci
会保持它们同步,确保编写路径不会偏离审计路径;用例3–4增加了基础的阶段正确读取和生命周期感知Flow收集。使用加载了本技能的模型运行每个提示,并检查所有期望是否满足。

Primary Sources

主要来源

Every rule in this skill traces back to one of:
  • https://developer.android.com/develop/ui/compose
    and its subpages
  • https://developer.android.com/kotlin/style-guide
  • https://kotlinlang.org/docs/coding-conventions.html
  • https://www.jetbrains.com/help/kotlin-multiplatform-dev/
  • https://android.googlesource.com/platform/frameworks/support/+/androidx-main/compose/docs/compose-api-guidelines.md
  • https://android.googlesource.com/platform/frameworks/support/+/androidx-main/compose/docs/compose-component-api-guidelines.md
When a supplemental source (blog post, conference talk) disagrees with these, the primary sources win.
本技能中的每一条规则都可追溯至以下来源之一:
  • https://developer.android.com/develop/ui/compose
    及其子页面
  • https://developer.android.com/kotlin/style-guide
  • https://kotlinlang.org/docs/coding-conventions.html
  • https://www.jetbrains.com/help/kotlin-multiplatform-dev/
  • https://android.googlesource.com/platform/frameworks/support/+/androidx-main/compose/docs/compose-api-guidelines.md
  • https://android.googlesource.com/platform/frameworks/support/+/androidx-main/compose/docs/compose-component-api-guidelines.md
当补充来源(博客文章、会议演讲)与这些来源冲突时,以主要来源为准。