adk-frontend

Guidelines for building frontend applications that integrate with Botpress ADK bots - covering authentication, type generation, client setup, and calling bot actions

16 stars

Best use case

adk-frontend is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Guidelines for building frontend applications that integrate with Botpress ADK bots - covering authentication, type generation, client setup, and calling bot actions

Teams using adk-frontend should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/adk-frontend/SKILL.md --create-dirs "https://raw.githubusercontent.com/diegosouzapw/awesome-omni-skill/main/skills/development/adk-frontend/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/adk-frontend/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How adk-frontend Compares

Feature / Agentadk-frontendStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Guidelines for building frontend applications that integrate with Botpress ADK bots - covering authentication, type generation, client setup, and calling bot actions

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# ADK Frontend Integration

Use this skill when users ask questions about building frontend applications that connect to Botpress ADK bots. This covers authentication patterns, type-safe API calls, client configuration, and integrating generated types.

## What is ADK Frontend Integration?

When you build a bot with the Botpress ADK, you often need a frontend application that interacts with it. This skill provides production-tested patterns for:

- **Authentication** - Cookie-based PAT storage with OAuth flow
- **Client Management** - Zustand store pattern for client caching and reuse
- **Type Generation** - Using ADK-generated types for full type safety
- **Action Calls** - Calling bot actions with proper error handling and optimistic updates

### Key Technologies

- **@botpress/client** - Official TypeScript client for Botpress API
- **Triple-slash references** - TypeScript pattern for importing generated types
- **React Query** - For mutations and cache management (optional but recommended)
- **Zustand** - For client state management

---

## When to Use This Skill

Activate this skill when users ask frontend-related questions like:

### Authentication Questions

- "How do I authenticate with Botpress from my frontend?"
- "What are Personal Access Tokens (PATs)?"
- "Should I use cookies or localStorage for tokens?"
- "How do I implement OAuth login flow?"
- "How do I protect routes based on authentication?"
- "How do I handle token expiration?"

### Client Setup Questions

- "How do I initialize the Botpress client?"
- "What's the best way to manage multiple client instances?"
- "Why use a client store?"
- "How do I create workspace-scoped vs bot-scoped clients?"
- "What's the difference between regular client and Zai client?"

### Type Generation Questions

- "How do I get types for my bot's actions?"
- "What are triple-slash references?"
- "How do I import generated types?"
- "Where are the .adk type files?"
- "How do I keep types in sync between bot and frontend?"
- "Why can't TypeScript find my action types?"

### Calling Actions Questions

- "How do I call a bot action from my frontend?"
- "What's the syntax for client.callAction()?"
- "How do I handle errors when calling actions?"
- "How do I implement optimistic updates?"
- "How do I chain multiple action calls?"
- "How do I use React Query with bot actions?"

---

## Available Documentation

Documentation files in `./references/`:

### Core Integration Patterns

- **authentication.md** - Complete authentication system with PATs, cookies, OAuth, route protection
- **botpress-client.md** - Client initialization, Zustand store pattern, Zai client setup
- **calling-actions.md** - Type-safe action calls, mutations, error handling, optimistic updates
- **type-generation.md** - Triple-slash references, generated types, maintaining type safety

---

## How to Answer Frontend Questions

Frontend questions typically fall into these categories:

### 1. Authentication Implementation

When users ask about authentication, reference the complete pattern from `authentication.md`:

**Key Concepts:**

- PAT generation in Botpress Cloud
- Cookie-based storage (not localStorage)
- AuthContext with React Context API
- OAuth callback flow via cli-login
- Route protection with TanStack Router
- Profile fetching from both Botpress API and bot tables

**Response Pattern:**

1. Explain the authentication strategy (cookies vs localStorage)
2. Show the AuthProvider implementation
3. Demonstrate the OAuth flow
4. Provide route protection examples
5. Highlight security best practices

### 2. Client Setup and Management

When users ask about client configuration, reference `botpress-client.md`:

**Key Concepts:**

- Client initialization with apiUrl, workspaceId, token, botId
- Zustand store for client caching
- Dynamic client keys for reuse
- Workspace-scoped vs bot-scoped clients
- Extended timeouts for Zai operations

**Response Pattern:**

1. Show the clientsStore.ts pattern
2. Explain how client caching works
3. Demonstrate getApiClient() usage
4. Show when to use workspace vs bot-scoped clients
5. Explain getZaiClient() for AI operations

### 3. Type Generation and Import

When users ask about types, reference `type-generation.md`:

**Key Concepts:**

- ADK generates types in `.adk/` directory during dev/build
- Triple-slash directives for referencing external types
- Generated files: action-types.d.ts, table-types.d.ts, workflow-types.d.ts
- Creating type aliases for cleaner code
- Keeping types in sync with adk dev

**Response Pattern:**

1. Explain how ADK generates types
2. Show triple-slash reference syntax
3. Demonstrate importing generated types
4. Provide examples of creating type aliases
5. Show how types stay in sync automatically

### 4. Calling Bot Actions

When users ask about calling actions, reference `calling-actions.md`:

**Key Concepts:**

- client.callAction() signature
- Type-safe input/output with BotActionDefinitions
- Service layer pattern for reusable action calls
- Using useMutation for loading states and error handling
- Optimistic updates for instant UI feedback
- Chaining actions (sequential vs parallel)

**Response Pattern:**

1. Show the basic callAction() syntax
2. Demonstrate type-safe service functions
3. Provide useMutation examples
4. Show error handling patterns
5. Explain optimistic updates when relevant

---

## Common Patterns Reference

### Authentication Flow

```typescript
// 1. Cookie helpers
function setCookie(name: string, value: string, days = 365);
function getCookie(name: string): string | null;
function deleteCookie(name: string);

// 2. AuthContext
interface AuthContextType {
  token: string | null;
  isAuthenticated: boolean;
  userProfile: UserProfile | null;
  isLoadingProfile: boolean;
  login: (token: string) => void;
  logout: () => void;
}

// 3. OAuth Flow
// Redirect: https://app.botpress.cloud/cli-login?redirect=...
// Callback: /auth/callback?pat=bp_pat_...
// Store PAT in cookie and navigate to app
```

### Client Store Pattern

```typescript
// stores/clientsStore.ts
const useClientsStore = create<ClientsState>()((set, get) => ({
  APIClients: {},
  getAPIClient: (props) => {
    const key = props?.botId
      ? `${props.workspaceId}-${props.botId}`
      : (props?.workspaceId ?? DEFAULT_API_CLIENT_KEY);

    const cached = get().APIClients[key];
    if (cached) return cached;

    const newClient = new APIClient({
      apiUrl: API_BASE_URL,
      workspaceId: props?.workspaceId,
      token: getPat() ?? "",
      botId: props?.botId,
    });

    set((state) => ({
      APIClients: { ...state.APIClients, [key]: newClient },
    }));

    return newClient;
  },
}));

export const getApiClient = (props?) =>
  useClientsStore.getState().getAPIClient(props);
```

### Type Import Pattern

```typescript
// types/index.ts
/// <reference path="../../../bot/.adk/action-types.d.ts" />
/// <reference path="../../../bot/.adk/table-types.d.ts" />

import type { BotActionDefinitions } from "@botpress/runtime/_types/actions";
import type { TableDefinitions } from "@botpress/runtime/_types/tables";

// Create type aliases
export type SendMessageAction = BotActionDefinitions["sendMessage"];
export type TicketTableRow = TableDefinitions["TicketsTable"]["Output"];
```

### Action Call Pattern

```typescript
// services/bot-service.ts
export async function sendMessage(input: SendMessageAction["input"]) {
  const client = getApiClient({ botId, workspaceId });
  const result = await client.callAction({
    type: "sendMessage",
    input,
  });
  return result.output as SendMessageAction["output"];
}

// Component usage with useMutation
const { mutate: send, isPending } = useMutation({
  mutationFn: sendMessage,
  onSuccess: () => {
    toast.success("Message sent");
    queryClient.invalidateQueries({ queryKey: ["messages"] });
  },
  onError: (error) => {
    toast.error("Failed to send message");
  },
});
```

---

## Examples of Questions This Skill Answers

### Beginner Questions

- "How do I connect my React app to a Botpress bot?"
- "What is a Personal Access Token?"
- "Where do I find my workspace ID and bot ID?"
- "How do I install @botpress/client?"

