agentsclimarketplace

Citrus migrate

Skill valasubramanian-kr/wallet-web-developer/skills/citrus-migrate

Claude plugin orchestrating spec-to-code automation workflow, enabling developers to leverage Claude Skills for productivity.From the repository description

Install
npx -y skills add valasubramanian-kr/wallet-web-developer --skill citrus-migrate

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

43.4 KB, ~10.3k tokens by cl100k_base, as published. Nobody here has run it

Citrus Migration Skill

Purpose

Migrate a single React component from vanilla/legacy UI to Citrus design system, following established patterns and maintaining existing functionality.

Usage

/citrus-migrate <component-path> [screenshot-path] [comments]

Arguments:

  • <component-path> (required): Relative path to React component (e.g., src/components/AddCardForm/AddCardForm.tsx)
  • [screenshot-path] (optional): Path to Figma screenshot showing post-migration UI
  • [comments] (optional): Migration instructions/hints for the skill (e.g., "Use ValidationMessage for Message component")

Examples:

# Basic migration
/citrus-migrate src/components/AddCardForm/AddCardForm.tsx

# With Figma screenshot
/citrus-migrate src/components/CardList/CardList.tsx ~/Downloads/cardlist-figma.png

# With user comments/instructions
/citrus-migrate src/components/ErrorDisplay/ErrorDisplay.tsx "Use ValidationMessage Citrus component for migrating Message component"

# With screenshot and comments
/citrus-migrate src/components/PaymentForm/PaymentForm.tsx ~/Downloads/payment-form.png "Follow ui/citrus/FormInput component pattern for form controls"

What This Skill Does

Initial Migration Mode

  1. Parse Arguments: Parse component path, optional screenshot, and optional user comments/instructions
  2. Analyze Component: Read component, CSS, and tests to understand structure and dependencies
  3. Process User Comments: Incorporate user-provided migration instructions and component preferences
  4. Check Dependencies: Flag unmigrated custom UI dependencies, warn user to migrate them first
  5. Visual Analysis (if screenshot provided): Analyze Figma screenshot to guide migration
  6. Map Components: Search citrus-react extensively for component matches (honoring user comments), propose wrappers if needed
  7. Migrate Component Files: Update .tsx, .module.css, and .test.ts files following CITRUS_MIGRATION.md patterns
  8. Full CSS Refactor: Group/organize styles, remove unused, apply Citrus utilities
  9. Ask Clarifications: Use AskUserQuestion for mapping gaps, approach decisions, confirmations
  10. Report Results: Display migration summary and next steps for testing

Feedback Mode (Re-run on Already Migrated Component)

  1. Detect Previous Migration: Check if migration document exists for this component
  2. Read Previous Migration: Load migration history and current state
  3. Process Feedback: Parse user feedback comments and determine changes needed
  4. Apply Feedback: Make incremental refinements based on feedback
    • Replace components as requested
    • Apply/remove utility classes
    • Answer questions about utilities
    • Cleanup CSS as requested
  5. Update Migration Document: Append feedback iteration with changes made
  6. Report Results: Display feedback summary and updates

IMPORTANT: No git actions, no auto-tests, no build validation. User handles all testing.

Instructions

You are performing autonomous Citrus migration for a single React component in the hosted-payment-page library.

Prerequisites

Required Context Files (read these first):

  1. Migration Plan: context/CITRUS_MIGRATION.md (in wallet-web-developer repo)
    • Contains complete migration strategy, guidelines, and component mapping reference
    • Step-by-step migration process documentation
    • Utility classes reference and CSS bundling strategy
    • Wrapper component patterns and best practices

External Repo Access (via GitHub MCP):

  • krogertechnology/citrus-web - CSS utilities, styles, design tokens, utility classes
  • krogertechnology/citrus-react - React components, props, TypeScript definitions, usage examples

Working Directory:

  • Skill runs in the context of the hosted-payment-page library
  • Migration Plan is accessed from the wallet-web-developer repo context directory

Step 0: Parse and Validate Arguments

Parse skill arguments from user input:

# Expected format: /citrus-migrate <component-path> [screenshot-path] [comments]
# Extract component-path (required)
COMPONENT_PATH="<first-arg>"

# Extract screenshot-path (optional)
SCREENSHOT_PATH="<second-arg-if-present-and-is-image>"

# Extract user comments/instructions (optional)
USER_COMMENTS="<remaining-args-or-quoted-string>"

Argument Parsing Logic:

  1. First arg is always component path
  2. Second arg:
    • If it's an image file path (.png, .jpg, .jpeg) → screenshot
    • Otherwise → user comments
  3. Third arg (if second was screenshot): user comments

Validation:

  1. Check COMPONENT_PATH is provided and exists
  2. Check file extension is .tsx
  3. If SCREENSHOT_PATH provided, check file exists and is image format (.png, .jpg, .jpeg)
  4. USER_COMMENTS is optional, no validation needed
  5. Fail fast with clear error if validation fails

Example validation:

if [ -z "$COMPONENT_PATH" ]; then
  echo "❌ Error: Component path is required"
  echo "Usage: /citrus-migrate <component-path> [screenshot-path] [comments]"
  exit 1
fi

if [ ! -f "$COMPONENT_PATH" ]; then
  echo "❌ Error: Component file not found: $COMPONENT_PATH"
  exit 1
fi

if [[ "$COMPONENT_PATH" != *.tsx ]]; then
  echo "❌ Error: Component must be a .tsx file"
  exit 1
