# Ui Restructure

> |

- **Type:** Skill
- **Install:** `agentstack add skill-vamsivarma27-ui-restructure-ui-restructure`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [vamsivarma27](https://agentstack.voostack.com/s/vamsivarma27)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [vamsivarma27](https://github.com/vamsivarma27)
- **Source:** https://github.com/vamsivarma27/ui-restructure/tree/main/ui-restructure

## Install

```sh
agentstack add skill-vamsivarma27-ui-restructure-ui-restructure
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Claude UI Restructure Skill

You are executing the `/restructure` skill. Your goal is to fully redesign the UI of this codebase without touching any business logic, API integrations, hooks, or data flow.

Follow the 10-step execution pipeline below. Read each step fully before acting on it.

---

## God Mode — Special Execution Path

If the command contains `--god-mode`, skip Steps 1–11 below and instead:

1. Read `references/user-mindset.md` fully — internalize the 10 Laws of User Behavior and all 10 developer mistakes
2. Read `modes/godmode.md` fully — this is your complete execution guide
3. Execute the 7-phase God Mode pipeline defined there
4. **Default: tokens are preserved.** Only add `--remove-tokens` if the user explicitly passed that flag.
5. If `--remove-tokens` is also passed, after completing God Mode, additionally run Step 7 (token reset) and Step 10 (token rebuild) from the standard pipeline using the style from `--style` (default: minimal).

God Mode does NOT combine with `--mode`. It replaces the mode entirely.
God Mode CAN combine with `--style` — the style engine defines visual language when `--remove-tokens` is also used.

---

## Behavior Rules (Non-Negotiable)

**NEVER modify:**
- Hooks (`useState`, `useEffect`, `useReducer`, custom hooks)
- Event handlers and callbacks
- API calls, fetch logic, server actions
- Data mapping and transformation
- Props interfaces and types
- Service layer files
- Database models
- Route handlers / API routes

**ONLY modify UI:**
- Layout wrappers and containers
- Spacing classes (`gap-*`, `p-*`, `m-*`, `space-*`)
- Typography classes
- Color/token usage
- Grid and flex structures
- Design token files

---

### Next.js App Router — Server vs Client Component Rules (Non-Negotiable)

When the framework is **Next.js App Router**, every component file is either a Server Component or a Client Component. The skill MUST respect this distinction at all times.

**How to identify each type:**
- **Client Component:** File begins with `"use client"` directive (first line, before any imports)
- **Server Component:** File has NO `"use client"` directive — it may use `async`/`await`, call `db.query(...)`, call `getServerSession()`, or other server-side APIs

**Rules — never violate these:**

1. **NEVER add `"use client"` to a Server Component.** Adding `"use client"` to a Server Component would break the application — it cannot use server-side APIs (DB, session, server-only imports) in a Client Component.

2. **NEVER remove `"use client"` from a Client Component.** Removing the directive would cause a build error — hooks (`useState`, `useCallback`, etc.) and event handlers (`onClick`, `onMouseEnter`, etc.) are not allowed in Server Components.

3. **NEVER modify the `"use client"` directive itself** — do not move it, rename it, or alter its position at the top of the file.

4. **Server-side data access is preserved like hooks:** Calls to `db.query(...)`, `getServerSession()`, `prisma.findMany(...)`, and other server-side APIs in Server Components fall under the NEVER modify rule (same protection as `fetch` and API calls). Treat them as protected logic regardless of whether they look like "API calls" or "database calls."

5. **Async Server Components:** A component defined as `export default async function MyComponent()` with no `"use client"` is a Server Component. Do NOT add `"use client"` to make it non-async or to enable hooks.

**In Step 4 (Scan UI Files):** When scanning App Router files, record for each file:
- Is it a Client Component? (starts with `"use client"`)
- Is it a Server Component? (no `"use client"` directive)

**In Step 6 (Strip UI Structure):** Strip layout/styling classes as normal. But for both Server and Client Components:
- Preserve the `"use client"` directive exactly as-is at the top of Client Component files
- Do NOT add `"use client"` to Server Component files during stripping

**In Step 10 (Rebuild UI):** Rebuild layout and classes as normal. The `"use client"` status of each file does not change during rebuild — only layout/styling classes change.

---

## Step 1 — Parse Command Arguments

Read the user's `/restructure` command and extract:

| Argument | Value |
|---|---|
| `--style` | `apple` / `linear` / `minimal` / `dashboard` / none |
| `--mode` | `full` / `layout` / `theme` / `grid` (default: `full`) |
| `--prompt` | Custom UI description string |
| `--keep-tokens` | Boolean flag — reuse existing tokens |
| `--grid` | `cards` / `list` |
| `--density` | `compact` / `comfortable` / `spacious` |

If no arguments, run full redesign.

Load the parser reference: `parser/commands.md`

---

## Step 2 — Detect Framework

Scan the project root and `src/` directory for these signals:

| Signal | Framework |
|---|---|
| `app/` directory (at root) + `layout.tsx` inside it | Next.js App Router |
| `src/app/` directory + `layout.tsx` inside `src/app/` | Next.js App Router (src/ layout convention) |
| `pages/` directory + `_app.tsx` | Next.js Pages Router |
| `vite.config.ts` + no `app/` dir | React (Vite) |
| `src/App.jsx` + `public/index.html` | React (CRA) |
| `*.vue` files + `vite.config.ts` | Vue 3 |

**`src/app/` pattern (Next.js App Router inside src/):** Many Next.js projects place the App Router directory inside `src/` — i.e., `src/app/layout.tsx` instead of `app/layout.tsx` at the project root. If `app/` is not present at the root but `src/app/` exists with a `layout.tsx`, detect this as **Next.js App Router**. In Step 4, scan `src/app/` as the App Router directory (instead of `app/`). All file exclusion rules and Server/Client Component rules apply identically. The scan root for App Router files is `src/app/` in this case.

**Conflict resolution — when multiple signals match:**
- If both `app/` (with `layout.tsx`) and `pages/` exist simultaneously: **App Router wins.** This is the Next.js 13+ hybrid convention. Treat the project as Next.js App Router and skip Pages Router scanning.
- If `src/app/` (with `layout.tsx`) and `pages/` exist simultaneously: **App Router wins** — same rule applies.
- If `*.vue` files exist alongside `app/` or `pages/`: Vue 3 wins (the `.vue` extension is a definitive signal).

State detected framework before proceeding.

---

## Step 3 — Detect Styling System

Scan for:

| File/Signal | Styling System |
|---|---|
| `tailwind.config.*` | Tailwind CSS |
| `*.module.css` files | CSS Modules |
| `styled-components` in package.json | styled-components |
| `components.json` (shadcn config) | shadcn/ui |
| Inline `style={{}}` props | Inline styles |
| Plain `*.css` imports | Plain CSS |

Multiple systems may coexist. Record all detected systems.

**Framer Motion detection (animation library — separate from styling system):**

Also check for Framer Motion in the project:
- `framer-motion` in `package.json` dependencies or devDependencies
- `import { motion } from 'framer-motion'` in any component file

If Framer Motion is detected:
- Record `framer-motion: true` alongside the styling system
- Step 11 (Polish Pass) MUST use Framer Motion variants instead of CSS transition classes for all motion effects
- Note in your reasoning: "Framer Motion detected — Step 11 will use motion variants"

---

## Step 4 — Scan UI Files

Scan directories based on the detected framework (Step 2):

**Always scan (recursively — all nested subdirectories included):**
- `components/`
- `src/`
- `layouts/`

**Scan conditionally (recursively — all nested subdirectories included):**
- `app/` — only if framework is Next.js App Router (or if both app/ and pages/ exist: App Router wins, scan only `app/`)
- `pages/` — only if framework is Next.js Pages Router (not when App Router is detected)

**Scanning is always recursive.** When a directory is listed for scanning, scan ALL files in ALL subdirectories at all depths — not just the top level. For example, `app/dashboard/analytics/components/ReportCard.tsx` (depth 4) and `app/dashboard/analytics/components/charts/LineChart.tsx` (depth 5) are both in scope when `app/` is scanned.

**Route group directories** (Next.js App Router convention): directories whose names are wrapped in parentheses — e.g., `(auth)/`, `(marketing)/`, `(dashboard)/` — are route groups. They do NOT affect the URL path but they DO contain real component and page files. Treat them as regular directories during recursive scanning. Example: `app/(auth)/login/components/LoginForm.tsx` is in scope and must be processed.

If both `app/` and `pages/` exist and App Router was detected: scan `app/` only (recursively). Do NOT scan or modify files in `pages/`.

**File exclusion rules — NEVER scan or modify these files:**

Before processing any file in a scanned directory, check for these exclusion patterns. Skip any file that matches:

1. **Barrel files** — files that contain ONLY re-export statements and no JSX/UI rendering:
   - Files whose entire content consists of `export { ... } from '...'`, `export * from '...'`, `export type { ... } from '...'`, or `export default ... from '...'` lines
   - Typically named `index.ts`, `index.tsx`, `index.js`, but can be any name
   - Detection: if a file has no JSX (` { fetchData() }, [])
