npm package: @nexstackchatbot/chat-widget
Description: Drop-in AI chat widget for React. Connect any backend to the Nana AI Gateway — your AI will call **your APIs** and talk to **your database**.
Author: NexStack
Latest version: 0.1.1

# @nexstackchatbot/chat-widget

Drop-in AI chat widget for React. Connect any backend to the Nana AI Gateway — your AI will call **your APIs** and talk to **your database**.

## Features

- 🚀 **One-line setup** — add `<ChatWidget />` and you're done
- 🤖 **AI-powered** — Nana AI Gateway turns natural language into API calls
- 🔌 **Auto-discovery** — `npx @nexstackchatbot/chat-widget init` scans your backend APIs
- 🎨 **Themeable** — full CSS variable customization
- 🎙️ **Voice input** — built-in speech-to-text
- 📎 **File upload** — drag & drop file attachments
- 🔒 **CSS isolation** — `nx-` prefixed classes, no conflicts with your app
- 📦 **Lightweight** — 29KB JS + 8KB CSS

---

## Quick Start

```bash
npm install @nexstackchatbot/chat-widget
```

```tsx
import { ChatWidget } from '@nexstackchatbot/chat-widget';
import '@nexstackchatbot/chat-widget/styles.css';

function App() {
  return (
    <ChatWidget
      gatewayUrl="https://nana-whatsapp.singaporetestlab.com"
      project={{
        id: "my_app",
        name: "My Assistant",
        description: "Helps users with tasks",
        persona: "You are a helpful assistant.",
        baseUrl: "https://my-api.com"
      }}
      tools={[
        {
          name: 'getProducts',
          description: 'Search products in the catalog',
          method: 'GET',
          path: '/api/products',
          parameters: [
            { name: 'query', type: 'string', required: false, description: 'Search term' }
          ]
        }
      ]}
      userId="user_123"
    />
  );
}
```

---

## CLI Auto-Discovery

Scan your backend project and generate tool definitions automatically:

```bash
npx @nexstackchatbot/chat-widget init
```

This will:
1. **Detect** your framework (Express, Hono, Strapi, Next.js, NestJS)
2. **Scan** all API routes in your project
3. **Generate** a `chat-widget.config.ts` file with all endpoints

### Options

```bash
# Auto-detect framework and scan
npx @nexstackchatbot/chat-widget init

# Use OpenAPI/Swagger spec
npx @nexstackchatbot/chat-widget init --openapi https://my-api.com/swagger.json

# Specify base URL and output path
npx @nexstackchatbot/chat-widget init --base-url https://my-api.com --output ./my-config.ts
```

### Using the Generated Config

```tsx
import config from './chat-widget.config';
import { ChatWidget } from '@nexstackchatbot/chat-widget';
import '@nexstackchatbot/chat-widget/styles.css';

<ChatWidget {...config} userId={currentUser.id} />
```

### Supported Frameworks

| Framework | Detection | What it scans |
|-----------|-----------|--------------|
| **Express / Hono** | `express` or `hono` in deps | `router.get/post/put/delete` patterns |
| **Strapi** | `@strapi/strapi` in deps | Content-type directories → CRUD |
| **Next.js** | `next` in deps | `app/api/**/route.ts` + exported methods |
| **NestJS** | `@nestjs/core` in deps | Falls back to regex + suggests `--openapi` |
| **Any** | `--openapi` flag | OpenAPI/Swagger JSON spec |

---

## Configuration

### ChatWidget Props

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `gatewayUrl` | `string` | ✅ | Nana AI Gateway URL |
| `project` | `ProjectConfig` | ✅ | Your project configuration |
| `tools` | `ToolDefinition[]` | ✅ | API endpoints the AI can call |
| `userId` | `string` | ✅ | Current user ID |
| `userName` | `string` | | User display name |
| `title` | `string` | | Chat header title |
| `subtitle` | `string` | | Chat header subtitle |
| `theme` | `ChatTheme` | | Theme customization |
| `position` | `'bottom-right' \| 'bottom-left'` | | Widget position |
| `showLauncher` | `boolean` | | Show floating button (default: true) |
| `isOpen` | `boolean` | | Control open state |
| `enableFileUpload` | `boolean` | | Enable file attachments |
| `enableVoiceInput` | `boolean` | | Enable speech-to-text |
| `welcomeMessage` | `string` | | Initial bot message |

### ProjectConfig

```typescript
{
  id: string;          // Unique ID (use underscores, no hyphens)
  name: string;        // Display name
  description: string; // What this project does
  persona?: string;    // AI personality/instructions
  baseUrl: string;     // Your API server URL
}
```

### ToolDefinition

```typescript
{
  name: string;           // e.g. "getProducts"
  description: string;    // Helps AI know when to use this tool
  method: 'GET' | 'POST' | 'PUT' | 'DELETE';
  path: string;           // e.g. "/api/products"
  parameters: [{
    name: string;
    type: 'string' | 'number' | 'boolean' | 'object' | 'array';
    required: boolean;
    description: string;
  }];
}
```

---

## Theming

```tsx
<ChatWidget
  theme={{
    colors: {
      primary: '#3b82f6',
      background: '#0f172a',
      surface: '#1e293b',
      text: '#f1f5f9',
      textSecondary: '#94a3b8',
      border: 'rgba(255, 255, 255, 0.1)',
    }
  }}
  // ...other props
/>
```

---

## Hooks

### useExternalChat

Use the chat logic without the built-in UI:

```tsx
import { useExternalChat } from '@nexstackchatbot/chat-widget';

const { messages, sendMessage, isLoading } = useExternalChat({
  gatewayUrl: 'https://nana-whatsapp.singaporetestlab.com',
  project: myProject,
  tools: myTools,
  userId: 'user_123',
});
```

---

## How It Works

```
User types: "Show me Nike shoes"
     ↓
ChatWidget → Nana AI Gateway (with your tools list)
     ↓
AI decides: "Call getProducts with query='Nike shoes'"
     ↓
Gateway → YOUR API: GET https://your-server.com/api/products?query=Nike+shoes
     ↓
YOUR database returns results
     ↓
AI formats response: "We have 3 Nike shoes available..."
     ↓
ChatWidget displays the response
```

Each installation is **completely independent** — different tools, different APIs, different databases.

---

## License

MIT © [NexStack](https://github.com/nexstacksg)