aural-ui 2.1.21 β†’ 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,11 +6,11 @@
6
6
  [![npm downloads](https://img.shields.io/npm/dm/aural-ui.svg)](https://www.npmjs.com/package/aural-ui)
7
7
  [![bundle size](https://img.shields.io/bundlephobia/minzip/aural-ui)](https://bundlephobia.com/package/aural-ui)
8
8
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
- [![Storybook](https://img.shields.io/badge/Storybook-FF4785?style=flat&logo=storybook&logoColor=white)](https://aural-ui.netlify.app)
9
+ [![Storybook](https://img.shields.io/badge/Storybook-FF4785?style=flat&logo=storybook&logoColor=white)](https://aural-ui.pocketfm.com/)
10
10
 
11
11
  A modern CLI toolkit for seamlessly integrating customizable UI components into React projects. Quickly scaffold, add, and manage production-ready components with minimal configuration.
12
12
 
13
- [πŸ“š Documentation](https://aural-ui.netlify.app) β€’ [🎨 Storybook](https://aural-ui.netlify.app) β€’ [πŸ“¦ NPM](https://www.npmjs.com/package/aural-ui) β€’ [πŸ› Issues](https://github.com/Pocket-Fm/fm-ui/issues)
13
+ [πŸ“š Documentation](https://aural-ui.pocketfm.com/) β€’ [🎨 Storybook](https://aural-ui.pocketfm.com/) β€’ [πŸ“¦ NPM](https://www.npmjs.com/package/aural-ui) β€’ [πŸ› Issues](https://github.com/Pocket-Fm/aural-ui/issues)
14
14
 
15
15
  </div>
16
16
 
@@ -104,11 +104,62 @@ aural-ui update
104
104
  | Command | Description | Example |
105
105
  |---------|-------------|---------|
106
106
  | `init` | Initialize aural-ui in your project | `aural-ui init` |
107
+ | `init --yes` | Non-interactive init with defaults | `aural-ui init --yes` |
107
108
  | `add <components>` | Add one or more components | `aural-ui add button card` |
108
109
  | `remove <components>` | Remove components from project | `aural-ui remove button` |
109
110
  | `update [components]` | Update components to latest version | `aural-ui update` |
110
111
  | `theme` | Configure theme and design tokens | `aural-ui theme` |
111
112
 
113
+ ## πŸ”Œ MCP (Cursor / AI assistant)
114
+
115
+ The **aural-ui MCP server** exposes the design system by reading from aural-ui source (components, icons, source and story files). No Storybook process is required.
116
+
117
+ ### Setup in Cursor
118
+
119
+ Add **aural-ui** in `.cursor/mcp.json` (or Cursor Settings β†’ MCP). Start the MCP server first (e.g. `npx tsx mcp/src/index.ts` from the aural-ui repo root, or run the Docker image), then point Cursor at the streamable HTTP endpoint:
120
+
121
+ ```json
122
+ {
123
+ "mcpServers": {
124
+ "aural-ui-mcp": {
125
+ "type": "streamableHttp",
126
+ "url": "http://localhost:3000/mcp"
127
+ }
128
+ }
129
+ }
130
+ ```
131
+
132
+ Use the same URL when the server runs in Docker or elsewhere (e.g. `http://your-host:3000/mcp`).
133
+
134
+ - **Config:** All MCP server settings are in `mcp/src/lib/env.ts` (no .env). You can set `AURAL_UI_SRC` there to the aural-ui repo `src` path if the workspace is not the aural-ui repo.
135
+
136
+ **HTTP / Docker:** When running the MCP server over HTTP (e.g. in Docker):
137
+ - **GET /health** β€” Returns `200` and `{ "ok": true, "server": "aural-ui" }` for load balancers and orchestrators (no MCP session required).
138
+ - **GET /metrics** β€” Returns Prometheus-format metrics: `mcp_sessions_active`, `mcp_sessions_max`, `mcp_tool_calls_total{tool="..."}` (no MCP session required).
139
+ - **Settings** (in `mcp/src/lib/env.ts`): `PORT` (default `3000`), `MCP_MAX_SESSIONS` (default `100`; 0 = unlimited), `MCP_SESSION_IDLE_TIMEOUT_MS` (default 15 min), `MCP_ALLOWED_PROJECT_ROOTS`, `MCP_LIST_CACHE_TTL_MS` (list cache TTL).
140
+
141
+ To have Cursor install Aural UI components in your project (instead of writing code manually), ask it to use **`add_aural_components`** with the component names (e.g. `["button", "card", "dialog"]`). The tool will run `npx aural-ui init --yes` if needed, then `npx aural-ui add ...`.
142
+
143
+ ### MCP tools
144
+
145
+ | Tool | Description |
146
+ |------|-------------|
147
+ | `add_aural_components` | **Runs the CLI:** init if needed, then `npx aural-ui add <components>`. Only use component names that exist; if the user's request is unclear or doesn't match, call `list_components` first and show available namesβ€”do not guess and add a different component. |
148
+ | `init_aural_ui` | **Runs the CLI:** runs `npx aural-ui init --yes` in the workspace. Use when the project has no aural-ui.json yet. |
149
+ | `get_aural_ui_status` | Where aural-ui source is resolved (env, repo, node_modules). |
150
+ | `get_aural_ui_version` | Returns the aural-ui design system version from the resolved source (package.json). |
151
+ | `list_components` / `list_icons` / `list_hooks` | **Call first when unsure:** returns available component, icon, or hook names. Use when the user asks for a component/hook that might not exist so you can show the list instead of guessing. |
152
+ | `get_component_source` / `get_component_story` / `get_component_docs` | Component source and story file content (read from repo). `get_component_docs` includes metadata (tokens, internal deps) when available. |
153
+ | `get_component_meta` | Component metadata: dependencies, internalDependencies, and design tokens. |
154
+ | `get_icon_source` | Icon component source. |
155
+ | `get_theme_source` | Theme CSS (design tokens) from aural-theme.css. Use for correct token names when implementing UI. |
156
+ | `get_hook_source` | Hook source code. Use list_hooks for available hook names. |
157
+ | `search_components` | Search components, icons, and hooks by name (substring). Use when the user describes something vaguely (e.g. "dropdown"). |
158
+
159
+ **Prompts:** The server exposes guided-flow prompts: "Add aural-ui components" and "Implement UI from Figma". **When the user pastes a Figma link, frame, or URL,** use "Implement UI from Figma" (or the aural-ui MCP tools): get design via Figma MCP, add missing components with `ensure_aural_components`, then build the UI with aural-ui only. In Cursor you can invoke these via the prompts UI for step-by-step instructions.
160
+
161
+ Design system docs and Storybook: [aural-ui.pocketfm.com](https://aural-ui.pocketfm.com/) (built on **Radix UI**).
162
+
112
163
  ## 🧩 Available Components
113
164
 
114
165
  ### Layout & Structure
@@ -181,7 +232,7 @@ aural-ui theme
181
232
 
182
233
  ## πŸ“– Storybook
183
234
 
184
- Interactive component documentation is available at: **[https://aural-ui.netlify.app](https://aural-ui.netlify.app)**
235
+ Interactive component documentation is available at: **[https://aural-ui.pocketfm.com/](https://aural-ui.pocketfm.com/)**
185
236
 
186
237
  ### Local Development
187
238
  ```bash
@@ -228,8 +279,22 @@ aural-ui/
228
279
  β”‚ β”‚ β”œβ”€β”€ πŸ“ icons/ # Icon components
229
280
  β”‚ β”‚ └── πŸ“ fonts/ # Font assets
230
281
  β”‚ └── πŸ“ stories/ # Storybook stories
282
+ β”œβ”€β”€ πŸ“ mcp/ # MCP server (Cursor / HTTP)
283
+ β”‚ β”œβ”€β”€ πŸ“ docs/ # MCP docs (guidelines, figma-workflow, etc.)
284
+ β”‚ └── πŸ“ src/
285
+ β”‚ β”œβ”€β”€ πŸ“ lib/ # env, logger, constants
286
+ β”‚ β”œβ”€β”€ πŸ“ transport/ # HTTP transport (sessions, /mcp, /health, /metrics)
287
+ β”‚ β”œβ”€β”€ πŸ“ tools/ # MCP tool handlers
288
+ β”‚ β”œβ”€β”€ πŸ“ resources/ # MCP resource providers
289
+ β”‚ β”œβ”€β”€ πŸ“ prompts/ # MCP prompts
290
+ β”‚ β”œβ”€β”€ design-system.ts # Resolve aural-ui source, list/get components
291
+ β”‚ β”œβ”€β”€ consumer-project.ts # Consumer detection, get_consumer_setup
292
+ β”‚ └── index.ts # Entry (runHttp)
293
+ β”œβ”€β”€ πŸ“ .storybook/ # Storybook config and manager
231
294
  β”œβ”€β”€ πŸ“ aural-ui-example/ # Example implementation
232
- β”œβ”€β”€ πŸ“ storybook-static/ # Built Storybook output
295
+ β”œβ”€β”€ πŸ“ .github/ # CI/CD (e.g. deploy-storybook)
296
+ β”œβ”€β”€ πŸ“„ Dockerfile # Build MCP HTTP server image (port 3000)
297
+ β”œβ”€β”€ πŸ“„ .dockerignore # Docker build exclusions
233
298
  β”œβ”€β”€ πŸ“„ package.json # Package configuration
234
299
  β”œβ”€β”€ πŸ“„ tsconfig.json # TypeScript configuration
235
300
  β”œβ”€β”€ πŸ“„ vite.config.mts # Vite configuration
@@ -243,7 +308,7 @@ The component documentation is automatically deployed to Netlify:
243
308
 
244
309
  1. **Build**: `npm run build-storybook`
245
310
  2. **Deploy**: `npm run deploy-storybook`
246
- 3. **Live URL**: [https://aural-ui.netlify.app](https://aural-ui.netlify.app)
311
+ 3. **Live URL**: [https://aural-ui.pocketfm.com/](https://aural-ui.pocketfm.com/)
247
312
 
248
313
  ### NPM Package
249
314
  ```bash
@@ -283,7 +348,7 @@ We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) f
283
348
  ### Development Setup
284
349
  ```bash
285
350
  # Clone the repository
286
- git clone https://github.com/Pocket-Fm/fm-ui.git
351
+ git clone https://github.com/Pocket-Fm/aural-ui.git
287
352
  cd aural-ui
288
353
 
289
354
  # Install dependencies
@@ -126,7 +126,7 @@ const DrawerContent = React.forwardRef<
126
126
  "data-[vaul-drawer-direction=top]:inset-x-0 data-[vaul-drawer-direction=top]:top-0 data-[vaul-drawer-direction=top]:mb-24 data-[vaul-drawer-direction=top]:max-h-[80vh] data-[vaul-drawer-direction=top]:rounded-b-lg",
127
127
  "data-[vaul-drawer-direction=bottom]:inset-x-0 data-[vaul-drawer-direction=bottom]:bottom-0 data-[vaul-drawer-direction=bottom]:mt-24 data-[vaul-drawer-direction=bottom]:max-h-[80vh] data-[vaul-drawer-direction=bottom]:rounded-t-lg",
128
128
  "data-[vaul-drawer-direction=right]:inset-y-0 data-[vaul-drawer-direction=right]:right-0 data-[vaul-drawer-direction=right]:w-3/4 data-[vaul-drawer-direction=right]:rounded-l-lg data-[vaul-drawer-direction=right]:sm:max-w-sm",
129
- "overflow-auto [scrollbar-width:none] data-[vaul-drawer-direction=left]:inset-y-0 data-[vaul-drawer-direction=left]:left-0 data-[vaul-drawer-direction=left]:w-3/4 data-[vaul-drawer-direction=left]:rounded-r-lg data-[vaul-drawer-direction=left]:sm:max-w-sm",
129
+ "overflow-hidden data-[vaul-drawer-direction=left]:inset-y-0 data-[vaul-drawer-direction=left]:left-0 data-[vaul-drawer-direction=left]:w-3/4 data-[vaul-drawer-direction=left]:rounded-r-lg data-[vaul-drawer-direction=left]:sm:max-w-sm",
130
130
  className,
131
131
  classes?.content
132
132
  )}
@@ -135,7 +135,9 @@ const DrawerContent = React.forwardRef<
135
135
  {showSwipeButton && (
136
136
  <div className="bg-fm-surface-primary mx-auto mt-4 hidden h-2 w-[100px] shrink-0 rounded-full group-data-[vaul-drawer-direction=bottom]/drawer-content:block" />
137
137
  )}
138
- {children}
138
+ <div className="scrollbar-hide flex min-h-0 flex-1 flex-col overflow-auto">
139
+ {children}
140
+ </div>
139
141
  </DrawerPrimitive.Content>
140
142
  </DrawerPortal>
141
143
  )
@@ -5,6 +5,7 @@ import React, {
5
5
  RefAttributes,
6
6
  useCallback,
7
7
  useEffect,
8
+ useId,
8
9
  useRef,
9
10
  useState,
10
11
  } from "react"
@@ -30,7 +31,7 @@ interface TextAreaBaseProps {
30
31
  onChange?: (e: React.ChangeEvent<HTMLTextAreaElement>) => void
31
32
  onBlur?: (e: React.FocusEvent<HTMLTextAreaElement>) => void
32
33
  onFocus?: (e: React.FocusEvent<HTMLTextAreaElement>) => void
33
- onInput?: (e: React.FocusEvent<HTMLTextAreaElement>) => void
34
+ onInput?: (e: React.InputEvent<HTMLTextAreaElement>) => void
34
35
  onKeyDown?: (e: React.KeyboardEvent<HTMLTextAreaElement>) => void
35
36
  id?: string
36
37
  name?: string
@@ -361,8 +362,8 @@ const TextArea = forwardRef<HTMLTextAreaElement, TextAreaProps>(
361
362
  const [textareaValue, setTextareaValue] = useState(value || "")
362
363
 
363
364
  // Generate unique IDs for accessibility
364
- const textareaId =
365
- id || `textarea-${Math.random().toString(36).substr(2, 9)}`
365
+ const reactId = useId()
366
+ const textareaId = id || `textarea-${reactId}`
366
367
  const helperTextId = helperText ? `${textareaId}-helper` : undefined
367
368
  const charCountId = showCharCount ? `${textareaId}-char-count` : undefined
368
369
 
@@ -410,7 +411,7 @@ const TextArea = forwardRef<HTMLTextAreaElement, TextAreaProps>(
410
411
  currentLength={currentLength}
411
412
  maxLength={maxLength}
412
413
  id={charCountId}
413
- className={cn("ml-auto", classes?.charCount)}
414
+ className="ml-auto"
414
415
  />
415
416
  )}
416
417
  </div>