fi

# Validate screenshot if provided
if [ -n "$SCREENSHOT_PATH" ]; then
  if [ ! -f "$SCREENSHOT_PATH" ]; then
    echo "❌ Error: Screenshot file not found: $SCREENSHOT_PATH"
    exit 1
  fi
  if [[ ! "$SCREENSHOT_PATH" =~ \.(png|jpg|jpeg)$ ]]; then
    echo "❌ Error: Screenshot must be an image file (.png, .jpg, .jpeg)"
    exit 1
  fi
fi

Check for Previous Migration:

# Check if migration document exists
MIGRATION_DOC="workflow/citrus-migration/<ComponentName>-migration.md"

if [ -f "$MIGRATION_DOC" ]; then
  echo "✓ Previous migration detected - entering FEEDBACK MODE"
  MODE="FEEDBACK"
else
  echo "✓ No previous migration found - entering INITIAL MIGRATION MODE"
  MODE="INITIAL"
fi

Output:

✓ Component: src/components/AddCardForm/AddCardForm.tsx
✓ Screenshot: ~/Downloads/figma-addcardform.png [OR "No screenshot provided"]
✓ User Comments: "Use ValidationMessage for Message component" [OR "No user comments provided"]
✓ Mode: [INITIAL MIGRATION / FEEDBACK MODE]

Branch based on mode:

  • INITIAL MIGRATION MODE: Proceed to Step 1 (normal migration flow)
  • FEEDBACK MODE: Proceed to Step 0.5 (feedback processing flow)

Step 0.5: Feedback Processing Flow (FEEDBACK MODE ONLY)

IMPORTANT: This step only executes when a previous migration document exists and user provides feedback comments.

If no user comments provided in FEEDBACK MODE:

⚠️ Warning: Re-running migration on already migrated component without feedback comments.
This will re-migrate the component from scratch.

Do you want to:
1. Provide feedback comments to refine the existing migration
2. Re-migrate from scratch (overwrite previous migration)
3. Cancel

Read Previous Migration Context:

  1. Read workflow/citrus-migration/<ComponentName>-migration.md
  2. Extract:
    • Previous component mappings
    • CSS changes made
    • Wrappers created
    • Dependencies handled
    • Feedback iterations (if any previous feedback)

Process Feedback Comments:

Categorize feedback into action types:

  1. Component Replacement Feedback:

    • Pattern: "Use [NewComponent] instead of [OldComponent]"
    • Example: "Instead of ValidationMessage, use GlobalMessage"
    • Action: Replace component imports and usage
  2. CSS Utility Feedback:

    • Pattern: "Use [utility-class] and remove [custom-class]"
    • Example: "Use 'w-full' utility class and remove custom CSS class 'fullWidth'"
    • Action: Apply utility class, remove custom CSS
  3. Utility Class Query:

    • Pattern: "Do we have utility class for [css-property]?"
    • Example: "Do we have matching utility class for margin-bottom 10px?"
    • Action: Search citrus-web for matching utility, propose replacement
  4. CSS Cleanup Feedback:

    • Pattern: "Cleanup CSS module" / "Remove unused CSS" / "Optimize CSS"
    • Action: Analyze CSS module, remove unused classes, consolidate duplicates
  5. General Refinement:

    • Any other feedback requesting changes or improvements
    • Action: Interpret feedback and apply changes

Execute Feedback Actions:

## Feedback Analysis

**Feedback Provided**: "<USER_COMMENTS>"

**Feedback Type**: [Component Replacement / CSS Utility / Utility Query / CSS Cleanup / General]

**Actions to Take**:
1. [Action 1 based on feedback]
2. [Action 2 based on feedback]
3. [Action 3 based on feedback]

**Files to Modify**:
- [List files that will be updated based on feedback]

For Component Replacement Feedback:

  1. Search citrus-react for the new component specified
  2. Read component props and usage from citrus-react
  3. Update imports in component file
  4. Replace old component usage with new component
  5. Preserve all props and behavior
  6. Update tests if component structure changes

For CSS Utility Feedback:

  1. Search citrus-web styles.config.js for the utility class mentioned
  2. Verify utility class exists in both esperanto.css and citrus.light.css
  3. Apply utility class to component
  4. Remove custom CSS class from module.css
  5. Update component to use utility class

For Utility Class Query:

  1. Search citrus-web styles.config.js for matching utilities
  2. Check both spacing utilities and custom properties
  3. Report findings to user:
    ✓ Found matching utility class: 'mb-[value]' for margin-bottom
    
    Available options:
    - mb-2 (margin-bottom: 0.5rem / 8px)
    - mb-2.5 (margin-bottom: 0.625rem / 10px) ← Exact match
    - mb-3 (margin-bottom: 0.75rem / 12px)
    
    Recommendation: Use 'mb-2.5' utility class
    
    Would you like to apply this change?
    
  4. If user confirms, apply the change

For CSS Cleanup Feedback:

  1. Read current CSS module
  2. Analyze for:
    • Unused classes (not referenced in component)
    • Duplicate styles (can be consolidated)
    • Classes that can be replaced with Citrus utilities
    • Overly specific selectors
  3. Propose cleanup plan to user via AskUserQuestion
  4. Apply approved cleanup changes

Update Migration Document with Feedback Iteration:

Append to existing migration document:

---

## Feedback Iteration <N>

**Date**: <timestamp>
**Feedback**: "<USER_COMMENTS>"
**Feedback Type**: [Type]

**Changes Made**:
- [Change 1]
- [Change 2]
- [Change 3]

**Files Modified**:
- [File 1] - [What changed]
- [File 2] - [What changed]

**Component Mapping Updates** (if applicable):
| Previous | Updated | Reason |
|----------|---------|--------|
| [OldComponent] | [NewComponent] | User feedback |

**CSS Updates** (if applicable):
| Previous | Updated | Reason |
|----------|---------|--------|
| .customClass | w-full | User feedback - use utility class |

**Outcome**: [Success / Partial / Need more feedback]

---

Report Feedback Results:

✓ Feedback applied to <ComponentName>

Feedback: "<USER_COMMENTS>"

Changes Applied:
  - [Change 1]
  - [Change 2]
  - [Change 3]

Files Modified:
  - ✓ src/components/<ComponentName>/<ComponentName>.tsx
  - ✓ src/components/<ComponentName>/<ComponentName>.module.css
  - [Other files if applicable]

Migration Document Updated: workflow/citrus-migration/<ComponentName>-migration.md
  - Added Feedback Iteration <N>

Next Steps:
1. Review changes: git diff src/components/<ComponentName>/
2. Run tests: yarn test
3. Visually verify changes
4. If satisfied, commit changes
5. If more refinements needed, re-run skill with additional feedback

⚠️ IMPORTANT: No git actions were performed. Review and commit changes manually.

After Feedback Processing: Exit skill (do NOT proceed to Step 1)

Step 1: Read Context and Component Files (INITIAL MIGRATION MODE ONLY)

Read migration context:

  1. Read context/CITRUS_MIGRATION.md from wallet-web-developer repo

    • Extract migration steps and guidelines
    • Review component mapping reference table
    • Note CSS bundling strategy and utility classes
    • Understand wrapper component strategy for reusable UI
  2. Process user comments (if provided):

    • Parse user instructions for specific component mappings
    • Extract any reference components to follow (e.g., "Follow ui/citrus/FormInput")
    • Identify specific Citrus components to use (e.g., "Use ValidationMessage for Message")
    • Note any custom migration requirements or constraints
    • These comments take precedence over default discovery for mentioned components

Read target component files:

  1. Component file: <COMPONENT_PATH>
  2. CSS file: <COMPONENT_PATH>.replace('.tsx', '.module.css')
  3. Test file: <COMPONENT_PATH>.replace('.tsx', '.test.tsx') or __tests__/<ComponentName>.test.tsx
  4. Related files referenced in component imports

If screenshot provided:

  • Read and analyze the screenshot using Read tool with image support
  • Extract visual patterns, component layout, spacing, colors, typography
  • Identify Citrus components visible in the design
  • Note any differences from current implementation

Document findings:

## Component Analysis

**Component**: <ComponentName>
**Path**: <COMPONENT_PATH>
**Type**: [Reusable UI Component / Consumer Component]

**Current Implementation**:
- HTML Elements: <list of div, input, button, etc.>
- Custom UI Components: <list from src/components/ui/>
- Citrus Components: <list from @kds/citrus-react>
- CSS Module: <path> (<N> lines, <N> KB)
- Tests: <path> (<N> test cases)

**Dependencies** (other custom components):
- <ComponentName1> (from src/components/ui/) - ⚠️ NOT MIGRATED
- <ComponentName2> (from src/components/ui/) - ⚠️ NOT MIGRATED

**Screenshot Analysis** [if provided]:
- Visual Layout: <description>
- Citrus Components Identified: <list>
- Design Tokens: <colors, spacing, typography>
- Key Differences from Current: <list>

**User Comments/Instructions** [if provided]:
- <User instruction 1>
- <User instruction 2>
- Examples:
  - "Use ValidationMessage Citrus component for migrating Message component"
  - "Follow ui/citrus/FormInput component pattern for form controls"
  - "Keep existing error handling logic, just wrap with Citrus components"

Step 2: Check Dependencies and Flag Blockers

Dependency Check Logic:

  1. Identify custom UI imports:

    • Parse imports from ../ui or @/components/ui
    • Exclude Citrus imports (from @kds/citrus-react)
    • Exclude non-UI imports (hooks, utils, services)
  2. Check migration status:

    • For each custom UI component, check if Citrus equivalent exists in src/components/ui/citrus/
    • If NOT found → unmigrated dependency
    • If found → already migrated ✓
  3. Flag blockers:

    ⚠️ **Migration Blockers Detected**
    
    The following custom UI components are used by <ComponentName> but have NOT been migrated to Citrus:
    
    - `InputComponent` (from src/components/ui/...)
      - **Action Required**: Migrate first OR create Citrus wrapper
      - **Citrus Equivalent**: Check src/components/ui/citrus/
    
    - `CustomComponent` (from src/components/ui/...)
      - **Action Required**: Migrate first OR create Citrus wrapper
      - **Citrus Equivalent**: Not found - needs investigation
    
    **Recommendation**:
    - If these are reusable UI components (exported from src/components/ui/index.ts):
      Create Citrus wrappers in src/components/ui/citrus/ following the wrapper pattern from CITRUS_MIGRATION.md
    - If these are consumer components:
      Migrate them separately before migrating <ComponentName>
    
    **Proceed?**
    - ✅ Yes - Continue migration, I'll handle dependencies manually
    - ❌ No - Stop migration, let me migrate dependencies first
    
  4. Use AskUserQuestion to confirm if blockers exist:

    {
      "questions": [{
        "question": "This component has unmigrated dependencies. How would you like to proceed?",
        "header": "Dependencies",
        "options": [
          {"label": "Continue migration", "description": "Proceed with migration, I'll handle dependencies separately"},
          {"label": "Stop migration", "description": "Stop here, let me migrate dependencies first"},
          {"label": "Create wrappers", "description": "Create Citrus wrappers for dependencies as part of this migration"}
        ],
        "multiSelect": false
      }]
    }
    
  5. Handle response:

    • "Stop migration" → Exit gracefully with summary of blockers
    • "Continue migration" → Proceed to Step 3
    • "Create wrappers" → Add wrapper creation to migration plan (Step 4)

