---
name: fluent-mystique-analyze
description: Analyze existing Mystique manifests for component usage patterns, complexity scoring, nesting depth, i18n coverage, query efficiency, and architectural health. Produces Mermaid diagrams and structured reports. Triggers on "analyze manifest", "mystique audit", "ui complexity", "manifest analysis", "component usage", "mystique health".
user-invocable: true
allowed-tools: Bash, Read, Write, Edit, Glob, Grep
argument-hint: <manifest-file-or-directory> [--deep] [--mermaid] [--deployed]
cursor-tier: manual
---

# Mystique Manifest Analyzer

Analyze existing Mystique manifest JSON definitions to understand component composition, measure complexity, trace data flows, detect architectural patterns and anti-patterns, and generate visual reports with Mermaid diagrams. This skill examines the **UI layer** of a Fluent Commerce implementation — the declarative manifest files and plugin bundles that drive the OMX frontend.

## Context

Mystique manifests are the declarative configuration layer for the Fluent Commerce OMX UI. A manifest defines routes, pages, component trees, GraphQL data queries, template strings, role-based visibility, and plugin references. Over time, manifests grow organically:

- **Complexity creeps in.** Pages accumulate deeply nested component trees. Data providers nest inside conditionals inside repeaters. A single page can exceed 500 lines of JSON.
- **Dead components accumulate.** Pages are copied and modified, leaving orphaned data queries that no component consumes, or conditional branches that never match.
- **i18n coverage drifts.** New strings are added with hardcoded labels instead of `i18n:` keys. Translation files fall behind.
- **Query duplication spreads.** The same GraphQL query appears verbatim on multiple pages instead of being shared through data providers or fragments.
- **Plugin references go stale.** URLs point to localhost dev servers, CDN bundles that no longer exist, or bundles whose components are no longer referenced.
- **Role guards are missing.** Admin-only pages lack `roles` restrictions. Sensitive mutation actions have no role checks.

This skill systematically measures all of these dimensions and produces a structured report with scored metrics, enabling teams to prioritize UI technical debt.

## Ownership Boundary

This skill owns manifest structural analysis, component usage metrics, complexity scoring, pattern detection, and Mermaid diagram generation for manifests.

| This skill OWNS | Other skills OWN |
|-----------------|------------------|
| Manifest structural analysis | Schema validation, prop type checking -> `/fluent-mystique-validate` |
| Component usage metrics | Manifest creation/editing -> `/fluent-mystique-builder` |
| Complexity scoring | SDK project scaffolding -> `/fluent-mystique-scaffold` |
| Pattern and anti-pattern detection | Workflow analysis -> `/fluent-workflow-analyzer` |
| i18n coverage analysis | Settings management -> `/fluent-settings` |
| Data query duplication analysis | Backend rule analysis -> `/fluent-custom-code` |
| Plugin URL health assessment | Account-level feature inventory -> `/fluent-implementation-map` |
| Mermaid diagram generation | Live GraphQL execution -> MCP tools |

## No Planning Gate

This is a **read-only analysis skill**. It writes analysis artifacts to `accounts/<PROFILE>/analysis/mystique/` but does not modify manifests, settings, or entities. Same category as `/fluent-workflow-analyzer` and `/fluent-connection-analysis`.

## When to Use

- Auditing existing manifests before a major UI refactor
- Understanding an unfamiliar manifest's structure and page inventory
- Measuring UI complexity to set refactoring priorities
- Detecting i18n coverage gaps before a localization push
- Finding duplicate GraphQL queries across pages for consolidation
- Generating architecture diagrams for stakeholder walkthroughs
- Validating that plugin bundles are production-ready (not localhost)
- Assessing the custom-vs-OOTB component ratio for maintenance planning
- Pre-deployment health check on manifest quality
- Cross-manifest comparison when multiple manifests serve different contexts (OMS App, Store App)

## Invocation Examples

```bash
/fluent-mystique-analyze admin-manifest.json
/fluent-mystique-analyze admin-manifest.json --deep --mermaid
/fluent-mystique-analyze accounts/<PROFILE>/SOURCE/frontend/mystique-project/manifests/ --mermaid
/fluent-mystique-analyze --deployed --profile <PROFILE> --setting fc.mystique.manifest.admin
```

## Inputs

| Parameter | Required | Default | Description |
|-----------|----------|---------|-------------|
| `<manifest-file-or-directory>` | Yes (unless `--deployed`) | N/A | Path to a single manifest JSON file or directory containing multiple manifests |
| `--deep` | No | `false` | Enable all 7 analysis dimensions including i18n cross-reference, query deduplication, and pattern detection |
| `--mermaid` | No | `false` | Generate Mermaid diagrams (route graph, component trees, data flow) |
| `--deployed` | No | `false` | Fetch manifest from deployed Fluent settings via MCP `setting.get` (preferred, supports `outputFile`) or `graphql.query` instead of local file |
| `--profile` | No | Active profile | Fluent CLI profile (used with `--deployed`) |
| `--setting` | No | N/A | Setting name containing deployed manifest (used with `--deployed`, e.g., `fc.mystique.manifest.admin`) |

