ToDos
Lightweight, project-scoped task tracking — accessible from the web UI, the Telegram bot, and the CLI. Useful for capturing follow-ups during meetings, filing CI failures as actionable items, or letting AI agents pick up work.
Each todo has a title, optional notes (up to 256 characters), a status, and an optional assignee.
Anatomy of a todo
Each todo has these fields:
| Field | Notes |
|---|---|
title | Required. ≤ 200 characters. |
notes | Optional. ≤ 256 characters. |
status | One of in_progress, complete, cancelled. Defaults to in_progress. |
assignee | Optional. Must be a project member (or the org owner). |
Storage — markdown files in your project
Each todo is a markdown file at todos/<id>.md in the project's storage,
with YAML frontmatter for the metadata and the markdown body for the notes.
This means AI agents and other tools can read and write todos through the
same file commands they'd use for any other project file — no separate API
to learn.
---
id: 9f3e2c1d-3c4d-4a8e-b1f2-1234567890ab
title: Wire up the LED driver
status: in_progress
assigned_to: 7a1b2c3d-...
assigned_to_username: alice
created_by: 5c8d9e0f-...
created_by_username: bob
created_at: 2026-04-26T10:30:00Z
updated_at: 2026-04-26T11:00:00Z
---
Up to 256 characters of notes here.
Permissions
Access to todos is controlled by the project role permission system, scoped to
the virtual /todos/* folder. A user's role must explicitly grant the
permission to see / create / delete todos:
Role permission on /todos/* | Allowed actions |
|---|---|
read | See the ToDos card; list todos |
write | Create a todo; change status, title, assignee |
delete | Remove a todo |
The organization owner always has full access, regardless of role.
If a user has no role granting access to /todos/*, the ToDos card on the
project page is hidden entirely.
In the web UI
The project page shows a ToDos card alongside Releases, Documents, etc.
- Click + New to create a todo (title, notes, optional assignee).
- Click the status pill to change status inline (yellow = in progress, green = complete, red = cancelled).
- Click the assignee chip to reassign or unassign.
- The trash icon deletes the todo.
From the Telegram bot
Once a Telegram group is linked to a project (see /configure), three commands are available:
/todos— list current todos with status iconsTodos for myorg/myproject:
1. ⏳ Wire up the LED driver — @alice
2. ✅ Update README — @bob
3. ❌ Investigate flaky CI — unassigned/newtodo— start a multi-step wizard. The bot asks for the title, then notes (or/skip), then shows project members as inline buttons for the assignee picker./canceltodo— abort an in-progress/newtodowizard.
Activity events are pushed to the linked group automatically:
- 📝
created todo "..." - 🔁
updated todo "..." (in_progress → complete) - 🗑️
deleted todo "..."
From the CLI
The embedhub todos command group works against the same backend. See the
CLI documentation for the full command reference.
embedhub todos list myorg/myproject
embedhub todos add myorg/myproject --title "ship v2" --assignee anuj
embedhub todos status myorg/myproject 9f3e2c1d done
embedhub todos rm myorg/myproject 9f3e2c1d --yes
For AI agents
An AI agent with the EmbedHub CLI installed can read and write todos with the same commands a human would. Two paths, depending on whether the agent wants structured JSON or raw markdown:
Structured JSON via the typed todos commands
embedhub todos list myorg/myproject --json
embedhub todos show myorg/myproject 9f3e2c1d --json
embedhub todos status myorg/myproject 9f3e2c1d done
Raw markdown via the files commands
embedhub list myorg/myproject --prefix todos/
embedhub pull myorg/myproject todos/9f3e2c1d.md
Either path respects the same /todos/* role permissions described above.
The file convention is todos/<id>.md where <id> matches the id in
the YAML frontmatter. An agent that produces a new markdown file and
embedhub pushes it under todos/ triggers the same todo.create
activity event the web UI would, so Telegram notifications fire as
expected.