mdtask
Source: RogerSquare/mdtask · mdtask on npm Category: Project tour
mdtask — a command-line task manager. Tasks are plain Markdown files in a .tasks/ directory inside your project. Schema is just YAML frontmatter; there’s no database, no cloud. Grep it, git-track it, hand-edit it.
What it is
Section titled “What it is”A Node CLI installed globally or run via npx. Commands manage a local .tasks/ directory: add, list, complete, edit, filter by tag/priority/status. Each task is one .md file with structured metadata on top and a freeform body below.
If the pattern sounds familiar — it’s the same one as Atrium’s task board, extracted into a standalone CLI for personal tracking without the web UI.
| Layer | Technology |
|---|---|
| Language | TypeScript |
| Runtime | Node 18+ (distributed on npm) |
| Install | npm install -g mdtask or npx mdtask |
Commands
Section titled “Commands”mdtask add "Buy groceries" -p high -t shoppingmdtask list # all open tasksmdtask list -t shopping # filter by tagmdtask list --status donemdtask done <id> # mark completemdtask edit <id> # opens in $EDITORmdtask rm <id>File shape
Section titled “File shape”---id: 001title: Buy groceriesstatus: todopriority: hightags: [shopping]created_at: 2026-04-12---
Milk, eggs, coffee.Files live at .tasks/001.md, .tasks/002.md, etc. IDs are sequential within the directory.
Non-obvious design choices
Section titled “Non-obvious design choices”- Per-project
.tasks/directory. Tasks live next to the code they’re about. Cloning a repo gets you the tasks..gitignoreit if you want them private. - No global task store. Run the command inside a project; it finds or creates
.tasks/at the nearest ancestor. Intentional: prevents a giant personal task blob across all projects. - YAML is the schema. Add a field to the frontmatter; it shows up in
listoutput. No migrations. - Uses
$EDITORfor edits. Instead of building an interactive UI, delegate to the editor the user already knows.
Gotchas
Section titled “Gotchas”- Frontmatter order matters for readability, not parsing.
gray-matterhandles any order, but keepidandtitleat the top soheadandcatare useful. - IDs are sequential, not UUIDs. Easier to type; hard to merge across copies of
.tasks/from different branches. If you git-branch and both branches add tasks, you’ll collide on ids at merge time. - No concurrent-edit protection. If two shells run
mdtask addsimultaneously, you can get duplicate ids. Rare in practice for a personal CLI. - Editor integration is primitive.
mdtask edit <id>just opens the file; it doesn’t know the task is nowin_progress. For that, use the API-style pattern in Atrium.
See also
Section titled “See also”- patterns/markdown-as-database — the data-model pattern mdtask and Atrium share
- projects/atrium — the web-UI counterpart to this CLI