Skip to main content

CLI-first todo manager with local SQLite storage

Project description

mb-todo

CLI-first todo manager. Data stored locally in SQLite. All GUIs (Raycast extension, etc.) interact through CLI commands with --json flag — CLI is the single source of truth.

Data Model

Project

Field Type Description
name TEXT NOT NULL PRIMARY KEY Project name

Todo

Field Type Nullable Description
id INTEGER PRIMARY KEY AUTOINCREMENT NO Short numeric ID for CLI ergonomics
title TEXT NOT NULL NO Todo title
body TEXT YES Extended description
closed INTEGER NOT NULL DEFAULT 0 CHECK (closed IN (0, 1)) NO 0 = open, 1 = closed
priority TEXT NOT NULL DEFAULT 'medium' CHECK (priority IN ('low','medium','high')) NO Priority level
project TEXT REFERENCES projects(name) ON UPDATE CASCADE ON DELETE RESTRICT YES Project name (direct FK)
tags TEXT NOT NULL DEFAULT '[]' NO JSON array of tag strings
created_at INTEGER NOT NULL NO Unix timestamp
closed_at INTEGER YES Unix timestamp, set on close
updated_at INTEGER NOT NULL NO Unix timestamp, set to created_at on insert

Indices

CREATE INDEX idx_todos_closed ON todos(closed);
CREATE INDEX idx_todos_project ON todos(project) WHERE project IS NOT NULL;

Design Decisions

  • Integer IDs — CLI ergonomics (mb-todo close 42)
  • Projects as name-only table — a project is just a label picked from a list; no metadata needed
  • Text FK for project — eliminates JOINs, project name stored directly in todos
  • RESTRICT on project delete — prevents orphaning; user must reassign todos first
  • CASCADE on project rename — transparent propagation
  • Tags as JSON array — simpler schema, queryable via json_each(), no junction table needed
  • updated_at NOT NULL — set to created_at on insert, refreshed on update; "never modified" = updated_at == created_at
  • closed_at nullable — set when closing, enables "done today/this week" queries
  • Priority defaults to medium
  • Timestamps as unix seconds
  • SQLite STRICT mode
  • No due_date — deferred; can add via migration later if needed

CLI

Global Flags

Flag Short Description
--json JSON output
--data-dir PATH Data directory (env: MB_TODO_DATA_DIR, default: ~/.local/mb-todo/)
--version Print version and exit

Todo Commands

mb-todo add <title>

Create a new todo.

Option Short Type Description
--body TEXT Extended description
--priority -P low|medium|high Priority level (default: medium)
--project -p TEXT Assign to project (partial name ok, comma-separated for multiple — creates one todo per project)
--tag -t TEXT (multiple) Add tags (repeatable)

mb-todo list

List todos. By default shows only open todos, sorted by updated_at (newest first).

Option Short Type Description
--closed FLAG Show only closed todos
--all -a FLAG Show all todos (open + closed)
--project -p TEXT Filter by project (partial name ok)
--priority -P low|medium|high Filter by priority
--tag -t TEXT Filter by tag
--sort -s created|priority|updated Sort order (default: updated)
--limit -n INT Max number of results

mb-todo show <id>

Show a single todo with all fields.

mb-todo edit <id>

Edit a todo. At least one option is required.

Option Short Type Description
--title TEXT New title
--body TEXT New body
--priority -P low|medium|high New priority
--project -p TEXT New project (partial name ok, empty to unset)
--tag -t TEXT (multiple) Replace all tags (repeatable)
--add-tag TEXT (multiple) Add tags (repeatable)
--remove-tag TEXT (multiple) Remove tags (repeatable)

Errors: NO_CHANGES if no options provided, TAG_CONFLICT if --tag used with --add-tag/--remove-tag.

mb-todo close <id>...

Close one or more todos. Sets closed = 1 and closed_at to current timestamp. Multiple IDs are processed best-effort.

mb-todo reopen <id>...

Reopen one or more closed todos. Sets closed = 0 and closed_at to null. Multiple IDs are processed best-effort.

mb-todo delete <id>...

Permanently delete one or more todos. Asks for confirmation before deleting (interactive mode only). Multiple IDs are processed best-effort.

Option Short Type Description
--yes -y FLAG Skip confirmation prompt

Project Commands

Subgroup: mb-todo project <command>

mb-todo project list

List all projects.

mb-todo project add <name>

Create a new project. Error: PROJECT_EXISTS if name is taken.

mb-todo project rename <old> <new>

Rename a project. All todos referencing the old name are updated automatically (CASCADE). Error: PROJECT_EXISTS if new name is taken.

mb-todo project delete <name>

Delete a project. Requires exact project name. Error: PROJECT_HAS_TODOS if any todos reference the project (unless --with-todos).

Option Short Type Description
--yes -y FLAG Skip confirmation prompt
--with-todos FLAG Also delete all todos assigned to this project

JSON Envelope

All --json output uses a consistent envelope (matches mb-pomodoro):

{"ok": true, "data": {...}}
{"ok": false, "error": "CODE", "message": "..."}

Error Codes

Code Description
TODO_NOT_FOUND Todo ID does not exist
ALREADY_CLOSED Todo is already closed
ALREADY_OPEN Todo is already open
PROJECT_NOT_FOUND Project name does not exist
AMBIGUOUS_PROJECT Partial project name matches multiple projects
PROJECT_EXISTS Project name already taken
PROJECT_HAS_TODOS Cannot delete project with assigned todos
NO_CHANGES edit called with no options
TAG_CONFLICT --tag used together with --add-tag/--remove-tag
VALIDATION_ERROR General input validation failure

Configuration

Optional TOML config file at {data_dir}/config.toml. If absent, all defaults apply.

TUI Columns

Column display order is fixed: id, status, priority, project, age, tags, body, title.

id and title are always shown. Optional columns (status, priority, project, age, tags, body) are shown by default with smart auto-hiding:

  • Filter-based: columns hidden when their filter is active (e.g., status hidden when filtering by open/closed)
  • Data-based: columns hidden when data is uniform or empty (e.g., tags hidden if no todos have tags, priority hidden if all same)

Force-hide columns via config:

[tui]
hide_columns = ["age"]

TUI Filters

Filter state is persisted automatically when changed in the TUI:

[tui.filters]
project = "work"
status = "open"
priority = "high"
tag = "urgent"
  • statusopen (default), closed (omitted = all)
  • project — project name (omitted = all projects)
  • prioritylow, medium, or high (omitted = all priorities)
  • tag — exact tag string (omitted = all tags)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mb_todo-0.0.11.tar.gz (26.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mb_todo-0.0.11-py3-none-any.whl (41.2 kB view details)

Uploaded Python 3

File details

Details for the file mb_todo-0.0.11.tar.gz.

File metadata

  • Download URL: mb_todo-0.0.11.tar.gz
  • Upload date:
  • Size: 26.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for mb_todo-0.0.11.tar.gz
Algorithm Hash digest
SHA256 4c55f8f4060f85a94952e3265a1e406c0d5e7a1912aaa55c04c643b58043044e
MD5 46bce16247dbcc105f16dd114fef93fa
BLAKE2b-256 7bf90fc2eb5b51a3bb115d557737782d1576a015aaab23e0b956b7f86b2db679

See more details on using hashes here.

File details

Details for the file mb_todo-0.0.11-py3-none-any.whl.

File metadata

  • Download URL: mb_todo-0.0.11-py3-none-any.whl
  • Upload date:
  • Size: 41.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for mb_todo-0.0.11-py3-none-any.whl
Algorithm Hash digest
SHA256 74b283b70c9ee6cf5deaa262859b92377487a1da9304fe3d9abff21e0cb6a403
MD5 4c5e6a8f8b8c6199e1aeb9343d7bf5f1
BLAKE2b-256 3c77b0329a89823b1d02ccd243b912c46ca85cc5eeb21b3f9bd0a6da63dc5466

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page