A modern web application for managing and executing tasks with apflow v2, built with Next.js and Mantine.
- 🎨 Modern UI: Built with Mantine UI components with collapsible sidebar navigation
- 🌍 Internationalization: Support for multiple languages (English, Chinese)
- 📊 Dashboard: Real-time task statistics and monitoring
- 📋 Task Management: Create, view, update, and delete tasks
- 🌳 Task Tree View: Visualize task dependencies and hierarchy
- 🕐 Scheduler: Schedule tasks with cron, interval, daily, weekly, monthly, and one-time expressions
- ⚡ Real-time Updates: Auto-refresh for running tasks
- 🔐 Authentication: JWT token and automatic cookie-based authentication
- 🤖 LLM Integration: Configure LLM API keys for AI-powered task execution
- 🎯 Type-safe: Full TypeScript support
- Framework: Next.js 16 (App Router)
- UI Library: Mantine 8
- Data Fetching: TanStack Query (React Query)
- Internationalization: i18next
- HTTP Client: Axios
- Icons: Tabler Icons
- Node.js 18+
- pnpm 9+ or npm 9+
- apflow >= 0.22.1 REST API server running (default: http://localhost:8080)
- Clone the repository and navigate to the project:
cd apflow-webapp- Install dependencies:
pnpm install- Start apflow v2 REST API server:
apflow rest --host 127.0.0.1 --port 8080 --cors http://localhost:3000,http://127.0.0.1:3000This webapp targets the apflow v2 REST module API introduced in apflow>=0.22.1.
Older v1/JSON-RPC-only servers are not supported by the current client.
- Create
.envfile (optional):
cp .env.example .envEdit .env and configure your settings:
# API URL
NEXT_PUBLIC_API_URL=http://localhost:8080
# Control visibility of authentication settings
# true: Show auth token input field (developer mode, default)
# false: Hide auth token input field (user mode)
NEXT_PUBLIC_SHOW_AUTH_SETTINGS=true
# Auto-login endpoint path (optional)
# If set, enables automatic cookie-based authentication
# Example: /auth/auto-login
# Leave empty or unset to disable auto-login
NEXT_PUBLIC_AUTO_LOGIN_PATH=Note: NEXT_PUBLIC_* environment variables are embedded at build time. You need to set them:
- Before
pnpm dev.env: For development mode (reads from.env) - Before
pnpm build.env: For production builds (reads from.env)
Available Scripts:
pnpm dev- Start development server (uses Next.js default env loading)pnpm dev.env- Start development server with.envfile (requiresdotenv-cli)pnpm build- Build for production (uses Next.js default env loading)pnpm build.env- Build for production with.envfile (requiresdotenv-cli)pnpm start- Start production server (uses Next.js default env loading)pnpm start.env- Start production server with.envfile (requiresdotenv-cli)
The .env scripts use dotenv-cli (already included in devDependencies) to load environment variables from .env file.
- Run the development server:
pnpm dev- Open http://localhost:3000 in your browser.
apflow-webapp/
├── app/ # Next.js App Router pages
│ ├── layout.tsx # Root layout
│ ├── page.tsx # Dashboard
│ ├── tasks/ # Task management pages
│ │ ├── page.tsx # Task list
│ │ ├── create/ # Create task
│ │ ├── running/ # Running tasks
│ │ └── [id]/ # Task detail
│ ├── scheduler/ # Scheduler page
│ │ └── page.tsx # Scheduled tasks management
│ └── settings/ # Settings pages
│ ├── page.tsx # API settings
│ └── llm/ # LLM key settings
│ └── page.tsx
├── components/ # React components
│ ├── layout/ # Layout components
│ │ ├── AppShell.tsx # Main layout wrapper
│ │ └── Navbar.tsx # Collapsible sidebar navigation
│ └── tasks/ # Task-related components
│ └── TaskTreeView.tsx # Task tree visualization
├── lib/ # Utilities and configurations
│ ├── api/ # API client
│ │ └── apflow.ts
│ ├── hooks/ # Custom React hooks
│ ├── i18n/ # Internationalization
│ │ ├── config.ts
│ │ ├── provider.tsx
│ │ └── locales/ # Translation files
│ └── providers/ # React context providers
│ └── QueryProvider.tsx
└── public/ # Static assets
└── logo.svg # Brand logo (starfish)
- View running tasks count
- Monitor task statistics
- Quick access to recent tasks
- Task List: Browse all tasks with search and filtering
- Create Task: Form to create new tasks with executor configuration
- Task Detail: View detailed task information, tree structure, inputs, and results
- Running Tasks: Monitor currently executing tasks with real-time progress
- View all scheduled tasks with status, type, expression, and run count
- Filter by schedule type (once, interval, cron, daily, weekly, monthly) and task status (pending, in_progress, completed, failed, cancelled)
- Toggle schedules on/off, trigger immediate execution, and configure schedule parameters
- Add schedules to existing tasks or remove them
- Export schedules as iCal (.ics) files
- API Settings: Configure API base URL and authentication
- Developer Mode: Show token input field (default)
- Auto Login Mode: Automatic cookie-based authentication
- User Mode: Hide token settings, show contact admin message
- LLM Settings: Manage LLM API keys for AI-powered task execution (supports header-based and server-side storage)
The application uses the apflow v2 REST module API to communicate with the apflow API server. It calls module endpoints such as /modules/apflow.task.create, /modules/apflow.task.get, and /modules/apflow.schedule.set.
The client requires apflow>=0.22.1. That version includes the REST module behavior and JSON-safe datetime serialization needed by the task detail and scheduler pages.
On apflow 0.24.x, failed root tasks are retried using run.retry and the new root is submitted with task.submit. The server must have an active dispatcher; the REST server starts one automatically. Retrying on older servers that do not expose these modules is unavailable.
Task creation uses params.executor_id to select an executor. Legacy schemas.method is converted to that field; other schemas fields are rejected because the REST creation API does not preserve them. Executor suggestions come from modules whose IDs end in _executor; custom IDs can also be entered manually.
All API methods are available through the apiClient instance:
import { apiClient } from '@/lib/api/apflow';
// Create tasks
await apiClient.createTasks([...]);
// Get task
await apiClient.getTask(taskId);
// Get task tree
await apiClient.getTaskTree(taskId);
// Cancel tasks
await apiClient.cancelTasks([taskId1, taskId2]);The LLM settings page supports two storage modes:
- Method 1: Request Header stores the key in the browser and sends it with each request as
X-LLM-API-KEY. This is the recommended mode for standardapflow>=0.22.1servers. - Method 2: User Config stores the key through server-side LLM key modules. If the connected apflow server does not expose those modules, the UI shows an unavailable notice and disables server-side controls.
Environment variables such as OPENAI_API_KEY are still read by apflow/LiteLLM on the server side.
The webapp supports two authentication modes:
For standard apflow servers:
- JWT token is required: Set the authentication token in Settings page
- Token is stored in
localStorageasauth_token - Token is sent in
Authorization: Bearer <token>header with every request - This is the default behavior and maintains backward compatibility
When the server exposes an auto-login endpoint (configured via NEXT_PUBLIC_AUTO_LOGIN_PATH):
- JWT token is optional: The server automatically issues a token via cookies
- If no token is set, the browser automatically sends cookies (
authorization) - Server middleware extracts the token from cookies and adds it to the Authorization header
- If a manual token is provided, it will override the auto-generated token
The webapp uses the following authentication strategy:
- Cookie Support: Cookie credentials are enabled only when
NEXT_PUBLIC_AUTO_LOGIN_PATHis configured - Conditional Authorization Header: Authorization header is only added if
auth_tokenexists in localStorage - Backward Compatible: Standard servers continue to work as before (token required)
- Auto-Login Compatible: Servers exposing an auto-login endpoint work automatically without manual token configuration
If you're building a custom client based on this webapp:
JWT Token Integration:
// Always send Authorization header with token
const token = localStorage.getItem('auth_token');
if (token) {
headers.Authorization = `Bearer ${token}`;
}Unified Approach (Recommended):
// Works for both token-based and cookie-based (auto-login) servers
const client = axios.create({
baseURL: apiUrl,
withCredentials: Boolean(process.env.NEXT_PUBLIC_AUTO_LOGIN_PATH),
});
// Only send Authorization header if a manual token exists;
// otherwise cookie-based auto-login (when enabled) handles auth automatically
const token = localStorage.getItem('auth_token');
if (token) {
headers.Authorization = `Bearer ${token}`;
}- Supported backend:
apflow>=0.22.1 - Default API URL:
http://localhost:8080 - Protocol: apflow v2 REST module endpoints under
/modules/{module_id} - Auto-login/cookie mode is optional and only enabled when
NEXT_PUBLIC_AUTO_LOGIN_PATHis set - Standard servers continue to work with manual JWT tokens when authentication is enabled server-side
The webapp behavior can be controlled via environment variables:
Control visibility of authentication settings in the UI.
true(default): Show authentication token input field (developer mode)false: Hide authentication token input field (user mode)
Configure the auto-login endpoint path for automatic cookie-based authentication.
- Unset or empty (default): Disable auto-login, require manual token configuration (standard mode)
- Set to path (e.g.,
/auth/auto-login): Enable auto-login via cookies
When set, the webapp will:
- Hide token input field
- Display "Auto Login Enabled" message
- Automatically use cookie-based authentication against a server that exposes the endpoint
Example values:
/auth/auto-login- Common auto-login endpoint path/api/auth/auto-login- Custom endpoint path- Empty or unset - Disable auto-login
For standard apflow deployments where developers need to configure tokens:
Configuration (create .env file):
NEXT_PUBLIC_SHOW_AUTH_SETTINGS=true
# NEXT_PUBLIC_AUTO_LOGIN_PATH= # Leave empty or unsetUsage:
pnpm dev.env # Development with .env file
pnpm build.env # Production build with .env fileBehavior:
- Shows API URL configuration
- Shows authentication token input field
- Developers can manually configure JWT tokens
For deployments with automatic cookie-based authentication:
Configuration (create .env file):
NEXT_PUBLIC_SHOW_AUTH_SETTINGS=false
NEXT_PUBLIC_AUTO_LOGIN_PATH=/auth/auto-loginUsage:
pnpm dev.env # Development with .env file
pnpm build.env # Production build with .env fileBehavior:
- Shows API URL configuration
- Hides token input field
- Displays "Auto Login Enabled" message
- Users don't need to configure anything - authentication works automatically via cookies
For enterprise deployments where authentication is managed centrally:
Configuration (create .env file):
NEXT_PUBLIC_SHOW_AUTH_SETTINGS=false
# NEXT_PUBLIC_AUTO_LOGIN_PATH= # Leave empty or unsetUsage:
pnpm build.env # Production build with .env file
pnpm start.env # Production server with .env fileBehavior:
- Shows API URL configuration
- Hides token input field
- Displays "Please contact your administrator" message
- Authentication configured by administrators
Important:
- Create
.envfile based on your needs (copy from.env.example) - Use
pnpm dev.env,pnpm build.env, orpnpm start.envto load from.envfile dotenv-cliis already included in devDependencies, no additional installation needed- For production deployments, set these environment variables before running
pnpm build.env, asNEXT_PUBLIC_*variables are embedded at build time
The application supports multiple languages. Currently available:
- English (en)
- Chinese (zh)
To add a new language:
- Create a new JSON file in
lib/i18n/locales/ - Add the translation keys
- Import and add to
lib/i18n/config.ts
pnpm dev- Start development server (uses Next.js default env loading)pnpm dev.env- Start development server with.envfile (usesdotenv-cli)pnpm build- Build for production (uses Next.js default env loading)pnpm build.env- Build for production with.envfile (usesdotenv-cli)pnpm start- Start production server (uses Next.js default env loading)pnpm start.env- Start production server with.envfile (usesdotenv-cli)pnpm lint- Run ESLintpnpm test- Run Node.js API client tests
- TypeScript for type safety
- ESLint for code quality
- Mantine components for UI consistency
- Create a new file in
app/directory - Use the
AppShelllayout (already included in root layout) - Add navigation item in
components/layout/Navbar.tsx
Edit lib/api/apflow.ts to add new API methods.
Mantine theme can be customized in app/layout.tsx:
<MantineProvider theme={{ /* your theme config */ }}>This is an open-source project. Contributions are welcome!
Apache-2.0