npm package: @fronx/use-claude-code
Description: Library for integrating Claude Code CLI into applications
Latest version: 0.1.3

# @fronx/use-claude-code

A reusable library for integrating Claude Code CLI conversations into applications.

## Features

- **Server-side**: Spawn and manage Claude CLI processes, handle conversation lifecycle, stream responses via SSE
- **Client-side**: Parse SSE streams, manage connection state, handle reconnection with exponential backoff
- **React**: `useClaudeConversation` hook for easy integration

## Installation

```bash
npm install @fronx/use-claude-code
```

## Publishing

```bash
# 1. Make changes, then build
npm run build

# 2. Bump version in package.json (patch/minor/major)
npm version patch

# 3. Publish (requires npm login as fronx + fingerprint 2FA)
npm publish --access public
```

## Usage

### Server (Node.js)

```typescript
import { ClaudeManager } from '@fronx/use-claude-code/server';

const manager = new ClaudeManager({
  sessionDir: './data/sessions',
});

// Start a conversation
const conversation = manager.start('user-123', {
  systemPrompt: 'You are a helpful assistant.',
  cwd: process.cwd(),
  initialMessage: 'Hello!',
});

// Subscribe to SSE events
conversation.subscribe(res);

// Send additional messages
conversation.send('How does this work?');

// Stop generation (SIGINT)
conversation.stop();

// Clear conversation
manager.clear('user-123');
```

### Client (Browser)

```typescript
import { ClaudeConnection } from '@fronx/use-claude-code/client';

const connection = new ClaudeConnection({
  baseUrl: '/api/claude',
  conversationId: 'user-123',
});

connection.on('stateChange', () => {
  console.log('Messages:', connection.messages);
  console.log('Streaming:', connection.streamingSegments);
});

connection.on('result', () => {
  console.log('Response complete');
});

// Check status and connect
await connection.connect();

// Start a new conversation
await connection.start('Hello!');

// Send a message
await connection.send('How does this work?');

// Stop generation
await connection.stop();

// Clear session
await connection.clear();
```

### React

```tsx
import { useClaudeConversation } from '@fronx/use-claude-code/react';

function Chat({ projectId }) {
  const {
    messages,
    status,
    isStreaming,
    streamingSegments,
    hasPersistedSession,
    start,
    send,
    stop,
    clear,
    resume,
  } = useClaudeConversation({
    baseUrl: '/api/claude',
    conversationId: projectId,
    onResult: () => console.log('Response complete'),
  });

  return (
    <div>
      {/* Completed messages */}
      {messages.map(msg => (
        <div key={msg.id} className={msg.role}>
          {msg.content}
        </div>
      ))}

      {/* Streaming content */}
      {streamingSegments.map((seg, i) =>
        seg.type === 'text' ? (
          <div key={i}>{seg.content}</div>
        ) : (
          <div key={i}>Running: {seg.name} {seg.param}</div>
        )
      )}

      {/* Resume link for persisted sessions */}
      {status === 'disconnected' && hasPersistedSession && (
        <button onClick={resume}>Resume Previous Session</button>
      )}

      {/* Controls */}
      <input type="text" id="message" />
      <button onClick={() => send(document.getElementById('message').value)}>
        Send
      </button>
      {isStreaming && <button onClick={stop}>Stop</button>}
    </div>
  );
}
```

## API Reference

### Server

#### `ClaudeManager`

Main class for managing Claude conversations.

```typescript
interface ClaudeManagerConfig {
  sessionDir: string;           // Where to persist sessions
  claudePath?: string;          // Path to claude CLI (default: 'claude')
  defaultAllowedTools?: string[]; // Default tools to allow
  autoPrewarm?: boolean;        // Auto-prewarm after clear (default: false)
}

interface StartOptions {
  systemPrompt: string | { file: string };
  cwd: string;
  allowedTools?: string[];
  initialMessage?: string;
}
```

Methods:
- `start(id, options)` - Start a new conversation
- `get(id)` - Get an active conversation
- `resume(id, options)` - Resume from persisted session
- `stop(id)` - Stop current response (SIGINT)
- `clear(id)` - Kill process and delete session
- `prewarm(id, options)` - Spawn without sending message
- `getStatus(id)` - Get conversation status
- `hasPersistedSession(id)` - Check for saved session

### Client

#### `ClaudeConnection`

Event-emitter based connection manager.

```typescript
interface ClaudeConnectionConfig {
  baseUrl: string;
  conversationId: string;
  reconnect?: {
    maxRetries?: number;    // Default: 10
    baseDelay?: number;     // Default: 1000ms
    maxDelay?: number;      // Default: 30000ms
  };
}
```

Properties (read-only):
- `status` - 'checking' | 'disconnected' | 'connecting' | 'connected' | 'reconnecting'
- `messages` - Array of completed messages
- `isStreaming` - Whether currently streaming
- `streamingSegments` - Current streaming content (text and tools)
- `hasPersistedSession` - Whether a saved session exists
- `lastError` - Most recent error

Methods:
- `connect()` - Check status and connect
- `disconnect()` - Close connection
- `start(message?)` - Start new conversation
- `send(message)` - Send message
- `stop()` - Stop generation
- `clear()` - Clear session
- `resume()` - Resume saved session
- `prewarm()` - Prewarm for faster response

Events:
- `stateChange` - Any state property changed
- `message` - New message added
- `streaming` - Streaming segments updated
- `tool` - Tool invocation
- `result` - Response complete
- `error` - Error occurred

### React

#### `useClaudeConversation`

```typescript
interface UseClaudeConversationOptions {
  baseUrl: string;
  conversationId: string;
  autoConnect?: boolean;    // Default: true
  reconnect?: ReconnectConfig;
  onResult?: () => void;    // Called when response completes
}
```

Returns all ClaudeConnection properties and methods as React state.

## HTTP API

The package expects these server endpoints:

| Endpoint       | Method | Purpose                   |
| -------------- | ------ | ------------------------- |
| `/:id/status`  | GET    | Check conversation status |
| `/:id/start`   | POST   | Start new conversation    |
| `/:id/connect` | GET    | SSE stream for updates    |
| `/:id/message` | POST   | Send message              |
| `/:id/stop`    | POST   | Stop generation           |
| `/:id/clear`   | POST   | Clear session             |
| `/:id/resume`  | POST   | Resume saved session      |
| `/:id/prewarm` | POST   | Prewarm conversation      |

## Architecture

### Streaming

When Claude runs tools, the streaming behavior differs from simple responses:

1. `assistant` events stream the **full** response content
2. `result` events may only contain the **final** portion after tool execution

The state machine accumulates streaming content correctly. Always use `streamingSegments` for display, not just the `result` event.

### Session Persistence

Sessions are saved to disk after each message, enabling:
- Resume after page reload
- Resume after server restart
- Multi-device continuation

### Prewarming

Call `prewarm()` before the user is likely to start a conversation. This spawns Claude without sending a message, making the first response faster.

## License

MIT