Я наблюдал, как умные, организованные люди пользуются ручными трекерами времени. Паттерн отказа всегда одинаковый.
В понедельник утром они помнят запустить таймер. К понедельничному дню они переключают контекст шесть раз и забывают переключить таймер вместе с ним. Во вторник замечают и обновляют записи понедельника по памяти. К среде таймер висит на «Email» четыре часа, потому что именно этот проект был открыт, когда они отвлеклись.
Данные неправильные, и человек, который их ведёт, знает, что они неправильные. Поэтому доверяет им меньше. Поэтому обновляет реже. Поэтому становится хуже. Ручной трекинг времени — это коллапс в замедленной съёмке.
Я пытался годами стать дисциплинированным исключением. Не стал. Никто из моих знакомых не стал. Тогда вопрос становится другим: если ручной трекинг — это фантазия, что реально захватывает автоматический трекинг и достаточно ли этого?
Что «автоматическое» на самом деле означает
Примерно три вещи, которые Mac может знать о том, что ты делаешь в любой момент, — и всё это без твоего участия:
Какое приложение на переднем плане. macOS публикует уведомление
NSWorkspaceкаждый раз, когда меняется активное приложение. Это жёсткий сигнал — система знает, Slack или Xcode сейчас сверху.Что написано в заголовке сфокусированного окна. Большинство приложений называют окна осмысленно. Xcode показывает проект. Slack — канал. Chrome — заголовок вкладки. Это мягкий сигнал — полезный, когда заголовки описательные, и бесполезный, когда нет (привет, Finder).
Какая вкладка браузера активна. Это требует, чтобы браузер передавал заголовок вкладки клиенту Accessibility — а на macOS это значит явно попросить у пользователя разрешение. Только по запросу.
Хороший автоматический трекер времени для Mac слушает всё три. Timex слушает всё три. То, что он хранит, — это поток строк, который выглядит примерно так:
2026-05-21 14:32:01 | Xcode | timex/AppDelegate.swift
2026-05-21 14:32:02 | Xcode | timex/AppDelegate.swift
2026-05-21 14:32:03 | Xcode | timex/AppDelegate.swift
2026-05-21 14:32:04 | Slack | #engineering
2026-05-21 14:32:05 | Slack | #engineering
2026-05-21 14:32:06 | Chrome | github.com — pull request #482
Вот и всё. Три колонки, одна строка в секунду. Цветная полоска в виде «Сегодня» — это просто те же строки, свёрнутые в смежные блоки и отрисованные вдоль 24-часовой линии.
Решение «1 Гц»
Меня спрашивают, почему выборка раз в секунду, а не раз в пять секунд, раз в минуту или раз в десятую долю секунды.
Медленнее 1 Гц теряет короткие переключения контекста. Если ты проверяешь уведомление Slack девять секунд и возвращаешься в Xcode, 60-секундный сэмплер запишет ту минуту либо как целиком Xcode, либо как целиком Slack — в зависимости от того, что было активно в момент захвата. Оба варианта неправильные. Ты хочешь видеть этот девятисекундный всплеск Slack.
Быстрее 1 Гц не даёт ничего нового — люди не переключают фокус 10 раз в секунду — зато раздувает SQLite-файл без информационного прироста. Рабочий день при 1 Гц — это около 30 000 строк. При 10 Гц — 300 000 строк за тот же инсайт. Мы оптимизировали за меньшее число.
Ещё одна вещь, которую даёт 1 Гц, — честное определение простоя. macOS отдаёт время с последнего пользовательского ввода. Если пауза превышает порог (в Timex по умолчанию 90 секунд), строка помечается как idle. Два подряд idle-блока становятся idle-периодом. Idle-периоды не идут в зачёт таймера перерывов, так что глубокий рабочий блок не режется несправедливо из-за похода за кофе.
Вопрос браузерных вкладок
Это та часть автоматического трекинга, которая людей беспокоит. И правильно беспокоит.
Если трекер времени для Mac видит заголовок вкладки браузера, которую ты смотришь, он теоретически может увидеть «Bank of America» или «MyChart Patient Portal» в твоей истории. Самый чистый ответ — спросить пользователя до того, как что-то из этого произойдёт. macOS нас к этому обязывает. При первом запуске Timex функция браузерных вкладок отключена. Нужно явно выдать разрешение Accessibility, и в любой момент его можно отозвать в Системных настройках.
Когда разрешение выдано, хранится строка заголовка окна, которую браузер публикует для текущей вкладки — и больше ничего. Мы не читаем URL. Не читаем содержимое страницы. Не читаем историю браузера. Мы храним ту же строку, которая видна в строке заголовка браузера в этот конкретный момент.
Если не хочется — оставь разрешение выключенным, и трекер всё равно работает. Просто видишь браузер как единый блок («Chrome — 41m») вместо разбивки по вкладкам.
Модель данных в SQLite
Для тех, кому интересен слой хранения: Timex использует единый SQLite-файл с небольшим набором таблиц. Ключевая форма — лог активности, который выглядит примерно так:
CREATE TABLE activity_samples (
ts INTEGER NOT NULL, -- unix seconds
app_bundle TEXT, -- e.g. "com.apple.dt.Xcode"
app_name TEXT, -- e.g. "Xcode"
window_title TEXT, -- e.g. "AppDelegate.swift"
browser_tab TEXT, -- nullable, only when permission granted
is_idle INTEGER NOT NULL -- 0 or 1
);
CREATE INDEX idx_samples_ts ON activity_samples(ts);
Вот и вся форма «что ты делал сегодня». Открой файл любым SQLite-клиентом. Запусти запрос. Ответ — в нескольких строках.
Я делился этой схемой раньше в Your data, your file — там развёрнутый аргумент, почему слой хранения и есть продукт. Короткая версия: инструмент, чей единственный output — проприетарный облачный дашборд, стареет плохо. Инструмент, чей единственный output — SQLite-файл, стареет вместе с тобой.
Вопросы, на которые отвечает автоматический трекинг
Вот запросы, которые мы реально гоняем на своих данных:
Куда делось утро? Перетащи на отрезок 09:00–12:00 на полоске. Итоги фильтруются по этому окну. Нажми на верхнее приложение. Разверни, чтобы посмотреть, какие окна съели отрезок.
Я двигался в нужном направлении на этой неделе? Суммируй время в строках
Xcodeс заголовками окон, совпадающими с именем активного проекта. Если меньше ожидаемого — это проблема календаря, не трекера.Когда я последний раз по-настоящему думал глубоко? Ищи самый длинный непрерывный блок
is_idle=0в одном приложении. Если самый длинный — 28 минут, ответ «никогда на этой неделе» — и это данные, с которыми можно работать.Что сожрал Chrome? Фильтруй строки, где
app_name='Google Chrome'. Группируй поbrowser_tab. Сортируй по количеству. В верхней части списка, к сожалению, чаще всего Reddit. Или Hacker News. Или один из двух ИИ-провайдеров, чьи названия рифмуются.
Вопросы, на которые не отвечает
Хочу честно сказать об ограничениях.
Он не может сказать, что ты собирался делать. Видит только то, какое приложение было на переднем плане. Если ты провёл сорок минут на Hacker News, исследуя что-то для работы, трекер видит Hacker News. Классификатор «стоило ли это того» — у тебя в голове, а не в данных. Мы не пытаемся это автоматизировать. Мы не думаем, что это возможно.
Он не может автоматически теговать проекты. Одни приложения делают это простым (заголовок окна Xcode — это путь к файлу, который маппится на проект). Другие нет (заголовок окна Chrome — это заголовок страницы, который ничего не говорит о работе). Ответ v1 — читать полоску самому и пользоваться глазами. В более поздней версии может появиться теговая разметка на основе правил («если заголовок окна содержит X, пометить как проект Y») для тех, кому нужна лёгкая структура проектов.
Он не может восстановить сессии, когда его не было открыто. Это очевидное. Установил сегодня — получишь данные с сегодня. Магической задней реконструкции нет.
Простой, сон и блокировка экрана
Три крайних случая, которые стоит проговорить вслух, потому что большинство автоматических трекеров обрабатывают их непоследовательно:
Простой — таймаут пользовательского ввода. По умолчанию 90 секунд. Строка помечается, используется для пропуска отсчётов таймера перерывов, но данные всё равно пишутся — полоска честно показывает пробел.
Сон дисплея — когда macOS гасит экран из-за системного простоя. Мы полностью приостанавливаем сэмплер. Строки не пишутся. Полоска показывает чистый пробел.
Блокировка экрана — когда нажимаешь Ctrl+Cmd+Q или отходишь достаточно надолго, чтобы сработала блокировка. То же самое, что сон дисплея: сэмплер на паузе, строк нет, чистый пробел.
Принцип: если тебя нет за Mac, данные не могут утверждать, что ты был.
«А проекты?»
Это всплывает достаточно часто, чтобы заслуживать прямого ответа.
Если твоя работа — выставлять часы клиенту, тебе действительно нужен выбор проектов. Автоматический трекер, который не знает о структуре твоих проектов, не может сгенерировать инвойс. Toggl и Harvest созданы для этого. У них есть выбор проектов, трение старта/стопа и экспортный пайплайн, которому доверяет твой бухгалтер.
Если твоя работа — понять свою собственную неделю, выбор проектов не нужен. Нужно посмотреть на полоску и заметить, что вторник после обеда — это четыре часа Slack без ничего в пределах Cmd+Tab от кодовой базы. Вот инсайт. Метка проекта для него не нужна.
Большинство людей, для которых я строил это, — из второго лагеря. Они уже внутри Claude Code, Cursor и запусков агента Octomind, которые съели среду утром. Они хотят видеть, куда приземлились часы, а не раскладывать их по кодам биллинга.
Тест среды
Вот тест, который я делаю для любого трекера времени, прежде чем рассматривать его как надёжный инструмент.
Среда утром. На стендапе спрашивают, что ты делал в понедельник. Ты открываешь трекер.
- Если данные восстановлены из памяти вечером вторника, они лгут. Ты неправильно помнишь Slack как Xcode и Xcode как Slack. Ответ на стендапе уверенно неправильный.
- Если данные автоматические, это та же скучная правда, которую показывала полоска в понедельник вечером. Ты её читаешь. Говоришь. Идёшь дальше.
Вот тот разрыв, который реально закрывает автоматический трекинг. Не продуктивность. Не фокус. Даже не память. Просто версия дня, которую выдаёт трекер, совпадает с версией, которая реально произошла.
Если хочешь посмотреть, как это выглядит на твоём Mac, скачай 100-часовую пробную версию. Три Mac, без аккаунта, без облака. Та же полоска, которой мы пользуемся на своих ноутбуках каждый день.