If NO blockers:

✓ No unmigrated dependencies detected
✓ Safe to proceed with migration

Step 3: Component Mapping Discovery

Goal: Map current vanilla/custom UI elements to Citrus components by extensively searching citrus-react repo.

Use Task tool with Explore agent for component discovery:

Task(
  subagent_type="Explore",
  description="Discover Citrus component matches",
  model="haiku",
  prompt="""
  You are discovering Citrus component matches for migration.

  CONTEXT:
  - Component to migrate: <ComponentName>
  - Current elements: <list of HTML elements and custom UI>
  - Citrus repo: krogertechnology/citrus-react
  - User Comments: <USER_COMMENTS if provided, otherwise "None">

  IMPORTANT: If user comments specify a particular Citrus component to use for a legacy component,
  prioritize that mapping. For example:
  - "Use ValidationMessage for Message component" → Use ValidationMessage instead of searching
  - "Follow ui/citrus/FormInput pattern" → Reference existing FormInput wrapper as example

  TASK:
  For each element/component in the list, search citrus-react extensively:

  1. Search by element type:
     - <input> → Search for "Input", "TextField", "TextInput"
     - <button> → Search for "Button", "IconButton", "ButtonGroup"
     - <select> → Search for "Select", "Dropdown", "Combobox"
     - <h1-h6> → Search for "Headline", "Heading", "Title", "Typography"
     - <p>, <span> → Search for "Paragraph", "Text", "Body"
     - <label> → Search for "Label", "FormLabel"
     - <checkbox> → Search for "Checkbox", "FormCheckbox"

  2. Search by functionality:
     - Form inputs → "FormControl", "Form", "Input"
     - Error messages → "Message", "Alert", "Notification", "ErrorMessage"
     - Loading states → "Spinner", "Loader", "LoadingIndicator", "Skeleton"
     - Modals → "Modal", "Dialog", "Overlay"
     - Tooltips → "Tooltip", "Popover", "HelpText"

  3. For each match found:
     - Component name and import path
     - Props available (check TypeScript definitions)
     - Usage examples (check Storybook or tests)
     - Whether it's a standalone component or needs FormControl wrapper

  4. If NO exact match found:
     - Note this explicitly
     - Suggest creating a wrapper component in src/components/ui/citrus/

  5. Return findings in this format:

  ## Component Mapping Results

  | Current Element | Citrus Component | Import Path | Props | Notes |
  |----------------|------------------|-------------|-------|-------|
  | <input type="text"> | Input | @kds/citrus-react | value, onChange, disabled, ... | Use with Label wrapper |
  | <h2> | Headline | @kds/citrus-react | tag, size, className | tag="h2" size="s" |
  | <CustomCheckbox> | Checkbox | @kds/citrus-react | checked, onChange, disabled | Wrap in Label component |
  | <ErrorMessage> | Message | @kds/citrus-react | type, message | **NOT FOUND** - create wrapper? |

  **Wrappers Needed**:
  - [List wrappers needed based on component analysis]
  - Example: InputWrapper (wraps Label + Input) - if component uses custom input with label
  - Example: CheckboxWrapper (wraps Label + Checkbox) - if component uses custom checkbox with label

  **Component Props to Preserve**:
  - [List existing props from legacy component that should be preserved in wrapper]
  - Common props: label, disabled, required, invalid, className, wrapperClassName

  **Citrus Components to Import Directly**:
  - [List components that can be used directly without wrappers]
  - Example: Headline (for headings), Button (for buttons), etc.
  """
)

Handle mapping results:

  1. If component not found in citrus-react → Ask user via AskUserQuestion:

    {
      "questions": [{
        "question": "No Citrus equivalent found for <ElementName>. How should we handle it?",
        "header": "Mapping",
        "options": [
          {"label": "Keep as-is", "description": "Leave the current implementation unchanged"},
          {"label": "Create wrapper", "description": "Create a Citrus wrapper component following the wrapper pattern from CITRUS_MIGRATION.md"},
          {"label": "Use alternative", "description": "I'll suggest a different Citrus component"}
        ],
        "multiSelect": false
      }]
    }
    
  2. Document final component mapping table for reference

Step 4: Plan Migration Approach

Create migration plan considering:

  • Component type (Reusable UI vs Consumer)
  • Wrapper creation needs
  • CSS refactoring scope
  • Test updates needed
  • User clarifications from Steps 2-3
  • User comments/instructions (if provided - incorporate these into the plan)

Process user comments:

  • If user specified a Citrus component to use → Use that component, skip discovery for that mapping
  • If user referenced an existing wrapper pattern → Follow that pattern instead of generic
  • If user provided custom requirements → Add to plan and document
  • User comments override default discovery and should be honored

