Skip to content

Repository files navigation

TidyTime

A passive time-capture and attribution assistant for Productive.

TidyTime is a native macOS menu bar app that watches how you actually spend your workday — foreground apps and window titles, Chrome (URL, title, visible page text), Google Calendar, Fathom meeting transcripts, and Slack — reconstructs the day into loggable blocks, matches each block to your Productive client → project → task, and hands you ready-to-enter time entries: the task, a duration rounded to 15 minutes, and a one-to-two sentence note with a copy button and a deep link.

It recommends; you enter. v1 is read-only against Productive — nothing is ever written back. It's built for backfill, not stopwatch discipline: capture everything passively, attribute afterward, and at end of day (or first thing the next morning) reconcile a whole day in a few minutes instead of an end-of-week archaeology session.

Status: running in production (one user), signed and validated on a real Mac. All seven phases (0–6) of logic ship as tested SwiftPM targets under Packages/TidyKit — 401 unit tests, 0 failures — covering capture, the read-only Productive mirror, Fathom/Calendar/Slack ingest, the classification ladder, the suggestion engine, the metered AI router, and the Google OAuth sign-in flow. The macOS app in App/ hosts those modules and has been launched and validated live (2026-07-25→27): signed dmg installed, TCC grants persisting, capture banking real sessions, credentials in the Keychain, and live Slack/Fathom syncs exercised (whose first-run failures were found and fixed exactly this way). Still awaiting first live use: the Google sign-in click and the cloud AI rungs. New here, or scoping the MVP? docs/MVP-HANDOFF.md — what the alpha measurably does today, what is written but dark, and what the MVP still needs. Running it: docs/RUNNING.md · review history in docs/PROJECT-REVIEW.md.

Why it exists

The billable time you forget is the time that never got captured: the 15 client minutes inside an hour-long colleague call, the drive-by Slack DMs, the block you'd have misremembered a week later. TidyTime's job is to surface exactly that, with enough context that logging it is a copy-paste.

How it works (one screen)

CAPTURE (local)                 INGEST (read-only APIs)
 app & window watcher            Productive  · Fathom
 Chrome URL/title/text           Google Calendar · Slack
 idle / away · meeting state
        └──────────────┬─────────────────┘
                       ▼
        STORE — SQLite (GRDB) + Keychain
                       ▼
        UNDERSTAND — sessionize · resolve entities ·
        classification ladder (rules → lexical → on-device
        → economy cloud → escalation) · sensitivity gate
                       ▼
        SUGGEST — round · pool micro-work · split meetings ·
        gap-analyze vs. what's already logged
                       ▼
        SURFACE — menu bar · nudges · end-of-day recap ·
        dashboard · settings

Everything runs in one menu bar process. Sensitive content (personnel, comp, legal) never leaves the machine. Every cloud AI call is metered and budget-capped. Full architecture: docs/architecture/overview.md.

Repository layout

Path What
PLAN.md The canonical vision & scope (source of truth)
CLAUDE.md Orchestration brief + prime directives (loaded by Claude Code)
docs/ All reference, architecture, phase, and decision docs
project.yml XcodeGen spec for the app target
App/ Thin app shell (@main, Info.plist, entitlements)
Packages/TidyKit/ All logic, as SwiftPM library targets
config.example.json Reference for every non-secret setting. Not the runtime file — the app writes a starter ~/Library/Application Support/TidyTime/config.json on first launch and never overwrites it.

Getting started (developer)

Prerequisites: macOS 14+ (macOS 26 + Apple Intelligence unlocks the on-device model rung), Xcode 16+, Homebrew. Hardware floor: Apple Silicon (M2 or newer).

make bootstrap                             # installs XcodeGen, generates TidyTime.xcodeproj
cp Local.xcconfig.example Local.xcconfig   # then set DEVELOPMENT_TEAM (a free Apple ID works)
make build                                 # build the app
make run                                   # build + launch (icon appears in the menu bar)
make test                                  # run the TidyKit unit tests

Important — stable signing. macOS ties Accessibility/Automation permission grants to the code signature. Sign with a stable identity (personal team) so grants survive rebuilds; an ad-hoc or rotating signature silently drops them. See docs/build/signing-and-tcc.md. One-time human setup (permissions, tokens, OAuth): docs/permissions-setup.md.

Build phases

Capture-first and strictly ordered; each phase ends in something usable with a human-verifiable acceptance check.

  1. Skeleton — menu bar, DB, config, signing
  2. Capture — watcher, Chrome, idle, sessionization
  3. Productive mirror — read-only sync
  4. Meetings & calendar — Fathom, Google
  5. Slack — DM/channel ingest
  6. Recap & rules — suggestion engine + recap UI
  7. Intelligence — gate, on-device, cloud router, ledger, nudges

Guarantees

  • Read-only against Productive. No write call exists in v1.
  • Sensitivity gate fails closed. Personnel/comp/legal content never reaches a cloud model.
  • No Screen Recording permission is requested — window titles come from Accessibility.
  • Secrets in Keychain only; local data stays on one Mac, purged on a retention schedule.

Details and enforcement: docs/guardrails.md.

License

Private / internal (4Site Studios). Not for redistribution.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages