AgenticTodo
A human + AI co-working app for managing projects, tasks, and discussions.
AgenticTodo is designed for humans and AI agents to collaborate on task management. It provides a structured workflow system where both parties can create tasks, ask questions, make decisions, and track progress together.
Key Features
- Two task modes — Simple (free movement) and Pipeline (7-column gated workflow)
- Action statuses — A second dimension on tasks indicating what needs to happen now
- Queue system — Smart prioritized view of what each person needs to work on
- Discussion threads — Typed entries (questions, answers, decisions) that auto-reassign tasks
- Agent API — Full REST API with API key auth for AI/automation integrations
- Recurring tasks — Templates that auto-generate daily/weekly/monthly instances
URLs
| Service | URL |
|---|---|
| App (Frontend) | agentictodo.pages.dev |
| API (Backend) | agentictodo-api.stefan-02a.workers.dev |
| Docs | docs-agentictodo.pages.dev |
Tech Stack
| Layer | Technology |
|---|---|
| Frontend | React + TypeScript + Vite + shadcn/ui + TailwindCSS |
| Backend | Cloudflare Workers + Hono |
| Database | Neon Postgres + Drizzle ORM |
| Auth | Better Auth (email/password) |
| Hosting | Cloudflare Pages (frontend) + Workers (API) |
| Docs Storage | Cloudflare R2 (agentictodo-docs bucket) |
Architecture
How the pieces fit together.
Frontend
React single-page application hosted on Cloudflare Pages. Auto-deploys from GitHub on push to main. Uses Vite for builds and shadcn/ui component library with TailwindCSS.
Backend
A Cloudflare Worker running Hono as the HTTP framework. Connects to Neon Postgres (serverless Postgres) via Drizzle ORM. Handles both user auth routes and the Agent API.
Database
Neon serverless Postgres. The schema uses cw_* prefixed tables (co-working) as the active system. Legacy tasks and projects tables exist but are deprecated — fully migrated to the unified cw_* tables.
Authentication
Better Auth with email/password. No Supabase — fully migrated to Neon + Better Auth. Bearer tokens stored in localStorage for cross-origin compatibility.
Docs Storage
An R2 bucket (agentictodo-docs) stores workspace documentation. Synced every 30 minutes from the local workspace. Accessible via the Agent API.
Data Flow
Browser (React SPA)
↓ HTTPS
Cloudflare Pages → Cloudflare Worker (Hono API)
↓ TCP/HTTP
Neon Postgres
Agent (AI/Bot)
↓ HTTPS + X-API-Key
Cloudflare Worker (Hono API)
↓
Neon Postgres
Authentication
How users and agents authenticate.
User Authentication (Better Auth)
Human users authenticate via email/password using Better Auth. The frontend stores the bearer token in localStorage for cross-origin compatibility.
Sign Up
POST /api/auth/sign-up/email
Content-Type: application/json
{
"email": "user@example.com",
"password": "your-password",
"name": "Your Name"
}
Sign In
POST /api/auth/sign-in/email
Content-Type: application/json
{
"email": "user@example.com",
"password": "your-password"
}
Agent Authentication (API Keys)
AI agents and automation tools use API keys (prefixed with ak_). Keys are created in the app UI under the Agents section, with granular permissions.
Authorization: Bearer ak_your-api-key-here
Agent Permissions
| Permission | Description |
|---|---|
read_tasks | View tasks |
create_tasks | Create new tasks |
update_tasks | Update existing tasks |
delete_tasks | Delete tasks |
read_projects | View projects |
create_projects | Create projects |
update_projects | Update projects |
delete_projects | Delete projects |
read_tags | View tags |
create_tags | Create tags |
read_meetings | View meetings |
create_meetings | Create meetings |
Core Concepts
The building blocks of AgenticTodo.
Projects
Containers for tasks. Each project has a name, color, status (active/archived), and owner. Projects group related work together and provide board views for task management.
Tasks
The fundamental unit of work. Tasks operate in one of two modes:
- Simple mode — Free movement between statuses:
planned,in_progress,blocked,done - Pipeline mode — A 7-column gated flow with validation at each gate (see Pipeline Flow)
Tasks also have a priority (critical, high, medium, low) and an assignee (a person or "both").
Action Statuses
A second dimension on tasks indicating what needs to happen right now. This drives the Queue system.
| Status | Meaning |
|---|---|
ready | Ready to work on — no blockers |
needs_spec | Needs specification/objective before work can begin |
needs_approval | Waiting for approval from someone |
has_question | Has an open question that needs answering |
needs_clarification | Needs clarification on requirements |
question_answered | A question was answered — review the answer |
clarified | Clarification was provided — continue work |
needs_review | Work is done, needs review |
needs_changes | Review complete, changes requested |
info_requested | Additional information was requested |
Subtasks
First-class tasks with a parent_task_id. They appear on the board with a parent link badge and inherit the project from their parent. In pipeline mode, subtask completion gates the parent task's progression.
Recurring Tasks
Templates that automatically generate task instances. A cron job runs at 6 AM Vienna time daily. Types:
- Daily — Every N days
- Weekly — On specific days of the week
- Monthly — On a specific date or Nth weekday
- Yearly — On a specific date each year
- Custom — Every N days (interval-based)
Ephemeral recurring tasks auto-delete uncompleted instances from previous days.
Tags
Colored labels that can be attached to tasks for categorization and filtering.
Meetings
Scheduled blocks with a date, start time, and end time. Used for planning and calendar integration.
Agents
API keys with granular permissions for AI and automation access. Each agent has an owner, a set of permissions, and activity logging.
Pipeline Flow
The 7-column gated workflow for structured task management.
Pipeline mode enforces a disciplined progression through seven stages. Each transition has gate validation — you can't skip ahead without meeting the requirements.
Gate Requirements
Unplanned → Breaking Down
The task must have:
- Objective — What are we trying to achieve?
- Acceptance Criteria — How do we know it's done right?
- Definition of Done — What does "done" look like?
Use the POST /api/agent/tasks/:id/specify endpoint or fill these fields in the UI.
Breaking Down → Planned
The task must have at least one subtask. Use POST /api/agent/tasks/:id/breakdown to create subtasks and auto-advance.
Planned → In Progress
At least one subtask must be completed. This ensures work has actually started before the parent moves to "in progress".
In Progress → Review
All subtasks must be done or marked obsolete. No incomplete subtasks allowed.
Review → Follow-Up
A final report must be submitted via POST /api/agent/tasks/:id/final-report. The report must confirm that all spec criteria are met (via metadata specMet: true).
Follow-Up → Done
Requires explicit confirmation:
followUpConfirmed: true— The follow-up check was done- Either
noFollowUpNeeded: trueorfollowUpTasksCreated: true
Mode Conversion
Tasks can be converted between simple and pipeline mode using POST /api/agent/tasks/:id/convert. Converting resets the status to the default for the new mode.
Queue System
Smart prioritized view of what needs attention.
The Queue is the default landing page. It shows all non-done tasks assigned to a person, sorted by urgency. You can view any person's queue.
Sorting Priority
Tasks are sorted by action status priority first, then task priority, then age:
| Priority | Action Status | Why it's urgent |
|---|---|---|
| 1 | has_question | Someone is blocked waiting for your answer |
| 2 | needs_approval | Work is paused pending your approval |
| 3 | needs_review | Completed work needs your review |
| 4 | needs_clarification | Requirements need clarifying |
| 5 | question_answered | Your question was answered — check it |
| 6 | clarified | Clarification provided — continue |
| 7 | needs_changes | Changes requested after review |
| 8 | ready | Ready to work on |
| 9 | needs_spec | Needs specification |
| 10 | info_requested | Info was requested |
Queue Tabs
- All — Every active task in the queue
- Questions — Tasks with
has_questionorneeds_clarification - Approvals — Tasks with
needs_approvalorneeds_review - Work — Tasks with
readyorin_progress
Discussion Threads
Structured communication on tasks.
Each task has a discussion thread with typed entries. The type determines behavior:
| Type | Behavior |
|---|---|
comment | General discussion — no side effects |
question | Sets task action status to has_question, auto-assigns to the other person |
answer | Marks parent question as answered, assigns back to question author. Sets action status to question_answered |
decision | Records a decision made on the task |
status_change | System-generated when status changes |
system | System-generated entries |
Auto-Assignment Flow
- Stefan posts a question → task assigns to Cleo with status
has_question - Cleo posts an answer → task assigns back to Stefan with status
question_answered - When all questions are resolved → action status returns to
ready
Agent API Overview
REST API for AI agents and automation.
Base URL
https://agentictodo-api.stefan-02a.workers.dev/api/agent
Authentication
Authorization: Bearer ak_your-api-key-here
API keys are created in the app UI. They start with ak_ and are hashed (SHA-256) server-side.
Response Format
All responses follow this shape:
// Success
{ "success": true, "data": { ... } }
// Error
{ "success": false, "error": "Error message" }
Endpoint Summary
| Resource | Endpoints |
|---|---|
| Projects | GET/POST /projects, GET/PUT/DELETE /projects/:id, GET/POST /projects/:id/tasks |
| Tasks | GET/POST /tasks, GET/PUT/DELETE /tasks/:id, POST /tasks/:id/move |
| Pipeline Ops | POST /tasks/:id/specify, /breakdown, /pickup, /complete, /block, /final-report, /follow-up |
| Thread | GET/POST /tasks/:taskId/thread, PATCH /tasks/:taskId/thread/:entryId |
| Queue | GET /queue, GET /queue/counts |
| Recurring | GET/POST /recurring-tasks, GET/PUT/DELETE /recurring-tasks/:id, POST /recurring-tasks/generate |
| Tags | GET/POST/PUT/DELETE via legacy resource API |
| Docs | GET /docs/tree, GET /docs/content/* |
Projects API
Manage projects and their tasks.
GET /projects
List projects. Defaults to active projects.
| Query Param | Description |
|---|---|
status | Filter by status (default: active) |
owner_id | Filter by owner ID |
Response includes taskCounts — an object mapping status → count.
POST /projects
Create a new project.
{
"name": "My Project", // required
"description": "Optional",
"color": "#22c55e", // default: green
"owner_id": "user-uuid" // default: authenticated user
}
GET /projects/:id
Get project details with task counts.
PUT /projects/:id
Update a project.
{
"name": "New Name",
"description": "Updated",
"status": "active",
"color": "#3b82f6",
"owner_id": "user-uuid"
}
DELETE /projects/:id
Archive a project (sets status to archived).
GET /projects/:id/tasks
Get all tasks for a project, structured as a tree with nested subtasks. Each task includes an activityCount.
POST /projects/:id/tasks
Create a task in a project.
{
"title": "Task title", // required
"description": "Optional",
"priority": "medium", // critical, high, medium, low
"assignee": "cleo", // or "stefan", "both", "unassigned"
"parent_task_id": "uuid", // for subtasks
"status": "unplanned", // default for pipeline mode
"deadline": "2024-12-31",
"target_date": "2024-12-25",
"scheduled_date": "2024-12-20",
"scheduled_start_time": "09:00",
"scheduled_end_time": "17:00",
"tag_ids": ["tag-uuid-1"]
}
GET /projects/:id/activity
Get recent activity for a project (last 50 entries).
Tasks API
CRUD operations on tasks.
GET /tasks
List tasks with filters.
| Query Param | Description |
|---|---|
status | Filter by status |
mode | Filter by mode (simple or pipeline) |
assignee | Filter by assignee name |
project_id | Filter by project |
scheduled_date | Filter by scheduled date (YYYY-MM-DD) |
deadline_before | Tasks with deadline before this date |
today | Set to true to get tasks scheduled or due today |
Response includes tags array on each task.
POST /tasks
Create a task (not tied to a project, or specify project_id).
{
"title": "Task title", // required
"project_id": "uuid",
"parent_task_id": "uuid",
"description": "Details",
"priority": "medium",
"assignee": "cleo",
"mode": "pipeline", // default: pipeline
"status": "unplanned",
"action_status": "needs_spec",
"deadline": "2024-12-31",
"target_date": "2024-12-25",
"scheduled_date": "2024-12-20",
"objective": "What to achieve",
"acceptance_criteria": "How to verify",
"definition_of_done": "What done looks like",
"tag_ids": ["tag-uuid"]
}
GET /tasks/:id
Get task details including subtasks, recent activity (last 20), and tags.
PUT /tasks/:id
Update a task. Any field from create can be updated. Pass tag_ids to replace all tags.
DELETE /tasks/:id
Delete a task and all its subtasks + activity.
POST /tasks/:id/move
Move a task to a new status with pipeline gate validation.
{
"status": "breaking_down",
"position": 0, // optional: reorder
"completionNote": "Done!", // optional: for subtask completion
"followUpConfirmed": true, // required for follow_up → done
"noFollowUpNeeded": true // or followUpTasksCreated: true
}
GET /tasks/:id/activity
Get all activity entries for a task.
POST /tasks/:id/activity
Add an activity entry to a task.
{
"type": "comment", // comment, question, result, specification, etc.
"content": "Activity text",
"author": "cleo", // optional, defaults to authenticated user
"metadata": {} // optional
}
Pipeline Operations
Convenience endpoints for pipeline workflow actions.
POST /tasks/:id/specify
Set objective and move to breaking_down.
{
"objective": "What we're building", // required
"acceptance_criteria": "How to verify",
"definition_of_done": "What done means"
}
POST /tasks/:id/breakdown
Create subtasks and auto-advance to planned.
{
"subtasks": [
{ "title": "Subtask 1", "description": "Details", "priority": "high", "assignee": "cleo" },
{ "title": "Subtask 2" }
]
}
Returns { task, subtasks }.
POST /tasks/:id/pickup
Pick up a task — sets status to in_progress and assignee to cleo.
POST /tasks/:id/complete
Mark task as done with a completion note.
{
"content": "Task completed successfully",
"metadata": {}
}
POST /tasks/:id/complete-subtask
Complete a subtask with a note. Auto-adds activity to both subtask and parent.
{
"completionNote": "Implemented the feature" // required
}
POST /tasks/:id/block
Block a task with a reason.
{
"content": "Waiting for API access",
"metadata": {}
}
POST /tasks/:id/final-report
Submit final report and move to follow_up.
{
"content": "Summary of what was done...", // required
"metadata": { "specMet": true } // required for gate validation
}
POST /tasks/:id/follow-up
Complete follow-up and move to done. Optionally create follow-up tasks.
{
"tasks": [
{ "title": "Follow-up item", "priority": "medium", "assignee": "stefan" }
]
}
Returns { task, followUpTasks }.
POST /tasks/:id/convert
Convert between simple and pipeline mode.
{
"mode": "pipeline" // or "simple"
}
Thread Entries API
Discussion threads on tasks.
/api/tasks prefix (not /api/agent). They require user authentication (Bearer token), not agent API keys.
GET /api/tasks/:taskId/thread
Get all thread entries for a task, ordered by creation date. Includes author name.
POST /api/tasks/:taskId/thread
Add a thread entry.
{
"type": "question", // comment, question, answer, decision
"content": "How should this work?",
"parentEntryId": "uuid", // required for answers (references the question)
"isBlocking": false,
"metadata": {}
}
Side effects:
question→ sets action status tohas_question, assigns to other personanswer→ marks question as answered, assigns back to question author, setsquestion_answered
PATCH /api/tasks/:taskId/thread/:entryId
Update a thread entry.
{
"content": "Updated text",
"questionStatus": "resolved" // open, answered, resolved
}
Resolving the last open question resets the task action status to ready.
Queue API
Prioritized task views per person.
GET /queue
Get the current user's queue — all non-done tasks sorted by urgency.
| Query Param | Description |
|---|---|
view | cleo, stefan, or both — view another person's queue |
Each task in the response includes:
- Task fields (id, title, status, actionStatus, priority, assignee, etc.)
projectNameandprojectColoropenQuestionscount
GET /queue/counts
Get badge counts for navigation — counts per action status plus totals.
// Response
{
"success": true,
"data": {
"has_question": 3,
"needs_approval": 1,
"ready": 5,
"total": 4, // actionable items only (excludes ready/needs_spec)
"all": 9 // total tasks in queue
}
}
Recurring Tasks API
Manage recurring task templates and generation.
GET /recurring-tasks
List all recurring task templates for the authenticated user.
POST /recurring-tasks
Create a recurring task template.
{
"title": "Daily standup notes", // required
"recurrence_type": "daily", // required: daily, weekly, monthly, yearly, custom
"description": "Optional details",
"priority": "medium",
"project_id": "uuid",
"assigned_to": "cleo",
"recurrence_rule": { // depends on type
"interval": 1 // daily: every N days
// weekly: { "days": ["monday", "wednesday", "friday"] }
// monthly: { "day_of_month": 15 } or { "week_of_month": 2, "day_of_week": "monday" }
// custom: { "interval_days": 3 }
},
"is_ephemeral": false, // auto-delete uncompleted past instances
"is_active": true,
"start_date": "2024-01-01",
"end_date": "2024-12-31" // optional
}
GET /recurring-tasks/:id
Get a single recurring task template.
PUT /recurring-tasks/:id
Update a recurring task template. Same fields as create.
DELETE /recurring-tasks/:id
Delete a recurring task template.
POST /recurring-tasks/generate
Trigger generation of recurring task instances for today. Normally called by the daily cron job at 6 AM Vienna time. Also cleans up old ephemeral instances.
Requires create_tasks permission for agent API keys.
// Response
{
"success": true,
"message": "Generated 3 recurring task instances",
"generated": 3,
"fromDate": "2024-06-15",
"toDate": "2024-06-15"
}
Docs API (R2)
Access workspace documentation stored in R2.
GET /docs/tree
List all files in the docs R2 bucket.
// Response
{
"success": true,
"data": [
{ "path": "README.md", "size": 1234, "updated": "2024-06-15T10:00:00Z" },
{ "path": "notes/ideas.md", "size": 567, "updated": "2024-06-14T08:00:00Z" }
]
}
GET /docs/content/{path}
Get the content of a specific file.
// GET /docs/content/README.md
{
"success": true,
"data": {
"path": "README.md",
"content": "# My Doc\n...",
"size": 1234,
"updated": "2024-06-15T10:00:00Z"
}
}
Database Schema
All tables in the Neon Postgres database.
cw_ are the active unified system. The old tasks, projects tables are legacy and deprecated.
Auth Tables (Better Auth)
| Table | Purpose |
|---|---|
user | User accounts (id, name, email, image, etc.) |
session | Active sessions with tokens and expiry |
account | Auth provider accounts (email/password) |
verification | Email verification tokens |
User Management
| Table | Purpose |
|---|---|
profiles | Extended user profiles |
user_roles | Role assignments for users |
Unified System (Active)
| Table | Key Columns |
|---|---|
cw_projects | id, name, description, color, status, owner_id, created_by |
cw_tasks | id, project_id, parent_task_id, title, description, status, mode, action_status, priority, assignee, objective, acceptance_criteria, definition_of_done, deadline, target_date, scheduled_date, position |
cw_task_tags | task_id, tag_id (join table) |
cw_thread_entries | id, task_id, author_id, type, content, parent_entry_id, question_status, is_blocking, metadata |
cw_activity | id, task_id, project_id, author, type, content, metadata |
Shared Tables
| Table | Purpose |
|---|---|
tags | Colored labels (id, name, color, owner_id) |
meetings | Scheduled meetings (date, time, title, notes) |
agents | API key agents (name, api_key_hash, permissions, owner_id, is_active) |
agent_activity_logs | Audit log of agent API actions |
Recurring Tasks
| Table | Purpose |
|---|---|
recurring_tasks | Templates with recurrence rules (type, rule JSON, ephemeral flag) |
recurring_task_skipped_dates | Dates to skip generation |
recurring_task_tags | Tags attached to recurring templates |
Legacy Tables (Deprecated)
| Table | Note |
|---|---|
projects | Old project system — replaced by cw_projects |
tasks | Old task system — replaced by cw_tasks. Still used by recurring task generation. |
task_tags | Old tag joins |
task_notes | Old notes system |
task_attachments | Old attachments |