Use AskUserQuestion for key decisions (skip if user comments already address these):

{
  "questions": [
    {
      "question": "This is a reusable UI component exported from src/components/ui/. Should we create a Citrus wrapper in src/components/ui/citrus/?",
      "header": "Wrapper",
      "options": [
        {"label": "Create wrapper (Recommended)", "description": "Create new Citrus wrapper following the wrapper pattern from CITRUS_MIGRATION.md"},
        {"label": "Migrate in-place", "description": "Update existing component to use Citrus directly"},
        {"label": "Skip for now", "description": "Mark as TODO for future migration"}
      ],
      "multiSelect": false
    },
    {
      "question": "CSS refactoring approach for this component?",
      "header": "CSS",
      "options": [
        {"label": "Full reorganization (Recommended)", "description": "Group styles, remove unused, apply Citrus utilities, clean up"},
        {"label": "Minimal changes", "description": "Only replace what maps to Citrus utilities, keep rest as-is"},
        {"label": "Keep existing CSS", "description": "Don't touch CSS, only update components"}
      ],
      "multiSelect": false
    }
  ]
}

Document migration plan:

## Migration Plan

**Approach**: [Wrapper Component / In-Place Migration]
**CSS Strategy**: [Full Reorganization / Minimal / No Changes]
**User Comments**: [User instructions provided / None]

**User Instructions Applied**:
- [List how user comments are being incorporated]
- [Example: "Using ValidationMessage component as specified for Message migration"]
- [Example: "Following ui/citrus/FormInput pattern as requested"]

**Steps**:
1. [✓/☐] Create wrapper components in src/components/ui/citrus/ (if needed for reusable UI)
   - [List specific wrappers needed based on component analysis]
   - Follow wrapper pattern from CITRUS_MIGRATION.md

2. [✓/☐] Update component imports
   - Remove: [List legacy imports to remove]
   - Add: [List Citrus wrapper imports from ../ui/citrus]
   - Add: [List direct Citrus imports from @kds/citrus-react]

3. [✓/☐] Replace component usage
   - [List specific replacements based on component mapping]
   - Example: Replace custom input structure with Citrus wrapper
   - Example: Replace heading elements with Headline component
   - Preserve existing props and behavior

4. [✓/☐] Refactor CSS
   - Remove unused classes: [List classes to remove]
   - Group similar styles: [List styles to group/consolidate]
   - Apply Citrus utilities: [List utility classes to apply]
   - Keep layout-specific styles: [List component-specific layout to preserve]

5. [✓/☐] Update tests
   - Update selectors for new component structure
   - Verify test coverage maintained
   - Add new tests for Citrus component integration (if needed)

6. [✓/☐] Document changes
   - Add comments for future components needing migration
   - Update component props documentation

Step 5: Execute Migration

Execute migration in this order:

5.1: Create Wrapper Components (if needed)

If creating wrappers for reusable UI components:

  1. Create directory structure:

    mkdir -p src/components/ui/citrus/<ComponentCategory>/
    
  2. Create wrapper component following the wrapper pattern from CITRUS_MIGRATION.md:

    General Wrapper Pattern:

    import { FC } from 'react';
    import { <CitrusComponent>, Label } from '@kds/citrus-react';
    import styles from './<Category>.module.css';
    
    // 1. Extend appropriate HTML attributes for the base element
    export interface <WrapperName>Props extends <BaseHTMLAttributes> {
      // 2. Add required props from legacy component
      label: string;
    
      // 3. Add optional props for customization
      wrapperClassName?: string;
      isRequired?: boolean;
      isInvalid?: boolean;
    
      // 4. Add any component-specific props from legacy implementation
      [key: string]: any;
    }
    
    export const <WrapperName>: FC<<WrapperName>Props> = ({
      label,
      id,
      wrapperClassName = '',
      className = '',
      // 5. Extract component-specific props
      ...props
    }) => {
      // 6. Add any custom logic from legacy component (validation, formatting, etc.)
    
      return (
        <div className={`${styles.wrapperLayout} ${wrapperClassName}`}>
          <Label htmlFor={id}>
            {label}
            <CitrusComponent
              id={id}
              className={className}
              aria-label={label}
              {...props}
            />
          </Label>
        </div>
      );
    };
    
  3. Create CSS module for wrapper (minimal layout only):

    .wrapperLayout {
      display: flex;
      flex-direction: column;
    }
    
  4. Create index.ts to export wrapper:

    export * from './<WrapperName>';
    
  5. Update src/components/ui/citrus/index.ts:

    export * from './<ComponentCategory>';
    

Key Principles for Wrapper Creation:

  • Extend appropriate HTML attributes for type safety
  • Preserve all props from legacy component
  • Wrap Citrus component with Label if needed for accessibility
  • Minimal CSS (layout only, no styling)
  • Add aria attributes for accessibility
  • Implement any custom logic from legacy component
  • Match existing component API to minimize consumer changes

