agentleFS
dbhq-ukdbhq-uk/garmin-skill/AGENTS.md

garmin-skill

AGENTS.md0 starsChanged 49 days agoMITView on GitHub

Guidance for AI agents (and people) working in this repository. The garmin skill for AI coding agents - Garmin Connect health, sleep, activity and training data, live or archived to markdown. It follows the Agent Skills layout (skills/<name>/SKILL.md) and ships as a Claude Code plugin. The venv lives at skills/garmin/.venv, built by scripts/setup.sh and gitignored. It is inside the skill directory on purpose: ${CLAUDE_SKILL_DIR}/.venv/bin/python is then correct under a personal install, a Codex install and a plugin install without a…

  • Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.

    Of the AGENTS.md files we read, the 31,700 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.

  • In this repositoryOne other file it gives its agents.

The file

We split this AGENTS.md into the rules it gives an agent

2 rules. About 1 is common, 1 is distinctive, and 0 are very specific to this project.

  • ≈1

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈1

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 0

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Common:

    No secrets in the repo, and no fixture that looks like one.

    line 37
  2. Distinctive:

    Do not "fix" that test by mocking it.

    line 46

≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
AGENTS.md

AGENTS.md

Guidance for AI agents (and people) working in this repository.

What this is

The garmin skill for AI coding agents - Garmin Connect health, sleep, activity and training data, live or archived to markdown. It follows the Agent Skills layout (skills/<name>/SKILL.md) and ships as a Claude Code plugin.

Layout

.claude-plugin/plugin.json          # plugin manifest
skills/garmin/SKILL.md              # the skill (agent-facing instructions)
skills/garmin/scripts/              # the CLI scripts and setup.sh
skills/garmin/tests/                # pytest suite, no network
skills/garmin/references/setup.md   # manual setup, for when setup.sh fails part-way
skills/garmin/requirements.txt      # garminconnect, pytest
install.sh / install-codex.sh       # local symlink installers (Claude / Codex)

The venv lives at skills/garmin/.venv, built by scripts/setup.sh and gitignored. It is inside the skill directory on purpose: ${CLAUDE_SKILL_DIR}/.venv/bin/python is then correct under a personal install, a Codex install and a plugin install without a lookup table.

The three constraints that must not be broken

Everything else here is a preference. These are not.

1. Every call is a read. The skill fetches from Garmin and never writes to it. There is no code path that creates, edits or deletes anything in a user's Garmin account, and adding one is not a feature request to weigh up - a health record the user did not enter themselves is worse than no record, and the moment this skill can write, every user has to audit it before trusting it with credentials. If the API grows a tempting setter, do not call it.

2. "No data" is not "the fetch failed". GarminFetchError means the call failed and the caller must abort rather than write. A None return means Garmin genuinely has nothing for that day, and the file still writes with "No data" in the section. Collapsing the two is a one-line change that quietly fills an archive with empty days indistinguishable from days the user did not wear the watch. The distinction is load-bearing; keep it.

3. Credentials stay on the machine, and stay owner-only. ~/.dbhq/garmin is created at 700 and config.json written at 600, before anything is written into them. The password is never stored: garmin_login.py asks for it, hands it to Garmin and forgets it, so config.json holds only the email and settings. Nothing is transmitted anywhere but Garmin. Do not add telemetry, do not add an aggregation service, and do not relax those modes because a test was easier without them.

Conventions

  • Any path a SKILL.md names must use ${CLAUDE_SKILL_DIR} (the skill's own directory), which Claude Code substitutes for personal, project and plugin installs alike. install.sh therefore symlinks the whole skill directory into ~/.claude/skills/ with no rewrite. install-codex.sh rewrites the variable, since Codex does not substitute it. Never hardcode an install path - it is wrong under a Codex install and wrong under a plugin install, and CI fails on it. Python that needs its own location derives it from __file__ rather than naming a directory, which is what RELOGIN_COMMAND in garmin_client.py does.
  • Shell scripts use set -e; errors go to stderr, output to stdout.
  • No secrets in the repo, and no fixture that looks like one.
  • House style: British English, plain hyphens, no em dashes. CI enforces the last one.

The upstream API is undocumented, and that shapes the tests

Garmin Connect has no public API, no versioning and no deprecation notices. garminconnect tracks it by reverse engineering, and things get renamed underneath it. Its 0.3 release dropped garth altogether and changed the token format, and this skill went on writing garth tokens nothing could read.

This is why tests/test_garmin_api_contract.py imports the real garminconnect rather than a mock. A MagicMock invents whatever attribute it is asked for, so a mocked suite stays green through an upstream rename - which is exactly how an auth-surface change (.garth -> .client) went unnoticed for months. That test constructs Garmin() and inspects its actual attributes. Attribute names are not enough on their own, so it also writes tokens the way garmin_login.py does and checks that garminconnect's own login(tokenstore) accepts them, with the token directory at 700 and the file at 600. It still makes no network call: the login strategy chain, the token refresh and the profile fetch are replaced, and the first two fail the test if anything reaches them.

Do not "fix" that test by mocking it. It is the only thing in the suite that can see the failure it exists to catch.

Validating a change

bash -n install.sh install-codex.sh
shellcheck ./install.sh ./install-codex.sh ./skills/*/scripts/*.sh
ruff check . && ruff format --check .
cd skills/garmin && .venv/bin/python -m pytest tests/ -v

CI runs all of that, on Python 3.12 and 3.13, plus both installers end to end. If you have Claude Code, claude plugin validate . is a useful extra check before a release, but it is local only: CI does not run it, because it would need a Claude Code install in every runner to check what the manifest step already checks.

What none of it covers is whether the data is right. The suite mocks Garmin's responses, so it proves the parsing and the formatting, not that the field you read is the field Garmin means. After changing a fetch or a formatter, run it against a real account and check one day's figures against the Garmin Connect app by eye. Nothing asserts that, and a plausible-looking wrong number is the failure this skill can actually ship.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.