OpenTodo 0.6.0

Released on

OpenTodo 0.6.0 speaks your language and looks back as well as ahead. The interface comes in English, German, French, Spanish, Italian and Portuguese. Statistics and a guided weekly review show what you finished, what slipped and what has no next action, computed on your device, with an optional weekly digest by email. Filter by completion date (completed = last week) and a day-by-day Completed logbook answer "what did I do this month?". Habits keep a streak and a month history, custom fields add typed values to a project's tasks, and display mode puts a view full screen on a wall tablet or an e-ink panel. Importers from Todoist, TickTick, Linear and Things keep more of what you had, and operators can run many OpenTodo servers in one process with host mode. Clicking a task's circle completes it again.

Upgrade notes

  • Migration 0034 (weekly digest settings) is applied automatically at startup. Back up /data before upgrading: there are no down-migrations.
  • No new environment variables are required. Host mode is off unless OPENTODO_HOST_URL is set; OPENTODO_HOST_TOKEN (required only with it), OPENTODO_HOST_OPERATOR_ADDR, OPENTODO_HOST_IDLE_MINUTES, OPENTODO_HOST_MAX_OPEN and OPENTODO_HOST_LIMITS configure it. A self-hosted server behaves exactly as before.
  • Sync is additive: the entities field and review, the task fields habit, skipped, completed_by and fields.<id>, and the user_prefs field language. Older clients ignore them; upgrade the server before the devices, as for every new field.
  • New routes: /api/v1/fields, GET/PUT /api/v1/me/email-digest, GET /api/v1/export/archive (owner), and completed_after/completed_before on GET /api/v1/tasks. All require authentication; the digest settings write is refused on the demo.
  • The installed app downloads the five language catalogs once (about 100 kB gzipped each) so a language switch works offline; the precache grows from about 2.7 to 4.4 MiB.
  • Binary size is about 27 MB (24 MB in 0.5): mostly the language catalogs.
  • Image tags. The release publishes ghcr.io/pixari/opentodo:0.6.0 and :0.6 for linux/amd64 and linux/arm64 (:latest follows main). The Coolify template now follows :0.6; if you use :0.5, change the tag in Edit Compose file and click Deploy.