5.2: Update Component File (.tsx)

  1. Update imports:

    // Remove old imports based on component mapping
    - import { <LegacyComponents> } from '<old-source>';
    
    // Add Citrus wrapper imports (for reusable UI components)
    + import { <WrapperComponents> } from '../ui/citrus';
    
    // Add direct Citrus imports (for components that don't need wrappers)
    + import { <CitrusComponents> } from '@kds/citrus-react';
    
    // Keep existing non-UI imports and unmigrated components
    import { <UnmigratedComponents> } from '../ui'; // NOT YET MIGRATED
    
  2. Replace component usage based on component mapping from Step 3:

    General Pattern:

    • Replace legacy component structure with Citrus wrapper or direct import
    • Add id prop to interactive elements for accessibility
    • Preserve all existing props and event handlers
    • Keep error/validation rendering in parent component (NOT in wrapper)
    • Update CSS class names as needed for new structure
    • Maintain all conditional rendering logic

    For Wrapped Components (when using wrappers from ../ui/citrus):

    // Replace legacy custom component
    <LegacyComponent
      label="Field Label"
      value={value}
      onChange={handleChange}
      {...existingProps}
    />
    
    // With Citrus wrapper
    <CitrusWrapper
      id="field-id"  // Add for accessibility
      label="Field Label"
      value={value}
      onChange={handleChange}
      {...existingProps}
    />
    

    For Direct Citrus Components (Typography, Buttons, etc.):

    // Replace HTML element
    <h2 className={styles.header}>Section Title</h2>
    
    // With Citrus component
    <Headline tag="h2" size="<size>" className={styles.headerLayout}>
      Section Title
    </Headline>
    
    // Check citrus-react documentation for:
    // - Available props (tag, size, className, etc.)
    // - Size values (xs, s, m, l, xl, etc.)
    // - Other component-specific props
    
  3. Preserve all props and behavior:

    • Keep all event handlers
    • Keep all validation logic
    • Keep all conditional rendering
    • Keep all state management
    • Do NOT change component logic

5.3: Refactor CSS Module (.module.css)

Full reorganization approach (following CITRUS_MIGRATION.md guidelines):

  1. Identify and remove unused classes:

    • Classes for elements replaced by Citrus components
    • Duplicate or redundant styles
    • Legacy browser-specific hacks no longer needed
    • Styles that can be replaced by Citrus utilities
  2. Group and consolidate similar styles:

    /* BEFORE: Multiple similar classes */
    .field1 { margin-bottom: 1rem; }
    .field2 { margin-bottom: 1rem; }
    .field3 { margin-bottom: 1rem; }
    
    /* AFTER: Grouped into single class */
    .fieldRow {
      margin-bottom: 1rem;
    }
    
  3. Apply Citrus utility classes where appropriate:

    • Replace custom spacing with CSS variables or utility classes
    • Use Citrus color tokens for colors
    • Use Citrus spacing scale for consistent spacing
    • Reference citrus-web styles.config.js for available utilities }
  4. Keep component-specific layout styles:

    • Layout unique to this component's structure
    • Complex positioning or flex/grid arrangements
    • Component-specific responsive behavior
    • Z-index and stacking contexts
    • Animations or transitions specific to this component
  5. Remove redundant responsive styles:

    • Styles that are no longer needed after migration
    • Duplicate media queries
    • Layout fixes that Citrus components handle natively
  6. Target outcome:

    • 30-50% reduction in CSS lines
    • Only component-specific layout remains
    • Typography and basic spacing handled by Citrus
    • Cleaner, more maintainable CSS module

5.4: Update Tests (.test.tsx)

  1. Update component imports in test file:

    // Match component file imports to maintain test consistency
    import { <WrapperComponents> } from '../ui/citrus';
    import { <CitrusComponents> } from '@kds/citrus-react';
    
  2. Update test selectors for new structure:

    • If component structure changed, update queries accordingly
    • Prefer accessible queries (getByRole, getByLabelText)
    • Maintain same test coverage and assertions
    • Update data-testid if used for targeting elements
  3. Verify test coverage maintained:

    • All existing tests should still pass
    • Add new tests ONLY if new functionality added
    • Update snapshot tests if structure changed
  4. Don't run tests - user will run them manually

5.5: Update Related Files

If component has other related files:

  • Update Storybook stories (if exists)
  • Update documentation (if exists)
  • Update examples (if exists)
  • Update any component-specific README or usage docs

Step 6: Document Migration

Create migration summary document at workflow/citrus-migration/<ComponentName>-migration.md:

# Citrus Migration: <ComponentName>

**Date**: <timestamp>
**Component Path**: <COMPONENT_PATH>
**Screenshot**: [Provided/Not Provided]
**User Comments**: [Provided/Not Provided]

---

## Migration Summary

**Component Type**: [Reusable UI Component / Consumer Component]
**Migration Approach**: [Wrapper Component / In-Place Migration]
**CSS Strategy**: [Full Reorganization / Minimal / No Changes]

**User Comments Applied** [if provided]:
- [List user instructions that were followed]
- Examples:
  - "Used ValidationMessage component as specified for Message migration"
  - "Followed ui/citrus/FormInput pattern for form controls"
  - "Kept existing error handling logic as requested"

**Changes Made**:
- [X] Created wrapper components in src/components/ui/citrus/ (if applicable)
  - [List wrappers created with line counts]
- [X] Updated component imports (N imports added, N removed)
- [X] Replaced component usage (N instances)
- [X] Refactored CSS module (before → after lines, N% reduction)
- [X] Updated tests (N test cases, N selectors updated)

**Files Modified**:
- ✓ src/components/<ComponentName>/<ComponentName>.tsx
- ✓ src/components/<ComponentName>/<ComponentName>.module.css
- ✓ src/components/<ComponentName>/__tests__/<ComponentName>.test.tsx
- [List any wrapper files created]
- [List any other files modified]

