atproto git client
Rust 96%
Python 1%
JavaScript <1%
Shell <1%
HTML <1%
Astro <1%
CSS <1%
TypeScript <1%
HCL <1%
<1%

README.md

atgc #

atgc

Current release: v0.16.0

ATproto Git Client.

The project page is atgc.codes.

Features #

atgc is intended for CLI workflows against Tangled.

  • Use either traditional or stacked PRs
  • Submit feature preview images in PR bodies
  • Log into ATproto via scoped OAuth (no app passwords!)
  • Use multiple simultaneous ATProto accounts
  • Set up Tangled-compatible .git/config for userinfo and SSH
  • Install shell completion
  • Submit bugs and feedback directly from atgc

Agentic support #

atgc is designed to support agentic workflows that run on high parallelism on git worktrees. Current features include:

  • Built-in briefing to explain usage to agents
  • Per-worktree credential switching
  • Per-agent credentials via did.bot
  • Maintain an audit log of operations
  • Agents can file their own bug reports

Install #

atgc is not on crates.io yet, see plan/publishing.md for more info.

# install remotely:
cargo install --git https://tangled.org/permadeath.com/atgc

# or if already checked out:
cargo install --path .

Commands #

Meta #

atgc about                 # info about atgc
atgc agent                 # working notes for AI agents (humans welcome)
atgc help [command]        # the same pages as --help, as a verb

Account management #

Logging in #

atgc auth login <handle|did>    # log in via OAuth (adds an account, changes no other)
atgc auth status                # list the accounts and show the active one
atgc auth default <handle|did>  # choose the default account
atgc auth refresh               # refresh the acting account's access token
atgc auth token                 # print the acting account's access token
atgc auth logout [handle|did]   # log out of one account (--all for every account)

Push keys #

atgc key list [owner]  # the SSH keys an account has registered
atgc key add [key]     # publish a public key so knots accept its pushes
atgc key create        # make one first, for an identity with no ~/.ssh
atgc key delete <key>  # withdraw one (by rkey, name, fingerprint or path)

Repository operations #

Repositories #

atgc repo create           # create a Tangled repo from this checkout and push
atgc repo create <name>    # ...or a blank one, with a checkout to start it in
atgc repo clone <repo>     # clone a Tangled repo and set its git identity
atgc repo configure        # point this checkout at the current account, and hook it
atgc repo configure --hook-config  # ...declaring the hook in prek.toml / .pre-commit-config.yaml
atgc repo edit             # change a repo's description, website, spindle or topics
atgc repo default-branch <branch>  # point a repo's HEAD at a different branch, on the knot
atgc repo delete-branch <branch>   # delete a branch on the knot (irreversible)
atgc repo delete <repo>    # delete a repo you own: record and git data (no undo)
atgc repo list [owner]     # list an account's repos
atgc repo view [repo]      # what a repo is: identity, hosting, git state
atgc browse [section]      # open the repo's Tangled page (e.g. browse pulls)
atgc browse --pr           # open the current branch's pull request
atgc browse --pr 23        # open a named one: number, rkey, at:// URI or URL
atgc search <query>        # full-text search (this repo, or --all for every one)

Pull requests #

atgc pr create             # push the branch and open a PR from it
                           #   (--patch-only: the patch alone, no branch)
atgc pr resubmit <pull>    # append a round to one of your PRs
                           #   (re-pushes the branch, if the PR records one)
atgc pr edit <pull>        # change a PR's title or body (--title/--body)
atgc pr close <pull>       # close a PR (yours, or one against a repo you own)
atgc pr reopen <pull>      # reopen a closed PR
atgc pr merge <pull>       # land a PR on its target branch (needs push access)

atgc pr list               # list PRs for this repo (--state open|closed|merged|all)
atgc pr list --author <who> # this repo, narrowed to one account
atgc pr list --all         # your PRs across every repo (--author for someone else's)
atgc pr view [pull]        # view a PR (defaults to the current branch's)
atgc pr diff <pull>        # print a PR's patch (--round N, --interdiff between rounds)
atgc pr checkout <pull>    # apply a PR onto a local branch with git am
                           #   (a stacked pull brings the pulls beneath it; --only skips them)
atgc pr comment <pull>     # comment on a PR (--body/--body-file, --round N)

Issues #

atgc issue create --title '…' --body '…'   # file one against this checkout's repo
atgc issue list                 # your issues on this repo (--all, --author, --state)
atgc issue view <issue>         # one issue, read live from its author's PDS
atgc issue comment <issue>      # comment (--body/--body-file)
atgc issue close <issue>        # close it (yours, or one on a repo you own)
atgc issue reopen <issue>       # reopen a closed one
atgc issue edit <issue>         # change your own issue's title or body

Stacks #

atgc stack mark HEAD~3     # cut here; the name comes off that commit
atgc stack mark part1 HEAD~3      # ...or name it yourself
atgc stack mark            # what is marked, and where each mark sits
atgc stack create          # push the branch, then a PR per mark
                           #   (or per commit, unmarked)
atgc stack create --per-commit    # ignore the marks
atgc stack sync            # rebase onto the target, then reconcile: the usual verb
atgc stack rebase          # ...just the replay, carrying the marks
atgc stack resubmit        # ...just the reconcile, after a rebase/amend/reorder
atgc stack link 12 15 17   # chain pulls that already exist, bottom first
atgc stack merge           # land the stack bottom-up (--through N stops partway)
atgc stack view            # the current branch's stack, top to bottom
atgc stack up / down       # stand on the member above / below (takes a count)
atgc stack top / bottom    # ...or the ends
atgc stack checkout part1  # ...or one by position or mark name

Checking and troubleshooting #

atgc doctor local          # is this machine, account and checkout set up to work?
atgc doctor remote         # are Tangled's services answering, and what are they running?

atgc logs oauth            # every OAuth operation (-f to follow, --json for jq)
atgc logs pds              # every write atgc has sent to a PDS
atgc logs git              # every git subprocess, and what it did to the checkout
atgc logs pds --failures --since 2h      # only what went wrong, recently
atgc logs oauth --incident               # the client_id and overlap comparison

atgc report bug            # file a Tangled issue on atgc's own repo
atgc report bug --agent    # the same, labelled `agent` (for AI agents)
atgc report <kind>         # feature requests and questions, onto atgc's public board

Other #

atgc api <nsid>            # call an XRPC method directly, as you, and print the answer
atgc api com.atproto.repo.listRecords -f repo=did:plc:… -f collection=sh.tangled.repo.pull
atgc api sh.tangled.search.query --host bobbin -f q='index lag'
atgc api sh.tangled.repo.forkSync --host knot:knot1.tangled.sh --input sync.json --dry-run

atgc completion <shell>    # print a completion script (bash|zsh|fish|powershell|elvish)

Documentation #

docs/ holds only what you cannot get by running the tool or reading the code: five short pages, listed in docs/index.md. The model is the one to read first: Tangled's shape is somebody else's system, and everything surprising about atgc follows from it.

They are compiled into the API documentation too, so prose and generated reference are one build:

cargo docs

Development #

This codebase is intended for a single user, and is largely AI generated. It is provided with no guarantee of stability, versioning, or any other best practices.

Please contact @permadeath.com before sending in issues or pull requests.

See CONTRIBUTING.md for more details.