{
  "feature": "component-registry-cli",
  "version": "1.0.0",
  "description": "CLI tool for initializing projects, adding UI components from registries, managing migrations, and providing MCP server integration for AI assistants",
  "category": "ui",
  "tags": [
    "cli",
    "component-registry",
    "code-generation",
    "developer-tools",
    "mcp"
  ],
  "actors": [
    {
      "id": "developer",
      "name": "Developer",
      "type": "human",
      "description": "End user running CLI commands to add components to their project"
    },
    {
      "id": "cli",
      "name": "Component Registry CLI",
      "type": "system",
      "description": "The CLI tool that orchestrates component installation"
    },
    {
      "id": "registry",
      "name": "Component Registry",
      "type": "external",
      "description": "Remote HTTP registry serving component definitions, styles, and metadata"
    },
    {
      "id": "mcp_client",
      "name": "MCP Client",
      "type": "external",
      "description": "AI assistant (Claude, Cursor, VS Code, Codex) consuming the MCP server"
    }
  ],
  "fields": [
    {
      "name": "style",
      "label": "Component Style",
      "type": "select",
      "required": true,
      "options": [
        {
          "value": "new-york",
          "label": "New York"
        },
        {
          "value": "base-vega",
          "label": "Vega"
        },
        {
          "value": "base-nova",
          "label": "Nova"
        },
        {
          "value": "base-lyra",
          "label": "Lyra"
        },
        {
          "value": "base-maia",
          "label": "Maia"
        },
        {
          "value": "base-mira",
          "label": "Mira"
        },
        {
          "value": "base-luma",
          "label": "Luma"
        }
      ]
    },
    {
      "name": "rsc",
      "label": "React Server Components",
      "type": "boolean",
      "required": false
    },
    {
      "name": "tsx",
      "label": "TypeScript JSX",
      "type": "boolean",
      "required": false
    },
    {
      "name": "base_color",
      "label": "Base Color",
      "type": "select",
      "required": true,
      "options": [
        {
          "value": "neutral",
          "label": "Neutral"
        },
        {
          "value": "stone",
          "label": "Stone"
        },
        {
          "value": "slate",
          "label": "Slate"
        },
        {
          "value": "gray",
          "label": "Gray"
        },
        {
          "value": "zinc",
          "label": "Zinc"
        }
      ]
    },
    {
      "name": "css_variables",
      "label": "CSS Variables",
      "type": "boolean",
      "required": false
    },
    {
      "name": "tailwind_prefix",
      "label": "Tailwind Prefix",
      "type": "text",
      "required": false
    },
    {
      "name": "icon_library",
      "label": "Icon Library",
      "type": "select",
      "required": false,
      "options": [
        {
          "value": "lucide",
          "label": "Lucide"
        },
        {
          "value": "feather",
          "label": "Feather"
        },
        {
          "value": "icon-library",
          "label": "Icon Library"
        },
        {
          "value": "heroicons",
          "label": "Heroicons"
        },
        {
          "value": "tabler-icons",
          "label": "Tabler Icons"
        },
        {
          "value": "hugeicons",
          "label": "Hugeicons"
        },
        {
          "value": "phosphor",
          "label": "Phosphor"
        },
        {
          "value": "remixicon",
          "label": "Remix Icon"
        }
      ]
    },
    {
      "name": "rtl",
      "label": "Right-to-Left",
      "type": "boolean",
      "required": false
    },
    {
      "name": "aliases_components",
      "label": "Components Alias",
      "type": "text",
      "required": true
    },
    {
      "name": "aliases_utils",
      "label": "Utils Alias",
      "type": "text",
      "required": true
    },
    {
      "name": "registries",
      "label": "Registry Configuration",
      "type": "json",
      "required": false
    },
    {
      "name": "component_type",
      "label": "Component Type",
      "type": "select",
      "required": true,
      "options": [
        {
          "value": "registry:lib",
          "label": "Library"
        },
        {
          "value": "registry:block",
          "label": "Block"
        },
        {
          "value": "registry:component",
          "label": "Component"
        },
        {
          "value": "registry:ui",
          "label": "UI Component"
        },
        {
          "value": "registry:hook",
          "label": "Hook"
        },
        {
          "value": "registry:page",
          "label": "Page"
        },
        {
          "value": "registry:file",
          "label": "File"
        },
        {
          "value": "registry:theme",
          "label": "Theme"
        },
        {
          "value": "registry:style",
          "label": "Style"
        },
        {
          "value": "registry:item",
          "label": "Item"
        },
        {
          "value": "registry:base",
          "label": "Base"
        },
        {
          "value": "registry:font",
          "label": "Font"
        }
      ]
    },
    {
      "name": "menu_color",
      "label": "Menu Color",
      "type": "select",
      "required": false,
      "options": [
        {
          "value": "default",
          "label": "Default"
        },
        {
          "value": "inverted",
          "label": "Inverted"
        },
        {
          "value": "default-translucent",
          "label": "Default Translucent"
        },
        {
          "value": "inverted-translucent",
          "label": "Inverted Translucent"
        }
      ]
    },
    {
      "name": "menu_accent",
      "label": "Menu Accent",
      "type": "select",
      "required": false,
      "options": [
        {
          "value": "subtle",
          "label": "Subtle"
        },
        {
          "value": "bold",
          "label": "Bold"
        }
      ]
    }
  ],
  "rules": {
    "preflight_checks": {
      "project_must_exist": true,
      "config_required_for_add": true,
      "framework_detection_required_for_init": true,
      "tailwind_must_be_configured": true,
      "import_alias_required": true
    },
    "security": {
      "safe_target_validation": true,
      "env_file_protection": true,
      "registry_auth_via_env_vars": true
    },
    "registry": {
      "namespace_must_start_with_at": true,
      "recursive_dependency_resolution": true,
      "response_caching": true,
      "rfc7807_error_parsing": true
    },
    "file_management": {
      "backup_before_config_change": true,
      "overwrite_requires_flag": true
    }
  },
  "outcomes": {
    "init_default_project": {
      "priority": 1,
      "given": [
        "Developer runs 'shadcn init' in a project directory",
        {
          "field": "cwd",
          "source": "input",
          "operator": "exists",
          "description": "Working directory contains a package.json"
        }
      ],
      "then": [
        {
          "action": "create_record",
          "type": "config_file",
          "target": "components_json",
          "description": "Write components.json with style, aliases, Tailwind config, and registry settings"
        },
        {
          "action": "call_service",
          "target": "registry.fetch_base_style",
          "description": "Fetch base style and color configuration from registry"
        },
        {
          "action": "emit_event",
          "event": "cli.init.completed",
          "payload": [
            "cwd",
            "style",
            "base_color",
            "framework"
          ]
        }
      ],
      "result": "Project is initialized with components.json, Tailwind CSS configured, and ready for component installation"
    },
    "init_with_template": {
      "priority": 2,
      "given": [
        "Developer provides --template flag (next, vite, astro, laravel, react-router, start)",
        {
          "field": "template",
          "source": "input",
          "operator": "in",
          "value": [
            "next",
            "vite",
            "astro",
            "laravel",
            "react-router",
            "start"
          ]
        }
      ],
      "then": [
        {
          "action": "call_service",
          "target": "template.init",
          "description": "Run template-specific initialization"
        },
        {
          "action": "call_service",
          "target": "template.post_init",
          "description": "Run post-initialization hooks (git init, etc.)"
        }
      ],
      "result": "New project created from template with shadcn configured"
    },
    "init_monorepo": {
      "priority": 3,
      "given": [
        "Developer runs init at monorepo root or with --monorepo flag",
        "pnpm-workspace.yaml or workspace config detected"
      ],
      "then": [
        {
          "action": "call_service",
          "target": "monorepo.detect_workspaces",
          "description": "Detect workspace targets for component installation"
        },
        {
          "action": "create_record",
          "type": "config_file",
          "target": "components_json",
          "description": "Write config with workspace-aware path resolution"
        }
      ],
      "result": "Monorepo initialized with workspace detection and shared component config"
    },
    "init_unsupported_framework": {
      "priority": 4,
      "error": "UNSUPPORTED_FRAMEWORK",
      "given": [
        "Framework cannot be detected from project structure",
        "Developer has not provided --defaults flag"
      ],
      "then": [
        {
          "action": "notify",
          "channel": "cli",
          "target": "developer",
          "description": "Prompt developer for manual configuration"
        }
      ],
      "result": "Developer is informed and can provide manual config or use --defaults"
    },
    "add_single_component": {
      "priority": 5,
      "given": [
        "Developer runs 'shadcn add <component>'",
        {
          "field": "components_json",
          "source": "system",
          "operator": "exists",
          "description": "components.json exists and is valid"
        }
      ],
      "then": [
        {
          "action": "call_service",
          "target": "registry.resolve_tree",
          "description": "Fetch component with all registry dependencies, CSS vars, fonts"
        },
        {
          "action": "call_service",
          "target": "updaters.update_files",
          "description": "Write component files to configured paths"
        },
        {
          "action": "call_service",
          "target": "updaters.update_dependencies",
          "description": "Install npm dependencies via package manager"
        },
        {
          "action": "call_service",
          "target": "updaters.update_css",
          "description": "Add CSS variables to global stylesheet"
        },
        {
          "action": "call_service",
          "target": "updaters.update_fonts",
          "description": "Register Google Fonts if component uses custom fonts"
        },
        {
          "action": "emit_event",
          "event": "cli.add.completed",
          "payload": [
            "component_name",
            "files_written",
            "dependencies_added"
          ]
        }
      ],
      "result": "Component and all its dependencies are installed in the project"
    },
    "add_from_url": {
      "priority": 6,
      "given": [
        "Developer provides a full URL instead of a component name",
        "URL points to a valid registry item"
      ],
      "then": [
        {
          "action": "call_service",
          "target": "registry.fetch_from_url",
          "description": "Fetch component directly from URL without namespace lookup"
        }
      ],
      "result": "Component installed from arbitrary URL source"
    },
    "add_from_custom_registry": {
      "priority": 7,
      "given": [
        "Component name includes registry namespace (e.g., @acme/button)",
        {
          "field": "registries",
          "source": "system",
          "operator": "exists",
          "description": "Registry namespace is configured in components.json"
        }
      ],
      "then": [
        {
          "action": "call_service",
          "target": "registry.build_url_with_headers",
          "description": "Resolve URL and auth headers from registry config"
        },
        {
          "action": "call_service",
          "target": "registry.fetch_with_auth",
          "description": "Fetch with authentication headers (env var substitution)"
        }
      ],
      "result": "Component installed from custom authenticated registry"
    },
    "add_missing_config": {
      "priority": 8,
      "error": "MISSING_CONFIG",
      "given": [
        "Developer runs 'shadcn add' without components.json"
      ],
      "then": [
        {
          "action": "notify",
          "channel": "cli",
          "target": "developer",
          "description": "Prompt to run 'shadcn init' first or interactively initialize"
        }
      ],
      "result": "Developer is guided to initialize project before adding components"
    },
    "search_registry": {
      "priority": 9,
      "given": [
        "Developer runs 'shadcn search --query <term>'"
      ],
      "then": [
        {
          "action": "call_service",
          "target": "registry.search",
          "description": "Fuzzy search across configured registries with pagination"
        }
      ],
      "result": "Matching components returned with name, type, description, and add command"
    },
    "migrate_icons": {
      "priority": 10,
      "given": [
        "Developer runs 'shadcn migrate icons'"
      ],
      "then": [
        {
          "action": "call_service",
          "target": "migration.scan_imports",
          "description": "Scan all UI component files for icon imports"
        },
        {
          "action": "call_service",
          "target": "migration.replace_imports",
          "description": "Replace old icon library imports with target library equivalents"
        }
      ],
      "result": "All icon imports across the project are migrated to the new library"
    },
    "migrate_radix": {
      "priority": 11,
      "given": [
        "Developer runs 'shadcn migrate radix'"
      ],
      "then": [
        {
          "action": "call_service",
          "target": "migration.update_radix_imports",
          "description": "Update component imports from Base UI to Radix primitives"
        }
      ],
      "result": "Components migrated from Base UI to Radix UI primitives"
    },
    "migrate_rtl": {
      "priority": 12,
      "given": [
        "Developer runs 'shadcn migrate rtl'"
      ],
      "then": [
        {
          "action": "call_service",
          "target": "migration.add_rtl_support",
          "description": "Update CSS, Tailwind config, and component code for RTL"
        }
      ],
      "result": "Project supports right-to-left languages"
    },
    "mcp_list_items": {
      "priority": 13,
      "given": [
        "MCP client calls list_items_in_registries tool"
      ],
      "then": [
        {
          "action": "call_service",
          "target": "registry.get_index",
          "description": "Fetch full registry index with pagination"
        }
      ],
      "result": "AI assistant receives component list for recommendation"
    },
    "mcp_search_items": {
      "priority": 14,
      "given": [
        "MCP client calls search_items_in_registries with a query"
      ],
      "then": [
        {
          "action": "call_service",
          "target": "registry.search",
          "description": "Fuzzy search with pagination"
        }
      ],
      "result": "AI assistant receives matching components"
    },
    "mcp_view_items": {
      "priority": 15,
      "given": [
        "MCP client calls view_items_in_registries with item names"
      ],
      "then": [
        {
          "action": "call_service",
          "target": "registry.resolve_items",
          "description": "Fetch full component details: files, dependencies, metadata"
        }
      ],
      "result": "AI assistant has complete component info including source code"
    },
    "mcp_get_add_command": {
      "priority": 16,
      "given": [
        "MCP client calls get_add_command_for_items"
      ],
      "then": [
        {
          "action": "call_service",
          "target": "mcp.format_command",
          "description": "Generate npx shadcn@latest add <items> command string"
        }
      ],
      "result": "AI assistant can suggest exact installation command to user"
    },
    "registry_not_found": {
      "priority": 17,
      "error": "REGISTRY_NOT_FOUND",
      "given": [
        "Requested component or registry returns HTTP 404"
      ],
      "then": [
        {
          "action": "notify",
          "channel": "cli",
          "target": "developer",
          "description": "Show error with suggestion to check component name or registry URL"
        }
      ],
      "result": "Developer sees clear error with resolution suggestion"
    },
    "registry_unauthorized": {
      "priority": 18,
      "error": "REGISTRY_UNAUTHORIZED",
      "given": [
        "Registry returns HTTP 401",
        "Auth headers missing or invalid"
      ],
      "then": [
        {
          "action": "notify",
          "channel": "cli",
          "target": "developer",
          "description": "Show error with suggestion to configure auth in components.json or set env vars"
        }
      ],
      "result": "Developer is guided to set up registry authentication"
    },
    "registry_missing_env_vars": {
      "priority": 19,
      "error": "REGISTRY_MISSING_ENV_VARS",
      "given": [
        "Registry config references environment variables that are not set"
      ],
      "then": [
        {
          "action": "notify",
          "channel": "cli",
          "target": "developer",
          "description": "List missing environment variable names"
        }
      ],
      "result": "Developer knows which env vars to configure"
    },
    "registry_parse_error": {
      "priority": 20,
      "error": "REGISTRY_PARSE_ERROR",
      "given": [
        "Registry response fails Zod schema validation"
      ],
      "then": [
        {
          "action": "notify",
          "channel": "cli",
          "target": "developer",
          "description": "Show validation errors with field details from Zod"
        }
      ],
      "result": "Registry maintainer can fix schema issues"
    }
  },
  "errors": [
    {
      "code": "MISSING_DIR_OR_EMPTY_PROJECT",
      "status": 404,
      "message": "No package.json found. Make sure you're in a valid project directory."
    },
    {
      "code": "MISSING_CONFIG",
      "status": 404,
      "message": "No components.json found. Run 'shadcn init' to set up your project."
    },
    {
      "code": "TAILWIND_NOT_CONFIGURED",
      "status": 422,
      "message": "Tailwind CSS is not configured in this project."
    },
    {
      "code": "IMPORT_ALIAS_MISSING",
      "status": 422,
      "message": "No import alias found in tsconfig.json. Configure path aliases before proceeding."
    },
    {
      "code": "UNSUPPORTED_FRAMEWORK",
      "status": 422,
      "message": "Could not detect a supported framework. Use --defaults for manual configuration."
    },
    {
      "code": "BUILD_MISSING_REGISTRY_FILE",
      "status": 404,
      "message": "registry.json not found. Create a registry file before building."
    },
    {
      "code": "REGISTRY_NOT_FOUND",
      "status": 404,
      "message": "The requested component or registry was not found."
    },
    {
      "code": "REGISTRY_UNAUTHORIZED",
      "status": 401,
      "message": "Authentication required. Configure registry credentials in components.json."
    },
    {
      "code": "REGISTRY_FORBIDDEN",
      "status": 403,
      "message": "Access denied. Check your registry permissions."
    },
    {
      "code": "REGISTRY_PARSE_ERROR",
      "status": 422,
      "message": "Invalid registry response. The component data does not match the expected schema."
    },
    {
      "code": "REGISTRY_MISSING_ENV_VARS",
      "status": 500,
      "message": "Required environment variables are not set for registry authentication."
    },
    {
      "code": "REGISTRY_FETCH_ERROR",
      "status": 500,
      "message": "Failed to fetch from registry. Check your network connection and registry URL."
    }
  ],
  "events": [
    {
      "name": "cli.init.completed",
      "description": "Project initialized with shadcn configuration",
      "payload": [
        "cwd",
        "style",
        "base_color",
        "framework",
        "template"
      ]
    },
    {
      "name": "cli.add.completed",
      "description": "Component(s) successfully installed",
      "payload": [
        "component_names",
        "files_written",
        "dependencies_added",
        "css_vars_added"
      ]
    },
    {
      "name": "cli.migrate.completed",
      "description": "Migration applied to project",
      "payload": [
        "migration_name",
        "files_modified"
      ]
    },
    {
      "name": "registry.fetch.success",
      "description": "Successfully fetched item from registry",
      "payload": [
        "registry_name",
        "item_name",
        "url"
      ]
    },
    {
      "name": "registry.fetch.error",
      "description": "Failed to fetch from registry",
      "payload": [
        "registry_name",
        "item_name",
        "error_code",
        "status_code"
      ]
    }
  ],
  "related": [
    {
      "feature": "shadcn-components",
      "type": "required",
      "reason": "The UI component library that this CLI distributes and installs"
    }
  ],
  "agi": {
    "goals": [
      {
        "id": "reliable_component_registry_cli",
        "description": "CLI tool for initializing projects, adding UI components from registries, managing migrations, and providing MCP server integration for AI assistants",
        "success_metrics": [
          {
            "metric": "success_rate",
            "target": ">= 99%",
            "measurement": "Successful operations divided by total attempts"
          },
          {
            "metric": "error_rate",
            "target": "< 1%",
            "measurement": "Failed operations divided by total attempts"
          }
        ],
        "constraints": []
      }
    ],
    "autonomy": {
      "level": "semi_autonomous",
      "human_checkpoints": [
        "before making irreversible changes"
      ],
      "escalation_triggers": [
        "error_rate > 5"
      ]
    },
    "safety": {
      "action_permissions": [
        {
          "action": "init_default_project",
          "permission": "autonomous"
        },
        {
          "action": "init_with_template",
          "permission": "autonomous"
        },
        {
          "action": "init_monorepo",
          "permission": "autonomous"
        },
        {
          "action": "init_unsupported_framework",
          "permission": "autonomous"
        },
        {
          "action": "add_single_component",
          "permission": "autonomous"
        },
        {
          "action": "add_from_url",
          "permission": "autonomous"
        },
        {
          "action": "add_from_custom_registry",
          "permission": "autonomous"
        },
        {
          "action": "add_missing_config",
          "permission": "autonomous"
        },
        {
          "action": "search_registry",
          "permission": "autonomous"
        },
        {
          "action": "migrate_icons",
          "permission": "autonomous"
        },
        {
          "action": "migrate_radix",
          "permission": "autonomous"
        },
        {
          "action": "migrate_rtl",
          "permission": "autonomous"
        },
        {
          "action": "mcp_list_items",
          "permission": "autonomous"
        },
        {
          "action": "mcp_search_items",
          "permission": "autonomous"
        },
        {
          "action": "mcp_view_items",
          "permission": "autonomous"
        },
        {
          "action": "mcp_get_add_command",
          "permission": "autonomous"
        },
        {
          "action": "registry_not_found",
          "permission": "autonomous"
        },
        {
          "action": "registry_unauthorized",
          "permission": "autonomous"
        },
        {
          "action": "registry_missing_env_vars",
          "permission": "autonomous"
        },
        {
          "action": "registry_parse_error",
          "permission": "autonomous"
        }
      ]
    },
    "tradeoffs": [
      {
        "prefer": "accessibility",
        "over": "aesthetics",
        "reason": "UI must be usable by all users including those with disabilities"
      }
    ],
    "coordination": {
      "protocol": "orchestrated",
      "consumes": [
        {
          "capability": "shadcn_components",
          "from": "shadcn-components",
          "fallback": "degrade"
        }
      ]
    }
  },
  "extensions": {
    "tech_stack": {
      "language": "TypeScript",
      "framework": "Commander.js (CLI)",
      "runtime": "Node.js",
      "validation": "Zod",
      "package_manager": "pnpm",
      "build": "Turborepo"
    },
    "mcp": {
      "tools": [
        "get_project_registries",
        "list_items_in_registries",
        "search_items_in_registries",
        "view_items_in_registries",
        "get_item_examples_from_registries",
        "get_add_command_for_items",
        "get_audit_checklist"
      ],
      "clients": [
        "claude",
        "cursor",
        "vscode",
        "codex",
        "opencode"
      ]
    },
    "supported_frameworks": [
      "next",
      "vite",
      "astro",
      "laravel",
      "react-router",
      "start"
    ]
  }
}