const memoized = useMemo(() => compute(data), [data])
const fn = useCallback((id) => handler(id), [handler])
const ref = useRef(null)
const value = useContext(MyContext)

// Handlers
const handleSubmit = async () => { ... }
const onDelete = (id) => { ... }

// Data mapping
{items.map(item => ( ... ))}

// API calls
const res = await fetch('/api/...')
const data = await res.json()

// Props
interface Props { userId: string; onSuccess: () => void }
```

**STRIP (remove layout bias):**
```
className="flex gap-4 p-4 max-w-7xl mx-auto"
className="grid grid-cols-3 gap-6"
className="text-sm font-medium text-gray-600"
className="rounded-lg shadow-md border border-gray-200"
```

---

## Step 6 — Strip UI Structure

For each UI component file:

1. Read the file
2. Identify all layout/spacing/typography classes
3. Remove them, leaving only semantic structure + logic

**Transformation example:**

Before:
```jsx

  
    {items.map(item => (
      
        {item.name}
        {item.description}
         handleDelete(item.id)}
                className="mt-3 px-3 py-1.5 text-xs bg-red-500 text-white rounded-md">
          Delete
        
      
    ))}
  

```

After (logic preserved, layout stripped):
```jsx

  
    {items.map(item => (
      
        {item.name}
        {item.description}
         handleDelete(item.id)}>
          Delete
        
      
    ))}
  

