From harness-claude
Generates token-bound mobile UI components for React Native, SwiftUI, Flutter, or Jetpack Compose from design tokens and aesthetic intent. Ensures platform-specific rules and verifies token references.
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeThis skill uses the workspace's default tool permissions.
> Token-bound mobile component generation. Scaffold from design tokens and aesthetic intent, implement with React Native, SwiftUI, Flutter, or Compose patterns following platform-specific design rules, and verify every value references the token set with native convention compliance.
Builds platform-independent design systems with design tokens, core/composite UI components (Button, Input, Card), and documentation. For React/shadcn-ui, Vue, Flutter, SwiftUI, Android.
Enforces mobile UI accessibility in React Native, iOS/Android/Flutter apps: 44pt touch targets, WCAG contrast, visible button boundaries, accessibility labels.
Generates token-bound web components from design tokens and aesthetic intent for React, Vue, or Svelte using Tailwind/CSS patterns. Ensures no hardcoded colors, fonts, or spacing by verifying token references.
Share bugs, ideas, or general feedback.
Token-bound mobile component generation. Scaffold from design tokens and aesthetic intent, implement with React Native, SwiftUI, Flutter, or Compose patterns following platform-specific design rules, and verify every value references the token set with native convention compliance.
on_new_feature triggers fire with mobile UI scope requiring token-bound component generationon_commit triggers fire and new mobile components contain hardcoded design values that should reference tokensdesign-system/DESIGN.md into platform-native styling (StyleSheet, SwiftUI modifiers, Flutter ThemeData, Compose MaterialTheme)Read design tokens. Load design-system/tokens.json (W3C DTCG format). Extract:
design-system/tokens.json does not exist, stop and instruct the user to run harness-design-system first.Read design intent. Load design-system/DESIGN.md for:
design-system/DESIGN.md does not exist, warn the user and proceed with tokens only.Check harness configuration. Read harness.config.json for:
design.strictness — enforcement level. Default to standard.design.platforms — confirm mobile is in the platforms list.Detect mobile platform. Scan the project for:
package.json contains react-native or expo, .tsx files with StyleSheet or react-native imports.swift files with import SwiftUI, Package.swift or .xcodeproj existspubspec.yaml exists, .dart files with import 'package:flutter/build.gradle.kts with compose dependencies, .kt files with @Composable--platform, use that override.Load platform-specific rules. Based on detected platform, read platform design guidelines from agents/skills/shared/design-knowledge/platform-rules/:
ios.yaml — Human Interface Guidelines, safe area insets, navigation bar patterns, tab bar conventions, dynamic type support, SF Symbols integrationandroid.yaml — Material Design 3, elevation system, shape system, dynamic color, navigation patterns, edge-to-edge layoutflutter.yaml — Flutter design patterns, ThemeData structure, widget composition, adaptive layouts, platform channel considerationsios.yaml and android.yaml — platform-specific overrides via Platform.select, safe area handling, navigation library patternsLoad anti-pattern definitions. Read anti-pattern files from agents/skills/shared/design-knowledge/anti-patterns/:
typography.yaml — typographic anti-patterns (too many fonts, inconsistent scales)color.yaml — color anti-patterns (hardcoded hex, insufficient contrast)layout.yaml — layout anti-patterns (magic numbers, inconsistent spacing)motion.yaml — motion anti-patterns (excessive animation, missing reduced-motion)Build token-to-platform mapping. Create a lookup table mapping tokens to platform-native representations:
color.primary.500 maps to StyleSheet value or themed constantcolor.primary.500 maps to Color("primary500") in asset catalog or Color(hex:) extensioncolor.primary.500 maps to Theme.of(context).colorScheme.primary or custom AppColors.primary500color.primary.500 maps to MaterialTheme.colorScheme.primary or custom AppTheme.colors.primary500Plan component structure. Define:
Generate platform-specific component code. Based on detected platform:
React Native (TypeScript):
Platform.select where iOS and Android differuseSafeAreaInsets for edge-to-edge contentSwiftUI:
Font extensions mapping to token values.font(.body) or custom scaled fonts.safeAreaInset modifiersFlutter (Dart):
Theme.of(context) or custom AppColors class referencing tokensTheme.of(context).textTheme or custom AppTypographyLayoutBuilder or MediaQuery for responsive behaviorCompose (Kotlin):
@Composable function with typed parametersMaterialTheme.colorScheme or custom theme referencing tokensMaterialTheme.typography or custom type scaleDp constantsApply platform-specific rules:
Add USES_TOKEN annotations. Insert platform-appropriate comments documenting token consumption:
// @design-token color.primary.500 — primary action background
// @design-token typography.heading.fontFamily — section heading
// @design-token spacing.md — card internal padding
Scan for hardcoded values. Search generated files for:
UIColor(red:green:blue:), Color(0xFF...), Color(red:green:blue:)Verify token coverage. For every design value in generated components:
design-system/tokens.jsonCheck platform guideline compliance:
Check anti-pattern compliance. Cross-reference against design-system/DESIGN.md anti-patterns and definitions in agents/skills/shared/design-knowledge/anti-patterns/.
Query the knowledge graph. If available at .harness/graph/:
DesignToken nodes exist for all referenced tokensPLATFORM_BINDING edges exist for the target mobile platformVIOLATES_DESIGN edges via DesignConstraintAdapterAssign severity based on designStrictness:
permissive — all findings are infostandard — hardcoded values are warn, platform guideline violations are warn, accessibility violations are errorstrict — hardcoded values are error (blocks), platform violations are warn, accessibility violations are errorReport verification results:
MOBILE-001 [warn] Hardcoded color Color(0xFF3B82F6) — should reference token
File: lib/widgets/action_button.dart:15
Fix: Use Theme.of(context).colorScheme.primary or AppColors.primary500
MOBILE-002 [warn] Touch target 32dp below minimum 48dp (Material Design 3)
File: lib/widgets/icon_action.dart:22
Fix: Set minimumSize to Size(48, 48) in ButtonStyle
MOBILE-003 [info] Missing dynamic type support
File: Sources/Views/ProductCard.swift:18
Fix: Use .font(.body) instead of .font(.system(size: 16))
Run harness validate. Confirm new components integrate cleanly.
harness validate — Run after generating components to verify project health.harness scan — Run after component generation to update the knowledge graph with USES_TOKEN and PLATFORM_BINDING edges.DesignIngestor (packages/graph/src/ingest/DesignIngestor.ts) — Verifies DesignToken nodes exist for all tokens referenced by generated components.DesignConstraintAdapter (packages/graph/src/constraints/DesignConstraintAdapter.ts) — Checks for VIOLATES_DESIGN edges during VERIFY phase. Reports constraint violations at configured strictness.harness-design-system — Dependency. Provides design-system/tokens.json. If tokens do not exist, instruct user to run harness-design-system first.harness-design — Dependency. Provides design-system/DESIGN.md with aesthetic intent and anti-patterns.harness-impact-analysis — Traces token changes to affected mobile components via USES_TOKEN edges.Graph naming convention: This skill uses PascalCase for node types (DesignToken, DesignConstraint) and UPPER_SNAKE for edge types (USES_TOKEN, PLATFORM_BINDING, VIOLATES_DESIGN) as conceptual labels. The graph schema registers these as snake_case identifiers (design_token, design_constraint, uses_token, platform_binding, violates_design). The adapter classes (DesignIngestor, DesignConstraintAdapter) handle the mapping — always use the adapters rather than constructing graph queries with raw type names.
@design-token annotations are present for every consumed tokendesign-system/DESIGN.mddesign.strictness configurationharness validate passes after component generationContext: Fitness app. React Native with Expo. Tokens from harness-design-system. Design intent: expressive, warm tone.
SCAFFOLD output:
Platform detected: React Native (Expo)
Tokens loaded: 38 tokens from design-system/tokens.json
Design intent: Expressive, warm (from DESIGN.md)
Component plan: WorkoutCard with progress indicator
Token consumption: color.primary.*, color.accent.*, typography.heading, spacing.md/lg
Platform rules: iOS 44pt touch targets, Android 48dp touch targets, safe area insets
IMPLEMENT output (WorkoutCard.tsx):
// @design-token color.primary.500 — card accent
// @design-token color.neutral.50 — card background
// @design-token color.neutral.900 — primary text
// @design-token typography.heading.fontFamily — workout title
// @design-token typography.body.fontFamily — workout details
// @design-token spacing.md — card padding
// @design-token spacing.sm — content gap
import { View, Text, StyleSheet, Platform } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { tokens } from '@/theme/tokens';
interface WorkoutCardProps {
title: string;
duration: string;
progress: number;
}
export function WorkoutCard({ title, duration, progress }: WorkoutCardProps) {
return (
<View style={styles.card}>
<Text style={styles.title}>{title}</Text>
<Text style={styles.detail}>{duration}</Text>
<View style={styles.progressTrack}>
<View style={[styles.progressFill, { width: `${progress}%` }]} />
</View>
</View>
);
}
const styles = StyleSheet.create({
card: {
backgroundColor: tokens.color.neutral[50],
borderRadius: tokens.radius.md,
padding: tokens.spacing.md,
gap: tokens.spacing.sm,
...Platform.select({
ios: {
shadowColor: tokens.color.neutral[900],
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.08,
shadowRadius: 8,
},
android: {
elevation: 2,
},
}),
},
title: {
fontFamily: tokens.typography.heading.fontFamily,
fontWeight: tokens.typography.heading.fontWeight,
fontSize: 18,
color: tokens.color.neutral[900],
},
detail: {
fontFamily: tokens.typography.body.fontFamily,
fontSize: 14,
color: tokens.color.neutral[600],
},
progressTrack: {
height: 6,
backgroundColor: tokens.color.neutral[200],
borderRadius: 3,
},
progressFill: {
height: 6,
backgroundColor: tokens.color.primary[500],
borderRadius: 3,
},
});
IMPLEMENT output (WorkoutRow.swift):
// @design-token color.primary.500 — accent color
// @design-token color.neutral.900 — primary text
// @design-token color.neutral.600 — secondary text
// @design-token typography.heading.fontWeight — title weight
// @design-token spacing.sm — content spacing
import SwiftUI
struct WorkoutRow: View {
let title: String
let duration: String
let progress: Double
var body: some View {
VStack(alignment: .leading, spacing: AppSpacing.sm) {
Text(title)
.font(.headline)
.foregroundColor(AppColors.neutral900)
Text(duration)
.font(.subheadline)
.foregroundColor(AppColors.neutral600)
ProgressView(value: progress)
.tint(AppColors.primary500)
}
.padding(AppSpacing.md)
.accessibilityElement(children: .combine)
}
}
| Rationalization | Reality |
|---|---|
| "The touch target is 40pt on iOS — that's close to 44pt and the designer approved the comp, so I'll leave it." | The 44pt iOS minimum and 48dp Android minimum are non-negotiable gates, not guidelines. Touch target violations are error severity regardless of strictness level. Designer comp approval does not override platform accessibility requirements. |
| "This is a cross-platform React Native component, so I only need to read the generic token mapping — platform-specific rules for iOS and Android are optional." | React Native components require both ios.yaml and android.yaml rules. Platform-specific rules govern safe areas, elevation, navigation patterns, and touch targets that differ between platforms. Missing either set produces non-compliant native behavior. |
"The component uses a hardcoded shadow for iOS — shadowColor, shadowOffset, etc. Those aren't design tokens, they're platform APIs." | Shadow colors must still reference token values. shadowColor: tokens.color.neutral[900] is the correct form. Hardcoded shadow values like #000 or rgba(0,0,0,0.2) are token binding violations the VERIFY phase will flag. |
"There's no design-system/DESIGN.md yet, but I know the aesthetic intent from our planning discussion — I'll proceed with tokens only." | Proceeding without DESIGN.md means anti-pattern enforcement is disabled for the entire VERIFY phase. The anti-pattern check is what catches design intent violations beyond token correctness. Warn the user and recommend running harness-design first. |
| "The scaffold plan is straightforward — a simple card component. I'll skip presenting it to the user and just generate." | The scaffold plan confirmation is when the user can catch incorrect platform assumptions (wrong StyleSheet structure, wrong platform APIs) before any code is written. Mobile components are harder to refactor than web components due to platform-specific branching. |
design-system/tokens.json. Do not generate components with hardcoded values as a fallback.error severity regardless of strictness level.design-system/tokens.json does not exist: Instruct the user: "Design tokens have not been generated. Run harness-design-system first, then re-run harness-design-mobile."harness scan later to populate."