OpenTodo 0.18.0 is about planning the day on the calendar. Meetings from your subscribed and connected calendars can count toward the day's capacity, Re-plan moves the blocks a slipped morning missed into the free time left, frames mark the hours you keep for one kind of work and slots gather several small tasks in one block. The calendar shows deadlines on their day, adds a task with a double-click, colours blocks by project, label or priority, takes a filter and can show completed tasks; a project gains a Calendar layout. Tasks can carry an energy (Deep, Medium, Low) to filter by, and the Daily check offers Bento: one Large, one Medium and one Small task. Label pages and saved views keep their own manual order, quick add reads every other friday and stops taking a month named in passing as the date, today's focus and the Bento slots can be filled by touch, a tap beside a task's circle completes it on a phone, and calendars published from Exchange on-premises load. Every new setting is off by default.
Upgrade notes
- Replace the image or the binary and restart. One migration (
0050_calendar_feed_browser_agent: a table that remembers which calendar feeds need a browser User-Agent); no new variables. Frames and slots are new synced entities andenergyandmanual_ordernew synced fields, so upgrade the server before the devices, as for every release. Back up first; there are no down-migrations.
Added
- Calendar clarity: deadlines on the calendar, adding with the mouse, Colour by and a filter. A task's deadline now shows on its day: a chip with an amber diamond in the Day and Week strip under the day's name (before all-day events, within the same three-item limit and +N), a row at the end of a Month day (counted in +N more) and of a Plan column, or the diamond on the task itself when it is planned on its deadline day; markers open the task with a click or Enter, are dimmed on past days, never count toward capacity and can't be dragged. Double-click an empty quarter hour of Day or Week, a day's Unscheduled lane or an empty part of a Month day to add a task there (created at once, offline too); a right-click or a 500 ms long press opens Add task here…, New frame here… and New slot here…; Month days and the quarter hour under a mouse are highlighted; q in Day and Week adds on the focused day, and
at 4pmtyped there sets the time on that day (#555). Colour by Project, Label or Priority in the calendar's menu (Day, Week, Month, Plan) and for boards (a project board's menu, a board view's Display options; a 3 px edge on each card), a device choice that is never synced (#554). Filter… narrows the calendar's four modes, or Upcoming, with a query in the filter language and label checkboxes that write@errand | @call; the active filter is one chip in the header, capacity still counts every task and its tooltip says how many are hidden, an invalid edit keeps the last valid filter, and each filter is remembered per device (#556). A project's layout switch gains Calendar after Timeline (v cycles List, Board, Timeline, Calendar): the calendar in its last mode, narrowed to the project and its sub-projects, inside the project page (#556). No op field, route or variable; new device meta keys only. (Add and colour on the calendar, Filter the calendar,calendar-clarity, closes #554, #555 and #556) - Energy: Deep, Medium or Low on a task. Turn on Energy levels in Settings → Account → How you work (off by default in every mode) and give a task the energy it asks for: from Add on the task page and the docked panel (a Deep / Medium / Low choice that works by touch and with the arrow keys), the row menu's Energy submenu (with Undo), or
~deep,~medium,~low(or~d,~m,~l) in quick add, in every language. A row shows the word when set, as a property a saved view can hide. The filter language gainsenergy,no energyandenergy: low, soenergy: low & unblocked & todayis an end-of-the-day list of easy wins. Turning the switch off hides the choice, never a value. The field travels everywhere a task does: the REST task shape (invalid_energyfor anything else),ot add/edit --energyand anENERGYlist column, the agent tools and MCP, CSV import (anenergycolumn), the export, CalDAV (X-OPENTODO-ENERGY) and the Markdown vault ([energy:: low]). It is not content, so it stays plaintext on an encrypted account like the priority. (task-energy) - See completed tasks on the calendar. Choose Show completed tasks in Day, Week, Month or Plan to show finished tasks at their scheduled date and time with struck-through titles. The choice is off by default, remembered on this device and works offline. Finished tasks can be opened for inspection and do not add to remaining planned capacity. Thanks to @arvkonstantin for the idea and the contribution (#626). (Calendar views,
calendar-completed-tasks, closes #624) - Meetings can count toward the day's capacity. Settings → Language and region → Calendar grid → Count meetings in capacity (shown once this device knows a subscribed or connected calendar, off by default) adds the busy meetings Day, Week and Month draw to each day's planned total:
6h 45m / 8h, with "4h 15m of tasks, 2h 30m in meetings" in the header's tooltip. Meetings are counted as the Plan counts them: timed busy events of enabled calendars, overlaps once, split at midnight; free and all-day events never, and nothing while the toolbar's Calendars button hides events. A day whose tasks alone go over stays red (Over capacity); one whose tasks fit but not around its meetings turns amber (Over with meetings), and both are said to screen readers. Offline, a day outside the device's event cache counts no meetings and its tooltip says so. The setting belongs to each device, like the day length; no op field, no server change. The capacity tooltip of the Day and Week headers, which never opened, now opens on hover and focus. (Place tasks on the calendar,meeting-aware-capacity) - Re-plan the rest of the day. When the morning slips, the Day and Week header reads 3 blocks behind · Re-plan (also in the calendar's and Today's menus and the command palette, only while something is behind). Re-plan moves today's missed time blocks, open timed tasks whose block has ended, in their original order and at their own length, into the first free time between the next quarter hour and the end of your grid, around other timed tasks and busy events of your calendars. It is a preview first: dashed ghosts at the new places and the old blocks faded, "4 tasks move · 1 doesn't fit", a choice to Leave the tasks that don't fit or Move them to tomorrow (with After its deadline where it applies), Apply (Enter) and Cancel (Esc); on a phone, a sheet listing "09:00 → 14:30 Write report". The preview follows completions and moves from other devices. Apply writes one batch of ordinary due changes with one Undo; tasks you may only view, tasks assigned to someone else, the task your timer runs on and tasks changed meanwhile are never moved. App only: no op field, no server, CLI or MCP change (assistants can still use
schedule_tasks). (Re-plan the rest of the day,replan-the-day) - Frames: the hours you keep for one kind of work. A frame such as Deep work on weekdays from 09:00 to 11:00, or Admin Monday to Thursday late in the afternoon, shows as a quiet tinted band behind the Day and Week blocks, with its title and times at the top; two frames that overlap share the column, and past days are dimmed. Frames only guide: they never move, block or create anything, tasks dropped inside one land where you drop them, and capacity and Re-plan ignore them. Manage them from ⋯ › Frames… in Day and Week or New frame in the command palette: title, days (in your week's order), start and end in quarter hours, colour, an optional Plan from project, label or saved view, and optional first and last days, up to 50 frames. A frame's title opens Plan from this frame (the planning list on the frame's source; s then proposes the first free quarter hour inside the frame that holds the task), Edit and Delete with Undo. On a phone the Week's list shows each frame as a heading above the tasks inside it. Frames are personal and sync to your own devices only; the title is encrypted with end-to-end encryption. REST
/api/v1/frames,ot frames(add,rm), the read toollist_framesand the resourceopentodo://framesread them; the export includes them. New synced entityframe, no migration. (Frames,calendar-frames) - Slots: several small tasks in one calendar block. A slot such as Admin · 16:00–16:45 is one block on the Day and Week grid with a stack icon, its title, a count (2 of 5 done) and a checklist of the small tasks done in it, as many rows as fit and +n for the rest; the tasks are no longer drawn as slivers or in the Unscheduled lane. Create one with ⋯ › New slot (the next free quarter hour), New slot in the command palette or Make a slot here in a frame's details. Drop a task on it, press Shift+Enter during a placement (s) over it, or pick Add to Admin 16:00 in a phone's Schedule sheet: the task is dated to the slot's day without a time in the same batch, with one Undo; a slot holds up to 20 tasks, and a task you may only view is added only when already on that day. Rows complete with a tick or Space, open with Enter, and can be dragged out onto the grid; the slot moves (its tasks follow to a new day) and resizes like a block, and Delete slot leaves its tasks in the lane. A slot counts once toward the day's capacity in Day, Week, Month and Plan, its length or its tasks' estimates when they add up to more (50m in 45m in the warning tone); Re-plan treats it as busy time. In lists a slotted task shows the slot's start with the stack icon in the time column; on a phone the Week lists a slot as one row that expands to its tasks. Slots are personal and sync to your own devices only; the title is encrypted with end-to-end encryption. REST
/api/v1/slots(withmove_tasks),ot slots(add,put,rm), the read toollist_slotsand the resourceopentodo://slotsread them; the export includes them. New synced entityslot, no migration. (Slots,calendar-slots) - Bento in the Daily check: one Large, one Medium and one Small task. Choose Daily focus › Bento in the Daily check's ⋯ menu or in Settings → Account → How you work, and today's focus becomes three slots above the list. f puts a task in the slot its estimate suggests (Small up to 30 minutes, Medium 31 to 89, Large 90 or more); when that slot is taken the message names the task in it and offers Choose a slot, and a task without an estimate opens a menu (a bottom sheet on a phone) with the free slots and Set estimate… (only for tasks you may edit). Any task can go in any free slot, a slot never changes the task, and every change has Undo. The Order, Frog (Large first, the default) or Summit (Medium first), applies to the Daily check, Today's focus on the Loop home and the task the Focus screen opens on. Three tasks stays the default and is unchanged. The slots are a new additive field
review.focus_slotsbesidefocus, which older devices keep reading; the choices areuser_prefs.focus_styleandbento_order. No migration, no API change. (Rhythms,bento-daily-check)
Changed
- Quick add understands "every other".
Send timesheet every other fridayrepeats every 2 weeks from the next Friday, andevery other day,week,monthandyearrepeat every 2 of them, with the phrase removed from the title. In the other languages:jeden zweiten Freitag,jede zweite Woche,alle zwei Tage;un vendredi sur deux,tous les deux jours;ogni due venerdì,a settimane alterne;cada dos viernes;a cada duas sextas. Germanjeden zweiten Freitagwithoutim Monatwas the second Friday of each month and is now every other Friday. The CLI and the parse route read the same. (Quick add,quick-add-month-and-every-other, closes #635) - The quick-add parse route follows your Day parts preference.
POST /api/v1/quick-add/parsewithoutday_partsnow reads the part phrases (tomorrow morning,this afternoon) when the account's Group by day part is on; an explicitday_partsstill wins either way. The browser extension's Quick save, which never sends the field, now previews and saves part phrases for accounts with day parts on. (API, Day parts,quick-add-day-parts-default)
Fixed
- A month named in passing no longer becomes the due date. In
Collect the invoices from September and send them to the accountant next monday at 10am, quick add took September as the date and cut it from the title. A month name alone now gives way to a later date in the line and stays in the title, and right afterfrom,since,oforfor(and the same words in the other five languages) it is never a date.Pay rent in Septemberis still due on 1 September. The CLI and the parse route read the same. (Quick add,quick-add-month-and-every-other, closes #634) - Calendars published from Exchange on-premises load. Outlook on the web on an organisation's own Exchange server answers 400 to any client that isn't a desktop browser, so its
.icsaddresses failed with http_400. Calendar feeds still identify as OpenTodo first; when a calendar answers 400, 403 or 406, the fetch is tried once more with a desktop browser's User-Agent, and a calendar that only answers that way keeps getting it until its address changes. No other error is retried. Thanks to @osenchenko for the diagnosis. New server-side table (migration 0050), no op field or API change. (Calendar feeds,calendar-feed-user-agent, closes #622) - List rows on wide touch screens line up again. On a touch screen 768 px or wider (a tablet in landscape, a touch laptop), a list row's title and its property column sat 10 px below the completion circle, because the row's 44 px touch height centred them; they now stay on the circle's line.
- A tap next to a task's circle completes it on a phone. The completion circle stays 20 px, and its 44 × 44 px touch area now sits above the rest of the row, so a tap a few pixels off the circle no longer opens the task, also while the row is moving (the first swipe hint, a swipe returning). Every row with a circle: lists, Today, board cards, the Daily check and the Loop home. The layout check now taps 8 px around the circle on every screen. (
phone-touch-focus, closes #636) - Today's focus and the Bento slots can be filled by touch. They only answered f. Tap an empty Bento slot in the Daily check to choose a task for it (today's and overdue tasks first, those whose estimate fits the slot first), or Add to focus under Three tasks in the Daily check and on the Loop home. A task's menu (the Actions menu, which a phone opens by holding the task, the task panel and page, and the Focus screen) offers Add to focus or Put in a slot, and Remove from focus, following the same rules as f; a task of a shared project you only view can join your focus too. Every change has Undo, now also f in Three tasks. (Pick the focus by touch,
phone-touch-focus, closes #641) - Reorder tasks on label pages and in saved views (#623, reported by @osenchenko). Order by: Manual order was offered there but dragging or Alt+↑ / ↓ did nothing. A label's page and a saved list view now keep their own manual order: drag a task above or below another one in its group (press and hold on a phone), or move it with Alt+↑ / ↓, Alt+Shift+↑ / ↓ or Vim's Shift+J / K, with Order changed and Undo. Under another order a move switches the page to Manual order first. The order is stored on the label or view (new synced field
manual_order, at most 500 task ids), follows you to your devices, works offline and never reorders a project, so a viewer of a shared project can order their own label page or view. Tasks never moved follow in their project order. The unsaved New view page no longer offers Manual order; save the view first.
Install
- Docker:
docker run -d -p 8080:8080 -v opentodo:/data ghcr.io/opentodoapp/opentodo:0.18.0 - Binary: download
opentodo-<os>-<arch>below, then run it (data goes to./data). - Command-line client:
ot-<os>-<arch>. Browser extension:opentodo-browser-extension-chrome.zipandopentodo-browser-extension-firefox.zip.
Verify downloads with sha256sum -c SHA256SUMS. Self-hosting guides: docs/self-hosting.