## Progress

Emit this block at each phase transition:

```
>> /fluent-mystique-analyze [1/7]
  Done: Load manifests         -> Component census
  Pending: Route mapping            Pending: Complexity scoring
  Pending: Data query analysis      Pending: i18n coverage
  Pending: Pattern detection        Pending: Diagrams & report
```

Update the block as each phase completes.

## Source of Truth: Manifest v2.0 Schema

The skill analyzes manifests conforming to the Mystique v2.0 schema:

```
MystiqueManifest
+-- manifestVersion: "2.0"
+-- name: string                    # App identifier
+-- title: string | i18n:key        # Display name
+-- context.level: account|retailer|location
+-- context.role: string|string[]   # Role restriction
+-- plugins: [{name, src}]          # CDN-hosted plugin bundles
+-- homePath: string                # Landing route
+-- routes: Route[]
    +-- Section {type:"section", nav{label,icon}, pages[]}
    +-- Page {type:"page", path, component, data{query,variables}, props, descendants[], roles[]}
    +-- Reference {type:"reference", settingName}
```

Each page contains a recursive component tree:

```
MystiqueComponentInstance
+-- component: string               # Registry alias (e.g., "fc.list", "fc.page")
+-- dataSource?: string             # JSONPath scoping data context
+-- props?: Record<string,any>      # Component-specific configuration
+-- descendants?: Instance[]        # Nested child components
+-- roles?: string[]                # Role-based visibility
```

---

## Analysis Dimensions

### Dimension 1: Component Census

Walk the entire manifest recursively, counting every component instance and tracking its nesting depth.

**Procedure:**

```
For each route in manifest.routes:
  If route is a section:
    For each page in section.pages:
      Walk page.descendants recursively at depth 0
  If route is a page:
    Walk page.descendants recursively at depth 0
  If route is a reference:
    Record as fragment reference (settingName)

Walk function (instances[], depth):
  For each instance:
    Record: { alias: instance.component, depth: depth }
    If instance.descendants:
      Walk(instance.descendants, depth + 1)
```

**Output: Component Usage Summary Table**

```
Component Usage Summary
+--------------------------+-------+----------+----------+
| Component Alias          | Count | Avg Depth| Max Depth|
+--------------------------+-------+----------+----------+
| fc.page                  | 47    | 0.0      | 0        |
| fc.list                  | 32    | 2.1      | 4        |
| fc.card.attribute        | 24    | 2.8      | 5        |
| fc.grid                  | 18    | 1.2      | 3        |
| fc.column                | 36    | 2.2      | 4        |
| fc.conditional           | 12    | 3.2      | 6        |
| fc.tabs.card             | 8     | 1.0      | 2        |
| fc.provider.graphql      | 6     | 2.5      | 5        |
| fc.repeater              | 4     | 2.0      | 3        |
| fc.filterPanel           | 5     | 2.3      | 4        |
| fc.tile.metric           | 8     | 3.0      | 4        |
| custom.order-tracker     | 3     | 2.0      | 3        |
+--------------------------+-------+----------+----------+
| Total instances          | 289   |          |          |
| Unique aliases           | 34    |          |          |
| OOTB aliases (fc.*)      | 29    |          |          |
| Custom aliases           | 5     |          |          |
| Max nesting depth        | 7     |          |          |
+--------------------------+-------+----------+----------+
```

**Category breakdown:** Classify each alias into one of the standard categories:

| Category | Aliases |
|----------|---------|
| Layout / Container | `fc.page`, `fc.grid`, `fc.column`, `fc.conditional`, `fc.repeater`, `fc.tabs.card`, `fc.accordion`, `fc.card`, `fc.provider.graphql`, `fc.provider.rest`, `fc.page.section`, `fc.page.section.header` |
| Content / Display | `fc.list`, `fc.card.attribute`, `fc.card.attributes.grid`, `fc.chart`, `fc.link`, `fc.image.card`, `fc.product.card`, `fc.json.viewer`, `fc.json.editor`, `fc.google.map.pin`, `fc.timeline`, `fc.stepper`, `fc.status.badge`, `fc.avatar`, `fc.badge`, `fc.chip`, `fc.divider`, `fc.text`, `fc.dynamic.value`, `fc.progress`, `fc.table`, `fc.tile.metric` |
| Form / Input | `fc.select`, `fc.input`, `fc.checkbox`, `fc.radio`, `fc.switch`, `fc.date.picker`, `fc.time.picker`, `fc.autocomplete`, `fc.slider`, `fc.file.upload`, `fc.quantity`, `fc.textarea`, `fc.color.picker`, `fc.filterPanel` |
| Action | `fc.button`, `fc.icon.button`, `fc.action.bar`, `fc.fab`, `fc.menu`, `fc.speed.dial` |
| Navigation | `fc.breadcrumb`, `fc.pagination`, `fc.drawer`, `fc.dialog`, `fc.popover`, `fc.tooltip` |
| Feedback | `fc.alert`, `fc.snackbar`, `fc.skeleton`, `fc.loading`, `fc.empty.state`, `fc.error.boundary` |
| Wizard | `fc.page.wizard`, `fc.page.wizard.action`, `fc.page.wizard.summary` |
| Custom | Any alias not starting with `fc.` or not in the known registry |

