Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases
日本語の概要は準備中です。原文の説明を表示しています。
Use when the mobile repository has no theme tokens or component library yet (a new app, an "Apply design system" task, or a task that asks for one), before building any screen - writes the approved design system's generated files from get_design_system (files true) and builds the theme from them when there is one.
インストールする前に、エージェントに与えられる指示の中身を確認できます。
A screen built before tokens and an atomic component library exist turns into Color(0x…), one-off paddings, and a library that never forms. This skill lays the foundation once, in order, so every screen after it is composition, not invention.
Core principle: Lay the foundation before the first screen — tokens, folders, and the first atoms come before any feature work.
get_design_system with files: true for this repository before anything else. When it returns a design system, the direction is already decided and approved: skip the design direction below and materialize it instead. Write every file in files verbatim at its path — DESIGN.md, design/tokens.json, design/tokens.css, design/INVENTORY.md; each carries a generated-file header and is never edited by hand, never transcribed. Then build the stack's theme from design/tokens.json by role (Flutter: ColorScheme light and dark plus ThemeExtensions for spacing, radius and sizes; SwiftUI: asset-catalog colour sets with Any/Dark appearances plus Theme.swift for type, spacing and radius; Compose: Color.kt / Theme.kt / Type.kt / Shape.kt with a light and a dark ColorScheme), each value exactly as its token holds it and named after it (color.light.primary → primary). Use the colours as given — no ColorScheme.fromSeed that would recompute them. The repository's own INVENTORY.md lists its components under the names design/INVENTORY.md gives them. A theme that already exists but differs from it gets its VALUES updated to the design system's, its structure kept. Only an empty answer leaves the direction to you.
A ThemeData/ThemeExtension, an asset-catalog colour set, a MaterialTheme wrapper, or an INVENTORY.md already present (and, when get_design_system returned a design system, the generated design/ files present and matching it) means this skill doesn't apply — stop, map and follow the existing structure (flutter-atomic-components / mobile-ui-ux) instead.
Only when get_design_system returned nothing. One line each, from the task brief (the brief's own words win over any default below): audience + tone; 4–6 named brand colours mapped onto semantic roles (primary/secondary/error at minimum); type pairing; radius choice; ASCII wireframe of the key screen at phone (360) and tablet (768) width.
Flutter (verified: flutter analyze clean):
@immutable
class AppSpacing extends ThemeExtension<AppSpacing> {
const AppSpacing({this.xs = 4, this.sm = 8, this.md = 16, this.lg = 24, this.xl = 32});
final double xs, sm, md, lg, xl;
@override AppSpacing copyWith({double? xs, double? sm, double? md, double? lg, double? xl}) =>
AppSpacing(xs: xs ?? this.xs, sm: sm ?? this.sm, md: md ?? this.md, lg: lg ?? this.lg, xl: xl ?? this.xl);
@override AppSpacing lerp(AppSpacing? other, double t) => this;
}
ThemeData buildTheme(Brightness b) => ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xFF2F5BEA), brightness: b), // brand colour lives ONLY here
extensions: const [AppSpacing()],
);
extension AppThemeX on BuildContext {
AppSpacing get space => Theme.of(this).extension<AppSpacing>()!;
ColorScheme get colors => Theme.of(this).colorScheme;
}
Folders: lib/ui/core/{theme,atoms,molecules,organisms} + lib/ui/features/<f>/ — this is the official Flutter architecture layout; follow the repo's existing layout if it already has one (e.g. lib/ui/atoms).
SwiftUI: asset-catalog colour sets with Any/Dark appearances, enum Space { static let xs: CGFloat = 4; static let sm: CGFloat = 8; static let md: CGFloat = 16; static let lg: CGFloat = 24 }, semantic Font text styles (never .system(size:) outside the theme), @ScaledMetric for any custom sizing so it still follows Dynamic Type.
Compose: data class AppSpacing(val xs: Dp = 4.dp, val sm: Dp = 8.dp, val md: Dp = 16.dp, val lg: Dp = 24.dp), val LocalSpacing = staticCompositionLocalOf { AppSpacing() }, val MaterialTheme.spacing @Composable get() = LocalSpacing.current; wrap the app in MaterialTheme(colorScheme = …) with dynamic colour on API 12+ and a static fallback below it.
Create the atomic folders (atoms/molecules/organisms, or the repo's existing naming) plus INVENTORY.md — header line One line per component: level · name · purpose · variants, one bullet per component added in the same commit that creates it.
Base atoms to start from: AppButton, AppTextField, AppIcon, StatusChip, Skeleton, EmptyState, ErrorView.
Wire a guard that runs inside the ordinary test command, so the build gate enforces it — not a separate CI step that can be skipped.
Flutter (verified: flags 4 violations in a raw-styled atom, passes on the token version):
// test/ui_guard_test.dart — runs inside `flutter test`, so the build gate enforces it
final banned = <String, RegExp>{
'raw colour (use context.colors / ColorScheme)': RegExp(r'Color\(0x|Colors\.(?!transparent)'),
'raw font size (use textTheme)': RegExp(r'fontSize:\s*\d'),
'raw spacing (use context.space)': RegExp(r'EdgeInsets\.(all|symmetric|only|fromLTRB)\([^)]*\d'),
};
// walks lib/ui/**.dart except lib/ui/**/theme/**, collects "path:line reason", expect(offenders, isEmpty)
Compose: a JVM unit test scanning src/main/**/ui/** (except ui/theme) for Color(0x and a numeric literal inside .padding(.
iOS: SwiftLint custom_rules (Color\(red:, \.font\(\.system\(size:, \.padding\(\d) when the repo already uses SwiftLint; skip if it doesn't rather than introducing a new lint dependency for this alone.
❌ Start writing a screen straight away: Color(0xFF2196F3) inline, EdgeInsets.all(16)
scattered across three widgets, no INVENTORY.md.
✅ 1. Detect: no ThemeData/ThemeExtension found → this skill applies.
2. Design direction (one paragraph) → 3. buildTheme() + AppSpacing extension
→ 4. lib/ui/core/{theme,atoms,...} folders + INVENTORY.md → 5. AppButton,
StatusChip, Skeleton atoms + widget tests → 6. ui_guard_test.dart green
→ 7. first screen, built entirely from atoms already in INVENTORY.md.
INVENTORY.md — the next task re-invents a Button.Color(0x…), Colors.*, or a numeric EdgeInsets/.padding( literal anywhere in the diff outside the theme files.lib/ui/ (or the repo's component folder) with no INVENTORY.md.まだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases
日本語の概要は準備中です。原文の説明を表示しています。
Use when the diff adds or changes an endpoint, resolver, RPC, job or query that takes an object id, a role check, a request binding or a tenant filter - BOLA/IDOR, function-level authorization, mass assignment and tenant scoping
日本語の概要は準備中です。原文の説明を表示しています。
Use on every UI change - semantic HTML, labels for controls, keyboard-navigable dialogs/menus, visible focus, and never color as the only signal
日本語の概要は準備中です。原文の説明を表示しています。
Use when a task changes any screen, form, dialog, menu or control - Lighthouse/axe scan of the changed screens, a keyboard walk, and the thresholds that fail a task
日本語の概要は準備中です。原文の説明を表示しています。
How to work a task returned with review, QA or UAT findings. Use when a task is in need_revision or PR review comments are in your context.
日本語の概要は準備中です。原文の説明を表示しています。
Use when deciding whether a request needs an analiz task before implementation - the conditions that require the architect's analysis versus going straight to implementation
日本語の概要は準備中です。原文の説明を表示しています。