npm package: @proposeflow/react
Description: React utilities for ProposeFlow - server components and hooks for human-in-the-loop AI
Author: Quinton Miller
Latest version: 0.1.2

# @proposeflow/react

React utilities for ProposeFlow, optimized for React Server Components.

## Installation

```bash
npm install @proposeflow/react
# or
pnpm add @proposeflow/react
```

## Quick Start

```typescript
// lib/proposeflow.ts
import { createProposeFlow, z } from '@proposeflow/react/server';

export const pf = createProposeFlow({
  schemas: {
    recipe: z.object({
      title: z.string(),
      ingredients: z.array(z.string()),
      steps: z.array(z.string()),
    }),
    task: z.object({
      title: z.string(),
      dueDate: z.string(),
    }),
  },
  schemaSync: 'hash',           // Use content-based versioning
  autoRegisterSchemas: true,    // Auto-register on first generate()
});
```

```typescript
// app/recipes/page.tsx (Server Component)
import { pf } from '@/lib/proposeflow';

export default async function RecipesPage() {
  const { data: proposals } = await pf.listProposals();

  return (
    <ul>
      {proposals.map((p) => {
        if (p.schemaName === 'recipe') {
          // p.generatedObject is typed as Recipe
          return <li key={p.id}>{p.generatedObject.title}</li>;
        }
        return null;
      })}
    </ul>
  );
}
```

## API Reference

### `createProposeFlow(config)`

Create a typed ProposeFlow server instance with request deduplication.

```typescript
const pf = createProposeFlow({
  apiKey?: string;                    // Uses PROPOSEFLOW_API_KEY env var if not set
  baseUrl?: string;                   // Uses PROPOSEFLOW_API_URL or localhost:3001
  schemas: {
    [name: string]: ZodSchema;
  };
  schemaSync?: 'live' | 'hash';       // Schema resolution mode (default: 'live')
  autoRegisterSchemas?: boolean;      // Auto-register schemas (default: false)
});
```

#### Schema Sync Modes

- `'live'` (default): Uses schema pointers to resolve the current "live" version
- `'hash'`: Uses content-based hashing to lock to a specific schema version

With `autoRegisterSchemas: true`, schemas are automatically registered on the first
`generate()` call. This eliminates manual registration and keeps schemas in sync
with your code.

### Methods

```typescript
// Get a proposal (cached per request)
const proposal = await pf.getProposal(id);

// List proposals (cached per request)
const { data, nextCursor } = await pf.listProposals({
  status?: 'pending' | 'approved' | 'rejected' | 'regenerating';
  schemaId?: string;
  limit?: number;
  cursor?: string;
});

// Generate a new proposal (not cached)
const { proposal, generation } = await pf.generate('recipe', {
  input: 'A quick pasta dish',
  metadata: { userId: 'user_123' },
});

// Record a decision
const decision = await pf.decide(proposalId, {
  action: 'approve',
  edits: { servings: 4 },
});

// Regenerate with feedback
const { proposal } = await pf.regenerate(proposalId, 'Make it vegetarian');

// Register an event
await pf.registerEvent('user.action', {
  object: { schema: 'recipe', id: recipeId },
  metadata: { action: 'viewed' },
});
```

## Features

### Request Deduplication

Read operations (`getProposal`, `listProposals`) are automatically cached within a single request using React's `cache()`. Multiple components calling the same method with the same arguments will only make one API call.

### Server-Only

The `/server` export is marked with `server-only` and will cause a build error if imported in a Client Component. This ensures API keys are never exposed to the browser.

### Type Safety

When using Zod schemas, all proposal objects are fully typed:

```typescript
const { data } = await pf.listProposals();

for (const proposal of data) {
  if (proposal.schemaName === 'recipe') {
    // TypeScript knows this is a Recipe
    console.log(proposal.generatedObject.title);
  }
}
```

## Exports

```typescript
// Server utilities (use in Server Components only)
import { createProposeFlow, z } from '@proposeflow/react/server';

// Client utilities (coming soon)
import { ... } from '@proposeflow/react';
```

## Development

```bash
# Build
pnpm build

# Watch mode
pnpm dev

# Type check
pnpm typecheck
```