### Dimension 2: Route Map

Build a hierarchical map of all routes showing sections, pages, and their primary component.

**Procedure:**

```
For each route:
  If section:
    Print section label, icon, roles (if any)
    For each page in section.pages:
      Print path, primary component, descendant count, roles
  If page (top-level):
    Print path, primary component, descendant count, roles
  If reference:
    Print settingName (fragment)
```

**Output: Route Structure Tree**

```
Route Structure
+-- /orders (section: "Order Management", icon: shopping_cart)
|   +-- /orders -- fc.list [12 columns, filter enabled]
|   +-- /orders/:id -- fc.page [18 components, 3 levels deep]
|   +-- /orders/:id/fulfilments -- fc.list [8 columns]
+-- /inventory (section: "Inventory", icon: inventory_2)
|   +-- /inventory/positions -- fc.page [fc.filterPanel + fc.list]
|   +-- /inventory/positions/:id -- fc.page [2 attribute cards]
+-- /settings (section: "Admin", icon: settings, roles: ["ADMIN"])
|   +-- /settings/general -- fc.page
|   +-- /settings/users -- fc.page [custom.user-management]
+-- [reference] fc.mystique.manifest.reporting (fragment)

Summary: 3 sections, 8 pages, 1 fragment reference
Home path: /orders (resolves to section "Order Management")
```

### Dimension 3: Complexity Scoring

Compute a weighted complexity score (0-100) for the overall manifest and per-page.

**Metric Weights:**

| Metric | Weight | Green (0-40) | Yellow (41-70) | Red (71-100) |
|--------|--------|-------------|----------------|--------------|
| Total component instances | 20% | <100 | 100-300 | >300 |
| Max nesting depth | 20% | <5 | 5-8 | >8 |
| Avg components per page | 15% | <5 | 5-15 | >15 |
| Custom component ratio | 15% | <10% | 10-30% | >30% |
| Data provider count | 15% | <5 | 5-15 | >15 |
| Conditional complexity | 15% | <3 nested | 3-6 nested | >6 nested |

**Scoring formula:**

```
For each metric:
  raw_score = linear_interpolate(value, green_max, red_min, 0, 100)
  clamped = clamp(raw_score, 0, 100)

overall_score = sum(metric_score * weight) for all metrics
```

**Output: Complexity Scorecard**

```
Manifest Complexity Scorecard
+------------------------------+--------+-------+--------+
| Metric                       | Value  | Score | Rating |
+------------------------------+--------+-------+--------+
| Total component instances    | 289    | 63    | YELLOW |
| Max nesting depth            | 7      | 50    | YELLOW |
| Avg components per page      | 8.2    | 32    | GREEN  |
| Custom component ratio       | 14.7%  | 47    | YELLOW |
| Data provider count          | 6      | 20    | GREEN  |
| Conditional complexity       | 4      | 50    | YELLOW |
+------------------------------+--------+-------+--------+
| OVERALL SCORE                |        | 44    | YELLOW |
+------------------------------+--------+-------+--------+

Per-Page Complexity (top 5):
  /orders/:id                  72  RED    (18 components, depth 6, 2 providers)
  /inventory/positions         58  YELLOW (12 components, depth 4, filterPanel)
  /settings/users              55  YELLOW (custom.user-management, depth 5)
  /orders                      35  GREEN  (fc.list, simple structure)
  /settings/general            12  GREEN  (2 attribute cards)
```

### Dimension 4: Data Query Analysis

Extract and analyze all GraphQL queries in the manifest — page-level `data.query` blocks and `fc.provider.graphql` query props.

**Procedure:**

```
1. Extract all queries:
   - Page-level: route.data.query for each page
   - Provider-level: descendants with component=="fc.provider.graphql", extract props.query
   - Filter panel: fc.filterPanel with props.query

2. Normalize queries (strip whitespace, normalize field order)

3. Detect duplicates:
   - Exact duplicates: identical normalized query text
   - Near duplicates: same root query, different field selection

4. Analyze query complexity:
   - Count fields per query
   - Count nested connections (edges/node patterns)
   - Flag queries with >10 top-level fields
   - Flag queries with >3 nested connection levels

5. Map query-to-component consumption:
   - Which components reference the query data via dataSource?
   - Are there orphan queries (defined but no descendant references the data)?
```

**Output: Data Query Report**