### Authentication Questions

- "How should I store authentication tokens?"
- "How do I implement login/logout?"
- "How do I protect authenticated routes?"
- "Should I use cookies or localStorage?"
- "How do I handle the OAuth callback?"

### Type Safety Questions

- "How do I get TypeScript types for my bot?"
- "What are triple-slash references?"
- "Why can't TypeScript find my action types?"
- "How do I keep types in sync?"
- "Where are the generated type files?"

### Implementation Questions

- "How do I call a bot action?"
- "How do I query bot tables from my frontend?"
- "How do I handle loading states?"
- "How do I implement optimistic updates?"
- "How do I chain multiple action calls?"

### Advanced Questions

- "How do I use Zai from my frontend?"
- "What's the difference between workspace and bot-scoped clients?"
- "How do I implement client caching?"
- "How do I handle token expiration?"
- "How do I implement retry logic?"

---

## Response Format

When answering:

1. **Start with a concise explanation** (1-2 paragraphs)
2. **Provide working code examples** from the references
3. **Include file references** (e.g., "From authentication.md:60-85")
4. **Highlight security considerations** when relevant
5. **Show common pitfalls** and how to avoid them
6. **Link to related topics** for deeper exploration

### Example Response Structure

```
Question: "How do I authenticate users in my frontend?"

Answer:
The recommended pattern uses cookie-based PAT storage with OAuth flow.
Here's the complete implementation:

1. Cookie Helpers (authentication.md:89-111)
   [code example]

2. AuthContext Setup (authentication.md:64-76)
   [code example]

3. OAuth Flow (authentication.md:473-533)
   [code example]

Key Security Considerations:
- Use SameSite=Lax for CSRF protection
- Always use HTTPS in production
- Never log PATs to console
- Implement token expiration handling

Related Topics:
- Route protection: authentication.md:369-467
- Profile fetching: authentication.md:304-347
- Client initialization: botpress-client.md:29-51
```

---

## Critical Patterns to Always Reference

When answering questions, always verify these patterns against the documentation:

### 1. Client Management

```typescript
// ✅ CORRECT - Use client store
const client = getApiClient({ workspaceId, botId });

// ❌ WRONG - Create new client every time
const client = new Client({ apiUrl, workspaceId, token, botId });
```

### 2. Type Imports

```typescript
// ✅ CORRECT - Triple-slash at top of file
/// <reference path="../../../bot/.adk/action-types.d.ts" />
import type { BotActionDefinitions } from "@botpress/runtime/_types/actions";

// ❌ WRONG - No triple-slash reference
import type { BotActionDefinitions } from "@botpress/runtime/_types/actions";
```

### 3. Action Calls

```typescript
// ✅ CORRECT - Service layer with types
export async function sendMessage(input: SendMessageAction["input"]) {
  const client = getApiClient({ botId, workspaceId });
  const result = await client.callAction({ type: "sendMessage", input });
  return result.output as SendMessageAction["output"];
}

// ❌ WRONG - Direct call in component
const result = await client.callAction({ type: "sendMessage", input: data });
```

### 4. Authentication Storage

```typescript
// ✅ CORRECT - Cookie with SameSite
document.cookie = `token=${value};expires=${expires};path=/;SameSite=Lax`;

// ❌ WRONG - localStorage without security
localStorage.setItem("token", value);
```

---

## Best Practices to Emphasize

When answering, always mention relevant best practices:

### Security

- Always use HTTPS in production
- Use cookies with SameSite protection
- Never log PATs or tokens
- Implement token expiration handling
- Use HttpOnly cookies when possible (SSR)

### Type Safety

- Always use generated types from ADK
- Create type aliases for cleaner code
- Use triple-slash references correctly
- Keep types in sync with adk dev
- Type all action inputs and outputs

### Performance

- Cache clients with Zustand store
- Use workspace-scoped clients when no bot operations needed
- Implement optimistic updates for better UX
- Use React Query for cache management
- Run independent actions in parallel

### Error Handling

- Always handle 401 (expired token) errors
- Provide user feedback on errors
- Implement retry logic for transient failures
- Log errors appropriately (never log tokens)
- Show loading states during async operations