Added

  • The app in your language: English, German, French, Spanish, Italian and Portuguese. Settings → General → Language picks the interface language for every device of the account (or System, the browser's first shipped language), and the app switches at once, without a reload, also offline once a language has been loaded on the device. Month and weekday names, the clock and the date order on System follow it with the browser's region kept (Swiss German stays Swiss German); quick add and voice capture try it first; reminder notifications (Snooze 10 min, Dismiss, the due date) are written in it by the service worker; server errors are shown in it by error code; the browser extension follows the browser's language. Tasks, project and label names, filter queries and repeat rules are never translated, and the documentation and the Help guide stay English (Help says so). Each language is a separate chunk of about 100 KB gzipped, loaded only when chosen and precached for offline switching; the main chunk grows by about 6.5 KB gzipped. Sync is additive (user_prefs.language); make check now runs catalog and untranslated-string checks. (The app in your language, Translating OpenTodo)
  • Custom fields per project: text, number, date, choice, link and checkbox values on tasks, filterable, exported, in the API and the assistant tools. Fields… in a project's menu (Shift+F) defines up to 30 typed fields, for editors and above; each task of the project then has a Fields group in its panel, rows and board cards show up to three values as badges, and on a wide screen the list offers a Columns layout, remembered per project on the device. Values work offline and converge field by field: two people editing different fields of one task both keep their change. Filter with cost > 100, client = "Acme", "Order date" <= friday or no client. A task moved to another project keeps its values, hidden until it comes back; deleting a field hides its values without touching them. The REST API has /api/v1/fields and a fields object on tasks, the export and own-export import carry both, webhooks deliver the values, and the MCP tools list a project's fields and set values. On end-to-end encrypted accounts field names, options and text values are encrypted. Sync is additive (the field entity and the task's fields.<id> values); upgrade the server before the devices, as for every new field. (Custom fields, Filter queries, API)
  • Statistics and weekly review: on-device numbers, a guided review, an optional weekly digest by email. Statistics (g Shift+S, under More) shows for this week, last week, the last 4 or 12 weeks what you completed (each day of a recurring task once, skipped habit days never), created, completed late and let slip, and what is overdue, with bar charts per day, week, weekday and project; everything is computed on the device from your tasks, offline, and nothing is sent or stored. In shared projects a completion counts for whoever completed it (completed_by), the assignee for older tasks. Review (g r) walks four steps with live data: get the Inbox clear, look back at the week and what is overdue, give every project a next action or archive it, and look ahead seven days; Finish review syncs to your devices and the sidebar marks a review as due after seven days. In Settings → Notifications each user can opt in to a weekly digest email on their review day (needs outgoing email; not offered with end-to-end encryption, and turning encryption on switches it off; refused on the demo). Sync is additive (a personal review entity); migration 0034 adds the digest settings table; GET/PUT /api/v1/me/email-digest. (Weekly review and statistics, API)
  • Host mode: one process serves many OpenTodo servers. For operators of a hosted service: with OPENTODO_HOST_URL=https://example.cloud, each tenant is an ordinary data directory answering at <name>.example.cloud. Tenants open on their first request (running their migrations), close when idle unless a device holds a live stream, and at most OPENTODO_HOST_MAX_OPEN stay open. One scheduler runs reminders, backups, Trash retention, webhooks, calendar fetches and weekly digests for tenants with work due only, so thousands of idle tenants cost nothing. Per-tenant limits on storage, changes per hour and in total, requests, import size and members refuse single changes with a named reason while the rest keeps syncing; the app keeps a refused change and shows it as waiting. Outgoing email, single sign-on, backup destinations, attachment limits and the AI switches belong to the operator. A token-authenticated operator interface on its own address creates tenants (empty with a setup link, or from any backup archive), suspends, resumes, deletes and exports them. (Host mode)
  • Owners of a hosted server can take their data away. Settings → Server → Download your data saves the whole server as one backup archive that opentodo restore reads, so moving to a self-hosted server takes one download. (Host mode, API)
  • Habits: track a repeating task as a habit with a streak and a month history; skip keeps the chain. Turn on Track as a habit under a task's repeat rule (any rule except after completion). Its row shows a streak chip, and the task panel shows the current and best streak and a month grid of done, skipped, missed and upcoming days, navigable with the keyboard. Everything is computed on the device from the series' occurrence records, offline too. Skipping a habit records the day as skipped, so the streak holds; a scheduled day that passes without a record breaks it. Skipped days are not completions: they stay out of Completed and completed filters and never count towards for N times. The new habit filter keyword makes a Habits saved view one word. Sync is additive (the task fields habit and skipped); upgrade the server before the devices, as for every new field. (Recurring tasks and reminders, Habits reference)
  • Filter by completion date. completed = last week, completed >= 7 days ago or ##Work & completed >= this month list what you finished; a completion date implies completed tasks. Every date term also takes periods: this week, last week, next week, this month, last month, next month, 2 weeks ago, 3 months ago, where = means within the period and weeks start on your first day of the week. Saved views keep the period, so "last week" moves with the calendar. Closes #86. (Filter queries)
  • Completed is a logbook. Completions are grouped by the day you finished them (Today, Yesterday, then the date) and Show more reaches older days instead of stopping at the latest 100. (Views)
  • Completion ranges for scripts and assistants. GET /api/v1/tasks?completed_after=…&completed_before=…, the same arguments on the MCP list_tasks tool, and ot list --completed-after … --completed-before … take a date, an RFC 3339 time or Unix milliseconds. (API, MCP, Command-line client)
  • Who completed a task. Tasks gain an additive completed_by field (the account id, written with every completion and cleared on reopen, null for public link ticks and older completions); the API and exports return it. Older clients keep syncing. (Sync protocol)
  • Display mode. Today, Upcoming, a project or a saved view full screen in large type with a clock, for a tablet on the fridge or an e-ink panel: open it with Display mode in the view's header or menu, leave it with Exit or Esc. Today shows overdue and today's tasks, what was done today ticked below, and the next days as columns; it follows other devices within seconds, keeps working offline with a "Last synced" line, and rolls over at midnight by itself. Options live in the address so a bookmark keeps them: size=m|l|xl, contrast=high, motion=none, days=1..7 and eink=1 (high contrast, no motion, a clock without seconds). Tasks can be ticked by touch or with Space only where the account may edit them, so a dedicated viewer account makes a safe shared screen. A display can be the device's start view, and a public link accepts ?display=1 for a panel with no account on it. No server change. (Display mode)
  • High-contrast and no-motion presentation for contributors: data-contrast="high" on the root overrides the tokens with pure white or black surfaces and 7:1 text, data-motion="none" makes every transition instant; both combine with any theme and accent, and the contrast check measures the override. (Design system)

Fixed

  • Clicking a task's circle completes it again. Since 0.5.0 the circle turned into a selection checkbox while the pointer was over the row, so a click meant to complete a task ticked it for bulk actions instead. The circle now always completes; selection checkboxes appear only once a task is ticked (Ctrl/⌘+click or Shift+click a row, or x) or in touch Select mode. (Bulk actions)
  • Imports from TickTick and Todoist keep more of what you had. TickTick tasks keep the time they were created and completed (the backup writes times as +0000, which was not read), and a reminder on an all-day TickTick task fires at the time you set (PT9H is 09:00 on the day, not 18:00). A Todoist task with several comments lists them under one "Comments" heading, and an absolute Todoist reminder fires at its time in the task's time zone. Each named format now has a second, richer test file covering recurring tasks, reminders, deadlines, checklists, completed and canceled items and boards. (Import formats)

Downloads and checksums for v0.6.0

Your to-do list, on your own server.

Try the demo in your browser. When you like it, install OpenTodo on your server and import your tasks.

OpenTodo is free and open source, with no paid tier. If it helps you, a star on GitHub helps other people find it, and a coffee helps keep it going.

Buy me a coffee