```

Repeat for all UI files. Do NOT strip logic. Do NOT strip semantic HTML tags. Do NOT strip key props.

**Non-className HTML attributes — NEVER strip (Non-Negotiable):**

The strip pass targets ONLY the `className` attribute (and `class=` in Vue templates). Every other HTML and JSX attribute on every element MUST be left completely untouched. The following attribute categories are explicitly protected — do not remove, rename, or alter them under any circumstances:

- **Element identity:** `id`, `name`
- **Element type/role:** `type`, `role`
- **Form values:** `value`, `defaultValue`, `checked`, `defaultChecked`
- **Form constraints:** `required`, `disabled`, `readOnly`, `maxLength`, `minLength`, `min`, `max`, `step`, `pattern`, `multiple`
- **Input hints:** `placeholder`, `autoComplete`, `spellCheck`, `autoFocus`, `autoCapitalize`
- **Accessibility:** `aria-*` (all ARIA attributes), `htmlFor`, `tabIndex`
- **Data attributes:** `data-*` (all data attributes — `data-testid`, `data-analytics`, etc.)
- **React-specific:** `key`, `ref`, `suppressHydrationWarning`, `suppressContentEditableWarning`
- **Event handlers (all):** `onClick`, `onKeyDown`, `onKeyUp`, `onKeyPress`, `onFocus`, `onBlur`, `onChange`, `onSubmit`, `onMouseEnter`, `onMouseLeave`, `onMouseDown`, `onMouseUp`, `onTouchStart`, `onTouchEnd`, and ALL other `on*` event handlers — these are logic, not styling
- **Media/link:** `src`, `href`, `alt`, `target`, `rel`, `download`, `action`, `method`
- **Content:** `dangerouslySetInnerHTML`, `style` (inline style prop — handled separately in Inline styles section)
- **HTML attributes:** Any attribute not listed in the "strip" category below is preserved as-is

**What you DO strip:** ONLY the string value(s) of `className="..."` attributes that contain Tailwind utility classes for layout, spacing, typography, and color. Nothing else.

If you are uncertain whether an attribute is a layout class or a logic attribute — PRESERVE it. The only attributes that change are `className` (its value is rebuilt) and `class`/`:class` in Vue templates.

**Vue SFC handling (when framework is Vue 3):**

Vue Single File Components have three blocks — handle each differently:

- **`` block:** Strip `class="..."` and `:class="..."` attributes that contain only layout/spacing/typography classes. Preserve `:class` expressions that contain conditional logic (e.g., `:class="isActive ? 'active' : ''"` — strip the class values but preserve the ternary structure). Preserve `v-for`, `:key`, `@click`, `v-if`, and all other Vue directives and bindings.
- **`` block (and `` block):** Do NOT modify. This contains all component logic — `defineProps`, `defineEmits`, `computed`, `ref`, `reactive`, event handlers. It is fully protected under the PRESERVE rules.
- **`` block (and `` block):** **Preserve as-is.** Do NOT strip, reset, or modify scoped styles. They are component-specific styles, not token files. Token files (Step 7) are separate global token sources.

Template literal classNames with embedded logic (e.g., `` className={`base-classes ${condition ? 'a' : 'b'}`} ``): strip the static CSS class strings but preserve the ternary/conditional logic and the template literal structure itself.

**`cn()` and `clsx()` utility wrapper handling:**

Many real-world Tailwind projects pass `className` through a `cn()` function (from shadcn/ui: `import { cn } from '@/lib/utils'`) or `clsx()` function (`import { clsx } from 'clsx'`). These are utility wrappers that merge and deduplicate Tailwind class strings. The `className` value is a **function call expression**, not a plain string literal.

Rules for handling `cn()` and `clsx()` wrappers:

1. **NEVER strip the wrapper function call.** `className={cn(...)}` must remain `className={cn(...)}` after strip. Do NOT replace it with `className=""` or a plain string.
2. **NEVER strip the `clsx()` wrapper.** Same rule: `className={clsx(...)}` remains `className={clsx(...)}`.
3. **Preserve the import statements** for `cn` and `clsx` — `import { cn } from '@/lib/utils'` and `import { clsx } from 'clsx'` are NOT layout classes and must remain.
4. **Strip the layout/spacing/typography class string values INSIDE the wrapper** — treat the arguments to `cn()` or `clsx()` the same as you would a plain `className` string: strip the Tailwind utility strings, but preserve conditional logic, ternaries, and object syntax (e.g., `{ "opacity-50": dismissed }` — preserve the object structure, update the class value if it is a layout class).
5. **Preserve all conditional logic inside the wrapper** — `variant === 'error' && "bg-red-50 border-red-200"` strips the class string values but preserves `variant === 'error' &&`.

Example:
```jsx
// Before (cn() wrapper)

  

// After strip (wrapper preserved, class strings cleared, conditional logic preserved):

  

// After rebuild (wrapper preserved, new style engine classes applied):

  
```

**`cva()` variant definitions (class-variance-authority) — flag for Step 10 rebuild:**

Many projects — especially those using shadcn/ui — define component styles using `cva()` (class-variance-authority) at the module level. A `cva()` call contains the base class string and variant class strings, but it is a **module-level function expression**, NOT a JSX `className=` attribute. The strip pass (Step 6) does NOT strip `cva()` calls.

Instead, during Step 6 scan, detect `cva()` usage and flag the file for `cva()` rebuild in Step 10:
-

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [vamsivarma27](https://github.com/vamsivarma27)
- **Source:** [vamsivarma27/ui-restructure](https://github.com/vamsivarma27/ui-restructure)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-vamsivarma27-ui-restructure-ui-restructure
- Seller: https://agentstack.voostack.com/s/vamsivarma27
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
