- created
- 2026-07-26
- updated
- 2026-10-30
Tasks
Tasks
A task is a Markdown checkbox line whose box character carries a named state. The notation stays
plain GFM — - [ ] and - [x] mean what they always meant — and extra states, priorities, and dates
are ordinary inline text, so a note remains readable anywhere Markdown renders.
Back to track. The commands referenced here are part of the CLI.
Task states
The character inside the brackets names the state (the Obsidian-style custom-checkbox convention):
- [ ] TODO — not started
- [/] DOING — in progress
- [?] WAITING — blocked on someone else
- [x] DONE — finished
- [-] CANCELLED — will not happenDONE and CANCELLED are done-family states: moving a task into one stamps a completion date on the line, and moving it back out removes the stamp again.
The set is fixed — these five states, these five markers, in every vault. A marker is a single character, so a vault that spelled them its own way would give the same pasted line a different meaning somewhere else, and every surface that draws a checkbox (the CLI, the web workspace, the published site, the Neovim plugin) has to know the set to render it. Fixing it is what lets them agree.
Every transition is appended to the note's sidecar metadata (task_log), so the history of when a
task moved between states survives without timestamps piling up in the note body.
Priorities and dates
Bracket tokens anywhere on the task line add metadata:
| Token | Meaning |
|---|---|
[#A], [#B], [#C] | Priority, A highest. Any single letter works. |
[sched:2026-07-18] | Scheduled — the day you plan to work on it. |
[due:2026-07-24] | Deadline — the day it must be finished. |
[done:2026-07-09] | Completion date, written automatically on entering a done-family state. |
Dates are always YYYY-MM-DD, independent of the vault's display date format, so task lines stay
portable between vaults.
- [ ] Write the report [#A] [due:2026-07-24]
- [/] Draft the slides [sched:2026-07-18]Repeating tasks
A [rpt:] token makes a task repeat: entering a done-family state rolls its [sched:] and [due:]
dates forward, so the next occurrence is already on the line. The token is an interval — a count and
one of d, w, m, y — in one of three modes:
| Token | Mode | Next occurrence |
|---|---|---|
[rpt:1w] | Fixed | One interval from the current scheduled/deadline date, whenever it is completed. |
[rpt:+.1w] | From completion | One interval from the completion date, so the cadence drifts with the day it was actually done. |
[rpt:++1m] | Skip | The fixed rhythm, but the first boundary strictly after the completion date — a late completion does not schedule a date that already passed. |
The roll is a side effect of track task set --state DONE (and the other done-family entries),
through the same engine path as the board. Both dates shift by the same offset, keeping their gap; a
line carrying neither gains a [sched:] token for the next occurrence. Month and year intervals clamp
to the end of the target month, so Jan 31 + 1m lands on the last day of February. A malformed token
— an empty or zero interval, an unknown unit — refuses the completion instead of silently stopping the
repeats. The transition is logged in the sidecar task_log like any other; no extra history is
written.
- [ ] Water the plants [rpt:1w] [sched:2026-09-07]Progress cookies
A [n/m] or [p%] cookie on a heading or on a parent list item tracks the tasks beneath it: a
heading counts every task until the next heading of the same or a shallower level, a list item
counts its deeper-indented children. The engine recomputes every cookie whenever a task changes
state, so the numbers never go stale.
## Sprint 12 [1/3]
- [x] Ship the parser
- [ ] Refresh the screenshots
- [ ] Announce it [2/2]
- [x] Draft the post
- [x] Review the postRendering
The notation is all the renderer needs — there is no dedicated fence to wrap a checklist in. In the
live Web workspace and on a published site, a checklist that uses task notation (a custom state
marker, or any bracket token) renders as one task table: a row per line with its state, text,
priority/cookie chips, and scheduled/due columns. The STATE, SCHED, and DUE headers sort the table
(view-only — the note keeps its order), and, live, the state cell is the state control and the date
cells are date pickers, all writing through the same engine path as the board's cards. A row with no
date shows an empty cell until you hover it, so a table you are only reading stays quiet. The whole list switches together, while a
checklist of plain - [ ]/- [x] lines — or one that mixes tasks with plain bullets — keeps its
native checkboxes. Those boxes are not decoration: live, ticking one writes through the same engine
path, so a plain checklist stays a plain checklist and still works. (The [done:] stamp the engine
writes when you tick a box does not count as notation — otherwise checking something would rebuild
the list as a table under your cursor.) Nesting does not split the decision either: an indented
sub-list is part of the checklist it sits in, so notation anywhere in it upgrades the whole thing,
and the nesting comes through as an indent in the table. A list item whose marker is outside the
state set is not a task and stays exactly as written. The note file keeps the plain notation, so a
task line remains readable
anywhere else Markdown renders. In a Neovim vault buffer the state marker conceals to a glyph and
the tokens are highlighted as written; the cursor line stays raw for editing.
CLI
| Command | Purpose |
|---|---|
track task set (--id N | --title S | --path P) --line N --state NAME | Move the task on line N into a named state. |
track task cycle (--id N | --title S | --path P) --line N | Advance the task to the next state in set order, wrapping at the end. |
track tasks [--state A,B] [--due YYYY-MM-DD] [--overdue] [--sort priority] | List indexed tasks as JSON, across the vault or one note. |
track toggle (--id N | --title S | --path P) --line N | Two-state shorthand: flip between the first open and first done state. |
track task set rewrites only the one line: it swaps the state marker, stamps or clears the
[done:...] token, recomputes parent progress cookies, logs the transition in the sidecar, and
reindexes the note. --line is the 1-based line number reported by track search and
track export.
track tasks filters compose: --state TODO,DOING keeps only those states, --due 2026-07-24
keeps open tasks due on or before that date, --overdue keeps open tasks whose deadline has
passed, and --sort priority orders open tasks first, [#A] before [#B] before unprioritized,
ties broken by deadline.
track task set --title "Release plan" --line 12 --state DOING
track tasks --overdue --sort priorityTask board
Task lines render styled wherever they appear; the board is the opt-in note-wide view for working
them. A ```taskboard fence renders the note's tasks as a kanban board — one column per state,
one card per task. The fence body stays empty: the board reads the note's task lines, not the fence
content, so the two lines of the fence are the entire syntax. In the live Web workspace a card
drags between columns (or moves via its state select), which runs the same engine write path as
track task set. On a published static site the board renders read-only.
On the calendar
A [sched:] or [due:] date puts a task on the calendar without anything else being written: the
month grid counts the tasks falling on each day, and the day page lists them under Tasks, marked
▷ for scheduled and ! for due, with the note each came from. A task carrying both dates appears
on both days. A day nothing was written on is still a day something is planned for, so it opens like
any other — on a published site too, which carries the same dated listing.
On the day page, Previous day and Next day move one local calendar day at a time, including across month and year boundaries and onto empty days. The heading, notes, and tasks follow the selected date. Moving between days does not create journals; Journal remains a separate action in the live workspace. The month grid's arrows still move by month, and Current month returns that grid to the current month. These controls also work in the desktop app and on published sites.
Plan today, tomorrow, or this week
At the top of Calendar, choose Today, Tomorrow, or This week to see open dated tasks in an agenda. Previous day/week and Next day/week move the agenda; the top shortcuts return to the current period. Month returns to the activity grid.
In the live workspace, Show: Tasks focuses the agenda on dated work; Events focuses on separate appointments, and All shows both. The selection stays through date and period changes within that Calendar screen. A reload or a newly opened screen starts with All. Day pages offer the same filter while preserving their activity notes and historical task states. Filtering changes visibility only; it does not mark a task complete or create an event. Published calendars keep their task snapshot without this live event filter.
Dates use your device's local calendar. A week runs Sunday through Saturday, matching the month grid, and includes days before today in the current week. Relative views update at local midnight and when the window regains focus. Tasks with both a scheduled day and a deadline appear on both days, once on each. Each row labels Scheduled and Due separately and shows its state and source note. Open the note to edit its task state or dates.
Overdue lists open deadlines before today when the visible period includes today. A task can also appear on its scheduled day: the overdue reminder does not change its dates. WAITING stays visible; DONE and CANCELLED are excluded from this agenda. The month activity grid and day pages still include completed dated tasks. Tasks without dates stay in their notes and are not added to the agenda. No notes or tasks are created by changing views.
A loading or failed task request is shown explicitly, rather than as an empty agenda. These views work in the live workspace, its desktop app, and calendar-enabled published sites, using the same dated task listing. This remains a task agenda. For separate all-day or timed events, use Calendar events in the live workspace.
In a published agenda, date headings are plain text: an empty day may not have an exported page. Task rows still link to their published source notes. In the live workspace, each date heading opens its day page.
Example
A full task section as it is written in a note — the heading cookie counts the tasks below it:
### Release checklist [2/5]
- [/] Write the announcement post [#A] [due:2026-07-24]
- [ ] Refresh the screenshots [#B] [sched:2026-07-18]
- [?] Wait for the mirror to sync
- [x] Tag the release candidate [done:2026-07-09]
- [-] Rewrite the changelog generatorIt renders as:
Release checklist [2/5]
| TASK | |||
|---|---|---|---|
| DOING | Write the announcement post #A | ! 2026-07-24 | |
| TODO | Refresh the screenshots #B | ▷ 2026-07-18 | |
| WAITING | Wait for the mirror to sync | ||
| DONE | Tag the release candidate ✓ 2026-07-09 | ||
| CANCELLED | Rewrite the changelog generator |