{"slug": "goat", "name": "goat", "category": "terminal", "category_name": "Terminal and shell", "description": "", "recommenders": 3, "commenters": 4, "warners": 0, "score": 2.794, "rising": -0.98, "first": "2025-11-26", "latest": "2026-07-10", "why": "has a linting command that instantly checks whether your changes pass the rules", "why_is_quote": true, "has_verdict": false, "sentiment": {"recommend": 3, "neutral": 1, "compare": 0, "warn": 0}, "spark": [1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0], "listed": true, "loved": [], "caveat": "", "short_quote": "has a linting command that instantly checks whether your changes pass the rules", "kind": "", "icon": true, "domain": null, "github_repo": "github.com/bluesky-social/goat", "official_url": "https://github.com/bluesky-social/goat", "pricing": "", "aliases": ["goat"], "verdict": null, "praise": [{"label": "", "summary": "", "quotes": [{"id": 761319072, "item_id": 47582442, "url": "https://news.ycombinator.com/item?id=47582442", "by": "verdverm", "date": "2026-03-30", "version": null, "stance": "recommend", "quote": "You can use `goat` for a CLI version", "excerpt": "You can use `goat` for a CLI version: https://whtwnd.com/bnewbold.net/3lj7jmt2ct72r I'm not sure if OAuth gives access to the account management APIs. Certainly much could be improved. Nudging users would be a good notification within the Bluesky app, like one of those on boarding task lists that doesn't have to be completed to get started, but remains visible until you complete or discard them. goat has since moved ", "context": "", "use_case": "", "switched_from": "", "story": "Why I'm betting on ATProto (and why you should, too)"}, {"id": 746754608, "item_id": 46672163, "url": "https://news.ycombinator.com/item?id=46672163", "by": "danabramov", "date": "2026-01-18", "version": null, "stance": "recommend", "quote": "has a linting command that instantly checks whether your changes pass the rules", "excerpt": "That's a great question! Adding new features is usually not a problem because you can always add optional fields and extend open unions. So, you just change `media: Link | Picture | unknown` to `media: Link | Picture | Video | unknown`. You can't remove things true, so records do get some deprecated fields. Re: updating safely, the rule is that you can't change which records it would consider valid after it gets used", "context": "", "use_case": "AT Protocol lexicon linting", "switched_from": "", "story": "A Social Filesystem"}, {"id": 737052848, "item_id": 46065803, "url": "https://news.ycombinator.com/item?id=46065803", "by": "icy", "date": "2025-11-26", "version": null, "stance": "recommend", "quote": "use goat (https://tangled.org/oppi.li/goat) or similar", "excerpt": "You can already do this for tags, but manually. Via CI, you\u2019ll need to set an app password and use goat (https://tangled.org/oppi.li/goat) or similar.", "context": "", "use_case": "uploading release blobs via CI", "switched_from": "", "story": "Migrating the main Zig repository from GitHub to Codeberg"}]}], "caveats": [], "who": [], "tags": [], "use_cases": ["migrating at protocol accounts", "at protocol lexicon linting", "uploading release blobs via ci"], "compared": [], "makers": [], "threads": [{"url": "https://news.ycombinator.com/item?id=48859784", "title": "ActivityPub over ATProto", "mentions": 1}, {"url": "https://news.ycombinator.com/item?id=47578741", "title": "Why I'm betting on ATProto (and why you should, too)", "mentions": 1}, {"url": "https://news.ycombinator.com/item?id=46665839", "title": "A Social Filesystem", "mentions": 1}, {"url": "https://news.ycombinator.com/item?id=46064571", "title": "Migrating the main Zig repository from GitHub to Codeberg", "mentions": 1}], "sentiment_by_month": {"2025-11": {"recommend": 1}, "2025-12": {}, "2026-01": {"recommend": 1}, "2026-02": {}, "2026-03": {"recommend": 1}, "2026-04": {}, "2026-05": {}, "2026-06": {}, "2026-07": {"neutral": 1}, "2026-08": {}, "2026-09": {}, "2026-10": {}}, "versions": [], "version_unnamed": 0, "family_ref": null, "runs_on": null, "lines": [], "quotes": [{"id": 781823313, "item_id": 48863957, "url": "https://news.ycombinator.com/item?id=48863957", "by": "jsmith45", "date": "2026-07-10", "version": null, "stance": "neutral", "quote": "If you migrate to a self hosted PDS using the all-in-one migration `goat account migrate` command", "excerpt": "The PLC keys are normally intended to be held by your current PDS. Not a hard protocol requirement, but without it, certain things like migrating to a custom domain handle cannot be done cleanly though the app, and would need to be done manually. It might be a requirement of the bluesky hosted PDSes though, as those have some extra requirements beyond the reference self-hosted PDS. The fact that BlueSky runs the PLC ", "context": "", "use_case": "migrating AT Protocol accounts", "switched_from": "", "story": "ActivityPub over ATProto"}, {"id": 761319072, "item_id": 47582442, "url": "https://news.ycombinator.com/item?id=47582442", "by": "verdverm", "date": "2026-03-30", "version": null, "stance": "recommend", "quote": "You can use `goat` for a CLI version", "excerpt": "You can use `goat` for a CLI version: https://whtwnd.com/bnewbold.net/3lj7jmt2ct72r I'm not sure if OAuth gives access to the account management APIs. Certainly much could be improved. Nudging users would be a good notification within the Bluesky app, like one of those on boarding task lists that doesn't have to be completed to get started, but remains visible until you complete or discard them. goat has since moved ", "context": "", "use_case": "", "switched_from": "", "story": "Why I'm betting on ATProto (and why you should, too)"}, {"id": 746754608, "item_id": 46672163, "url": "https://news.ycombinator.com/item?id=46672163", "by": "danabramov", "date": "2026-01-18", "version": null, "stance": "recommend", "quote": "has a linting command that instantly checks whether your changes pass the rules", "excerpt": "That's a great question! Adding new features is usually not a problem because you can always add optional fields and extend open unions. So, you just change `media: Link | Picture | unknown` to `media: Link | Picture | Video | unknown`. You can't remove things true, so records do get some deprecated fields. Re: updating safely, the rule is that you can't change which records it would consider valid after it gets used", "context": "", "use_case": "AT Protocol lexicon linting", "switched_from": "", "story": "A Social Filesystem"}, {"id": 737052848, "item_id": 46065803, "url": "https://news.ycombinator.com/item?id=46065803", "by": "icy", "date": "2025-11-26", "version": null, "stance": "recommend", "quote": "use goat (https://tangled.org/oppi.li/goat) or similar", "excerpt": "You can already do this for tags, but manually. Via CI, you\u2019ll need to set an app password and use goat (https://tangled.org/oppi.li/goat) or similar.", "context": "", "use_case": "uploading release blobs via CI", "switched_from": "", "story": "Migrating the main Zig repository from GitHub to Codeberg"}]}