---

## Component Mapping

| Original | Citrus Replacement | Import Source | Notes |
|----------|-------------------|---------------|-------|
| [Legacy component/element] | [Citrus component] | [Import path] | [Wrapper created / Direct import / Props] |
| [Example: <input> + <label>] | [Example: InputWrapper] | [../ui/citrus] | [Wrapper created] |
| [Example: <h2>] | [Headline] | [@kds/citrus-react] | [Direct import, tag="h2" size="s"] |
| [Unmigrated component] | [Unmigrated component] | [../ui] | [**NOT MIGRATED** - future task] |

---

## CSS Changes

**Removed Classes** (N classes, ~N lines):
- [List removed classes]
- [Classes no longer needed after Citrus migration]
- [Redundant or duplicate styles]

**Updated Classes** (N classes):
- [List modified classes and what changed]

**Added Classes** (N classes):
- [List new classes needed for layout]

**Preserved Classes** (N classes):
- [List component-specific classes preserved]
- [Layout classes still needed]
- [Media queries preserved]

**Bundle Size Impact**: ~N KB reduction (N lines → N lines CSS)

---

## Dependencies Status

**Migrated Dependencies** (used in this component):
- [List components migrated to Citrus as part of this migration]
- [Wrapper created / Direct import]

**Unmigrated Dependencies** (flagged for future migration):
- [List custom components still using legacy UI]
- [Path to component] - Keep as-is for now

**Note**: [Summary of unmigrated dependencies and migration strategy]

---

## Testing Checklist

**Manual Testing Required**:
- [ ] Run `yarn test` to verify all tests pass
- [ ] Run `yarn start` to start dev server
- [ ] Visually verify component renders correctly
- [ ] Test all component interactions and functionality
- [ ] Test error/edge case states display correctly
- [ ] Test responsive behavior (mobile, tablet, desktop)
- [ ] Verify accessibility (keyboard navigation, screen reader, ARIA)
- [ ] Compare with Figma screenshot (if provided)

**Expected Test Results**:
- All existing tests should pass
- Component behavior unchanged
- Visual appearance consistent (or improved if screenshot provided)

---

## Next Steps

1. **Test Migration**:
   ```bash
   yarn test
   yarn start
  1. Review Changes:

    git diff src/components/<ComponentName>/
    git diff src/components/ui/citrus/
    
  2. If Tests Pass:

    • Review and commit changes
    • Update migration tracking document
    • Proceed to next component
  3. If Tests Fail:

    • Review test failures
    • Fix issues or rollback changes
    • Re-run migration with clarifications
  4. Future Migrations:

    • [List unmigrated dependencies that need migration]
    • [Update this component after dependencies are migrated]

Migration Patterns Learned

Wrapper Component Pattern (if wrappers were created):

  • [Describe wrapper pattern used]
  • [Key props preserved from legacy component]
  • [Custom logic implemented]
  • [Accessibility improvements]

Component Replacement Pattern:

  • [How legacy components were replaced with Citrus]
  • [Import strategy used]
  • [Props mapping approach]
  • [Error/validation handling approach]

CSS Refactoring Pattern:

  • [Classes removed and why]
  • [Classes consolidated and how]
  • [Citrus utilities applied]
  • [Layout patterns preserved]

Migration completed successfully - ready for testing


### Step 7: Report Results

Display migration summary to user:

✓ Citrus migration completed for <ComponentName>

User Comments: [Provided/Not Provided]

  • [If provided, list user instructions that were applied]

Files Modified:

  • ✓ src/components/<ComponentName>/<ComponentName>.tsx (N replacements)
  • ✓ src/components/<ComponentName>/<ComponentName>.module.css (N% reduction)
  • ✓ src/components/<ComponentName>/tests/<ComponentName>.test.tsx (N selectors updated)

Wrappers Created (if applicable):

  • [List wrapper files created]

Component Mapping:

  • [Legacy] → [Citrus] (wrapper/direct import)
  • [List all component replacements]
  • [If user comments specified mapping, note: "As per user instruction"]
  • [Unmigrated] → [Unmigrated] (NOT MIGRATED - future task)

CSS Impact:

  • Removed: N classes (~N lines)
  • Updated: N classes
  • Added: N classes
  • Total reduction: N → N lines (N%)

Bundle Size: ~N KB reduction (estimated)

Dependencies:

  • ✓ [Migrated dependencies]
  • ⚠️ [Unmigrated dependencies flagged for future]

Screenshot Analysis: [Completed/Skipped]

Migration Document: workflow/citrus-migration/<ComponentName>-migration.md

Next Steps:

  1. Review changes: git diff src/components/<ComponentName>/
  2. Run tests: yarn test
  3. Start dev server: yarn start
  4. Visually verify component renders correctly
  5. Test all interactions and error states
  6. If tests pass, commit changes and proceed to next component

⚠️ IMPORTANT: No git actions were performed. Review and commit changes manually.


## Error Handling

### Common Errors

**Component file not found**:
- Exit with error: "Component file not found at <COMPONENT_PATH>"
- Suggest checking path and trying again

**Screenshot file not found** (if provided):
- Exit with error: "Screenshot file not found at <SCREENSHOT_PATH>"
- Suggest checking path or proceeding without screenshot

**Unmigrated dependencies detected**:
- Ask user via AskUserQuestion how to proceed
- Options: Continue / Stop / Create wrappers

**Citrus component not found in citrus-react**:
- Ask user via AskUserQuestion for alternative
- Suggest creating wrapper or keeping as-is

**CSS module not found**:
- Continue without CSS refactoring
- Note in migration document: "No CSS module found"

**Test file not found**:
- Continue without test updates
- Note in migration document: "No test file found"

### Recovery Strategies

**Migration partially complete**:
- Document which files were modified
- Suggest manual rollback if needed
- Provide clear error message for what failed

**User cancels migration mid-way**:
- Document progress made
- List files modified so far
- Suggest manual cleanup or completion

**Citrus repo access fails**:
- Fall back to CITRUS_MIGRATION.md component catalog
- Warn user: "Could not access citrus-react repo, using fallback mapping"

## Token Optimization

**Efficient agent usage**:
- Use Explore agent (haiku model) for component discovery (~10-15k tokens)
- Read only necessary files (component, CSS, tests, CITRUS_MIGRATION.md)
- Use tables for component mapping (saves ~5k tokens vs. prose)
- Reference file:line numbers instead of code blocks
- Keep migration document concise (<5 KB)

**Avoid token waste**:
- Don't re-read CITRUS_MIGRATION.md multiple times (cache it after first read)
- Don't fetch entire citrus-react repo
- Don't include full code examples in prompts
- Use targeted Grep searches vs. broad exploration

**Target token budget**:
- Context reading: ~20-30k tokens
- Component discovery: ~10-15k tokens
- Migration execution: ~10-15k tokens
- Total: ~40-60k tokens per component migration

## Examples

### Example 1: Reusable UI Component

```bash
/citrus-migrate src/components/ui/CustomInput/CustomInput.tsx

Expected outcome:

  • Create Citrus wrapper in src/components/ui/citrus/CustomInput.tsx
  • Replicate existing component props and behavior
  • Wrap Citrus component appropriately (with Label if needed)
  • Create minimal CSS module for layout
  • Export from src/components/ui/citrus/index.ts

Example 2: Consumer Component with Screenshot

/citrus-migrate src/components/MyComponent/MyComponent.tsx ~/Downloads/my-component-figma.png

Expected outcome:

  • Analyze Figma screenshot for visual guidance
  • Map components based on screenshot analysis + citrus-react search
  • Update imports to use Citrus wrappers/components
  • Replace component usage following CITRUS_MIGRATION.md guidelines
  • Full CSS refactoring (30-50% reduction target)
  • Update tests with new selectors
  • Document unmigrated dependencies as future tasks

Example 3: Component with User Comments/Instructions

/citrus-migrate src/components/ErrorDisplay/ErrorDisplay.tsx "Use ValidationMessage Citrus component for migrating Message component"

Expected outcome:

  • Skip discovery for Message component → Use ValidationMessage as specified
  • Apply user instruction in component mapping
  • Document user comment in migration plan and final document
  • Prioritize user's specified component over default discovery

Example 4: Component with Screenshot and User Comments

/citrus-migrate src/components/PaymentForm/PaymentForm.tsx ~/Downloads/payment-form.png "Follow ui/citrus/FormInput pattern for all form controls. Keep validation logic intact."

Expected outcome:

  • Analyze Figma screenshot for visual guidance
  • Reference existing ui/citrus/FormInput wrapper as pattern for all form controls
  • Preserve validation logic as requested
  • Document both screenshot analysis and user instructions
  • Create consistent wrapper pattern following FormInput

Example 5: Component with Unmigrated Dependencies

/citrus-migrate src/components/ComplexComponent/ComplexComponent.tsx

Expected outcome:

  • Detect custom UI dependencies not yet migrated
  • Flag blocker and ask user how to proceed (Continue/Stop/Create wrappers)
  • If user chooses "Stop", exit gracefully with blocker summary
  • If user chooses "Continue", proceed and document dependencies in migration doc
  • If user chooses "Create wrappers", create wrappers as part of migration

Success Criteria

Migration is successful when:

  • ✓ All target files (.tsx, .module.css, .test.tsx) migrated
  • ✓ Component behavior preserved (no logic changes)
  • ✓ CSS reduced by 30-50% through cleanup and utilities
  • ✓ Wrapper components follow the wrapper pattern from CITRUS_MIGRATION.md
  • ✓ User comments/instructions honored and applied correctly (if provided)
  • ✓ Migration document created with full details (including user comments applied)
  • ✓ No git actions performed
  • ✓ User provided with clear next steps for testing
  • ✓ Dependencies flagged for future migration if not migrated

Migration fails when:

  • ✗ Component logic or behavior changed
  • ✗ Cannot find suitable Citrus equivalent and user declines wrapper
  • ✗ Critical files cannot be read or written
  • ✗ Unmigrated dependencies exist and user chooses to stop

Notes

DO:

  • Follow CITRUS_MIGRATION.md guidelines
  • Search citrus-web and citrus-react extensively via GitHub MCP
  • Ask clarifying questions via AskUserQuestion
  • Document all decisions and changes
  • Preserve component logic and behavior exactly
  • Flag unmigrated dependencies
  • Create wrappers following the pattern from CITRUS_MIGRATION.md

DO NOT:

  • Perform any git actions (stage, commit, push, branch)
  • Run tests or build validation
  • Change component logic or state management
  • Auto-migrate dependencies without user confirmation
  • Bundle Citrus styles in component CSS
  • Skip CSS refactoring (unless user chooses minimal approach)

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 326,758. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.