### Code Organization

- Use service layer for action calls
- Centralize types in single file
- Keep authentication logic in context
- Separate client configuration from usage
- Reuse service functions across components

---

## Troubleshooting Common Issues

Be prepared to help with these common problems:

### "Cannot find module '@botpress/runtime/\_types/actions'"

- Check triple-slash reference path
- Verify .adk/ directory exists
- Restart TypeScript server
- Ensure adk dev/build has run

### "Types not updating after bot changes"

- Restart adk dev
- Delete .adk/ and rebuild
- Restart TypeScript server
- Check for bot compilation errors

### "Authentication fails after reload"

- Implement reload retry logic (authentication.md:191-220)
- Check cookie expiration
- Verify token is being retrieved correctly
- Check for CORS issues

### "Client timeout on long operations"

- Use getZaiClient() with extended timeout for AI operations
- Don't use regular client for Zai operations
- Consider breaking into smaller operations

## Summary

This skill covers the complete frontend integration story for Botpress ADK:

**Core Topics:**

1. Authentication with PATs and cookies
2. Client management with Zustand
3. Type generation and import with triple-slash references
4. Calling bot actions with full type safety

**When to Use:**

- Any frontend integration question
- Authentication and security patterns
- Type safety and generated types
- Client setup and configuration
- Action calls and error handling

**Key Principle:**
Always provide production-ready patterns that emphasize type safety, security, and maintainability.

Related Skills

agentic-jumpstart-frontend

16
from diegosouzapw/awesome-omni-skill

Frontend UI patterns with shadcn/ui, Radix UI, Tailwind CSS v4, and Lucide icons. Use when building UI components, styling, layouts, buttons, cards, dialogs, forms, responsive design, or when the user mentions UI, styling, Tailwind, components, or design.

project-frontend-design

16
from diegosouzapw/awesome-omni-skill

comprehensive design guide for the Meatballs project, combining high-quality frontend principles with the specific "Craft & Chao" design system. Use this skill for all frontend work in this project.

frontend-ui

16
from diegosouzapw/awesome-omni-skill

Create aesthetically pleasing, visually distinctive frontend UIs using research-backed prompting strategies from Anthropic's frontend aesthetics cookbook

frontend-styleguide

16
from diegosouzapw/awesome-omni-skill

Use when asked to create or edit style guides, design systems, component libraries, or update existing frontend components for web projects

frontend-style-layout

16
from diegosouzapw/awesome-omni-skill

Apply consistent styling and layout patterns with Tailwind v4. Use when building page layouts, choosing spacing methods, implementing responsive images, or migrating Tailwind v3 classes to v4. Covers Section Compound Pattern, spacing selection, CLS-free responsive images, and v4 class changes.

frontend-governance

16
from diegosouzapw/awesome-omni-skill

Enforces Contemplative design system and Anti-Slop protocols for all UI generation

frontend-design

16
from diegosouzapw/awesome-omni-skill

Create distinctive, bold UI designs that avoid generic AI aesthetics. This skill should be used when users want frontend components with strong visual identity, creative typography, intentional color palettes, and production-grade animations - specifically to avoid the bland, safe, homogeneous "AI slop" that plagues most generated interfaces.

bgo

10
from diegosouzapw/awesome-omni-skill

Automates the complete Blender build-go workflow, from building and packaging your extension/add-on to removing old versions, installing, enabling, and launching Blender for quick testing and iteration.

Coding & Development

analyze-rust-optimizations

16
from diegosouzapw/awesome-omni-skill

This skill performs thorough analysis of Rust libraries to find optimization opportunities. It should be used when reviewing Rust code for performance improvements, memory efficiency, or when profiling indicates bottlenecks. Focuses on runtime performance and memory usage through dynamic profiling tools and static code analysis.

analyze-project-architecture

16
from diegosouzapw/awesome-omni-skill

LLM-based architectural analysis that transforms raw project data into meaningful structure

analyze-pr-performance

16
from diegosouzapw/awesome-omni-skill

Analyze code review pipeline performance for a specific PR. Use when investigating slow PRs, identifying bottlenecks, or debugging performance issues in code reviews.

analyze

16
from diegosouzapw/awesome-omni-skill

Deep analysis and investigation