Add v0 prompt for frontend generation
This commit is contained in:
parent
f9b873d331
commit
ab52debf8b
1 changed files with 322 additions and 0 deletions
322
v0-prompt.md
Normal file
322
v0-prompt.md
Normal file
|
|
@ -0,0 +1,322 @@
|
||||||
|
# BloxServer Frontend — v0 Prompt
|
||||||
|
|
||||||
|
Build a Next.js 14+ frontend for BloxServer, a visual AI agent workflow builder. The UI paradigm is like **Excel meets n8n** — toolbar at top, tabs at bottom, flow canvas in the middle.
|
||||||
|
|
||||||
|
## Tech Stack
|
||||||
|
- **Framework:** Next.js 14 (App Router)
|
||||||
|
- **Components:** shadcn/ui + Tailwind CSS
|
||||||
|
- **Flow Canvas:** React Flow (@xyflow/react)
|
||||||
|
- **Code Editor:** Monaco Editor (for YAML and WASM/AssemblyScript)
|
||||||
|
- **State:** Zustand
|
||||||
|
- **Auth:** Clerk
|
||||||
|
- **API:** REST (see types below)
|
||||||
|
|
||||||
|
## Pages
|
||||||
|
|
||||||
|
| Route | Purpose |
|
||||||
|
|-------|---------|
|
||||||
|
| `/` | Landing page (marketing) |
|
||||||
|
| `/dashboard` | Flow list, usage stats, quick actions |
|
||||||
|
| `/flow/[id]` | Main flow editor (canvas + YAML tabs) |
|
||||||
|
| `/flow/[id]/runs` | Execution history for a flow |
|
||||||
|
| `/marketplace` | Browse/install tools and flow templates |
|
||||||
|
| `/settings` | Account, billing, API keys |
|
||||||
|
|
||||||
|
## Flow Editor Layout
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────────┐
|
||||||
|
│ TOOLBAR: [Save] [Run ▶] [Stop ■] [Canvas|YAML|Split] │
|
||||||
|
├─────────────────────────────────────────────────────────────────┤
|
||||||
|
│ ┌─────────┐ │
|
||||||
|
│ │ PALETTE │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
|
||||||
|
│ │ │ │ Webhook │ ───▶ │ LLM │ ───▶ │ Output │ │
|
||||||
|
│ │[Triggers] │ Trigger │ │ Agent │ │ │ │
|
||||||
|
│ │[LLM] │ └─────────┘ └─────────┘ └─────────┘ │
|
||||||
|
│ │[HTTP] │ │
|
||||||
|
│ │[Code] │ Drag nodes from palette onto canvas. │
|
||||||
|
│ │[Branch] │ Connect outputs to inputs. │
|
||||||
|
│ │[Output] │ Canvas auto-saves. │
|
||||||
|
│ │ │ │
|
||||||
|
│ │[Market] │ YAML tab shows generated config. │
|
||||||
|
│ │ ↳ search│ Edits in YAML reflect back on canvas. │
|
||||||
|
│ └─────────┘ │
|
||||||
|
├─────────────────────────────────────────────────────────────────┤
|
||||||
|
│ STATUS BAR: Nodes: 3 │ Status: Saved │ Last run: 2m ago │
|
||||||
|
└─────────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
## Node Types
|
||||||
|
|
||||||
|
| Type | Icon | Purpose |
|
||||||
|
|------|------|---------|
|
||||||
|
| `trigger` | 🎯 | Entry point (webhook, schedule, manual) |
|
||||||
|
| `llmCall` | 🤖 | LLM agent (Claude, GPT, Grok) |
|
||||||
|
| `httpRequest` | 🌐 | External API call |
|
||||||
|
| `codeBlock` | 📝 | Custom WASM code (Pro) |
|
||||||
|
| `conditional` | 🔀 | Branch based on condition |
|
||||||
|
| `output` | 📤 | Terminal node / response |
|
||||||
|
|
||||||
|
## Dashboard Features
|
||||||
|
- List of user's flows (cards or table)
|
||||||
|
- Flow status indicator (stopped/running/error)
|
||||||
|
- Quick actions: New Flow, Import, Run
|
||||||
|
- Usage stats (executions this month, limit)
|
||||||
|
|
||||||
|
## Key UX Patterns
|
||||||
|
1. **Bidirectional sync:** Canvas changes update YAML, YAML changes update canvas
|
||||||
|
2. **Auto-save:** Changes saved automatically (debounced)
|
||||||
|
3. **Run/Stop:** Single click to deploy/undeploy a flow
|
||||||
|
4. **Execution history:** Click a run to see logs, input/output payloads
|
||||||
|
5. **Node inspector:** Click a node to edit its config in a side panel
|
||||||
|
|
||||||
|
## API Base URL
|
||||||
|
`https://api.openblox.ai/v1` (placeholder — backend on Render)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## TypeScript API Types
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Common
|
||||||
|
export type UUID = string;
|
||||||
|
export type ISODateTime = string;
|
||||||
|
|
||||||
|
// User (synced from Clerk)
|
||||||
|
export interface User {
|
||||||
|
id: UUID;
|
||||||
|
clerkId: string;
|
||||||
|
email: string;
|
||||||
|
name: string | null;
|
||||||
|
avatarUrl: string | null;
|
||||||
|
tier: 'free' | 'paid' | 'pro' | 'enterprise';
|
||||||
|
createdAt: ISODateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flow
|
||||||
|
export type FlowStatus = 'stopped' | 'starting' | 'running' | 'stopping' | 'error';
|
||||||
|
|
||||||
|
export interface Flow {
|
||||||
|
id: UUID;
|
||||||
|
userId: UUID;
|
||||||
|
name: string;
|
||||||
|
description: string | null;
|
||||||
|
organismYaml: string;
|
||||||
|
canvasState: CanvasState | null;
|
||||||
|
status: FlowStatus;
|
||||||
|
containerId: string | null;
|
||||||
|
errorMessage: string | null;
|
||||||
|
createdAt: ISODateTime;
|
||||||
|
updatedAt: ISODateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FlowSummary {
|
||||||
|
id: UUID;
|
||||||
|
name: string;
|
||||||
|
description: string | null;
|
||||||
|
status: FlowStatus;
|
||||||
|
updatedAt: ISODateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CreateFlowRequest {
|
||||||
|
name: string;
|
||||||
|
description?: string;
|
||||||
|
organismYaml?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UpdateFlowRequest {
|
||||||
|
name?: string;
|
||||||
|
description?: string;
|
||||||
|
organismYaml?: string;
|
||||||
|
canvasState?: CanvasState;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Canvas State (React Flow)
|
||||||
|
export interface CanvasState {
|
||||||
|
nodes: CanvasNode[];
|
||||||
|
edges: CanvasEdge[];
|
||||||
|
viewport: { x: number; y: number; zoom: number };
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CanvasNode {
|
||||||
|
id: string;
|
||||||
|
type: NodeType;
|
||||||
|
position: { x: number; y: number };
|
||||||
|
data: NodeData;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type NodeType =
|
||||||
|
| 'trigger'
|
||||||
|
| 'llmCall'
|
||||||
|
| 'httpRequest'
|
||||||
|
| 'codeBlock'
|
||||||
|
| 'conditional'
|
||||||
|
| 'output'
|
||||||
|
| 'custom';
|
||||||
|
|
||||||
|
export interface NodeData {
|
||||||
|
name: string;
|
||||||
|
label: string;
|
||||||
|
description?: string;
|
||||||
|
handler?: string;
|
||||||
|
payloadClass?: string;
|
||||||
|
isAgent?: boolean;
|
||||||
|
config?: Record<string, unknown>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CanvasEdge {
|
||||||
|
id: string;
|
||||||
|
source: string;
|
||||||
|
target: string;
|
||||||
|
sourceHandle?: string;
|
||||||
|
targetHandle?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Triggers
|
||||||
|
export type TriggerType = 'webhook' | 'schedule' | 'manual';
|
||||||
|
|
||||||
|
export interface Trigger {
|
||||||
|
id: UUID;
|
||||||
|
flowId: UUID;
|
||||||
|
type: TriggerType;
|
||||||
|
name: string;
|
||||||
|
config: TriggerConfig;
|
||||||
|
webhookToken?: string;
|
||||||
|
webhookUrl?: string;
|
||||||
|
createdAt: ISODateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TriggerConfig =
|
||||||
|
| { type: 'webhook' }
|
||||||
|
| { type: 'schedule'; cron: string; timezone?: string }
|
||||||
|
| { type: 'manual' };
|
||||||
|
|
||||||
|
export interface CreateTriggerRequest {
|
||||||
|
type: TriggerType;
|
||||||
|
name: string;
|
||||||
|
config: TriggerConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Executions (Run History)
|
||||||
|
export type ExecutionStatus = 'running' | 'success' | 'error' | 'timeout';
|
||||||
|
|
||||||
|
export interface Execution {
|
||||||
|
id: UUID;
|
||||||
|
flowId: UUID;
|
||||||
|
triggerId: UUID | null;
|
||||||
|
triggerType: TriggerType;
|
||||||
|
status: ExecutionStatus;
|
||||||
|
startedAt: ISODateTime;
|
||||||
|
completedAt: ISODateTime | null;
|
||||||
|
durationMs: number | null;
|
||||||
|
errorMessage: string | null;
|
||||||
|
inputPayload: string | null;
|
||||||
|
outputPayload: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ExecutionSummary {
|
||||||
|
id: UUID;
|
||||||
|
status: ExecutionStatus;
|
||||||
|
triggerType: TriggerType;
|
||||||
|
startedAt: ISODateTime;
|
||||||
|
durationMs: number | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Marketplace
|
||||||
|
export type MarketplaceListingType = 'tool' | 'flow';
|
||||||
|
|
||||||
|
export interface MarketplaceListingSummary {
|
||||||
|
id: UUID;
|
||||||
|
authorName: string;
|
||||||
|
type: MarketplaceListingType;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
category: string;
|
||||||
|
downloads: number;
|
||||||
|
rating: number | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// API Responses
|
||||||
|
export interface PaginatedResponse<T> {
|
||||||
|
items: T[];
|
||||||
|
total: number;
|
||||||
|
page: number;
|
||||||
|
pageSize: number;
|
||||||
|
hasMore: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ApiError {
|
||||||
|
code: string;
|
||||||
|
message: string;
|
||||||
|
details?: Record<string, unknown>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stats
|
||||||
|
export interface FlowStats {
|
||||||
|
flowId: UUID;
|
||||||
|
executionsTotal: number;
|
||||||
|
executionsSuccess: number;
|
||||||
|
executionsError: number;
|
||||||
|
avgDurationMs: number;
|
||||||
|
lastExecutedAt: ISODateTime | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UsageStats {
|
||||||
|
userId: UUID;
|
||||||
|
period: 'day' | 'month';
|
||||||
|
flowCount: number;
|
||||||
|
executionCount: number;
|
||||||
|
executionLimit: number;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## API Endpoints
|
||||||
|
|
||||||
|
### Flows
|
||||||
|
- `GET /flows` — List user's flows (returns `FlowSummary[]`)
|
||||||
|
- `POST /flows` — Create flow
|
||||||
|
- `GET /flows/:id` — Get full flow
|
||||||
|
- `PATCH /flows/:id` — Update flow
|
||||||
|
- `DELETE /flows/:id` — Delete flow
|
||||||
|
- `POST /flows/:id/start` — Start flow (deploy container)
|
||||||
|
- `POST /flows/:id/stop` — Stop flow
|
||||||
|
|
||||||
|
### Triggers
|
||||||
|
- `GET /flows/:id/triggers` — List triggers
|
||||||
|
- `POST /flows/:id/triggers` — Create trigger
|
||||||
|
- `DELETE /triggers/:id` — Delete trigger
|
||||||
|
|
||||||
|
### Executions
|
||||||
|
- `GET /flows/:id/executions` — List runs (paginated)
|
||||||
|
- `GET /executions/:id` — Get run details
|
||||||
|
- `GET /executions/:id/logs` — Stream logs (WebSocket)
|
||||||
|
|
||||||
|
### Marketplace
|
||||||
|
- `GET /marketplace` — Browse listings
|
||||||
|
- `GET /marketplace/:id` — Get listing details
|
||||||
|
- `POST /marketplace/:id/install` — Install to user's library
|
||||||
|
|
||||||
|
### User
|
||||||
|
- `GET /me` — Current user info + usage stats
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Design Notes
|
||||||
|
|
||||||
|
1. **Dark mode default** — Developer audience prefers dark
|
||||||
|
2. **Keyboard shortcuts** — Cmd+S save, Cmd+Enter run, etc.
|
||||||
|
3. **Toast notifications** — For save/run/error feedback
|
||||||
|
4. **Loading states** — Skeleton loaders, not spinners
|
||||||
|
5. **Mobile:** Dashboard is responsive, flow editor is desktop-only (show message on mobile)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Start With
|
||||||
|
1. Dashboard page with flow list
|
||||||
|
2. Flow editor with React Flow canvas
|
||||||
|
3. Basic YAML tab (Monaco, read-only first)
|
||||||
|
4. Run/Stop buttons that call API
|
||||||
|
|
||||||
|
Then iterate: node inspector panel, execution history, marketplace.
|
||||||
Loading…
Reference in a new issue