Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

673 linesCodeBlameRaw
1---
2title: The g1t CLI
3description: Install the g1t command line, sign in, and work with repositories, issues, pull requests, runs, workflows, deployments, secrets and logs from a terminal, a script or an agent.
4---
5
6`g1t` is the command line for g1t. It does the work you would otherwise do on
7the site: open and review pull requests, wait on checks, read a failing run's
8logs, set secrets, read a project's logs, and call any operation of the
9[API](/reference/api/). It is one file with nothing to install alongside it,
10and it is built to be run by agents as much as by people: every command can
11print JSON, nothing waits for input unless a person is at the terminal, and
12exit codes say what happened.
13
14```sh
15g1t issue list --label bug
16g1t pr create --fill
17g1t pr checks --watch --fail-fast
18g1t run logs --failed
19```
20
21Every command and flag is listed in the [command reference](/reference/cli/).
22
23## Install
24
25On Linux or macOS:
26
27```sh
28curl -fsSL https://g1t.sh/install | sh
29```
30
31On Windows, in PowerShell:
32
33```powershell
34irm https://g1t.sh/install.ps1 | iex
35```
36
37The script picks the build for your system, checks it against the
38release's `SHA256SUMS`, and puts `g1t` in `~/.local/bin` (Windows:
39`%LOCALAPPDATA%\g1t\bin`, which it adds to your `PATH`). Set
40`G1T_INSTALL_DIR` to put it elsewhere, or `G1T_VERSION` to install a
41version other than the latest.
42
43### Upgrade
44
45From 0.3.4 on, `g1t upgrade` updates g1t to the newest release:
46
47```sh
48g1t upgrade # download and install the newest release
49g1t upgrade --check # only say whether there is one
50```
51
52It reads the newest release's manifest, `latest.json`, and checks its
53signature (`latest.json.sig`) against g1t's release key, which is built
54into every release. It then downloads the build for your system, checks
55its SHA-256 against the manifest, and puts it where the running `g1t` is.
56If anything does not check out, nothing changes. Releases come from
57`https://g1t.sh/downloads/cli`, or from `G1T_DOWNLOAD_URL` if you set it.
58
59In a terminal, g1t looks for a newer release about once a day, in the
60background, and says so after a command when there is one. It never looks
61in CI or when its output is not a terminal. Set `G1T_NO_UPDATE_NOTIFIER=1`
62to turn it off.
63
64A g1t built from source has no release key and cannot upgrade itself.
65Neither can versions before 0.3.4. Update those by running the install
66script again.
67
68### Without the script
69
70Each release is a single file per platform, at
71`https://g1t.sh/downloads/cli/latest/`:
72
73| Platform | File |
74| --- | --- |
75| Linux, x64 | `g1t-linux-x64` |
76| Linux, ARM | `g1t-linux-arm64` |
77| macOS, Apple silicon | `g1t-macos-arm64` |
78| macOS, Intel | `g1t-macos-x64` |
79| Windows, x64 | `g1t-windows-x64.exe` |
80
81```sh
82curl -fsSLo g1t https://g1t.sh/downloads/cli/latest/g1t-linux-x64
83chmod +x g1t && mv g1t ~/.local/bin/
84```
85
86Check a download against `https://g1t.sh/downloads/cli/latest/SHA256SUMS`.
87`latest.json` beside it names the version and each file's SHA-256, and
88`latest.json.sig` is its signature. A given version's files are at
89`/downloads/cli/<version>/` and never change.
90
91To build it from source, with [Rust](https://www.rust-lang.org/tools/install):
92
93```sh
94git clone https://g1t.sh/flagon-io/g1t
95cargo install --path g1t/crates/g1t
96```
97
98`g1t --version` prints the version you have.
99
100## Sign in
101
102```sh
103g1t auth login
104```
105
106`g1t` shows a one-time code and opens your browser at
107[g1t.sh/device](https://g1t.sh/device). Sign in there if you are not
108already, check the code matches, and approve. The command finishes on its
109own once you have. Where there is no browser (a server, a container, a
110remote shell), it prints the link instead: open it on any device.
111
112To use an [access token](/guides/authentication/#access-tokens) you already
113have, pipe it in:
114
115```sh
116g1t auth login --with-token < token.txt
117```
118
119The token is kept in your system's credential store: the Keychain on
120macOS, Credential Manager on Windows, the Secret Service on Linux. Where
121there is none, as on most servers, it goes in the [config
122file](#settings-and-environment), readable only by you; `--insecure-storage`
123puts it there on purpose.
124
125| Command | What it does |
126| --- | --- |
127| `g1t auth status` | Each account you are signed in as, on each host, whether its token still works, and its scopes. Exits `4` when the active account's token does not work. |
128| `g1t auth token` | Prints the token in use, for another program. |
129| `g1t auth logout` | Forgets an account's token. |
130| `g1t auth switch` | Makes another signed-in account on the same host the active one. |
131
132### G1T_TOKEN
133
134When `G1T_TOKEN` is set, every command uses it instead of a stored token.
135This is how to give `g1t` a token in containers, in agents' sandboxes, and
136in [workflows](/guides/actions/), where the job's own token is
137`secrets.G1T_TOKEN`:
138
139```yaml
140- run: g1t pr comment ${{ github.event.pull_request.number }} -b "Preview is up."
141 env:
142 G1T_TOKEN: ${{ secrets.G1T_TOKEN }}
143```
144
145### Self-hosted g1t
146
147`g1t` works with any g1t, not only g1t.sh. Sign in to yours with its
148address:
149
150```sh
151g1t auth login --hostname git.example.com
152```
153
154`g1t` asks it where its API is (its `/.well-known/g1t.json`), and remembers.
155After that, commands in a clone of one of its repositories talk to it on
156their own. Elsewhere, name it with `--hostname` or `G1T_HOST`; the first host
157you sign in to is the default. You can be signed in to several hosts, and
158as several accounts on each.
159
160## Use it with git
161
162```sh
163g1t auth setup-git
164```
165
166This makes `g1t` git's credential helper for each host you are signed in
167to, so `git push`, `git fetch` and `git clone` over HTTPS use the same
168token, with nothing more to type. It changes your global git config only for
169those hosts' addresses (`credential.https://g1t.sh.helper`). `g1t auth login
170--git` does both at once. To see the config lines without changing anything,
171add `--dry-run`.
172
173[`g1t push`](/guides/containers/#push-large-layers-with-g1t-push), which sends container
174images to g1t's registry, uses the same signed-in token.
175
176## Which repository
177
178Commands about a repository work on the one the current directory is a
179clone of, found from its git remotes: `upstream` if it is on g1t, then
180`origin`, then the first one that is. In a pull request's own [working
181copy](/concepts/forks/#working-copies-for-pull-requests), they work on the repository the pull request
182is for.
183
184Anywhere else, or to choose another, pass `--repo` (`-R`), or set
185`G1T_REPO`:
186
187```sh
188g1t issue list -R acme/web
189g1t pr view 14 -R git.example.com/acme/web
190```
191
192## Everyday work
193
194### Repositories
195
196```sh
197g1t repo create my-project --source . --remote g1t # make it, add it as a remote, push
198g1t repo create acme/web --public --clone
199g1t repo list acme
200g1t repo view acme/web --web
201g1t repo clone acme/web
202g1t repo fork acme/web --clone
203g1t repo sync # bring your fork's default branch up to date
204```
205
206A repository is private unless `--public` says otherwise, and is made in
207your own workspace unless its name says `WORKSPACE/NAME`. `--source`
208adds it as a remote of a local repository (`origin` unless `--remote`
209names another) and pushes its current branch. `g1t repo fork` forks into
210your own workspace, or `--workspace`; see
211[forking a repository](/guides/forking-repositories/).
212
213### Issues
214
215```sh
216g1t issue list # open issues, newest first
217g1t issue list --label bug --assignee @me
218g1t issue view 12 --comments
219g1t issue create -t "Greeting should name the caller" -b "Take a name from the first argument."
220g1t issue comment 12 -b "Fixed in #14."
221g1t issue edit 12 --add-label p1 --add-assignee @me
222g1t issue close 12 --reason not_planned
223```
224
225`@me` is you. At a terminal, `g1t issue create` without `--title` asks for
226one and opens your editor for the body.
227
228### Pull requests
229
230From a branch with your commits on it:
231
232```sh
233git switch -c greet-by-name
234# ...commit...
235g1t pr create --fill --issue 12
236```
237
238`g1t pr create` pushes the branch, then opens the pull request into the
239default branch (`--base` for another). `--fill` takes the title and body from
240the branch's commits; `--issue` says which issue it is for; `--draft` opens
241it as a draft.
242
243To start a pull request for an issue without a branch of your own, as
244coding agents usually do, run it with `--issue` from the default branch. g1t opens a draft
245with a [working copy](/concepts/forks/#working-copies-for-pull-requests) of its own and prints the
246copy's git remote. Push your commits there, then mark it ready with a
247summary of what changed and why:
248
249```sh
250g1t pr create --issue 12
251git push https://g1t.sh/pulls/pr_….git HEAD:main
252g1t pr ready --summary "Reads a name from the first argument."
253```
254
255Then, for any pull request:
256
257```sh
258g1t pr list
259g1t pr view 14 # the current branch's when left out
260g1t pr diff 14
261g1t pr checkout 14 # check its head out locally
262g1t pr checks 14 --watch
263g1t pr review 14 --approve -b "Reads well."
264g1t pr review 14 --request-changes -b "Trim the name first."
265g1t pr merge 14 --delete-branch
266```
267
268`g1t pr merge` merges the way the repository is set to, once
269[required checks](/guides/checks/) pass and [rules](/guides/rules/) allow;
270`--admin` merges past them, with the Admin role.
271
272### Checks and runs
273
274`g1t pr checks` lists a pull request's checks: g1t Actions jobs, check runs
275and commit statuses. With `--watch` it waits until they have all finished,
276redrawing at a terminal and printing a line per change when piped.
277`--fail-fast` stops at the first failure instead of waiting for the rest. It
278exits `0` when every check passed, `1` when one failed, and, without
279`--watch`, `8` while any are still running.
280
281```sh
282g1t run list --branch main
283g1t run view # the current branch's latest run
284g1t run watch run_01kpx7b3c6d9e2f5g8h1j4k7mr
285g1t run logs --failed
286g1t run rerun --failed
287```
288
289A run is named by its id (`run_…`), its number, or its address; left out,
290it is the current branch's latest. `g1t run logs --failed` prints only the
291steps that failed, each with its last 60 lines (`-n` for more or fewer):
292what you need to see why, without the rest of the log. `g1t run watch`
293exits `1` if the run fails.
294
295### Workflows
296
297`g1t workflow` works with the workflows in `.g1t/workflows`, as the
298repository's **Actions** page does.
299
300```sh
301g1t workflow list # those turned on; --all for every one
302g1t workflow view ci.yml # its triggers, inputs and latest runs
303g1t workflow view release.yml --yaml --ref v1.4.0
304g1t workflow run release.yml -f channel=stable
305g1t workflow disable Nightly
306g1t workflow enable nightly.yml
307```
308
309A workflow is named by its file name (`ci.yml`), its id (`wfl_…`) or its
310name (`CI`, in any case). When more than one has that name, name it by its
311file. Left out at a terminal, g1t asks which; in a script it is an error
312that names what to pass.
313
314`g1t workflow run` runs a workflow that has `on: workflow_dispatch`, on the
315default branch or the branch or tag `--ref` names, and prints its run's
316address once the run is there, so `g1t run watch` can follow it. Give its
317inputs with `-f key=value` (or `-F key=@file` to read a value from a file),
318or as one JSON object on stdin with `--json`:
319
320```sh
321echo '{"channel":"stable","dry_run":true}' | g1t workflow run release.yml --json
322```
323
324At a terminal with no inputs given, g1t asks for each, offering its
325default. Only the inputs the workflow declares are taken, as on the
326[Actions page](/guides/actions/#runs-and-logs). `g1t workflow view --yaml`
327prints the workflow's file as it is on the default branch, or on `--ref`.
328Turning a workflow off keeps its file: nothing starts it until it is
329turned on again, and a workflow the workspace requires stays on.
330
331### Deployments, logs and secrets
332
333```sh
334g1t deploy list --env production
335g1t deploy view dep_01kq8m3t5v7x9z1b3d5f7h9k2m
336
337g1t logs --since 1h --level error,fatal
338g1t logs -q '"payment failed"' --follow
339g1t logs --errors --state open
340
341g1t secret list
342echo "$NPM_TOKEN" | g1t secret set NPM_TOKEN
343g1t secret set STRIPE_KEY --env production < stripe-key.txt
344g1t secret set NPM_TOKEN --brokered-host registry.npmjs.org < npm-token.txt
345g1t secret delete STRIPE_KEY --env preview
346g1t secret list --workspace acme
347```
348
349`g1t logs` reads the [observability](/guides/observability/) data of the
350current repository's project, or of `--project WORKSPACE/SLUG`. A secret's
351value is read from stdin, so it stays out of your shell's history; at a
352terminal with nothing piped, `g1t` asks for it without echoing. Values are
353never printed. `--brokered-host` makes it a [brokered
354secret](/guides/secrets-and-variables/#brokered-secrets).
355
356### What needs you
357
358```sh
359g1t status
360```
361
362Your open pull requests and their checks, reviews asked of you, what is
363assigned to you, and failing checks, across every repository you can see.
364Inside a working copy it also lists your active sessions and claims in that
365repository.
366
367## Coordinating work
368
369When several people and agents work in one repository, `g1t session` and
370`g1t work` say who is on what, so nobody starts work that is already under
371way and everyone hears what changes under them. Claims are advisory: a
372claim never stops anyone, it tells them.
373
374### Sessions
375
376A session is one run of an agent's harness, such as one Claude Code
377session. Starting one remembers it for the working copy, and the commands
378after it use it:
379
380```sh
381g1t session start --harness claude-code --issue 12
382g1t session log "Split the parser before touching the lexer."
383g1t session attach --pull 14 --head-commit "$(git rev-parse HEAD)"
384g1t session heartbeat
385g1t session end --reason done
386```
387
388| Command | What it does |
389| --- | --- |
390| `g1t session start` | Starts a session and prints its id. `--harness` (`claude_code`, `codex`, `cursor`, `copilot` or `other`; `claude-code` works too), `--harness-session-id`, `--issue`, `--pull`, `--branch` (the current one by default) and `--title`. Starting again with the same `--harness-session-id` returns the same session. For a subagent, `--parent` (the session that started it), `--agent-type`, `--task`, `--prompt` and `--model`; a subagent's session is not kept as the working copy's (nor is one with `--no-remember`). |
391| `g1t session heartbeat` | Says the session is still working, and renews its claims. A session with no heartbeat for 15 minutes reads as idle, and after 2 hours as ended. |
392| `g1t session log TEXT` | Records a note. `--kind` takes `note`, `prompt`, `message`, `tool_call` (or `tool-call`) or `skill` (a skill's name), `--tool` names the tool, and `--key` makes recording the same entry twice do nothing. `-` reads the text from stdin; put `--` before text that starts with a dash. |
393| `g1t session attach` | Points the session at an `--issue`, a `--pull`, a `--branch` or its latest `--head-commit`, or gives it a `--title`: what it is for, which replaces the title it had. |
394| `g1t session touch` | Says what the session touched: `--file PATH`, `--commit SHA`, `--branch NAME`, `--pull N` (one it opened), `--issue N`, each repeatable. Ties the session to the pull requests and issues they lead to; a file another active session touched too is an `overlap.detected` for both. |
395| `g1t session updates [ID]` | What other sessions did that concerns this one (claims, overlaps, dependency changes, decisions, merge queue results), oldest first, up to 100. Reading never clears them. It first says which files the working copy changed, so overlapping edits are noticed (`G1T_TOUCH=0` turns that off). |
396| `g1t session acknowledge ID... --note TEXT` | Records your decision about those updates (what changes in your plan, or why nothing does) and clears exactly the IDs given, for this session only; `--session` names another of yours. Saying the same again does nothing. |
397| `g1t session end` | Ends it, with an optional `--reason` and `--result` (what it reported; `-` reads it from stdin), and forgets it. Its subagents still going end with it. |
398| `g1t session list` | The repository's sessions; `--state active`, `--issue`, `--pull` (any session tied to it), `--path` (those that touched a file, or a folder ending in `/`), `--subagents` to list subagents under the sessions that started them. |
399| `g1t session view [ID]` | A session and what it recorded, its subagents and their results, the issues and pull requests it worked on, and the skills used; the current one without an id. |
400
401The id is kept in `.git/g1t/session`, in the working copy's own git
402directory, so each worktree has its own. `G1T_SESSION` overrides it, for
403a harness that runs several sessions in one working copy.
404
405### Claims and context
406
407```sh
408g1t work context 12 # everything about #12's work
409g1t work claim 12 --note "Taking the parser" --ttl 1h
410g1t work claim --title "Preview builds time out" --body "Over 1 GB, the build stops at 10 minutes."
411g1t work release 12 --reason done
412g1t work handoff 12 --to ana --note "Parser done; lexer tests still fail."
413g1t work list # active claims and sessions here
414```
415
416`g1t work context` is the one call to make before starting: the issue and
417its definition of done, who has claimed it, its sessions, its pull
418requests with their checks, overlaps and place in the merge queue, what it
419waits on and what waits on it, its decisions, its last integration failure
420and its recent events.
421
422`g1t work claim` says you are working on an issue. It lasts 30 minutes
423unless `--ttl` says otherwise (at most `4h`), and a heartbeat of the session
424it was made in renews it. It is made in the current session, if there is
425one. If others have claimed the issue too, or it waits on issues that are
426not done, the answer says so. `g1t work handoff` ends your claim and asks
427`--to` someone, or anyone without it, to take the issue over, with a
428`--note` saying where it stands. Claims, releases and hand-offs are the
429current session's, so two sessions of yours (sibling subagents) each hold
430their own.
431
432For work that has no issue yet, `g1t work claim --title "…"` (with
433`--body` for its description) opens the issue and claims it in one step,
434and attaches the current session to it; it prints the new issue's number.
435Use it once the work is a change others should know about, after looking
436for an issue that already covers it; questions, exploration and trivial
437fixes need none. A number and `--title` together are refused.
438
439### Starting a session on an issue
440
441```sh
442g1t work dispatch 12 # on the workspace's Anthropic account
443g1t work dispatch 12 --mode plan --instruction "Keep the old flag"
444g1t work dispatch --title "Add a healthcheck" --handoff # open the issue; print a claude command
445```
446
447`g1t work dispatch` starts work on an issue in a session on your own
448Claude: with the workspace's Anthropic [AI provider](/guides/ai/), a Claude Managed Agents
449session on that account (it prints the session's page on g1t); without
450one, or with `--handoff`, the `claude` command line to run in your working
451copy with g1t's [Claude Code plugin](/guides/claude-code-plugin/).
452`--managed` fails rather than hand off. `--mode` is `plan`, `implement` or
453`review`. See [Start a session on your Anthropic account](/guides/sessions/#start-a-session-on-your-anthropic-account).
454
455`g1t issue edit 12 --add-assignee g1t` does the same as **Assign to g1t**
456on the site: g1t starts a session on the issue on the workspace's
457Anthropic account, as you. See
458[Assign g1t](/guides/sessions/#assign-g1t-or-ask-it-in-the-thread).
459
460### Dependencies
461
462```sh
463g1t work block 12 --by 9 --by 10 # #12 waits on #9 and #10
464g1t work unblock 12 --by 9
465```
466
467These change the issue's `blocked_by` through `update_issue`. An issue
468cannot wait on itself, and g1t refuses a cycle.
469
470### Following events
471
472`g1t work events` prints the repository's recent events, oldest first.
473With `--follow` it keeps printing them as they happen, without a webhook or
474a public address, until you stop it with Ctrl-C:
475
476```sh
477g1t work events --follow --issue 12
478g1t work events --follow --type integration.failed --type overlap.detected --json
479```
480
481| Flag | |
482| --- | --- |
483| `--type`, `-t` | Only events of this type, such as `work.claimed`; repeat for more. |
484| `--issue`, `-i` | Only events about this issue or pull request; repeat for more. |
485| `--since`, `-s` | Only events since then: `15m`, `2h`, `1d`, or an RFC 3339 time. |
486| `--after` | Start after this event id, to resume where an earlier follow stopped. |
487| `--limit`, `-L` | How many past events to show first; 20 by default. |
488
489Each event is one line: its time, type, issue or pull request, a summary
490and its id. With `--json`, each is one compact JSON object on a line of its
491own, so a program can read them as they come. Following asks
492[`list_events`](/reference/api/repositories/list-events/) with `after` and
493`wait`, so the server holds each request until something happens; when a
494call fails, `g1t` waits (1 second, then longer, up to 30) and resumes from
495the last event it printed. A refused token stops it with exit code `4`.
496
497### Why a line is as it is
498
499```sh
500g1t why src/parser.rs:120
501g1t why src/parser.rs --ref main
502```
503
504`g1t why` follows a line to the commit that last changed it, the pull
505request that merged that commit, the issue the pull request was for, and
506the decisions and sessions recorded on them. A path is read from where you
507are in the working copy.
508
509### In an agent's hooks
510
511These commands are made to be run by a harness's hooks in the background:
512they never ask anything, they fail at once with exit code `4` when there is
513no token, and they give up on a call after 15 seconds. Against a g1t server
514older than the CLI, a command it cannot do yet fails saying so.
515
516## Scripting with JSON
517
518Every command takes `--json`. Alone, it prints every field the API returns;
519with a comma-separated list, only those (`g1t workflow run` is the one
520exception: there, `--json` alone reads the inputs from stdin):
521
522```sh
523g1t pr list --json number,title,check_status
524```
525
526```json
527[{"check_status":"passed","number":14,"title":"Greeting should name the caller"}]
528```
529
530The fields are the API's own, named as in the [API reference](/reference/api/)
531and always `snake_case`. A field that does not exist is an error that lists
532the ones that do. Piped, JSON is one compact line with its keys in a fixed
533order, so the same input gives the same output; at a terminal it is
534indented.
535
536`--jq` runs a [jq](https://jqlang.org/manual/) expression over the JSON,
537with nothing else to install. Strings come out bare, everything else as
538JSON:
539
540```sh
541g1t pr list --jq '.[] | select(.check_status == "failed") | .number'
542g1t run list --jq '.[] | [.id, .conclusion] | @tsv'
543```
544
545Without `--json`, output piped to another program is one record per line,
546fields separated by tabs, with no header and no color, ready for `cut`,
547`awk` or `while read`. Lists show 20 entries unless `--limit` (`-L`) says
548otherwise.
549
550### Exit codes
551
552| Code | Meaning |
553| --- | --- |
554| `0` | It worked. |
555| `1` | It failed: the API refused it, the network failed, checks or a run failed. |
556| `2` | The command was used wrongly: an unknown flag, a missing argument, a JSON field that does not exist. |
557| `4` | Signing in is needed, or the token was refused. |
558| `8` | Checks are still running (`g1t pr checks` without `--watch`). |
559
560An error is one line on stderr, starting `g1t:`. When a token lacks a
561[scope](/guides/authentication/#scopes) the call needs, the line names it.
562
563### No questions when piped
564
565`g1t` asks for a missing title, opens an editor for a body, or offers a
566choice only when stdin and stderr are both a terminal. Anywhere else, and
567whenever `G1T_PROMPT_DISABLED` is set, a command missing something fails at
568once with exit code `2` and names the flag that supplies it.
569
570## Call any operation
571
572`g1t api` calls any operation of the [API](/reference/api/) by its name,
573with your token, and fills the repository in from where you are:
574
575```sh
576g1t api list_issues -f state=closed --jq '.[].title'
577g1t api create_label -f name=p1 -f color=d73a4a
578g1t api get_workflow_run -f id=run_01kpx7b3c6d9e2f5g8h1j4k7mr
579g1t api --list label # the operations about labels
580```
581
582A path works too, with `{owner}`, `{name}` and `{workspace}` filled in:
583
584```sh
585g1t api /repos/{owner}/{name}/labels
586g1t api user --jq .username
587```
588
589`-f key=value` sends a string, `-F key=value` sends `true`, `false`, `null`
590and numbers as JSON and `@file` as a file's contents, and `key[]=value` adds
591to a list. Fields go in the query of a `GET` and in the JSON body otherwise.
592`-X` sets the method, `-H` adds a header, and `--input file` sends a file as
593the body. `--paginate` follows each next page, and with `--slurp` puts every
594page's items in one array. A request the API refuses prints its error body
595and exits `1`.
596
597In Git Bash on Windows, an argument starting with `/` is turned into a
598Windows path before `g1t` sees it: leave the leading slash off
599(`g1t api repos/{owner}/{name}`), or set `MSYS_NO_PATHCONV=1`.
600
601## From agents and harnesses
602
603An agent with a shell, such as Claude Code, Codex or Cursor, can use `g1t`
604the way you do. A command and its JSON cost an agent less of its context
605than a set of tool definitions, and the agent finds what it needs with
606`--help`. For clients without a shell, use the [MCP server](/reference/mcp/).
607
6081. Install `g1t` where the agent runs, as [above](#install).
6092. Give it a token. Either sign in once with `g1t auth login` as the user
610 the agent runs as, or set `G1T_TOKEN` in its environment. Make a token
611 with only the [scopes](/guides/authentication/#scopes) it needs.
6123. Tell it `g1t` is there. A few lines in the project's `CLAUDE.md` or
613 `AGENTS.md` are enough:
614
615```md
616This repository is on g1t. Use the `g1t` CLI for issues, pull requests,
617checks and runs; add `--json` to read results, and see `g1t <command> --help`.
618
619- Open a pull request: `g1t pr create --fill --issue <n>`
620- Wait for checks: `g1t pr checks --watch --fail-fast` (exit 0 passed, 1 failed)
621- See why a run failed: `g1t run logs --failed`
622- Run a workflow by hand: `g1t workflow run <file> -f key=value`
623- Anything else: `g1t api --list <word>`, then `g1t api <operation>`
624```
625
626`g1t` never waits for input in an agent's shell, since its stdin is not a
627terminal. Its JSON is compact and in a stable order, its lists are short
628by default, and `g1t pr checks --watch --fail-fast` and `g1t run logs
629--failed` give an agent the one thing it is waiting for, and no more.
630
631## Aliases and completion
632
633An alias is a shortcut for a command you type often. `$1`, `$2`… take the
634arguments after it, and the rest go on the end:
635
636```sh
637g1t alias set bugs 'issue list --label bug'
638g1t alias set co 'pr checkout'
639g1t alias set mine '!g1t pr list --author @me --json number,title'
640g1t bugs --limit 5
641```
642
643An alias starting with `!` runs in `sh`. `g1t alias list` lists them, and
644`g1t alias delete` removes one.
645
646`g1t completion <shell>` prints a completion script for `bash`, `zsh`,
647`fish`, `powershell` or `elvish`:
648
649```sh
650g1t completion bash > ~/.local/share/bash-completion/completions/g1t
651g1t completion zsh > "${fpath[1]}/_g1t"
652g1t completion fish > ~/.config/fish/completions/g1t.fish
653g1t completion powershell >> $PROFILE
654```
655
656## Settings and environment
657
658`g1t` keeps the hosts you are signed in to, their accounts and your aliases
659in `config.json`, in `~/.config/g1t` (`%APPDATA%\g1t` on Windows;
660`$XDG_CONFIG_HOME/g1t` when that is set).
661
662| Variable | |
663| --- | --- |
664| `G1T_TOKEN` | A token to use instead of the stored one. |
665| `G1T_HOST` | The host to use when no repository names one. |
666| `G1T_REPO` | The repository, as `[HOST/]OWNER/NAME`. |
667| `G1T_CONFIG_DIR` | Where to keep `config.json`. |
668| `G1T_KEYRING` | `off` keeps tokens out of the system's credential store. |
669| `G1T_PROMPT_DISABLED` | Never ask anything. |
670| `G1T_EDITOR`, `VISUAL`, `EDITOR` | The editor for bodies and summaries. |
671| `G1T_BROWSER`, `BROWSER` | The browser `--web` and `g1t browse` open. |
672| `NO_COLOR` | Plain output at a terminal too. |
673| `G1T_DEBUG` | Print each request's method, address and status on stderr. |