{"id":48483229,"url":"https://github.com/bpauli/gccli","last_synced_at":"2026-04-07T09:00:58.077Z","repository":{"id":338027920,"uuid":"1156275280","full_name":"bpauli/gccli","owner":"bpauli","description":"A command-line interface for Garmin Connect — activities, health, courses, workouts, devices, and more — with JSON output and secure credential storage.","archived":false,"fork":false,"pushed_at":"2026-03-31T20:39:32.000Z","size":611,"stargazers_count":8,"open_issues_count":2,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-31T22:24:38.929Z","etag":null,"topics":["cli","fitness","garmin","garmin-connect","golang","health"],"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/bpauli.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","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":"2026-02-12T13:17:16.000Z","updated_at":"2026-03-31T20:39:29.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/bpauli/gccli","commit_stats":null,"previous_names":["bpauli/gccli"],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/bpauli/gccli","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bpauli%2Fgccli","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bpauli%2Fgccli/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bpauli%2Fgccli/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bpauli%2Fgccli/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bpauli","download_url":"https://codeload.github.com/bpauli/gccli/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bpauli%2Fgccli/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31506577,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-07T03:10:19.677Z","status":"ssl_error","status_checked_at":"2026-04-07T03:10:13.982Z","response_time":105,"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":["cli","fitness","garmin","garmin-connect","golang","health"],"created_at":"2026-04-07T09:00:46.219Z","updated_at":"2026-04-07T09:00:58.065Z","avatar_url":"https://github.com/bpauli.png","language":"Go","funding_links":["https://buymeacoffee.com/mail7j"],"categories":[],"sub_categories":[],"readme":"# gccli — Garmin Connect in your terminal.\n\n[![ci](https://github.com/bpauli/gccli/actions/workflows/ci.yml/badge.svg)](https://github.com/bpauli/gccli/actions/workflows/ci.yml)\n[![Go Report Card](https://goreportcard.com/badge/github.com/bpauli/gccli)](https://goreportcard.com/report/github.com/bpauli/gccli)\n[![Docs](https://img.shields.io/badge/docs-gccli.sh-blue)](https://gccli.sh)\n[![Buy Me A Coffee](https://img.shields.io/badge/Buy%20Me%20A%20Coffee-support-yellow?logo=buymeacoffee)](https://buymeacoffee.com/mail7j)\n\nFast, script-friendly CLI for Garmin Connect. Access activities, health data, body composition, workouts, courses, devices, gear, goals, badges, and more. JSON-first output, multiple accounts, and secure credential storage built in.\n\n## Features\n\n- **Activities** — list, search, view details, download (FIT/GPX/TCX/KML/CSV), upload, create manual entries (with date), rename, retype, delete, set exercise sets for strength training\n- **Exercise Catalog** — browse Garmin's exercise categories and exercises for strength training\n- **Health Data** — daily summaries, steps, heart rate, resting HR, sleep, stress, HRV, SpO2, respiration, body battery, floors, training readiness/status, VO2max, fitness age, race predictions, endurance/hill scores, intensity minutes, lactate threshold, cycling FTP\n- **Body Composition** — weight tracking, body fat, muscle mass, blood pressure, FIT file encoding for composition uploads\n- **Workouts** — list, view, download as FIT, upload from JSON, create with sport types and targets (pace/HR/power/cadence), schedule (add/list/remove), delete\n- **Courses** — list courses, view favorites, get full course detail, import GPX files as new courses, send courses directly to a device, delete courses\n- **Devices** — list registered devices, view settings, solar data, alarms, primary/last-used device\n- **Gear** — list gear, usage stats, linked activities, defaults per activity type, link/unlink to activities\n- **Goals \u0026 Badges** — active goals, earned/available/in-progress badges, challenges, personal records\n- **Training** — browse and view training plans\n- **Profile** — user profile and settings\n- **Hydration** — view and log daily water intake\n- **Nutrition** — view daily food logs, meals, and nutrition settings\n- **Events** — list, add, and delete calendar events (races, group rides, etc.) with goals and training priority support\n- **Wellness** — menstrual cycle data, pregnancy summary\n- **Multiple accounts** — manage multiple Garmin accounts via `--account` flag\n- **Secure credential storage** using OS keyring (macOS Keychain, Linux Secret Service, encrypted file fallback)\n- **Auto-refreshing tokens** — authenticate once, tokens refresh automatically on 401\n- **Resilient networking** — automatic retry on 429/5xx with exponential backoff, circuit breaker for fault tolerance\n- **Shell completion** — generated scripts for bash, zsh, fish, and PowerShell\n- **Parseable output** — JSON and plain/TSV modes for scripting and automation\n\n## Installation\n\n### Homebrew (macOS / Linux)\n\n```bash\nbrew install bpauli/tap/gccli\n```\n\n### Build from Source\n\nRequires Go 1.24+.\n\n```bash\ngit clone https://github.com/bpauli/gccli.git\ncd gccli\nmake build\n```\n\nThe binary is output to `./bin/gccli`.\n\nRun:\n\n```bash\n./bin/gccli --help\n```\n\nHelp:\n\n- `gccli --help` shows top-level command groups.\n- Drill down with `gccli \u003cgroup\u003e --help` (and deeper subcommands).\n- Make shortcut: `make run -- --help` (or `make run -- activities --help`).\n\n## Quick Start\n\n### 1. Log In (Browser SSO)\n\n```bash\ngccli auth login you@example.com\n```\n\nThis opens your browser for Garmin SSO authentication. The OAuth tokens are stored securely in your system keyring.\n\n### 2. Log In (Headless)\n\nFor servers or environments without a browser:\n\n```bash\ngccli auth login you@example.com --headless\n```\n\nYou'll be prompted for your password. If your account has two-factor authentication:\n\n```bash\ngccli auth login you@example.com --headless --mfa-code 123456\n```\n\nLogin automatically saves your email as the default account, so you don't need to pass `--account` or set `GCCLI_ACCOUNT` on every command.\n\n### 3. Test Authentication\n\n```bash\ngccli auth status\ngccli activities list --limit 5\n```\n\n## Authentication \u0026 Secrets\n\n### Accounts and Tokens\n\n`gccli` stores your OAuth tokens in a keyring backend. Default is auto-detection (best available backend for your OS/environment).\n\nList current auth state:\n\n```bash\ngccli auth status\n```\n\nPrint the raw OAuth2 access token (useful for scripting):\n\n```bash\ngccli auth token\n```\n\nRemove stored credentials:\n\n```bash\ngccli auth remove\n```\n\n### Keyring Backend\n\nBackends:\n\n- **auto** (default) — picks the best backend for the platform\n- **keychain** — macOS Keychain\n- **secret-service** — Linux D-Bus (GNOME Keyring, KWallet)\n- **file** — encrypted on-disk keyring (fallback)\n\nSet backend via environment variable:\n\n```bash\nexport GCCLI_KEYRING_BACKEND=file\n```\n\nOr in the config file (`config.json`):\n\n```json\n{\n  \"keyring_backend\": \"file\"\n}\n```\n\nOn Linux, if D-Bus is unavailable, `gccli` automatically falls back to the file backend.\n\n### Garmin Domain (China)\n\nFor Garmin China accounts (garmin.cn):\n\n```bash\nexport GCCLI_DOMAIN=garmin.cn\n```\n\nOr in `config.json`:\n\n```json\n{\n  \"domain\": \"garmin.cn\"\n}\n```\n\n## Configuration\n\n### Account Selection\n\nThe account is resolved in this order:\n\n1. `--account` flag\n2. `GCCLI_ACCOUNT` environment variable\n3. Default account saved by `gccli auth login` (stored in `config.json`)\n\n```bash\n# Via flag\ngccli activities list --account you@example.com\n\n# Via environment\nexport GCCLI_ACCOUNT=you@example.com\ngccli activities list\n\n# Via login default (no flag or env var needed)\ngccli auth login you@example.com\ngccli activities list\n```\n\n### Output\n\n- Default: human-friendly tables on stdout.\n- `--plain`: stable TSV on stdout (best for piping).\n- `--json` / `-j`: JSON on stdout (best for scripting).\n- Human-facing messages (errors, warnings, info) go to stderr.\n- Colors are enabled by default in TTY mode and disabled for `--json` and `--plain`.\n\n### Config File\n\nConfig path:\n\n- macOS: `~/Library/Application Support/gccli/config.json`\n- Linux: `~/.config/gccli/config.json` (or `$XDG_CONFIG_HOME/gccli/config.json`)\n\nExample:\n\n```json\n{\n  \"default_account\": \"you@example.com\",\n  \"keyring_backend\": \"file\",\n  \"domain\": \"garmin.com\"\n}\n```\n\n### Environment Variables\n\n| Variable | Description |\n| --- | --- |\n| `GCCLI_ACCOUNT` | Default account email (overrides config file default) |\n| `GCCLI_DOMAIN` | Garmin domain (`garmin.com` or `garmin.cn`) |\n| `GCCLI_JSON` | Enable JSON output (`1`, `true`, `yes`) |\n| `GCCLI_PLAIN` | Enable plain/TSV output (`1`, `true`, `yes`) |\n| `GCCLI_COLOR` | Color mode: `auto`, `always`, `never` |\n| `GCCLI_KEYRING_BACKEND` | Keyring backend: `keychain`, `secret-service`, `file` |\n\n## Security\n\n### Credential Storage\n\nOAuth tokens are stored securely in your system's keyring:\n\n- **macOS**: Keychain Access\n- **Linux**: Secret Service (GNOME Keyring, KWallet)\n- **Fallback**: Encrypted on-disk file store\n\nThe CLI uses [github.com/99designs/keyring](https://github.com/99designs/keyring) for secure storage.\n\nTokens are keyed by email (`gccli:token:\u003cemail\u003e`) and never stored in plaintext files.\n\n## Commands\n\n### Authentication\n\n```bash\ngccli auth login \u003cemail\u003e               # Log in via browser SSO\ngccli auth login \u003cemail\u003e --headless    # Log in via email/password\ngccli auth login \u003cemail\u003e --headless --mfa-code \u003ccode\u003e  # With MFA\ngccli auth status                      # Show auth state and token expiry\ngccli auth token                       # Print OAuth2 access token\ngccli auth export                      # Export credentials (for transfer to another machine)\ngccli auth import \u003ctoken\u003e              # Import credentials from another machine\ngccli auth remove                      # Remove stored credentials\n```\n\n### Activities\n\n```bash\n# List and search\ngccli activities list --limit 20 --start 0\ngccli activities list --type running\ngccli activities count\ngccli activities search --start-date 2024-01-01 --end-date 2024-12-31\n\n# View details\ngccli activity summary \u003cid\u003e\ngccli activity details \u003cid\u003e\ngccli activity splits \u003cid\u003e\ngccli activity typed-splits \u003cid\u003e\ngccli activity split-summaries \u003cid\u003e\ngccli activity weather \u003cid\u003e\ngccli activity hr-zones \u003cid\u003e\ngccli activity power-zones \u003cid\u003e\ngccli activity exercise-sets \u003cid\u003e\ngccli activity exercise-sets set \u003cid\u003e -e \"BENCH_PRESS/BARBELL_BENCH_PRESS:12@20:d30:r60\" -e \"BENCH_PRESS/BARBELL_BENCH_PRESS:10@25:d25\"\ngccli activity gear \u003cid\u003e\n\n# Download and upload\ngccli activity download \u003cid\u003e --format fit\ngccli activity download \u003cid\u003e --format gpx --output track.gpx\ngccli activity upload ./activity.fit\n\n# Create and modify\ngccli activity create --name \"Morning Run\" --type running --duration 30m --distance 5000\ngccli activity create --name \"Upper Body\" --type strength_training --duration 34m --date 2026-03-13T19:01:00\ngccli activity rename \u003cid\u003e \"New Name\"\ngccli activity retype \u003cid\u003e --type-id 1 --type-key running\ngccli activity delete \u003cid\u003e\ngccli activity delete \u003cid\u003e --force\n```\n\n### Health Data\n\n```bash\n# Daily summary\ngccli health summary                   # Today\ngccli health summary yesterday\ngccli health summary 2024-06-15\ngccli health summary 3d                # 3 days ago\n\n# Vitals\ngccli health steps                     # Step chart for today\ngccli health steps daily --start 2024-01-01 --end 2024-01-31\ngccli health steps weekly --weeks 4\ngccli health hr [date]                 # Heart rate\ngccli health rhr [date]                # Resting heart rate\ngccli health floors [date]             # Floors climbed\ngccli health sleep [date]              # Sleep data\ngccli health respiration [date]\ngccli health spo2 [date]               # Blood oxygen\ngccli health hrv [date]                # Heart rate variability\n\n# Stress and recovery\ngccli health stress                    # Stress for today\ngccli health stress weekly --weeks 4\ngccli health body-battery [date]\ngccli health body-battery range --start 2024-01-01 --end 2024-01-07\ngccli health training-readiness [date]\ngccli health training-status [date]\n\n# Fitness metrics\ngccli health fitness-age [date]\ngccli health max-metrics [date]        # VO2max and more\ngccli health lactate-threshold\ngccli health cycling-ftp\ngccli health race-predictions\ngccli health race-predictions range --start 2024-01-01 --end 2024-06-30\ngccli health endurance-score [date]\ngccli health hill-score [date]\ngccli health intensity-minutes [date]\ngccli health intensity-minutes weekly --start 2024-01-01 --end 2024-01-31\n\n# Wellness events\ngccli health events [date]\ngccli health lifestyle [date]\n```\n\n### Body Composition\n\n```bash\n# View data\ngccli body composition                 # Today\ngccli body composition --start 2024-01-01 --end 2024-01-31\ngccli body weigh-ins --start 2024-01-01 --end 2024-01-31\ngccli body daily-weigh-ins [date]\n\n# Add data\ngccli body add-weight 75.5 --unit kg\ngccli body add-weight 166.4 --unit lbs\ngccli body add-composition 75.5 --body-fat 15.2 --muscle-mass 35.0\n\n# Blood pressure\ngccli body blood-pressure --start 2024-01-01 --end 2024-01-31\ngccli body add-blood-pressure --systolic 120 --diastolic 80 --pulse 65\n\n# Delete entries\ngccli body delete-weight \u003cpk\u003e --date 2024-01-15\ngccli body delete-blood-pressure \u003cversion\u003e --date 2024-01-15\n```\n\n### Workouts\n\n```bash\ngccli workouts list --limit 20\ngccli workouts detail \u003cid\u003e\ngccli workouts download \u003cid\u003e --output workout.fit\ngccli workouts upload ./workout.json   # See JSON structure below\ngccli workouts schedule add \u003cid\u003e \u003cYYYY-MM-DD\u003e\ngccli workouts schedule list \u003cYYYY-MM-DD\u003e\ngccli workouts schedule list --start 2024-06-01 --end 2024-06-30\ngccli workouts schedule remove \u003cschedule-id\u003e\ngccli workouts schedule remove \u003cschedule-id\u003e --force\ngccli workouts delete \u003cid\u003e\n\n# Create a running workout with pace targets\ngccli workouts create \"Easy 30min Run\" --type run \\\n  --step \"warmup:5m@pace:5:30-6:00\" \\\n  --step \"run:20m@pace:5:00-5:30\" \\\n  --step \"cooldown:5m\"\n\n# Running with heart rate targets\ngccli workouts create \"HR Zone Run\" --type run \\\n  --step \"warmup:10m\" \\\n  --step \"run:20m@hr:140-160\" \\\n  --step \"cooldown:10m\"\n\n# Cycling with power targets\ngccli workouts create \"FTP Intervals\" --type bike \\\n  --step \"warmup:10m\" \\\n  --step \"run:5m@power:250-280\" \\\n  --step \"recovery:3m\" \\\n  --step \"run:5m@power:250-280\" \\\n  --step \"cooldown:10m\"\n\n# Imperial paces (miles)\ngccli workouts create \"Easy 30min Run\" --type run \\\n  --step \"warmup:5m@pace:8:51-9:39\" \\\n  --step \"run:20m@pace:8:03-8:51\" \\\n  --step \"cooldown:5m\" \\\n  --unit mi\n\n# Strength workout (no targets)\ngccli workouts create \"Full Body\" --type strength \\\n  --step \"warmup:5m\" \\\n  --step \"run:30m\" \\\n  --step \"cooldown:5m\"\n```\n\n**Workout JSON structure** for `gccli workouts upload`:\n\n```json\n{\n  \"workoutName\": \"Tempo Run\",\n  \"sportType\": {\n    \"sportTypeId\": 1,\n    \"sportTypeKey\": \"running\"\n  },\n  \"workoutSegments\": [\n    {\n      \"segmentOrder\": 1,\n      \"sportType\": {\n        \"sportTypeId\": 1,\n        \"sportTypeKey\": \"running\"\n      },\n      \"workoutSteps\": [\n        {\n          \"type\": \"ExecutableStepDTO\",\n          \"stepOrder\": 1,\n          \"stepType\": { \"stepTypeId\": 1, \"stepTypeKey\": \"warmup\" },\n          \"endCondition\": { \"conditionTypeId\": 2, \"conditionTypeKey\": \"time\" },\n          \"endConditionValue\": 600,\n          \"targetType\": { \"workoutTargetTypeId\": 1, \"workoutTargetTypeKey\": \"no.target\" }\n        },\n        {\n          \"type\": \"ExecutableStepDTO\",\n          \"stepOrder\": 2,\n          \"stepType\": { \"stepTypeId\": 3, \"stepTypeKey\": \"interval\" },\n          \"endCondition\": { \"conditionTypeId\": 2, \"conditionTypeKey\": \"time\" },\n          \"endConditionValue\": 1200,\n          \"targetType\": { \"workoutTargetTypeId\": 6, \"workoutTargetTypeKey\": \"pace.zone\" },\n          \"targetValueOne\": 3.333333,\n          \"targetValueTwo\": 3.030303\n        },\n        {\n          \"type\": \"ExecutableStepDTO\",\n          \"stepOrder\": 3,\n          \"stepType\": { \"stepTypeId\": 2, \"stepTypeKey\": \"cooldown\" },\n          \"endCondition\": { \"conditionTypeId\": 2, \"conditionTypeKey\": \"time\" },\n          \"endConditionValue\": 600,\n          \"targetType\": { \"workoutTargetTypeId\": 1, \"workoutTargetTypeKey\": \"no.target\" }\n        }\n      ]\n    }\n  ]\n}\n```\n\nKey reference values:\n- **Sport types**: running (1), cycling (2), other (3), swimming (4), strength\\_training (5), cardio\\_training (6), yoga (7), pilates (8), hiit (9), multi\\_sport (10), mobility (11)\n- **Step types**: warmup (1), cooldown (2), interval (3), recovery (4), rest (5), other (7)\n- **Target types**: no.target (1), power.zone (2), cadence (3), heart.rate.zone (4), pace.zone (6)\n- **End condition**: time (2) — value in seconds\n- **Pace values**: in m/s (e.g., 5:00/km = 1000/300 = 3.333 m/s)\n\n### Exercise Catalog\n\n```bash\n# List all exercise categories\ngccli exercises list\n\n# List exercises in a category\ngccli exercises list -c BENCH_PRESS\n\n# Full catalog as JSON\ngccli exercises list --json\n```\n\n### Courses\n\n```bash\ngccli courses list                             # List all courses\ngccli courses favorites                        # List favorite courses\ngccli courses detail \u003cid\u003e                      # View full course detail\ngccli courses import route.gpx                 # Import GPX as new course (default: cycling, private)\ngccli courses import route.gpx --name \"Ride\"   # Import with custom name\ngccli courses import route.gpx --type hiking   # Override activity type\ngccli courses import route.gpx --privacy 1     # Import as public course\ngccli courses send \u003ccourse-id\u003e \u003cdevice-id\u003e     # Send course to a device\ngccli courses delete \u003cid\u003e                      # Delete a course\ngccli courses delete \u003cid\u003e -f                   # Delete without confirmation\n```\n\n### Devices\n\n```bash\ngccli devices list\ngccli devices settings \u003cdevice-id\u003e\ngccli devices primary\ngccli devices last-used\ngccli devices alarms\ngccli devices solar \u003cdevice-id\u003e --start 2024-06-01 --end 2024-06-30\n```\n\n### Gear\n\n```bash\ngccli gear list\ngccli gear stats \u003cuuid\u003e\ngccli gear activities \u003cuuid\u003e --limit 20\ngccli gear defaults\ngccli gear link \u003cuuid\u003e \u003cactivity-id\u003e\ngccli gear unlink \u003cuuid\u003e \u003cactivity-id\u003e\n```\n\n### Goals, Badges \u0026 Challenges\n\n```bash\ngccli goals list\ngccli goals list --status active\ngccli badges earned\ngccli badges available\ngccli badges in-progress\ngccli challenges list\ngccli challenges badge\ngccli records\n```\n\n### Profile\n\n```bash\ngccli profile\ngccli profile settings\n```\n\n### Hydration\n\n```bash\ngccli hydration [date]                 # View hydration data\ngccli hydration add 500                # Log 500ml of water\ngccli hydration add 500 --date 2024-06-15\n```\n\n### Nutrition\n\n```bash\ngccli nutrition [date]                 # View daily food log\ngccli nutrition meals [date]           # View meal summaries\ngccli nutrition settings [date]        # View nutrition settings\n```\n\n### Training Plans\n\n```bash\ngccli training plans --locale en\ngccli training plan \u003cid\u003e\n```\n\n### Events\n\n```bash\ngccli events list                      # List upcoming events\ngccli events list --start 2024-01-01 --limit 50\ngccli events list --sort eventDate_desc\ngccli events delete \u003cid\u003e               # Delete an event (with confirmation)\ngccli events delete \u003cid\u003e -f            # Delete without confirmation\n\n# Add a race event\ngccli events add --name \"Berlin Marathon\" --date 2026-09-27 --type running \\\n  --race --location \"Berlin, Germany\" --distance 42.195km \\\n  --time 09:15 --timezone Europe/Berlin\n\n# Add an event with a goal and training priority\ngccli events add --name \"Spring 10K\" --date 2026-05-10 --type running \\\n  --race --distance 10km --goal 40m --training\n```\n\n**Event flags:**\n- **Required:** `--name`, `--date` (YYYY-MM-DD, today, +30d), `--type` (running, trail_running, cycling, gravel_cycling, mountain_biking, swimming, triathlon, multi_sport, hiking, walking, fitness_equipment, motorcycling, winter_sport, other)\n- **Optional:** `--race`, `--location`, `--time` (HH:MM), `--timezone`, `--distance` (e.g. 10km, 26.2mi, 400m), `--private`, `--note`, `--url`\n- **Goal \u0026 training priority:** `--goal` (duration, e.g. 50m, 1h30m, 2400s), `--primary` or `--training` (mutually exclusive)\n\n### Wellness\n\n```bash\ngccli wellness menstrual-cycle --start-date 2024-01-01 --end-date 2024-03-31\ngccli wellness menstrual-summary --start-date 2024-01-01 --end-date 2024-03-31\ngccli wellness pregnancy-summary\n```\n\n### Data Reload\n\n```bash\ngccli reload                           # Reload today's data\ngccli reload 2024-06-15                # Reload specific date\n```\n\n### Shell Completion\n\nGenerate completion scripts for your shell:\n\n```bash\ngccli completion bash\ngccli completion zsh\ngccli completion fish\ngccli completion powershell\n```\n\nTo enable completions, add the appropriate line to your shell profile:\n\n**Bash** (`~/.bashrc`):\n```bash\nsource \u003c(gccli completion bash)\n```\n\n**Zsh** (`~/.zshrc`):\n```bash\nsource \u003c(gccli completion zsh)\n```\n\n**Fish** (`~/.config/fish/config.fish`):\n```fish\ngccli completion fish | source\n```\n\n**PowerShell** (`$PROFILE`):\n```powershell\ngccli completion powershell | Invoke-Expression\n```\n\nCompletions cover all commands, subcommands, flags, and enum flag values (e.g. `--color auto|always|never`).\n\n## Output Formats\n\n### Table (default)\n\nHuman-readable output with colors:\n\n```bash\n$ gccli activities list --limit 3\nID          NAME                TYPE       DATE\n123456789   Morning Run         running    2024-06-15\n123456780   Evening Walk        walking    2024-06-14\n123456771   Cycling Workout     cycling    2024-06-13\n```\n\n### JSON\n\nMachine-readable output for scripting and automation:\n\n```bash\n$ gccli --json activities list --limit 3\n[\n  {\n    \"activityId\": 123456789,\n    \"activityName\": \"Morning Run\",\n    \"activityType\": {\"typeKey\": \"running\"},\n    \"startTimeLocal\": \"2024-06-15 07:30:00\"\n  },\n  ...\n]\n```\n\nData goes to stdout, errors and progress to stderr for clean piping:\n\n```bash\ngccli --json activities list --limit 100 | jq '.[] | select(.activityType.typeKey == \"running\")'\n```\n\n### Plain (TSV)\n\nStable, tab-separated output for scripting:\n\n```bash\n$ gccli --plain activities list --limit 3\n123456789\tMorning Run\trunning\t2024-06-15\n123456780\tEvening Walk\twalking\t2024-06-14\n123456771\tCycling Workout\tcycling\t2024-06-13\n```\n\n## Examples\n\n### Export all runs from the last month\n\n```bash\ngccli --json activities search --start-date 2024-05-15 --end-date 2024-06-15 --limit 100 | \\\n  jq -r '.[] | select(.activityType.typeKey == \"running\") | .activityId' | \\\n  while read id; do\n    gccli activity download \"$id\" --format gpx --output \"run_${id}.gpx\"\n  done\n```\n\n### Daily health check script\n\n```bash\ngccli --json health summary | jq '{\n  steps: .totalSteps,\n  calories: .totalKilocalories,\n  distance_km: (.totalDistanceMeters / 1000),\n  active_minutes: .moderateIntensityMinutes + .vigorousIntensityMinutes\n}'\n```\n\n### Track weight over time\n\n```bash\ngccli --json body weigh-ins --start 2024-01-01 --end 2024-06-30 | \\\n  jq -r '.dailyWeightSummaries[] | [.summaryDate, .weight.value] | @tsv'\n```\n\n### Download the latest activity\n\n```bash\nlatest=$(gccli --json activities list --limit 1 | jq -r '.[0].activityId')\ngccli activity download \"$latest\" --format fit\n```\n\n## Global Flags\n\nAll commands support these flags:\n\n| Flag | Description |\n| --- | --- |\n| `--account \u003cemail\u003e` | Account to use (overrides `GCCLI_ACCOUNT` and config default) |\n| `--json`, `-j` | Output JSON to stdout |\n| `--plain` | Output stable TSV to stdout |\n| `--color \u003cmode\u003e` | Color mode: `auto`, `always`, `never` (default: `auto`) |\n| `--version` | Print version information |\n| `--help` | Show help for any command |\n\n## Date Format Reference\n\nMany commands accept flexible date formats:\n\n| Format | Example | Description |\n| --- | --- | --- |\n| `YYYY-MM-DD` | `2024-06-15` | Explicit date |\n| `today` | | Today's date |\n| `yesterday` | | Yesterday's date |\n| `Nd` | `3d`, `7d` | N days ago |\n\n## Development\n\nAfter cloning, install tools:\n\n```bash\nmake tools\n```\n\nBuild, test, and lint:\n\n```bash\nmake build          # Build to ./bin/gccli\nmake test           # Unit tests with race detector\nmake lint           # golangci-lint\nmake fmt            # Format with goimports + gofumpt\nmake ci             # Full CI gate (fmt-check + lint + test)\n```\n\nRun individual tests:\n\n```bash\ngo test -run TestFuncName ./internal/pkg/...\n```\n\n### E2E Tests (Live Garmin API)\n\nEnd-to-end tests hit the real Garmin Connect API. They require a `.env` file with test credentials:\n\n```bash\ncp .env.example .env\n# Edit .env with your test account credentials\nmake test-e2e\n```\n\n**Warning:** E2E tests create and delete activities/workouts. Use a dedicated test account.\n\n## Architecture\n\nInspired by [gogcli](https://github.com/steipete/gogcli). API coverage based on [python-garminconnect](https://github.com/cyberjunky/python-garminconnect) (113 API methods).\n\nPlatforms: macOS (amd64, arm64), Linux (amd64, arm64). macOS builds with CGO enabled for Keychain access.\n\n## License\n\nMIT\n\n## Links\n\n- [Garmin Connect](https://connect.garmin.com)\n- [python-garminconnect](https://github.com/cyberjunky/python-garminconnect) — API reference\n- [gogcli](https://github.com/steipete/gogcli) — architecture inspiration\n\n## Credits\n\nArchitecture inspired by [gogcli](https://github.com/steipete/gogcli) by Peter Steinberger. API coverage modeled after [python-garminconnect](https://github.com/cyberjunky/python-garminconnect) by Ron Klinkien.\n\n---\n\n\u003csub\u003eNot affiliated with Garmin. Garmin and Garmin Connect are trademarks of Garmin Ltd. or its subsidiaries.\u003c/sub\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbpauli%2Fgccli","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbpauli%2Fgccli","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbpauli%2Fgccli/lists"}