Skip to content
leberton-devPublic

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

49 Commits

Folders and files

Repository files navigation

mya

Move Your Ass.

I program, watch videos and game all day, but I don't take care of my house and sometimes not even of myself. mya is a CLI that fixes that: it hooks into zsh and locks me out of my terminal while a task is overdue.

How the lock works

mya init zsh prints a hook that runs mya task check before every prompt (precmd). As long as a task is overdue (exit code 3), the shell is replaced by a restricted prompt:

overdue tasks
  - vacuum
  - do the dishes
terminal locked: only mya commands allowed (e.g. 'done bags'), Ctrl+D to quit
mya task>

At this prompt only task sub-commands are accepted, without the mya task prefix. Mark the overdue tasks as done (done vacuum) to get your terminal back.

Installation

You need uv. From the repository root:

uv tool install .

Shell setup

In your .zshrc:

# mya: lock the terminal while a task is overdue
eval "$(mya init zsh)"

Example

$ mya task add "do the dishes" --every 1 --at 21:00
$ mya task done "do the dishes"
$ mya task list
NAME                                      DUE       AT     REPEAT     LAST DONE
do the dishes                             tomorrow  21:00  every 1d   2026-10-07

Commands

Every command accepts -h for its full usage.

Task

Command Description
mya task add (--every N | --on DAYS) --at HH:MM [--no-freeze] NAME Create a task
mya task edit [--every N | --on DAYS] [--at HH:MM] [--no-freeze] NAME Change the schedule of a task
mya task remove NAME Delete a task
mya task done NAME Mark a task as done
mya task list List all tasks
mya task today List the tasks due today
mya task tomorrow List the tasks due tomorrow
mya task check Exit with code 3 if a task is overdue (used by the shell hook)
mya task freeze [--until YYYY-MM-DD] Suspend the lock
mya task unfreeze Resume the lock

Timer

Command Description
mya timer new --for DURATION [--font FONT] [--frame FRAME] [--then-done NAME] Start a countdown

Other

Command Description
mya init zsh Print the zsh hook
mya --version Print the version

Scheduling: --on vs --every

--on schedules a task on specific days of the week, as a comma-separated list: --on mon,thu. Available days: mon,tue,wed,thu,fri,sat,sun.

--every schedules a task every N days: --every 1, --every 15, --every 30. N must be an integer.

The two flags are mutually exclusive. One of them is required in mya task add; both are optional in mya task edit.

Freeze

For vacations, or when you're simply not at home, mya task freeze stops mya from locking the terminal. With --until YYYY-MM-DD (a date in the future) the freeze ends by itself on that date. Without it, the freeze lasts until mya task unfreeze.

A task created with --no-freeze ignores freezes: it still locks the terminal while frozen. On mya task edit, --no-freeze is a toggle: it flips the setting of the task, so passing it to a non-freezable task makes it freezable again.

Timer

For tasks where I tell myself "I'll do this for 10 minutes":

mya timer new --for 25m --then-done "do the dishes"

--then-done NAME marks the task as done once the timer is finished.

The look of the timer can be changed with --font and --frame:

  • Fonts: NUMBER, SEG, BLOCK, DOT
  • Frames: SQUARE, ROUNDED, ASCII, SHADE

Exit codes

Code Where When
0 everywhere success
1 task add task already exists
1 task edit, task remove, task done task does not exist
1 task freeze already frozen, or --until is not in the future
1 task unfreeze not frozen
1 task today, task tomorrow no due task
2 mya without sub-command shows help
2 task edit --on and --every passed together
2 argparse (automatically) wrong arguments, unknown option
3 task check at least one task is overdue
4 all commands tasks.json or freeze.json unreadable or corrupted
130 timer interrupted by Ctrl-C

Data location

All data lives in $XDG_DATA_HOME/mya/, or ~/.local/share/mya/ if XDG_DATA_HOME is not set:

  • tasks.json: the tasks
  • freeze.json: the freeze state

A task is saved as follows:

{
  "do the dishes": {
    "name": "do the dishes",
    "every": 1,
    "on": null,
    "at": "21:00",
    "last_done": "2026-10-07",
    "freezable": true
  }
}

Exactly one of every and on is set, the other is null.

Known limitations

  • A task at 00:00 never shows up in today or tomorrow: the window runs from 00:01 to 23:59. The same goes for a task at 23:59:30 if --at is given with seconds. This is the current intended behavior and is covered by a test.

Ideas

  • A mya finance module to track my finances
  • A plugin to block YouTube and other websites
  • Revisit the today/tomorrow window (see above)

Development

Commits follow Conventional Commits, which drive the version number:

Commit Effect on version
feat: ... minor
fix: ... patch
docs: ..., chore: ..., refactor: ..., test: ... none
feat!: ..., fix!: ... major (breaking change)

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages