CLI-based time-tracking automation for Clockify with idle monitoring, Jira integration, Google Calendar sync, and a web dashboard.
Most users only need the dashboard — a web UI to manage timers, connect integrations, and monitor idle time.
Bun is required (used as the runtime):
curl -fsSL https://bun.sh/install | bashbun install -g clocktopus --trustNote:
--trustallows the postinstall script to build native addons (required for idle monitor on macOS). Without it, addon compilation is skipped and the monitor may fail to load.
# Start dashboard in foreground
clocktopus dash
# Or as a background daemon
clocktopus serveOpen http://localhost:4001 in your browser.
- Go to Settings tab
- Enter your Clockify API key (get one here)
- Click Pull from Clockify in the Projects tab
- Optionally connect Jira and Google Calendar with one click
That's it. Start/stop timers from the Home tab.
| Command | Description |
|---|---|
clocktopus dash |
Start dashboard (foreground) |
clocktopus serve |
Start dashboard as background daemon |
clocktopus serve:stop |
Stop the dashboard daemon |
clocktopus serve:logs |
View dashboard daemon logs |
clocktopus start |
Start a timer (interactive) |
clocktopus stop |
Stop the current timer |
clocktopus status |
Check timer status |
clocktopus monitor |
Start idle monitor as background daemon |
clocktopus monitor:stop |
Stop the idle monitor |
clocktopus monitor:logs |
View idle monitor logs |
clocktopus hook:install |
Install global git post-checkout hook |
clocktopus hook:uninstall |
Remove the global git post-checkout hook |
clocktopus hook:install-husky |
Add .husky/post-checkout in current repo |
Auto-prompt to start a timer when you git checkout a branch. Extracts Jira tickets from branch names (e.g. feature/RST-100-login → RST-100), fetches the ticket summary from Jira as the default description, and maps to a Clockify project.
clocktopus hook:installInstalls a global hook at ~/.clocktopus/hooks/post-checkout and sets git config --global core.hooksPath + init.templateDir.
Opt out per repo: touch .clocktopus-ignore at the repo root.
Opt out per session: export CLOCKTOPUS_HOOK_DISABLE=1.
Husky sets a local core.hooksPath, which overrides the global one — so the hook won't fire in husky repos by default. Inside each husky-enabled repo, run:
clocktopus hook:install-huskyThis writes .husky/post-checkout that chains to the global hook. Commit it so teammates get it too.
A menu bar app is available — download the .dmg from GitHub Releases.
After installing, remove the quarantine flag (app is not code-signed):
xattr -cr /Applications/Clocktopus.appThe app manages the dashboard server for you:
- Install Clocktopus — if the CLI is not installed, the popup offers a one-click installer that runs
bun i -g clocktopus --trustfor you. - Start Server — when the dashboard is not running, the popup shows a "Start Server" button. Click it and the app spawns
clocktopus dashin the background, then loads the dashboard once it's up. - Stop Server / Restart Server — available from the tray menu when the server is reachable. Stop also kills any pre-existing process on port 4001 (terminal, PM2, prior session).
See desktop/README.md for details.
git clone https://github.com/sajxraj/clocktopus.git
cd clocktopus
bun install
bun run buildWhen running from source, use bun run clock instead of clocktopus:
bun run build # Build TypeScript
bun run dashboard # Start dashboard (foreground)
bun run clock start "Task" # Start a timer
bun run clock start -j PROJ-1 # Start with Jira ticket
bun run clock stop # Stop timer
bun run clock status # Check timer status
bun run monitor # Start idle monitor (PM2 daemon)
bun run monitor:stop # Stop monitor
bun run monitor:restart # Restart monitor
bun run monitor:logs # View monitor logs
bun run google-auth # Authenticate Google account
bun run log-calendar -t # Log today's events
bun run db:cleanup # Clean old session logsAll configuration is stored in a local SQLite database and managed through the dashboard Settings tab.
| Setting | How to configure |
|---|---|
| Clockify API Key | Dashboard > Settings > Clockify |
| Jira (OAuth) | Dashboard > Settings > Click "Connect Atlassian" |
| Jira (API token) | Dashboard > Settings > "or use API token" |
| Google Calendar | Dashboard > Settings > Click "Connect Google" |
OAuth for Jira and Google is handled transparently through a Cloudflare Worker proxy — no client credentials needed from users.
clocktopus/
├── index.ts # CLI entry point (Commander)
├── clockify.ts # Clockify API client
├── lib/ # Core libraries (db, auth, credentials)
├── dashboard/ # Web dashboard (Hono server)
│ ├── server.ts # Dashboard server
│ ├── views.ts # HTML/CSS/JS (single-page app)
│ └── routes/ # API routes
├── desktop/ # Tauri macOS menu bar app
├── proxy/ # Cloudflare Worker (OAuth proxy)
├── scripts/ # Google auth & calendar scripts
└── data/ # SQLite DB & config (gitignored)
Go to System Settings > Notifications and ensure terminal-notifier has notifications enabled.
Enable Require password immediately in System Settings > Lock Screen.
bun remove -g clocktopus
# If the above doesn't work, delete the binary directly:
rm ~/.bun/bin/clocktopusBun caches registry data aggressively. Clear the cache and reinstall:
bun pm cache rm && bun i -g clocktopus@latestBun skips postinstall scripts for untrusted packages. Install with --trust to fix this:
bun install -g clocktopus --trustOr if already installed, rebuild manually:
cd ~/.bun/install/global/node_modules/macos-notification-state && npx node-gyp rebuildapt install libxss-dev pkg-config build-essentialDuring install you may see:
gyp ERR! stack Error: Cannot find module './entry-index'
gyp ERR! stack Require stack:
gyp ERR! stack - .../node_modules/cacache/lib/get.js
...
error: install script from "desktop-idle" exited with 1
Caused by a broken node-gyp@12.2.0 / cacache bundle fetched via bunx on newer Node versions (e.g. Node 25).
Fixes, in order:
-
Use Node 20 LTS (most reliable):
nvm install 20 && nvm use 20 bun i -g clocktopus@latest --trust -
Clear the bunx node-gyp cache and retry:
rm -rf /var/folders/**/bunx-*-node-gyp@latest bun i -g clocktopus@latest --trust
-
Install via npm (uses its own node-gyp):
npm i -g clocktopus@latest
desktop-idle is a native addon and must be compiled at install time — skipping postinstall leaves idle detection disabled.
MIT
