Исполняемая команда проекта называется timetk. Во время разработки её обычно
запускают как uv run --no-sync timetk.
timetk [--version] [-p PROFILE] [-o text|json|ndjson] [--debug] COMMAND ...
Глобальные параметры должны стоять до COMMAND:
timetk -p university -o json unread --with-posts| Параметр | Назначение |
|---|---|
--version |
показать версию пакета |
-p, --profile |
выбрать Time-профиль |
-o, --format |
формат stdout: text, json или ndjson |
--debug |
включить диагностические сообщения в stderr |
Профиль обязателен для каждой операции записи. Чтение может использовать профиль по умолчанию, но в скриптах лучше всегда указывать его явно.
| Команда | Назначение и параметры |
|---|---|
profile list |
показать все профили и профиль по умолчанию |
profile add NAME URL |
добавить профиль |
profile show NAME |
показать одну конфигурацию без секретов |
profile update NAME |
изменить существующий профиль |
profile default NAME |
выбрать профиль чтения по умолчанию |
profile remove NAME |
удалить профиль и его токен/CSRF из keyring |
Параметры profile add:
--team-id ID
--timezone IANA_NAME default: Europe/Moscow
--disable-mcp
--write-policy readonly|approval|fullauto
--websocket-host HOST[:PORT] можно повторять
--team-id полезен, если у аккаунта несколько команд и нужна не первая. Для
нового профиля по умолчанию действует approval.
Параметры profile update:
--url URL
--team-id ID
--timezone IANA_NAME
--enable-mcp | --disable-mcp
--write-policy readonly|approval|fullauto
--websocket-host HOST[:PORT] заменить allowlist; можно повторять
--clear-websocket-hosts
--websocket-host разрешает передачу токена на отдельный host, рекламируемый
сервером для realtime-событий. Сначала подтвердите адрес у владельца инстанса.
Указание нескольких параметров заменяет весь текущий allowlist.
Удаление поддерживает --dry-run и --yes. При реальном удалении исчезает только
локальная настройка и локальные секреты; серверная сессия Time не отзывается.
| Команда | Назначение |
|---|---|
| `auth set [--stdin] [--method bearer | cookie] [--csrf]` |
auth status [--check] |
проверить наличие токена; --check делает запрос к Time |
auth clear [--dry-run] [--yes] |
удалить токен и CSRF из keyring |
doctor [--all] [--public] |
проверить сервер, авторизацию, пользователя и команды |
auth set по умолчанию использует скрытый ввод. --stdin предназначен для
защищённого pipe, но вызывающий процесс отвечает за то, чтобы секрет не попал в
лог. --public проверяет сервер без токена. --all возвращает отдельный результат
для каждого профиля и код 1, если хотя бы одна проверка не прошла.
Ни одна команда из этого раздела не отмечает сообщения прочитанными.
| Команда | Параметры | Результат |
|---|---|---|
me |
— | текущий пользователь |
teams |
— | доступные Mattermost-команды |
channels |
--pattern TEXT, `--type O |
P |
categories |
— | sidebar categories выбранного team в серверном порядке |
category-channels CATEGORY |
точный ID или отображаемое имя | доступные каналы папки в её порядке |
dms |
--with USER, --limit N |
личные и групповые диалоги |
resolve |
--user TEXT, --channel TEXT, --limit N |
точные объекты пользователя/канала |
Типы каналов: O — public, P — private, D — direct message, G — group
message. В resolve нужен хотя бы один из --user и --channel.
category-channels сначала использует уже видимые каналы, затем по одному
запрашивает отсутствующие ID. Удалённый или недоступный канал пропускается, не
ломая остальной результат. Команды категорий выполняют только GET-запросы и не
меняют read state.
| Команда | Параметры | Результат |
|---|---|---|
posts CHANNEL |
--author CSV, --contains TEXT, --since TIME, --until TIME, --limit N |
сообщения канала, новые первыми |
search QUERY |
--channel CSV, --author CSV, границы времени, --limit N |
глобальный поиск по доступной команде |
thread TARGET |
— | root и все ответы, старые первыми |
threads |
--limit N, --with-posts |
отслеживаемые треды |
unread |
--channel CHANNEL, --with-posts, --limit N |
unread-счётчики и при необходимости сообщения |
mentions |
--unread, --channel CSV, границы времени, --limit N |
исторические или непрочитанные упоминания |
flagged |
--channel CHANNEL, --limit N |
сообщения, отмеченные флагом |
pinned CHANNEL |
— | закреплённые сообщения канала |
user USERNAME |
границы времени, --limit N |
пользователь и сводка активности |
posts-by-user |
--user CSV, --channel CSV, границы времени, --limit N |
сообщения выбранных авторов |
CSV означает значения через запятую без пробелов либо с пробелами вокруг
разделителя. Имена пользователей можно передавать с @ или без него.
| Команда | Назначение |
|---|---|
reactions TARGET |
реакции на сообщение |
readers TARGET [TARGET ...] |
read receipts для собственных сообщений |
file info FILE_ID |
метаданные вложения |
file download FILE_ID --output PATH [--overwrite] |
потоково скачать файл |
Скачивание сначала пишет временный файл рядом с назначением, затем атомарно его
заменяет. Без --overwrite существующий файл не меняется.
Общие параметры всех серверных записей:
| Параметр | Поведение |
|---|---|
--dry-run |
вывести точный план и завершиться без записи |
--yes |
подтвердить неинтерактивную автоматическую запись |
Без этих параметров CLI показывает план и спрашивает Proceed? [y/N]. В pipe или
другом неинтерактивном stdin отсутствие --yes даёт код 8.
Локальная политика проверяется перед каждым изменением:
| Политика | Интерактивное подтверждение | --yes |
|---|---|---|
readonly |
запрещено | запрещено |
approval |
разрешено | запрещено |
fullauto |
разрешено | разрешено |
| Команда | Аргументы | Изменение |
|---|---|---|
post TARGET |
-m/--message TEXT, повторяемый --file-id ID, --idempotency-key KEY |
новое сообщение в канале или @username |
reply TARGET |
те же параметры | ответ в тред |
edit TARGET |
-m/--message TEXT |
изменить своё сообщение |
delete TARGET |
— | удалить своё сообщение |
pin TARGET, unpin TARGET |
— | изменить закрепление |
react TARGET EMOJI, unreact TARGET EMOJI |
— | добавить/удалить реакцию |
flag TARGET, unflag TARGET |
— | изменить личный флаг |
follow TARGET, unfollow TARGET |
— | изменить подписку на тред |
mark-unread TARGET |
— | отметить сообщение непрочитанным |
mark-read CHANNEL |
— | отметить канал просмотренным |
file upload CHANNEL FILE [FILE ...] |
— | загрузить локальные файлы |
Если --message отсутствует или равен -, post, reply и edit читают текст
из stdin. В интерактивном терминале отсутствие текста считается ошибкой, чтобы
команда не зависла в ожидании ввода.
post и reply создают случайный idempotency key, если он не задан. Передавайте
свой стабильный ключ при повторе одной логической отправки после сбоя. Не
используйте один ключ для разных сообщений.
Примеры:
timetk -p university post general -m "Привет" --dry-run
timetk -p university post @alex -m "Привет"
printf '%s' 'Текст из процесса' | \
timetk -p university -o json reply POST_ID --yes --idempotency-key job-1842
timetk -p example mark-read engineeringПоследняя команда с политикой approval разрешена только после интерактивного
подтверждения. Добавление --yes приведёт к коду 4; для automation сначала
нужно осознанно выбрать fullauto.
Канал можно задать:
- 26-символьным Mattermost ID;
- точным системным именем, с
~или без него; - единственным совпадением по системному или отображаемому имени.
Если частичное имя совпало с несколькими каналами, команда завершается кодом 7
и перечисляет варианты в details.matches. Автоматический выбор запрещён.
TARGET сообщения или треда принимает 26-символьный ID либо Time URL, содержащий
/thread/ID, /pl/ID или /posts/ID.
--since и --until принимают:
- дату
2026-07-20; - ISO 8601, например
2026-07-20T12:30:00+03:00или...Z; - относительное значение
7d,24h,30m.
Дата и время без offset трактуются в таймзоне профиля. Для --until 2026-07-20
используется конец дня 23:59:59.999, то есть верхняя граница включительна.
Относительное значение всегда означает момент в прошлом от времени запуска.
watch [--channel CHANNEL ...] [--event TYPE ...] [--once]
[--max-events N] [--lifecycle] [--no-reconnect] [--max-reconnects N]
По умолчанию выбирается событие posted, каналы не фильтруются, а
переподключение продолжается без ограничения. --max-reconnects 0 означает
неограниченное число попыток. Задержка растёт 1, 2, 4 секунды и ограничена 30
секундами. Последние 2000 нормализованных событий дедуплицируются в памяти.
Для -o json и -o ndjson поток всегда выдаёт NDJSON: один завершённый объект на
строку. --once останавливает поток после первого подходящего события;
--max-events N — после N событий.
--lifecycle добавляет служебную строку перед событиями каждого соединения.
У неё meta.kind="lifecycle", а data содержит state="connected",
reconnected и connection_id. На этой строке долговременный consumer должен
выполнить REST catch-up с overlap до обработки следующих строк. Lifecycle-строки
всегда записываются раньше обычных событий соединения и не учитываются в --once
и --max-events.
Рекламируемый сервером WebSocket URL автоматически принимается только для того же
hostname и порта, что основной профиль. Другой endpoint нужно разрешить через
profile update --websocket-host HOST[:PORT]; downgrade с HTTPS на ws://
блокируется всегда.
| Команда | Назначение |
|---|---|
mcp |
запустить MCP-сервер по STDIO |
service-key create |
создать или ротировать ключ HTTP API; значение показывается один раз |
service-key status |
проверить наличие ключа без его вывода |
service-key clear |
удалить ключ |
serve |
запустить read-only HTTP API |
service-key create спрашивает подтверждение только при ротации существующего
ключа. --dry-run всегда показывает эффект без изменения. serve принимает
--host (по умолчанию 127.0.0.1), --port (по умолчанию 8765) и
--allow-network. Нелокальный host без --allow-network отклоняется.
text рассчитан на человека и не считается стабильным машинным контрактом.
json возвращает envelope:
{
"profile": "university",
"server": "https://time.cu.ru",
"data": {},
"meta": {},
"schema_version": "1.0"
}data бывает объектом, массивом или скаляром. Dataclass-модели рекурсивно
преобразуются в JSON. ndjson выдаёт по строке на элемент массива; у каждой
строки есть schema_version, profile, server и data. Непустое meta
переносится в строку аддитивно. Для одиночного результата получается одна строка.
Ошибки идут в stderr. В json и ndjson формат один:
{"schema_version":"1.0","error":"...","code":5,"details":{}}Stdout можно безопасно направить парсеру, не смешивая его с диагностикой stderr.
| Код | Значение |
|---|---|
| 0 | успех |
| 1 | общая ошибка или неуспешный doctor --all |
| 2 | неверные параметры или неподдерживаемое действие |
| 3 | токен отсутствует, истёк или отклонён |
| 4 | операция запрещена правами Time или локальной политикой |
| 5 | профиль, канал, сообщение или другой объект не найден |
| 6 | ошибка сети |
| 7 | конфликт, неоднозначный канал или существующий файл |
| 8 | требуется подтверждение или пользователь отменил операцию |
| 130 | процесс прерван Ctrl+C |
Скрипт должен разбирать JSON ошибки и код завершения, а не текст сообщения.