```
Data Query Analysis
+---+-----------------------------------+--------+--------+-----------+----------+
| # | Root Query                        | Fields | Nesting| Pages     | Status   |
+---+-----------------------------------+--------+--------+-----------+----------+
| 1 | orders(first, after, retailerId)  | 12     | 2      | /orders   | OK       |
| 2 | orderById(id)                     | 18     | 3      | /orders/:id| COMPLEX |
| 3 | orderById(id)                     | 8      | 2      | /orders/:id/ful | SIMILAR_TO_2 |
| 4 | inventoryPositions(first, after)  | 6      | 1      | /inventory| OK       |
| 5 | locationByRef(ref)                | 5      | 1      | (provider)| OK       |
| 6 | orders(first, after, retailerId)  | 12     | 2      | /dashboard| DUPLICATE_OF_1|
+---+-----------------------------------+--------+--------+-----------+----------+

Unique queries: 5 (1 exact duplicate, 1 near-duplicate)
Orphan queries: 0 (all queries have consuming components)
Large queries: 1 (query #2 has 18 fields, 3 nesting levels)
Provider queries: 1 (fc.provider.graphql on /orders/:id)

Recommendation: Consolidate queries #1 and #6 into a shared fragment or data provider.
```

### Dimension 5: i18n Coverage

Extract all user-facing strings and classify them as internationalized or hardcoded.

**Procedure:**

```
1. Extract i18n strings:
   - Strings starting with "i18n:" prefix (properly internationalized)
   - Template strings using {{t "key"}} pattern

2. Extract hardcoded strings:
   - Section nav.label values without i18n: prefix
   - Page props.title values without i18n: prefix or template strings
   - Component props with string values that appear to be user-facing labels
   - List column labels, card titles, button labels

3. If translation files are available (i18n/locales/*/translation.json):
   - Cross-reference extracted i18n: keys against translation files
   - Report missing keys (referenced but not in translation file)
   - Report unused keys (in translation file but not referenced in manifest)
   - Report language coverage (which locales have complete translations)
```

**Output: i18n Coverage Report**

```
i18n Coverage Analysis
+----------------------------+-------+
| Metric                     | Value |
+----------------------------+-------+
| Total user-facing strings  | 156   |
| i18n: prefixed             | 112   |
| Template strings           | 24    |
| Hardcoded strings          | 20    |
| Coverage                   | 71.8% |
+----------------------------+-------+

Hardcoded Strings (fix these):
  /orders -- page title "Orders" (should be i18n:fc.om.orders.title)
  /orders/:id -- back button label "Back to Orders"
  /settings/users -- nav label "Advanced User Management"
  ... (17 more)

Translation Cross-Reference (en):
  Missing keys: 3 (referenced in manifest but not in translation.json)
  Unused keys: 12 (in translation.json but not referenced)
  Locales found: en, de, fr, ja, zh
  Complete locales: en (100%), de (94%), fr (91%), ja (87%), zh (82%)
```

### Dimension 6: Pattern Detection

Scan the manifest for known good patterns and anti-patterns.

| Pattern | Type | Detection | Severity |
|---------|------|-----------|----------|
| **Consistent layouts** | Good | Same component hierarchy across entity detail pages (fc.page -> fc.grid -> fc.column -> fc.card.attribute) | INFO |
| **Deep nesting** | Warning | Components nested >6 levels deep | MEDIUM |
| **Orphan data** | Warning | Page `data.query` defined but no descendant uses `dataSource` referencing it | MEDIUM |
| **Duplicate pages** | Refactor | Near-identical page structures (>80% component overlap) that could share a fragment | LOW |
| **Missing actions** | Gap | Detail pages (entity by ID) without `actions` prop on fc.page — no workflow integration | MEDIUM |
| **No role guards** | Security | Pages under admin/settings sections without `roles` restriction | HIGH |
| **Fragment opportunity** | Optimization | Repeated section/page structures across multiple manifests in the same directory | LOW |
| **Localhost plugins** | Error | Plugin `src` URLs containing `localhost`, `127.0.0.1`, or non-HTTPS URLs | HIGH |
| **Dead plugins** | Warning | Plugin `name` registered but no component in the manifest uses an alias from that plugin | MEDIUM |
| **Provider inside list** | Warning | `fc.provider.graphql` nested inside `fc.list` — known compatibility issue per Fluent docs | HIGH |
| **Missing page titles** | Warning | `fc.page` components without `title` prop — poor UX for browser tabs and breadcrumbs | LOW |
| **Excessive list columns** | Warning | `fc.list` with >12 attribute columns — renders poorly on smaller screens | LOW |
| **Deeply nested conditionals** | Warning | `fc.conditional` nested inside another `fc.conditional` >2 levels — hard to maintain | MEDIUM |
| **Missing filter** | Gap | `fc.list` with large data sets but no `filter` prop enabled | LOW |
| **Wizard step count** | Warning | `fc.page.wizard` with >6 steps — violates recommended practices | MEDIUM |

