npm.io
0.5.0 • Published 6d ago

anyclaude-react

Licence
MIT
Version
0.5.0
Deps
1
Size
73 kB
Vulns
0
Weekly
0

anyclaude-react

Restylable React UI kit for anyclaude-sdk — hooks + components to build chatbots, AI agents, research assistants, and browser IDEs. Includes built-in serverless "survivor" stream-stitching (long runs span function time-limits transparently) and client-side tool execution (the server-side agent runs bash/file tools in the user's browser). Markdown via streamdown.

Live demo — a full IDE built with this kit, running in your browser.

npm install anyclaude-react anyclaude-sdk react

Quick start (browser / in-process)

Drive the agent in-process by wrapping the SDK's query() in a run function:

import { AgentChat } from 'anyclaude-react'
import 'anyclaude-react/styles.css'
import { query, createOpenAIClient, MemoryFileSystem, NoopCommandExecutor, composeWorkspace } from 'anyclaude-sdk'

const ws = composeWorkspace(new MemoryFileSystem(), new NoopCommandExecutor(), '/work')
const llm = createOpenAIClient({ baseUrl: '…', model: 'gpt-4o', apiKey: KEY })

export default function App() {
  return (
    <AgentChat
      run={({ prompt, sessionId, continueRun }) =>
        query({ prompt: continueRun ? '' : prompt, workspace: ws, llm, model: 'gpt-4o',
                sessionId, resume: continueRun, continueRun, includePartialMessages: true })}
    />
  )
}

Serverless (survivor)

Point at a function that streams NDJSON SDKMessages. When the function pauses at its time-limit ({type:'system',subtype:'paused'}), the client auto-continues in a new request with the same sessionId — invisibly:

<AgentChat endpoint="/api/agent" />

Your function runs query({ ..., maxDurationMs, sessionStore, sessionId, resume: continueRun, continueRun }) and writes each message as a JSON line.

Hook

const { messages, streamingText, status, tokens, cost, send, interrupt, clear } =
  useAgent({ run /* | endpoint | client */, sessionId })
  • status: 'idle' | 'running' | 'paused'
  • send(text) starts/continues; interrupt() aborts; clear() resets (new session).

Client-side tools (server brain, browser hands)

Run the agent on your server but execute its file/shell tools in the browser — against a WebContainer, an IndexedDB filesystem, OPFS, or memory. Pair query({ clientTools: WORKSPACE_TOOL_NAMES }) server-side with a turnkey executor map here. client_tool_requests are auto-executed and the results streamed back; it reuses the real SDK tool implementations, so behavior matches server-side exactly.

import { useAgent, createWebContainerClientTools, createWorkspaceClientTools } from 'anyclaude-react'
import { DexieFileSystem } from 'anyclaude-sdk/fs'

// real shell + files in a WebContainer:
useAgent({ endpoint: '/api/agent', clientTools: createWebContainerClientTools(wc) })

// or point the file tools at the user's own IndexedDB (no shell):
useAgent({ endpoint: '/api/agent', clientTools: createWorkspaceClientTools(new DexieFileSystem('my-db')) })

// fully overridable per tool:
createWorkspaceClientTools(workspace, { only: ['write_file','read_file'], extra: { bash: myBash } })

You can still hand-write a clientTools map ({ bash: async ({command}) => ({ content }) }) for full control.

Components

Chat

Component Purpose
<AgentChat> All-in-one: Transcript + Working + Composer wired to useAgent.
<ChatPanel> Like AgentChat with a header (status / tokens / cost).
<Transcript messages streamingText> Renders messages; pairs tool calls with results.
<Message> / <MarkdownMessage> Chat bubbles; markdown via streamdown (override via render).
<ToolCall> Collapsible tool call + result.
<Composer onSend> Textarea + send (Enter sends, Shift+Enter newline).
<Working active paused> Shimmering "Working…" indicator.

Lightweight UI (root, no heavy deps)

Component Purpose
<FileExplorer list onOpen> Collapsible file tree over any filesystem adapter.
<AskUser question onAnswer> Renders an ask_user_question prompt; pair with the SDK's onAskUser.

IDE — anyclaude-react/ide subpath (so the root barrel stays dependency-light)

import { Terminal, CodeEditor } from 'anyclaude-react/ide'
Component Purpose Peer dep
<Terminal spawn> xterm.js terminal bound to a streaming shell (e.g. a WebContainer process). @xterm/xterm + @xterm/addon-fit
<CodeEditor value onChange> Controlled CodeMirror 6 editor. codemirror + @codemirror/*

The root export (useAgent, chat components, FileExplorer, AskUser, the client/workspace helpers) pulls neither @xterm nor codemirror — install those only if you import from /ide.

Styling

Everything is class-based (.ac-*) with data-role attributes. Import the optional anyclaude-react/styles.css and override the CSS variables on .ac-chat (--ac-accent, --ac-bg, --ac-fg, …), or skip it and style with your own CSS / Tailwind. No emojis — icons are inline SVG.