{"id":32565904,"url":"https://github.com/apfohl/unitrack","last_synced_at":"2026-01-12T07:35:39.642Z","repository":{"id":308596857,"uuid":"1033258274","full_name":"apfohl/unitrack","owner":"apfohl","description":"A Bubble Tea TUI to track time per Linear issue","archived":false,"fork":false,"pushed_at":"2025-10-22T06:05:21.000Z","size":58,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-22T08:17:45.284Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/apfohl.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-06T14:34:44.000Z","updated_at":"2025-10-22T06:04:22.000Z","dependencies_parsed_at":null,"dependency_job_id":"a881753a-f772-402b-9362-db41a31cccee","html_url":"https://github.com/apfohl/unitrack","commit_stats":null,"previous_names":["apfohl-uninow/unitrack","apfohl/unitrack"],"tags_count":17,"template":false,"template_full_name":null,"purl":"pkg:github/apfohl/unitrack","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apfohl%2Funitrack","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apfohl%2Funitrack/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apfohl%2Funitrack/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apfohl%2Funitrack/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/apfohl","download_url":"https://codeload.github.com/apfohl/unitrack/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apfohl%2Funitrack/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28336560,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-12T06:09:07.588Z","status":"ssl_error","status_checked_at":"2026-01-12T06:05:18.301Z","response_time":98,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-10-29T04:54:42.123Z","updated_at":"2026-01-12T07:35:39.637Z","avatar_url":"https://github.com/apfohl.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# unitrack\n\nA 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.\n\n## Features\n\n- **Issue Title Display**: Automatically fetches and displays Linear issue titles next to the input field as you type\n- **Smart Input**: Enter just the issue number (e.g. `1234`) or full ID (e.g. `UE-1234`) - prefix is handled automatically\n- **Time Tracking**: Start/pause/resume timers with automatic quarter-hour rounding\n- **Limited Timers**: Set time limits that automatically stop and submit when reached - perfect for timeboxing\n- **Auto-save \u0026 Recovery**: Crash protection with automatic timer state persistence\n- **History Navigation**: Quick access to previously tracked issues via arrow keys\n- **Theme Support**: Dark and light themes for optimal terminal readability\n- **In-memory Caching**: Fast issue title lookup for previously accessed issues during the session\n\n## Install\n\n1. **Recommended:** Install via Go:\n   ```shell\n   go install github.com/apfohl/unitrack@latest\n   ```\n   The binary will be available as `unitrack` in your `$GOPATH/bin` (usually `~/go/bin`).\n\n2. **Manual install:**\n   - Clone this repo\n   - Run `go mod tidy`\n   - Build: `go build .`\n   - Binary will be available as `./unitrack`\n\n## Setup\n\n### Linear API Key Configuration\n\n1. **Create a Linear API Key**:\n   - Go to Linear Settings → API\n   - Create a new API key with **both** required permissions:\n     - **`Read`** - Required to fetch issue titles and information\n     - **`Create comments`** - Required to post time tracking comments\n   - Copy the generated API key\n\n2. **Configure unitrack**:\n   - Ensure Go (\u003e=1.20) is installed, and `$GOPATH/bin` (`~/go/bin` by default) is in your system `$PATH`\n   - Create config file at `~/.config/unitrack/unitrack.json`:\n   ```json\n   {\n     \"api_key\": \"YOUR_LINEAR_API_KEY\",\n     \"prefix\": \"UE\",\n     \"timer_expire_days\": 5,\n     \"theme\": \"dark\"\n   }\n   ```\n   - `api_key`: Your Linear API key with `Read` and `Create comments` permissions\n   - `prefix`: The project key in issue IDs (e.g. \"UE\" for UE-1234)\n   - `timer_expire_days` (optional): Days before saved timers expire (default: 5)\n   - `theme` (optional): Color scheme - `\"dark\"` (default) or `\"light\"`\n\n⚠️ **Important**: Your Linear API key must have **both `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.\n\n## Usage\n\n- Run with: `unitrack`\n- **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\n- The issue input placeholder uses your configured prefix (e.g. `UE-1234`)\n- 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\n- **Smart Caching**: Issue titles are cached in memory during the session for faster subsequent lookups\n- Press `Enter` to start the timer for the issue\n- The timer runs and shows elapsed time (hh:mm:ss)\n- Press `p` to pause, `r` to resume the timer\n- **Quick Time Adjustment**: While the timer is running:\n  - Press `+` to add 15 minutes to the timer\n  - Press `-` to subtract 15 minutes from the timer (only if timer has at least 15 minutes)\n  - For limited timers, `+` only works if there are more than 15 minutes remaining\n- Press `c` to cancel (you'll get a y/n confirmation)\n- Press `s` to stop, round to nearest quarter hour, and post as a comment to Linear\n- Previous full issue IDs are saved in history; cycle them with `Up`/`Down` arrows\n- Quit with `q` or `ctrl+c`\n- All logs/output are in `$HOME/.config/unitrack/unitrack.log`\n\n### Limited Timer\n\nunitrack supports limited timers that automatically stop and submit time when a specified duration is reached:\n\n- Press `l` (instead of `Enter`) to set up a limited timer\n- Enter the desired time limit in minutes (e.g., `15`, `30`, `60`)\n- Press `Enter` to start the limited timer\n- The timer shows a progress bar indicating how much time remains\n- When the time limit is reached, the timer automatically:\n  - Stops the timer\n  - Rounds to the nearest quarter hour\n  - Posts the time as a comment to Linear\n  - Shows a system notification (if supported)\n- You can still pause (`p`), resume (`r`), cancel (`c`), or manually submit (`s`) before the limit is reached\n\n**Use cases**: Perfect for timeboxing work sessions, Pomodoro technique, or ensuring you don't exceed allocated time for specific tasks.\n\n### Auto-save \u0026 Recovery\n\n- The timer state (including limited timers) is automatically saved every minute to `~/.config/unitrack/saved_timer_\u003cissue_id\u003e.json`\n- If you start tracking an issue that has a saved timer, you'll be prompted to either:\n  - Continue from the saved time (press `y`) - this preserves the original timer type and limit\n  - Start fresh and discard the saved time (press `n`)\n- Saved timers are automatically deleted when:\n  - You submit the time to Linear\n  - You cancel a timer\n  - The saved timer is older than the configured expiration (default: 5 days)\n- This feature helps recover from crashes or accidental closures, preserving both regular and limited timer states\n\n### Theme Configuration\n\nunitrack supports both light and dark color themes to provide optimal readability in different terminal environments:\n\n- **Dark theme** (default): Uses muted, lighter colors optimized for dark terminal backgrounds\n- **Light theme**: Uses darker, higher-contrast colors optimized for light terminal backgrounds\n\nConfigure the theme in your `~/.config/unitrack/unitrack.json`:\n\n```json\n{\n  \"api_key\": \"YOUR_LINEAR_API_KEY\",\n  \"prefix\": \"UE\",\n  \"theme\": \"light\"\n}\n```\n\nIf no theme is specified, unitrack defaults to the dark theme.\n\n## Troubleshooting\n\n### Issue Titles Not Displaying\n\nIf issue titles are not appearing next to the input field:\n\n1. **Check API Key Permissions**: Ensure your Linear API key has **both** required permissions:\n   - `Read` - Required for fetching issue titles\n   - `Create comments` - Required for posting comments\n   \n2. **Verify API Key**: Check that your API key in `~/.config/unitrack/unitrack.json` is correct\n\n3. **Check Logs**: Review `~/.config/unitrack/unitrack.log` for any API errors\n\n4. **Network Connectivity**: Ensure you can reach Linear's API at `https://api.linear.app/graphql`\n\nCommon error: `\"Invalid scope: 'read' required\"` means your API key needs the `Read` permission added.\n\n### Notes\n- Customize the prefix for issue IDs in the config (e.g. \"UI\" for UI-1234).\n- History, config, and logs are created/loaded automatically per session.\n\n## CI / Releases\n\n- **Build/test on PRs and push to main is automatic via GitHub Actions.**\n- **Tagged versions like `v0.1.0` trigger a macOS build and release binary upload to repo assets.**\n- **Install stable releases with:**\n\n  ```shell\n  go install github.com/apfohl/unitrack@latest\n  ```\n\n- **Or install by specific tag:**\n\n  ```shell\n  go install github.com/apfohl/unitrack@v0.1.0\n  ```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapfohl%2Funitrack","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fapfohl%2Funitrack","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapfohl%2Funitrack/lists"}