A Bubble Tea TUI to track time per Linear issue, rounding to the next quarter hour and posting as a comment via Linear's GraphQL API. Features real-time issue title display for better context and tracking accuracy.
- Issue Title Display: Automatically fetches and displays Linear issue titles next to the input field as you type
- Smart Input: Enter just the issue number (e.g.
1234) or full ID (e.g.UE-1234) - prefix is handled automatically - Time Tracking: Start/pause/resume timers with automatic quarter-hour rounding
- Limited Timers: Set time limits that automatically stop and submit when reached - perfect for timeboxing
- Auto-save & Recovery: Crash protection with automatic timer state persistence
- History Navigation: Quick access to previously tracked issues via arrow keys
- Theme Support: Dark and light themes for optimal terminal readability
- In-memory Caching: Fast issue title lookup for previously accessed issues during the session
-
Recommended: Install via Go:
go install github.com/apfohl/unitrack@latest
The binary will be available as
unitrackin your$GOPATH/bin(usually~/go/bin). -
Manual install:
- Clone this repo
- Run
go mod tidy - Build:
go build . - Binary will be available as
./unitrack
-
Create a Linear API Key:
- Go to Linear Settings → API
- Create a new API key with both required permissions:
Read- Required to fetch issue titles and informationCreate comments- Required to post time tracking comments
- Copy the generated API key
-
Configure unitrack:
- Ensure Go (>=1.20) is installed, and
$GOPATH/bin(~/go/binby default) is in your system$PATH - Create config file at
~/.config/unitrack/unitrack.json:
{ "api_key": "YOUR_LINEAR_API_KEY", "prefix": "UE", "timer_expire_days": 5, "theme": "dark" }api_key: Your Linear API key withReadandCreate commentspermissionsprefix: The project key in issue IDs (e.g. "UE" for UE-1234)timer_expire_days(optional): Days before saved timers expire (default: 5)theme(optional): Color scheme -"dark"(default) or"light"
- Ensure Go (>=1.20) is installed, and
Read and Create comments permissions for unitrack to work properly. The Read permission enables issue title fetching, while Create comments permission allows posting time tracking comments.
- Run with:
unitrack - Issue Title Display: As you type an issue ID, unitrack automatically fetches and displays the issue title next to the input field for better context
- The issue input placeholder uses your configured prefix (e.g.
UE-1234) - Enter either the full issue ID (e.g.
UE-1234) or just the number (e.g.1234). If only the number is entered, the prefix from the config is used automatically - Smart Caching: Issue titles are cached in memory during the session for faster subsequent lookups
- Press
Enterto start the timer for the issue - The timer runs and shows elapsed time (hh:mm:ss)
- Press
pto pause,rto resume the timer - Quick Time Adjustment: While the timer is running:
- Press
+to add 15 minutes to the timer - Press
-to subtract 15 minutes from the timer (only if timer has at least 15 minutes) - For limited timers,
+only works if there are more than 15 minutes remaining
- Press
- Press
cto cancel (you'll get a y/n confirmation) - Press
sto stop, round to nearest quarter hour, and post as a comment to Linear - Previous full issue IDs are saved in history; cycle them with
Up/Downarrows - Quit with
qorctrl+c - All logs/output are in
$HOME/.config/unitrack/unitrack.log
unitrack supports limited timers that automatically stop and submit time when a specified duration is reached:
- Press
l(instead ofEnter) to set up a limited timer - Enter the desired time limit in minutes (e.g.,
15,30,60) - Press
Enterto start the limited timer - The timer shows a progress bar indicating how much time remains
- When the time limit is reached, the timer automatically:
- Stops the timer
- Rounds to the nearest quarter hour
- Posts the time as a comment to Linear
- Shows a system notification (if supported)
- You can still pause (
p), resume (r), cancel (c), or manually submit (s) before the limit is reached
Use cases: Perfect for timeboxing work sessions, Pomodoro technique, or ensuring you don't exceed allocated time for specific tasks.
- The timer state (including limited timers) is automatically saved every minute to
~/.config/unitrack/saved_timer_<issue_id>.json - If you start tracking an issue that has a saved timer, you'll be prompted to either:
- Continue from the saved time (press
y) - this preserves the original timer type and limit - Start fresh and discard the saved time (press
n)
- Continue from the saved time (press
- Saved timers are automatically deleted when:
- You submit the time to Linear
- You cancel a timer
- The saved timer is older than the configured expiration (default: 5 days)
- This feature helps recover from crashes or accidental closures, preserving both regular and limited timer states
unitrack supports both light and dark color themes to provide optimal readability in different terminal environments:
- Dark theme (default): Uses muted, lighter colors optimized for dark terminal backgrounds
- Light theme: Uses darker, higher-contrast colors optimized for light terminal backgrounds
Configure the theme in your ~/.config/unitrack/unitrack.json:
{
"api_key": "YOUR_LINEAR_API_KEY",
"prefix": "UE",
"theme": "light"
}If no theme is specified, unitrack defaults to the dark theme.
If issue titles are not appearing next to the input field:
-
Check API Key Permissions: Ensure your Linear API key has both required permissions:
Read- Required for fetching issue titlesCreate comments- Required for posting comments
-
Verify API Key: Check that your API key in
~/.config/unitrack/unitrack.jsonis correct -
Check Logs: Review
~/.config/unitrack/unitrack.logfor any API errors -
Network Connectivity: Ensure you can reach Linear's API at
https://api.linear.app/graphql
Common error: "Invalid scope: 'read' required" means your API key needs the Read permission added.
- Customize the prefix for issue IDs in the config (e.g. "UI" for UI-1234).
- History, config, and logs are created/loaded automatically per session.
-
Build/test on PRs and push to main is automatic via GitHub Actions.
-
Tagged versions like
v0.1.0trigger a macOS build and release binary upload to repo assets. -
Install stable releases with:
go install github.com/apfohl/unitrack@latest
-
Or install by specific tag:
go install github.com/apfohl/unitrack@v0.1.0