**Output: Pattern Detection Report**

```
Pattern Detection
+-+------+-----------------------------+-----------------------------------+
|#| Sev  | Pattern                     | Location                          |
+-+------+-----------------------------+-----------------------------------+
|1| HIGH | No role guards              | /settings/general (no roles[])    |
|2| HIGH | Localhost plugin             | plugin "dev-components" src=http://localhost:3001/bundle.js |
|3| HIGH | Provider inside list         | /orders/:id -> fc.list -> fc.provider.graphql |
|4| MED  | Deep nesting (7 levels)     | /orders/:id -> grid -> column -> tabs -> ... |
|5| MED  | Orphan data query           | /dashboard has query but no dataSource consumers |
|6| MED  | Missing actions             | /inventory/positions/:id has no actions prop |
|7| LOW  | Duplicate page structure     | /orders and /fulfilments share 85% component overlap |
|8| LOW  | Missing page title          | /settings/general has no title prop |
|9| INFO | Consistent layout detected  | 5 detail pages use fc.page -> fc.grid -> fc.column pattern |
+-+------+-----------------------------+-----------------------------------+

Summary: 3 HIGH, 3 MEDIUM, 2 LOW, 1 INFO
```

### Dimension 7: Mermaid Diagrams (--mermaid)

Generate copy-pasteable Mermaid diagram blocks for visual architecture documentation.

#### Diagram 1: Route Graph

Shows the hierarchical route structure with sections as containers and pages as nodes.

**Template:**

````markdown
```mermaid
flowchart TD
    subgraph SEC_OM["Order Management"]
        ORDERS["/orders<br/><small>fc.list</small>"]
        ORDER_DET["/orders/:id<br/><small>fc.page 18 components</small>"]
        ORDER_FUL["/orders/:id/fulfilments<br/><small>fc.list</small>"]
        ORDERS --> ORDER_DET
        ORDER_DET --> ORDER_FUL
    end

    subgraph SEC_INV["Inventory"]
        INV_POS["/inventory/positions<br/><small>fc.page + filterPanel</small>"]
        INV_DET["/inventory/positions/:id<br/><small>fc.page</small>"]
        INV_POS --> INV_DET
    end

    subgraph SEC_ADMIN["Admin (ADMIN role)"]
        SET_GEN["/settings/general<br/><small>fc.page</small>"]
        SET_USR["/settings/users<br/><small>custom.user-mgmt</small>"]
    end

    HOME(("homePath")) --> ORDERS

    style SEC_ADMIN fill:#fff3cd,stroke:#856404
    style HOME fill:#d4edda
```
````

**Generation algorithm:**

```
1. For each section, create a subgraph with the section label
2. For each page in the section, create a node with path and primary component
3. Draw edges between list pages and their detail pages (matching /:id patterns)
4. Mark homePath with a special node pointing to its target
5. Highlight role-restricted sections with warning colors
6. Mark pages with custom components using distinct styling
```

#### Diagram 2: Component Tree (per page)

Shows the component hierarchy for a specific page — useful for understanding complex pages.

**Template:**

````markdown
```mermaid
graph TD
    PAGE["fc.page<br/>title: Order Detail"]
    PAGE --> GRID["fc.grid"]
    GRID --> COL1["fc.column md:8"]
    GRID --> COL2["fc.column md:4"]
    COL1 --> TABS["fc.tabs.card"]
    TABS --> TAB1_LIST["fc.list<br/>dataSource: items"]
    TABS --> TAB2_CARD["fc.card.attribute<br/>Fulfilment Details"]
    COL2 --> ATTR["fc.card.attribute<br/>Order Summary"]
    COL2 --> ACTIONS["fc.page (actions)"]
    COL2 --> COND["fc.conditional<br/>status==ACTIVE"]
    COND --> ALERT["fc.alert<br/>Active Order"]

    style PAGE fill:#e3f2fd
    style COND fill:#fff3cd
    style ACTIONS fill:#d4edda
```
````

**Generation algorithm:**

```
For a given page:
  1. Create root node for the page component with title
  2. Recursively walk descendants:
     a. Create node for each component (alias + key props summary)
     b. Draw edge from parent to child
     c. For fc.conditional, add condition text to node
     d. For fc.provider.graphql, add query summary to node
     e. For fc.list, add dataSource and column count
     f. For fc.repeater, add dataSource
  3. Color-code by category:
     - Layout: light blue
     - Data providers: light purple
     - Conditionals: light yellow
     - Actions: light green
     - Custom: light orange
```

#### Diagram 3: Data Flow (per page)

Shows how data moves from GraphQL queries through the component tree.

**Template:**

````markdown
```mermaid
sequenceDiagram
    participant Browser as Browser
    participant Page as Page /orders/:id
    participant GQL as GraphQL API
    participant Comp as Components

    Browser->>Page: Navigate to /orders/123
    Page->>GQL: orderById(id: 123)
    GQL-->>Page: order data (18 fields)
    Page->>Comp: fc.page receives order data
    Comp->>Comp: fc.list uses dataSource=items
    Comp->>Comp: fc.card.attribute uses order fields
    Note over Comp: fc.provider.graphql triggers
    Comp->>GQL: locationByRef(ref: locationRef)
    GQL-->>Comp: location data
    Comp->>Comp: fc.card.attribute uses location fields
```
````

**Generation algorithm:**

```
For a given page:
  1. Start with browser navigation to the page path
  2. If page has data.query, show the page-level GraphQL call
  3. Show data flowing to child components via dataSource paths
  4. For each fc.provider.graphql descendant:
     a. Show a secondary GraphQL call
     b. Show data flowing to the provider's descendants
  5. For fc.repeater, show iteration over the data array
  6. For fc.conditional, show branch decision
```

---

## Execution Flow

### Step 1: Load Manifests

```
1. If --deployed:
   a. Use MCP setting.get with outputFile to save manifest to disk (keeps large JSON out of LLM context):
      setting.get({ name: "fc.mystique.manifest.<app>", outputFile: "accounts/<PROFILE>/manifests/<setting-name>.json" })
   b. Read the saved file locally with the Read tool to parse the manifest JSON
   c. Handle fragment references (type:"reference") by fetching each referenced setting with outputFile:
      setting.get({ name: "<fragment-setting-name>", outputFile: "accounts/<PROFILE>/manifests/<fragment-name>.json" })
   d. Read each fragment file locally
   e. For wildcard discovery (all manifests at once):
      setting.get({ name: "fc.mystique.manifest.%", outputFile: "accounts/<PROFILE>/manifests/" })
      Multiple matches auto-save as individual files to the directory
2. If file path provided:
   a. If file: read and parse single manifest JSON
   b. If directory: glob for *.json, parse each, filter by manifestVersion:"2.0"
3. Validate each loaded manifest has manifestVersion and routes
4. Report: N manifests loaded, M total routes, K total pages
```

### Step 2: Component Census (Dimension 1)

Walk all manifests recursively. Produce the component usage summary table with counts, average depth, max depth, and category breakdown.

### Step 3: Route Map (Dimension 2)

Build the hierarchical route tree. Identify sections, pages, fragment references. Map homePath to its target. Flag any route path duplicates.

### Step 4: Complexity Scoring (Dimension 3)

Compute the weighted complexity score for the overall manifest and per-page. Generate the scorecard with Green/Yellow/Red ratings.

### Step 5: Data Query Analysis (Dimension 4)

Extract all GraphQL queries. Normalize, deduplicate, compute field counts. Map query-to-component consumption chains. Flag orphan queries and large queries.

### Step 6: i18n Coverage (Dimension 5, --deep only)

Extract all user-facing strings. Classify as i18n-prefixed, template, or hardcoded. If translation files are available, cross-reference for missing and unused keys.

### Step 7: Pattern Detection (Dimension 6)

Run the pattern detection rules against the analyzed manifest. Produce findings sorted by severity.

### Step 8: Plugin Analysis

```
1. Extract all plugins[] entries from manifests
2. Classify each plugin URL:
   - localhost / 127.0.0.1 / 0.0.0.0 -> DEV (flag as error for production)
   - CDN URL (https://*.cdn.*, *.vercel.app, *.cloudfront.net) -> PROD
   - HTTP (not HTTPS) -> INSECURE (flag as warning)
   - Broken/empty URL -> BROKEN (flag as error)
3. Cross-reference plugin names against component aliases in the manifest:
   - If a plugin is declared but no custom alias from that plugin is used -> DEAD PLUGIN
4. Compute custom vs OOTB ratio:
   - OOTB: aliases matching fc.* from the known registry
   - Custom: all other aliases
   - Report: N custom / M total = X% custom
```

**Output: Plugin Analysis**

```
Plugin Analysis
+---+---------------------+-------------------------------------------+--------+--------+
| # | Plugin Name         | Source URL                                | Status | Used   |
+---+---------------------+-------------------------------------------+--------+--------+
| 1 | omx-components      | https://cdn.fluent.com/omx/bundle.js      | PROD   | Yes(3) |
| 2 | dev-widgets          | http://localhost:3001/bundle.js            | DEV    | Yes(1) |
| 3 | analytics-plugin     | https://analytics.vercel.app/bundle.js    | PROD   | No     |
+---+---------------------+-------------------------------------------+--------+--------+

Custom vs OOTB: 5 custom / 34 total = 14.7% custom ratio
Bundle dependencies: custom.order-tracker (omx-components), custom.user-management (omx-components)
```

### Step 9: Mermaid Diagrams (--mermaid)

Generate all three diagram types. For the component tree and data flow diagrams, generate for the top 3 most complex pages (by per-page complexity score).

### Step 10: Cross-Manifest Analysis

When multiple manifests are loaded (directory mode), run additional cross-manifest checks:

```
1. Shared component aliases across manifests:
   - Which aliases appear in all manifests?
   - Are there inconsistent prop shapes for the same alias?

2. Route path collisions:
   - Do any manifests define the same route path?

3. Fragment reuse opportunities:
   - Which page structures are repeated across manifests?
   - Could they be extracted into shared fragments (type:"reference")?

4. Plugin consistency:
   - Do all manifests reference the same plugin versions?
   - Are there version mismatches?

5. Context comparison:
   - Compare context.level across manifests (admin=account, store=location, etc.)
   - Compare role restrictions
```

### Step 11: Write Report

Compile all dimensions into a structured markdown report and write artifacts.

---

## Output Location

All generated artifacts are written to:

```
accounts/<PROFILE>/analysis/mystique/
+-- manifest-analysis.md          # Human-readable report with all dimensions
+-- component-census.json         # Machine-readable component usage metrics
+-- diagrams/                     # Mermaid diagram source files
|   +-- route-graph.mmd           # Route structure flowchart
|   +-- <page-path>-tree.mmd     # Component tree per complex page
|   +-- <page-path>-flow.mmd     # Data flow per complex page
+-- cross-manifest.md             # Cross-manifest comparison (directory mode only)
```

When a single file is analyzed outside an accounts directory, write to the same directory as the manifest file with an `analysis/` subdirectory.

---

## Frontend Development Context

This skill analyzes the **UI layer** of a Fluent Commerce implementation. Key distinctions:

### Manifest vs Backend

- **Manifests** define what the user sees: routes, pages, component trees, data queries, labels, actions, role guards. They are declarative JSON deployed as Fluent settings.
- **Workflows** define what happens on the backend: entity state machines, rule execution, event chains. Analyzed by `/fluent-workflow-analyzer`.
- **The bridge** between them is user actions: the manifest's `actions` prop on `fc.page` connects to workflow-defined user actions. Missing actions in the manifest means the UI does not expose backend capabilities.

### Local vs Deployed Analysis

- **Local files**: Read manifest JSON from the filesystem. Useful during development before deployment.
- **Deployed manifests**: Fetch from Fluent settings API via MCP `setting.get` (preferred — supports wildcards and `outputFile` to save to disk) or `graphql.query`. Setting names follow the convention `fc.mystique.manifest.<app-name>`. The setting value is the full manifest JSON stored in `lobValue` (new settings use `valueType: "JSON"`; legacy settings may use `valueType: "LOB"`). Fragment references (`type:"reference"`) point to additional settings named `fc.mystique.manifest.<app>.fragment.<name>` that must be fetched separately. Use `setting.get` with `name: "fc.mystique.manifest.%"` to discover all manifest settings at once.

### Plugin URL Health

Plugin bundles are external JavaScript files loaded at runtime. The `plugins[]` array in a manifest specifies CDN URLs. This skill classifies plugin URLs:

| URL Pattern | Classification | Action |
|-------------|---------------|--------|
| `http://localhost:*` | DEV | Must replace before deployment |
| `http://127.0.0.1:*` | DEV | Must replace before deployment |
| `http://*` (non-HTTPS) | INSECURE | Upgrade to HTTPS |
| `https://*.cdn.*`, `*.vercel.app`, `*.cloudfront.net` | PROD | OK for production |
| Empty or malformed URL | BROKEN | Fix immediately |

### Custom vs OOTB Component Ratio

The ratio of custom components to OOTB (out-of-the-box) `fc.*` components indicates maintenance burden:

- **<10% custom**: Mostly standard UI. Low maintenance. Upgrades are straightforward.
- **10-30% custom**: Extended UI. Moderate maintenance. Plugin bundles must be versioned.
- **>30% custom**: Heavily customized. High maintenance. Plugin compatibility with platform upgrades is a risk.

### Bundle Dependency Mapping

For each custom component alias, trace it back to the plugin that provides it. Report which plugins are actually consumed vs declared-but-unused. This helps identify dead plugin dependencies that increase bundle size without benefit.

### Custom Component Cataloging

When custom components are found, catalog them as individual `.md` files following the template in `fluent-mystique-builder/COMPONENT_TEMPLATE.md`. For each custom alias:

1. Find the SDK project in `accounts/<PROFILE>/SOURCE/frontend/*/src/index.tsx` — locate `ComponentRegistry.register('<alias>', Component)` calls
2. Read the component's TypeScript props interface
3. Check Storybook stories and usage in manifests
4. Create a component file (e.g., `custom.order-tracker.md`) using the `COMPONENT_TEMPLATE.md` format with `module: Custom`
5. Write to `fluent-mystique-builder/components/` (OOTB companion) or `accounts/<PROFILE>/analysis/mystique/components/` (per-account)

This structured catalog enables `/fluent-mystique-builder` to grep `components/*.md` and make informed Build vs Configure decisions that account for BOTH OOTB and existing client custom components — avoiding duplicate implementations.

---

## Integration with Other Skills

| User Request After Analysis | Skill to Invoke |
|-----------------------------|-----------------|
| "Fix the issues found" | `/fluent-mystique-validate` (for schema validation), then `/fluent-mystique-builder` (for edits) |
| "Scaffold a new component to replace the custom one" | `/fluent-mystique-scaffold` |
| "Deploy the manifest" | `/fluent-mystique-validate` -> `/fluent-settings` (upload as setting) |
| "Map the full implementation" | `/fluent-implementation-map` (discovers manifests as part of account onboarding) |
| "Analyze the backend workflows" | `/fluent-workflow-analyzer` |
| "Check cross-entity connections" | `/fluent-connection-analysis` |
| "What custom rules power the user actions?" | `/fluent-custom-code` |

### Integration with /fluent-implementation-map

When `/fluent-implementation-map` discovers deployed Mystique manifests during account onboarding (settings with `fc.mystique.manifest.*` keys), it can invoke this skill to produce the UI layer analysis as part of the full implementation map. The manifest analysis report is referenced from the implementation map's UI section.

### Integration with /fluent-mystique-validate

This skill and `/fluent-mystique-validate` are complementary:

- **validate** answers: "Is this manifest structurally correct?" (schema compliance, prop types, cross-references)
- **analyze** answers: "Is this manifest well-architected?" (complexity, patterns, coverage, health)

After running analyze, recommend validate for any manifests with HIGH severity findings.

---

## Graceful Degradation

| Input Source | Available | Fallback |
|-------------|-----------|----------|
| Local manifest files | Always | N/A (primary input) |
| Deployed manifests (`--deployed`) | Requires MCP `setting.get` (with `outputFile`) | Fallback: official CLI MCP `graphql.execute` (no budget), or ask user to export manifest JSON and provide as local file |
| Translation files (i18n/) | Optional | Skip i18n cross-reference; report only i18n: prefix coverage from manifest strings |
| Plugin URL validation | Requires network | Classify by URL pattern only; skip HTTP HEAD checks |
| Source code (SDK projects) | Optional | Skip bundle dependency mapping; report custom aliases as "origin unknown" |

---

## Handoff Protocol

On completion:

```
-> REVIEW: accounts/<PROFILE>/analysis/mystique/manifest-analysis.md
-> NEXT: /fluent-mystique-validate (validate manifests with HIGH findings)
-> NEXT: /fluent-mystique-builder (fix issues, refactor duplicate pages, add fragments)
-> NEXT: /fluent-implementation-map (include UI analysis in full account map)
-> BLOCKED: No manifest files found at the specified path
-> BLOCKED: --deployed requires MCP setting.get tool (not available)
```

## Error Reporting

| Error Type | Phase | Severity | Recovery |
|------------|-------|----------|----------|
| `PREREQ_MISSING` | Step 1 | CRITICAL | No manifest files found at specified path |
| `VALIDATION_FAILED` | Step 1 | MEDIUM | JSON parse error on manifest file -- skip file, continue with others |
| `ENV_UNREACHABLE` | Step 1 | HIGH | MCP unavailable for --deployed mode -- fall back to local files |
| `PREREQ_MISSING` | Step 6 | LOW | No translation files found -- skip i18n cross-reference |

## Session Tracking

Track: files written (`manifest-analysis.md`, `component-census.json`, `diagrams/*.mmd`), manifests analyzed (count, paths), MCP tools called (`graphql.query` if `--deployed`). No environment mutations -- this is a read-only skill.

## Tips

- **Start without --deep** for a quick overview. Add --deep when you need the full i18n cross-reference and pattern detection.
- **Use --mermaid** to generate diagrams for architecture reviews and stakeholder walkthroughs.
- **Point at a directory** to compare multiple manifests (OMS App, Store App) and find fragment opportunities.
- **Combine with --deployed** to analyze the live production manifest rather than a potentially stale local copy.
- **Large manifests** (>1000 lines): the skill processes by section/page rather than loading the entire manifest into context at once. Per-page analysis is streamed.
- **Fragment references** (`type:"reference"`, `settingName`): these point to separately deployed manifest fragments. When analyzing locally, the skill reports them as unresolved references. When analyzing with `--deployed`, the skill fetches and inlines them.
- **Custom component aliases** cannot be validated against a registry since they are defined in plugin bundles. The skill flags them as "custom" in the census but does not treat unknown aliases as errors (that is the validator's job).
- **Template helper inventory:** When plugin source is available (`accounts/<PROFILE>/SOURCE/frontend/`), scan `src/index.tsx` for `TemplateRegistry.register()` calls and catalog custom helpers alongside components and fields. Report: helper name, alias(es), whether it's used in any analyzed manifest template string. Include in `component-census.json` under a `templateHelpers` key. When source is unavailable, extract helper names from manifest template strings (anything in `{{helperName ...}}` not in the built-in 50).
