CLI tool for managing TODO.md files
Project description
ltc
CLI-инструмент для управления TODO.md файлами прямо из терминала.
ltc читает и записывает обычные markdown-файлы с задачами — без базы
данных, без проприетарных форматов, без привязки к редактору. Изменения
применяются точечно через patch-based сериализатор: ваш TODO.md
сохраняет комментарии, пустые строки и форматирование нетронутыми.
$ ltc init
Created TODO.md
$ ltc add backend: Реализовать API [!!]
Created group backend
Added Реализовать API → backend
$ ltc add auth Добавить OAuth2 -n "Использовать PKCE flow"
Added Добавить OAuth2 → auth
$ ltc done auth
Done: Добавить OAuth2
$ ltc
## backend
✓ backend.1 Реализовать API [!!]
## auth
✓ auth.1 Добавить OAuth2
1/2 tasks done
Содержание
- Установка
- Быстрый старт
- Формат TODO.md
- Команды
- Reference resolution
- Приоритеты
- Опции
- Разработка
- Лицензия
Установка
Из исходников (uv)
git clone https://github.com/liannnix/ltc.git
cd ltc
uv sync
uv run ltc --help
Глобальная установка (pip)
pip install .
ltc --help
Требование: Python ≥ 3.12
Быстрый старт
ltc init # создать TODO.md
ltc Fix баг в парсере # добавить задачу в Inbox
ltc !! tests: Покрыть тестами → группа tests, высокий приоритет
ltc # показать список
ltc done 1 # отметить выполненной
Формат TODO.md
ltc работает с обычными markdown-файлами. Пример:
# TODO
## Backend
- [ ] Реализовать API [!!]
- [x] Настроить роутинг
- [ ] Добавить middleware
Использовать composition pattern
- [ ] Деплой на staging
## Inbox
- [ ] Купить кофе
Элементы формата
| Элемент | Синтаксис | Описание |
|---|---|---|
| Группа | ## Name |
Заголовок второго уровня |
| Задача | - [ ] Title |
Незавершённая |
| Выполнена | - [x] Title |
Завершённая |
| Подзадача | - [ ] Title |
Вложенный чекбокс (отступ 2+) |
| Описание | Текст с отступом |
Строки ниже задачи без чекбокса |
| Приоритет | Title [!!] |
Маркер в конце строки задачи |
Группа Inbox
Задачи без указанной группы попадают в Inbox. Inbox всегда отображается последним при выводе списка. Новые группы вставляются перед Inbox в файле. Пустой Inbox не отображается.
Приоритеты
| Маркер | Уровень | Пример |
|---|---|---|
[!!] |
Высокий | - [ ] Срочный баг [!!] |
[!] |
Средний | - [ ] Важно, но не срочно [!] |
[] |
Низкий | - [ ] Когда-нибудь [] |
| нет | Обычный | - [ ] Обычная задача |
Приоритет указывается в конце строки задачи. Маркер не в конце строки считается частью названия.
Подзадачи
Подзадачи обозначаются вложенным чекбоксом с отступом (2+ пробела или таб) относительно родительской задачи. Уровень вложенности определяется относительным отступом, а не абсолютным количеством пробелов:
- [ ] Родительская задача
- [ ] Дочерняя задача (отступ 2)
- [ ] Внучатая задача (отступ 4)
Deep nested description
Описания
Описание задачи — текст с отступом ниже чекбокса, не являющийся подзадачей. Описание может быть многострочным и содержать code blocks:
- [ ] Реализовать OAuth2
Использовать PKCE flow
const verifier = generateCodeVerifier();
Passthrough
Строки, не распознанные как элементы TODO (комментарии, произвольный
текст, H3+ заголовки), сохраняются как есть и не модифицируются при
сериализации.
Команды
init — создать файл
Создаёт пустой TODO.md с заголовком и группой Inbox.
ltc init
# TODO
## Inbox
С указанием пути:
ltc init -f ~/projects/myapp/TODO.md
ls — список и фильтры
Без аргументов — вывод всех задач по группам:
ltc ls
## Backend
✓ backend.1 Реализовать API [!!]
✓ backend.1.1 Настроить роутинг
[ ] backend.1.2 Добавить middleware
[ ] backend.2 Деплой на staging
## Inbox
[ ] inbox.1 Купить кофе
3/5 tasks done
Фильтры
Аргументы к ls объединяются через AND:
| Фильтр | Пример | Действие |
|---|---|---|
| Группа | ltc ls backend |
Только задачи группы backend |
| Приоритет | ltc ls !! |
Только высокий приоритет |
| Приоритет | ltc ls ! |
Только средний приоритет |
| Статус | ltc ls done |
Только завершённые |
| Статус | ltc ls undone |
Только незавершённые |
| Подстрока | ltc ls auth |
Title содержит "auth" (ignorecase) |
Комбинирование:
# Незавершённые задачи с высоким приоритетом в backend
ltc ls backend !! undone
# Все незавершённые задачи, содержащие "api"
ltc ls undone api
# Завершённые подзадачи в группе auth
ltc ls auth done
Короткая форма
ltc без субкоманды и без аргументов — то же, что ltc ls:
ltc # = ltc ls
add — добавить задачу
Команда add использует order-independent парсинг аргументов:
порядок токенов не важен. Команда сама определяет, что вы хотите —
новую задачу, подзадачу или группу.
Базовые примеры
# Простая задача в Inbox
ltc add Fix баг в парсере
# То же самое через default-команду (без слова add)
ltc Fix баг в парсере
# Задача с высоким приоритетом
ltc add !! Fix критический баг
ltc add Fix критический баг !! # порядок не важен
# Задача в конкретной группе (группа создаётся автоматически)
ltc add backend: Реализовать API [!!]
# Все токены можно менять местами
ltc add [!!] Реализовать API backend:
ltc add Реализовать API backend: !!
Группа автоматически создаётся
Если указана группа, которой не существует — она создаётся автоматически:
ltc add tests: Написать unit-тесты
Created group tests
Added Написать unit-тесты → tests
Подзадачи через ref
Если первый значимый токен резолвится в существующую задачу — создаётся подзадача:
# По точному ID
ltc add 1 Добавить валидацию
ltc add backend.1 Обработать ошибки
# По fuzzy-совпадению
ltc add api Добавить rate limiting
# → подзадача к "Реализовать API"
# С приоритетом и описанием
ltc add 1 Важная подзадача !! -n "Не забыть про edge cases"
С описанием
ltc add Настроить CI/CD -n "GitHub Actions + Docker"
ltc add auth: Интеграция с Google -n "OAuth2, scope: email profile"
Создание пустой группы
Если указать только группу без названия задачи:
ltc add docs:
Created group docs
done / undone — статус
Отмечает задачу выполненной или возвращает в pending. Если у задачи есть подзадачи — они меняют статус вместе с родителем.
# По индексу
ltc done 1
# По group.index
ltc done backend.2
# По fuzzy
ltc done deploy
ltc done auth
# Возврат в pending
ltc undone 1
ltc undone auth
Пример каскадного выполнения:
$ ltc done backend.1
Done: Реализовать API
2 child(ren) also marked done
edit — редактирование
Изменяет существующую задачу. Ref обязателен. Все остальные параметры опциональны и применяются частично — только то, что указано.
Изменение названия
ltc edit 1 Новое название
ltc edit backend.1 Refactor API layer
Изменение приоритета
ltc edit 1 [!!]
ltc edit auth !!
ltc edit backend.2 [] # низкий приоритет
Изменение описания
ltc edit 1 -n "Новое описание"
ltc edit auth -n "Updated: использовать Keycloak"
Перемещение между группами
ltc edit 1 frontend:
ltc edit backend.2 inbox:
Комбинированное редактирование
# Название + приоритет + группа + описание — всё сразу
ltc edit 1 Новый заголовок !! frontend: -n "Полное обновление"
# То же самое в другом порядке токенов
ltc edit 1 frontend: !! Новый заголовок -n "Полное обновление"
Только описание (без названия)
ltc edit 1 -n "Только меняю описание, title не трогаю"
rm — удаление
Удаляет задачу и все её подзадачи.
# По индексу
ltc rm 1
# По group.index
ltc rm backend.2
# По fuzzy
ltc rm deploy
note — описание
Устанавливает описание задачи. Удобно для добавления деталей без
полного edit.
ltc note 1 JWT-based auth with RS256
ltc note auth Использовать PKCE flow вместо implicit
groups / group — управление группами
groups — таблица групп
ltc groups
Group Tasks Done
─────────────────────────
Backend 5 3
Auth 2 2
Tests 4 1
group — создать пустую группу
ltc group DevOps
Created group DevOps
Reference resolution
Аргумент <ref> во всех командах (done, undone, edit, rm,
note, add для подзадач) резолвится следующими способами:
| Приоритет | Формат | Пример | Описание |
|---|---|---|---|
| 1 | group.index |
backend.1 |
Имя группы + номер задачи |
| 1 | group.idx.sub |
backend.1.2 |
Группа + путь к подзадаче |
| 2 | N.M |
2.3 |
Глобальный индекс группы и задачи |
| 3 | N |
5 |
Сквозной номер задачи |
| 4 | fuzzy |
auth |
Substring-поиск по title |
Примеры fuzzy
# Задача "Реализовать API [!!]" в группе backend
ltc done api # ✓ 1 match → resolved
ltc done реализовать # ✓ 1 match → resolved (ignorecase)
# Две задачи с "test" в названии
ltc done test # ✗ "Ambiguous match. Candidates:"
# Backend: Test parser
# Tests: Test serializer
# Нет совпадений
ltc done xyz # ✗ "Nothing matches 'xyz'"
Ref в команде add
При добавлении подзадачи ref определяется автоматически из токенов:
# "1" похож на ID → всегда трактуется как ref
ltc add 1 Subtask title
# "api" НЕ похож на ID → fuzzy, но есть title → становится ref
ltc add api Refactor endpoints
# "auth" единственный токен → не ref, а название новой задачи
ltc add auth
# → создаётся задача "auth" в Inbox, а НЕ подзадача
# Fuzzy + приоритет + описание
ltc add api rate limiting !! -n "100 req/min"
Опции
--file / -f
Все команды поддерживают указание пути к TODO.md:
ltc ls -f ~/projects/myapp/TODO.md
ltc add Fix bug -f ~/work/project/TODO.md
ltc done 1 -f ~/projects/myapp/TODO.md
По умолчанию используется ./TODO.md.
--note / -n
Добавление или изменение описания задачи:
ltc add Task -n "Описание задачи"
ltc add 1 Subtask -n "Детали подзадачи"
ltc edit 1 -n "Обновлённое описание"
Разработка
Технологии
- Python ≥ 3.12
- Typer — CLI-фреймворк
- Rich — форматирование вывода
- uv — управление зависимостями
- ruff — линтер
- mypy (strict) — типизация
- pytest — тесты
Команды разработки
uv sync # установить зависимости
uv run pytest # запустить тесты
uv run pytest --cov=ltc # тесты с покрытием
uv run ruff check # линтер
uv run mypy ltc # типизация
Архитектура
Подробное описание архитектуры — в docs/ARCHITECTURE.md.
Лицензия
GPL-3.0-or-later © Andrey Limachko
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file liannnix_todo_cli-1.1.0.tar.gz.
File metadata
- Download URL: liannnix_todo_cli-1.1.0.tar.gz
- Upload date:
- Size: 4.8 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.0 {"installer":{"name":"uv","version":"0.10.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"ALT Workstation","version":"11.2","id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fe6be5954f6f59efb1336934d5c035ecbb7dc11e1c8678c71326d9900816ad77
|
|
| MD5 |
dbfda54eb45031cbfa466ea6a0257120
|
|
| BLAKE2b-256 |
0d6e77b47b4496fd40cf15f63926fd708b20a6fff828aadef93993339bb9ec75
|
File details
Details for the file liannnix_todo_cli-1.1.0-py3-none-any.whl.
File metadata
- Download URL: liannnix_todo_cli-1.1.0-py3-none-any.whl
- Upload date:
- Size: 39.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.0 {"installer":{"name":"uv","version":"0.10.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"ALT Workstation","version":"11.2","id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8657066415e41478d54f6445e746f3be4f353e1f939880a85b2e2bd27cfcd0d7
|
|
| MD5 |
61483e1131f34150e3e2b5d5538c2ef7
|
|
| BLAKE2b-256 |
035c9f0717a321b8c774e8b76e17b3b9b6e0d95f19c8c0dd959835be6631a6fb
|