The docs have a guide to the Claude Code plugin, under Coding agents: installing it with the CLI it needs, what each hook records and what it never records (what a tool returned, Claude's replies, your files), the context Claude starts with, its skills and commands, what happens when the CLI is missing or signed out, opting out with G1T_RECORD_PROMPTS=0 or G1T_RECORD=0, moving off the earlier hook, and the AGENTS.md lines and MCP setup for Codex and other agents. Connect a coding agent, Sessions and why-blame, Integrations and llms.txt point to the plugin instead of the hook installer, and llms.txt no longer mentions the retired agents:run, models:read and models:write scopes. g1t.sh/install/claude.sh now prints the plugin's two commands and installs the g1t CLI only with --cli; it no longer edits ~/.claude/settings.json, so setup.mjs is gone. For anyone still on the earlier hook, it updates ~/.g1t/hook.mjs, which no longer remembers that a branch had no pull request (a session started before its pull request was never recorded), no longer sends what a tool returned, and keeps prompts back with G1T_RECORD_PROMPTS=0.
8 files+301−500/8 viewed
| 153 | 153 | label: 'Coding agents', | |
| 154 | 154 | items: [ | |
| 155 | 155 | { label: 'Connect a coding agent', slug: 'guides/bring-your-own-agent' }, | |
| 156 | + | { label: 'Claude Code plugin', slug: 'guides/claude-code-plugin' }, | |
| 156 | 157 | { label: 'Sessions and why-blame', slug: 'guides/why-blame' }, | |
| 157 | 158 | { label: 'Memory', slug: 'guides/memory' }, | |
| 158 | 159 | ], |
| 124 | 124 | - Read `overlaps` and `behind` on `pull_request` `get` before going far. | |
| 125 | 125 | ``` | |
| 126 | 126 | ||
| 127 | + | An agent with a shell can use the [g1t CLI](/guides/cli/) instead of the | |
| 128 | + | tools, and claim the issue, record its session and hand off with it: the | |
| 129 | + | lines for that are in | |
| 130 | + | [other coding agents](/guides/claude-code-plugin/#other-coding-agents). | |
| 131 | + | With Claude Code, the [plugin](/guides/claude-code-plugin/) does this for | |
| 132 | + | you. | |
| 133 | + | ||
| 127 | 134 | ## Record the session | |
| 128 | 135 | ||
| 129 | 136 | A pull request's session is the record of how it was made: the prompts, | |
| ⋯ | |||
| 140 | 147 | ||
| 141 | 148 | ### Recording sessions automatically | |
| 142 | 149 | ||
| 143 | − | This is for Claude Code. To have every session recorded without the agent | |
| 144 | − | having to remember, install g1t's hook: | |
| 150 | + | With Claude Code, install g1t's plugin and every session in a g1t | |
| 151 | + | repository is recorded without the agent having to remember: | |
| 145 | 152 | ||
| 146 | 153 | ```sh | |
| 147 | − | curl -fsSL https://g1t.sh/install/claude.sh | sh | |
| 154 | + | claude plugin marketplace add https://g1t.sh/flagon-io/g1t.git | |
| 155 | + | claude plugin install g1t@g1t | |
| 148 | 156 | ``` | |
| 149 | 157 | ||
| 150 | − | It signs you in through the browser, keeps the token in `~/.g1t`, and adds | |
| 151 | − | a hook to `~/.claude/settings.json`. From then on, whenever Claude Code | |
| 152 | − | works in a g1t pull request's working copy, your prompts, its tool calls | |
| 153 | − | and its closing account are recorded onto that pull request's session as | |
| 154 | − | they happen. It recognises a fork (`g1t.sh/pulls/<id>`) and a branch of a | |
| 155 | − | g1t repository with an open pull request; anywhere else it does nothing. | |
| 156 | − | It needs Node 18 or later, which Claude Code runs on. | |
| 158 | + | Its hooks record your prompts, the tools Claude uses and what it called | |
| 159 | + | them with, and its pushes, through the [g1t CLI](/guides/cli/). They never | |
| 160 | + | send what a tool returned. The plugin also gives Claude the issue's work | |
| 161 | + | context when a session starts, g1t's MCP server, and commands to claim and | |
| 162 | + | hand off issues. See [Claude Code plugin](/guides/claude-code-plugin/) for | |
| 163 | + | everything it records, and how to opt out. | |
| 157 | 164 | ||
| 158 | − | To stop recording, remove the `node ~/.g1t/hook.mjs` entries from | |
| 159 | − | `~/.claude/settings.json`. | |
| 165 | + | Other agents record a session with the same CLI commands, from their | |
| 166 | + | instructions file: see | |
| 167 | + | [other coding agents](/guides/claude-code-plugin/#other-coding-agents). | |
| 160 | 168 | ||
| 161 | 169 | ## Share what agents learn | |
| 162 | 170 | ||
| 1 | + | --- | |
| 2 | + | title: Claude Code plugin | |
| 3 | + | description: Install g1t's plugin for Claude Code, which records your sessions on g1t, gives Claude the issue's work context, and adds g1t's MCP server, skills and commands. What each hook records and never records, and how to opt out. | |
| 4 | + | --- | |
| 5 | + | ||
| 6 | + | g1t's plugin for Claude Code connects the sessions you run on your own | |
| 7 | + | machine to the work on g1t. With it installed, working in a g1t repository: | |
| 8 | + | ||
| 9 | + | - each Claude Code session is recorded on g1t as a | |
| 10 | + | [session](/guides/why-blame/#sessions), attached to its issue and pull | |
| 11 | + | request, so the people and agents also working there can see it; | |
| 12 | + | - Claude starts each session knowing the issue it is on: its definition of | |
| 13 | + | done, who has claimed it, its pull requests and what blocks it; | |
| 14 | + | - Claude has g1t's [MCP tools](/reference/mcp/), three skills for working | |
| 15 | + | on issues, and the commands `/g1t:claim`, `/g1t:status` and | |
| 16 | + | `/g1t:handoff`. | |
| 17 | + | ||
| 18 | + | Your session runs where it always does. g1t keeps the record and the | |
| 19 | + | coordination; nothing about how Claude Code runs changes. | |
| 20 | + | ||
| 21 | + | ## Install | |
| 22 | + | ||
| 23 | + | You need Claude Code, Node 18 or later (Claude Code runs on it) and the | |
| 24 | + | [g1t CLI](/guides/cli/), which the plugin's hooks use. | |
| 25 | + | ||
| 26 | + | 1. Install the g1t CLI and sign in, if you have not: | |
| 27 | + | ||
| 28 | + | ```sh | |
| 29 | + | curl -fsSL https://g1t.sh/install | sh | |
| 30 | + | g1t auth login | |
| 31 | + | ``` | |
| 32 | + | ||
| 33 | + | On Windows, `irm https://g1t.sh/install.ps1 | iex` installs it. | |
| 34 | + | ||
| 35 | + | 2. Add g1t's plugin marketplace and install the plugin: | |
| 36 | + | ||
| 37 | + | ```sh | |
| 38 | + | claude plugin marketplace add https://g1t.sh/flagon-io/g1t.git | |
| 39 | + | claude plugin install g1t@g1t | |
| 40 | + | ``` | |
| 41 | + | ||
| 42 | + | Or run `/plugin` inside Claude Code and choose the marketplace there. | |
| 43 | + | ||
| 44 | + | 3. Start Claude Code again, run `/mcp` and choose **g1t** to sign g1t's | |
| 45 | + | MCP server in through your browser. | |
| 46 | + | ||
| 47 | + | `curl -fsSL https://g1t.sh/install/claude.sh | sh` prints the same | |
| 48 | + | commands; add `-s -- --cli` to have it install the CLI too. | |
| 49 | + | ||
| 50 | + | The plugin works in any working copy whose git remote is on g1t.sh, or on | |
| 51 | + | the host in `G1T_HOST` for a self-hosted g1t. Everywhere else its hooks do | |
| 52 | + | nothing. | |
| 53 | + | ||
| 54 | + | ## What it records | |
| 55 | + | ||
| 56 | + | The plugin's hooks call the `g1t` CLI, signed in as you, so a session is | |
| 57 | + | recorded as yours and is as visible as the repository it is in. | |
| 58 | + | ||
| 59 | + | | When | The hook runs | What g1t receives | | |
| 60 | + | | --- | --- | --- | | |
| 61 | + | | A session starts or resumes | `g1t session start --harness claude_code --harness-session-id ID` | A session for this Claude Code session. Starting the same session again, as a resume does, finds it rather than making another. | | |
| 62 | + | | You send a prompt | `g1t session log --kind prompt TEXT` | Your prompt's first 2,000 characters. | | |
| 63 | + | | Claude uses a tool | `g1t session log --kind tool_call TEXT` | The tool's name and one line on what it was called with: the command, file, pattern or address, up to 200 characters, with anything that looks like a token or password replaced by `…`. | | |
| 64 | + | | A `git push` reaches the remote | `g1t api update_session -f id=ID -f head_commit=SHA` | The commit you pushed, so the session's entries line up with the code. | | |
| 65 | + | | Claude finishes a turn | `g1t session heartbeat` | That the session is still active, which also renews its claims. | | |
| 66 | + | | The session ends | `g1t session end --reason REASON` | That it ended, and why: you exited, cleared it or logged out. | | |
| 67 | + | ||
| 68 | + | It never records: | |
| 69 | + | ||
| 70 | + | - what a tool returned: command output, file contents, search results and | |
| 71 | + | web pages are never read or sent; | |
| 72 | + | - Claude's replies or reasoning; | |
| 73 | + | - your files, environment or transcript. | |
| 74 | + | ||
| 75 | + | A session that stops sending heartbeats reads as idle after 15 minutes and | |
| 76 | + | ended after two hours, so a closed laptop does not leave work looking | |
| 77 | + | claimed. | |
| 78 | + | ||
| 79 | + | The hooks return at once: the CLI calls run in a background process, so a | |
| 80 | + | slow network never holds Claude up. | |
| 81 | + | ||
| 82 | + | ## The context Claude starts with | |
| 83 | + | ||
| 84 | + | When a session starts, the plugin looks for the issue it is working on: | |
| 85 | + | the one the session claimed earlier, or a number in the branch's name | |
| 86 | + | (`42-fix-login`, `issue-42`, `fix/42`). If it finds one, it runs | |
| 87 | + | `g1t work context N` and gives Claude the answer: the issue and its | |
| 88 | + | definition of done, its claims and sessions, its pull requests with their | |
| 89 | + | checks and overlaps, what blocks it and what it blocks, the decisions | |
| 90 | + | recorded on it and the last integration failure. If the answer takes longer | |
| 91 | + | than a second, Claude is told to load it itself. | |
| 92 | + | ||
| 93 | + | With no issue in sight, Claude is told how to load and claim one. | |
| 94 | + | ||
| 95 | + | ## Skills | |
| 96 | + | ||
| 97 | + | Claude uses a skill when the task matches it, or you can run one by name. | |
| 98 | + | ||
| 99 | + | | Skill | What it does | | |
| 100 | + | | --- | --- | | |
| 101 | + | | `/g1t:work-on-issue N` | Loads the issue's context, claims it, makes a branch named for it, opens a draft pull request early with `g1t pr create --issue N --draft`, does the work, watches the checks and merges, or adds the pull request to the [merge queue](/guides/merge-queue/). | | |
| 102 | + | | `/g1t:fix-integration N` | For a pull request the merge queue failed together with others: reads the `integration.failed` event and the failing check, compares the other pull requests in the combination, fixes, pushes and queues it again. | | |
| 103 | + | | `/g1t:coordinate N` | Follows the issue's events in the background with `g1t work events --follow --issue N`, and acts on another claim, an overlapping pull request, a change to what blocks it or an integration result as it happens. | | |
| 104 | + | ||
| 105 | + | ## Commands | |
| 106 | + | ||
| 107 | + | | Command | What it does | | |
| 108 | + | | --- | --- | | |
| 109 | + | | `/g1t:claim N [note]` | Loads issue N's context and claims it for this session, telling you who else holds a claim. | | |
| 110 | + | | `/g1t:status` | This session, and the repository's active claims and sessions. | | |
| 111 | + | | `/g1t:handoff N [@login]` | Pushes what is unpushed, writes a hand-off note and hands the issue off, to anyone or to one person. | | |
| 112 | + | ||
| 113 | + | A claim says you are working on an issue. It is never a lock: a second | |
| 114 | + | claim is allowed, and whoever makes it is told about the first. | |
| 115 | + | ||
| 116 | + | ## When the CLI is missing or signed out | |
| 117 | + | ||
| 118 | + | If `g1t` is not installed, or not signed in, the hooks record nothing and | |
| 119 | + | Claude Code says so once. The plugin never installs anything itself. | |
| 120 | + | Install the CLI or run `g1t auth login`, and the next session is recorded. | |
| 121 | + | ||
| 122 | + | ## Opt out | |
| 123 | + | ||
| 124 | + | | To | Do | | |
| 125 | + | | --- | --- | | |
| 126 | + | | Not send prompts | Set `G1T_RECORD_PROMPTS=0` in the environment Claude Code runs in. | | |
| 127 | + | | Not record anything | Set `G1T_RECORD=0`. | | |
| 128 | + | | Turn the plugin off for now | `claude plugin disable g1t@g1t` | | |
| 129 | + | | Remove it | `claude plugin uninstall g1t@g1t` | | |
| 130 | + | ||
| 131 | + | To set one of these for every session, put it under `env` in Claude Code's | |
| 132 | + | settings, for example in `~/.claude/settings.json`: | |
| 133 | + | ||
| 134 | + | ```json | |
| 135 | + | { "env": { "G1T_RECORD_PROMPTS": "0" } } | |
| 136 | + | ``` | |
| 137 | + | ||
| 138 | + | A recorded session can be read on the pull request's **Session** tab. | |
| 139 | + | ||
| 140 | + | ## The earlier hook installer | |
| 141 | + | ||
| 142 | + | An earlier `curl -fsSL https://g1t.sh/install/claude.sh | sh` added a hook | |
| 143 | + | of its own, `node ~/.g1t/hook.mjs`, to `~/.claude/settings.json`. The | |
| 144 | + | plugin replaces it. Once the plugin is installed, remove those entries from | |
| 145 | + | `~/.claude/settings.json` so a session is not recorded twice. Running the | |
| 146 | + | installer again brings the old hook up to date and prints the plugin's | |
| 147 | + | commands. | |
| 148 | + | ||
| 149 | + | ## Other coding agents | |
| 150 | + | ||
| 151 | + | Agents without plugins use the same CLI commands from their instructions | |
| 152 | + | file. Put this in the repository's `AGENTS.md`: | |
| 153 | + | ||
| 154 | + | ```md title="AGENTS.md" | |
| 155 | + | ## Working on g1t | |
| 156 | + | ||
| 157 | + | This repository is on g1t. Other agents and people may be working in it at | |
| 158 | + | the same time; the `g1t` CLI is how you see them and how they see you. | |
| 159 | + | ||
| 160 | + | - When you start, record a session: `g1t session start --harness codex` | |
| 161 | + | (or `cursor`, `copilot`, `other`: the harness you are). The CLI remembers | |
| 162 | + | it for this working copy. Run `g1t session heartbeat` every few minutes | |
| 163 | + | while you work, and `g1t session end` when you stop. | |
| 164 | + | - Before working on an issue, load it with `g1t work context N`: its | |
| 165 | + | definition of done, who has claimed it, its pull requests, checks and | |
| 166 | + | overlaps, and what blocks it. Then claim it with | |
| 167 | + | `g1t work claim N --note "what you are about to do"`. If someone else | |
| 168 | + | holds a claim, say so before going on. | |
| 169 | + | - Work on a branch whose name starts with the issue number | |
| 170 | + | (`42-short-description`), and open a draft pull request early: | |
| 171 | + | `g1t pr create --issue N --draft --fill`. | |
| 172 | + | - Log decisions worth keeping with `g1t session log --kind note "TEXT"`. | |
| 173 | + | Never log secrets or command output. | |
| 174 | + | - Run the repository's tests before each push, and watch the checks with | |
| 175 | + | `g1t pr checks --watch --fail-fast` (and `g1t run logs --failed` for why | |
| 176 | + | one failed). When the merge queue reports an integration failure, read | |
| 177 | + | it with `g1t work events --type integration.failed --issue N`, diff the | |
| 178 | + | other pull requests in the combination (`g1t pr diff OTHER`), fix, push | |
| 179 | + | and merge again. | |
| 180 | + | - If you stop before the issue is done, hand it off: | |
| 181 | + | `g1t work handoff N --note "what is done, what is left"`. | |
| 182 | + | ``` | |
| 183 | + | ||
| 184 | + | The same text is in the g1t repository at | |
| 185 | + | `plugins/other-harnesses/AGENTS.snippet.md`. | |
| 186 | + | ||
| 187 | + | To give Codex g1t's MCP tools as well: | |
| 188 | + | ||
| 189 | + | ```sh | |
| 190 | + | codex mcp add g1t --url https://mcp.g1t.sh | |
| 191 | + | codex mcp login g1t | |
| 192 | + | ``` | |
| 193 | + | ||
| 194 | + | or, in `~/.codex/config.toml`, with a token in `G1T_TOKEN` instead of | |
| 195 | + | signing in through the browser: | |
| 196 | + | ||
| 197 | + | ```toml | |
| 198 | + | [mcp_servers.g1t] | |
| 199 | + | url = "https://mcp.g1t.sh" | |
| 200 | + | bearer_token_env_var = "G1T_TOKEN" | |
| 201 | + | ``` | |
| 202 | + | ||
| 203 | + | [Connect a coding agent](/guides/bring-your-own-agent/) covers Cursor, | |
| 204 | + | OpenCode and other MCP clients. |
| 53 | 53 | ||
| 54 | 54 | | Category | Workspace | Personal | | |
| 55 | 55 | | --- | --- | --- | | |
| 56 | − | | Code & CI | [GitHub](/guides/github/) import, [webhooks](/guides/webhooks/) | [Signing in with GitHub](/guides/github/#link-and-unlink-github); [MCP clients](/guides/authentication/#signing-in-with-oauth): your [coding agent](/guides/bring-your-own-agent/), connected to g1t as you | | |
| 56 | + | | Code & CI | [GitHub](/guides/github/) import, [webhooks](/guides/webhooks/) | [Signing in with GitHub](/guides/github/#link-and-unlink-github); [MCP clients](/guides/authentication/#signing-in-with-oauth): your [coding agent](/guides/bring-your-own-agent/), connected to g1t as you; [Claude Code plugin](/guides/claude-code-plugin/) | | |
| 57 | 57 | | Issues & projects | [Jira and Linear](#trackers) | | | |
| 58 | 58 | | Monitoring & incidents | [Sentry, Datadog, and any system that sends a webhook](#alerts) | | | |
| 59 | 59 | | AI models | [Your AI providers](#your-ai-providers): Anthropic, OpenAI, Google Gemini, xAI, Mistral, DeepSeek, Azure OpenAI, OpenRouter, Groq, Together AI, Fireworks AI, Cerebras, and any Anthropic- or OpenAI-compatible endpoint | | |
| 33 | 33 | ||
| 34 | 34 | Your coding agent records its session in one of two ways. | |
| 35 | 35 | ||
| 36 | − | **With the hook installer**, for Claude Code. Every session is recorded | |
| 37 | − | without the agent having to remember: | |
| 36 | + | **With g1t's Claude Code plugin.** Every session is recorded without the | |
| 37 | + | agent having to remember: | |
| 38 | 38 | ||
| 39 | 39 | ```sh | |
| 40 | − | curl -fsSL https://g1t.sh/install/claude.sh | sh | |
| 40 | + | claude plugin marketplace add https://g1t.sh/flagon-io/g1t.git | |
| 41 | + | claude plugin install g1t@g1t | |
| 41 | 42 | ``` | |
| 42 | 43 | ||
| 43 | − | See [recording sessions automatically](/guides/bring-your-own-agent/#recording-sessions-automatically) | |
| 44 | − | for what it installs and how to remove it. | |
| 44 | + | See [Claude Code plugin](/guides/claude-code-plugin/) for what it records, | |
| 45 | + | what it never records and how to opt out. | |
| 45 | 46 | ||
| 46 | 47 | **With the `pull_request` tool's `record_session` action**, from any agent. It takes a list of entries, each | |
| 47 | 48 | with a `kind` from the table above and `text`, and `tool` for tool entries. |
| 1 | 1 | #!/bin/sh | |
| 2 | − | # Connects Claude Code on this machine to g1t, so the sessions of your own | |
| 3 | − | # agent are recorded onto the pull requests they belong to: | |
| 2 | + | # Connects Claude Code on this machine to g1t. g1t's Claude Code plugin | |
| 3 | + | # records your sessions on g1t, loads an issue's work context, and adds | |
| 4 | + | # g1t's MCP server and commands; this prints the two commands that install | |
| 5 | + | # it. With --cli it also installs the g1t CLI, which the plugin's hooks use: | |
| 4 | 6 | # | |
| 5 | 7 | # curl -fsSL https://g1t.sh/install/claude.sh | sh | |
| 8 | + | # curl -fsSL https://g1t.sh/install/claude.sh | sh -s -- --cli | |
| 6 | 9 | # | |
| 7 | − | # It downloads two small scripts into ~/.g1t, signs you in through the | |
| 8 | − | # browser, and adds a hook to ~/.claude/settings.json. Needs Node 18 or | |
| 9 | − | # later, which Claude Code itself runs on. | |
| 10 | + | # It changes nothing else. An earlier version of this script installed a | |
| 11 | + | # hook in ~/.g1t; if that is there, it is brought up to date, and you can | |
| 12 | + | # remove it once the plugin is installed (see below). | |
| 10 | 13 | set -eu | |
| 11 | 14 | ||
| 12 | 15 | BASE="${G1T_SITE:-https://g1t.sh}" | |
| 13 | 16 | ||
| 14 | − | if ! command -v node >/dev/null 2>&1; then | |
| 15 | − | echo "g1t: Node 18 or later is needed (Claude Code runs on it too)." >&2 | |
| 16 | − | exit 1 | |
| 17 | + | if [ "${1:-}" = "--cli" ]; then | |
| 18 | + | curl -fsSL "$BASE/install" | sh | |
| 17 | 19 | fi | |
| 18 | 20 | ||
| 19 | − | mkdir -p "$HOME/.g1t" | |
| 20 | − | curl -fsSL "$BASE/install/hook.mjs" -o "$HOME/.g1t/hook.mjs" | |
| 21 | − | curl -fsSL "$BASE/install/setup.mjs" -o "$HOME/.g1t/setup.mjs" | |
| 22 | − | # Read from the terminal, not from the pipe this script arrived on. | |
| 23 | − | node "$HOME/.g1t/setup.mjs" < /dev/tty | |
| 21 | + | if [ -f "$HOME/.g1t/hook.mjs" ]; then | |
| 22 | + | curl -fsSL "$BASE/install/hook.mjs" -o "$HOME/.g1t/hook.mjs" | |
| 23 | + | echo "Updated the earlier g1t hook in ~/.g1t/hook.mjs. The plugin replaces it:" | |
| 24 | + | echo "once the plugin is installed, remove the \`node \"$HOME/.g1t/hook.mjs\"\`" | |
| 25 | + | echo "entries from ~/.claude/settings.json, so a session is not recorded twice." | |
| 26 | + | echo | |
| 27 | + | fi | |
| 28 | + | ||
| 29 | + | cat <<EOF | |
| 30 | + | Install g1t's plugin for Claude Code: | |
| 31 | + | ||
| 32 | + | claude plugin marketplace add $BASE/flagon-io/g1t.git | |
| 33 | + | claude plugin install g1t@g1t | |
| 34 | + | ||
| 35 | + | The plugin's hooks use the g1t CLI. If you do not have it yet, install it | |
| 36 | + | (curl -fsSL $BASE/install | sh) and sign in with \`g1t auth login\`. | |
| 37 | + | Then, in Claude Code, run /mcp and choose g1t to sign its tools in. | |
| 38 | + | ||
| 39 | + | Guide: https://docs.g1t.sh/guides/claude-code-plugin/ | |
| 40 | + | EOF |
| 8 | 8 | // of a g1t repository with an open pull request. Anywhere else it does | |
| 9 | 9 | // nothing. It never fails the agent's turn. | |
| 10 | 10 | // | |
| 11 | − | // Installed by `curl -fsSL https://g1t.sh/install/claude.sh | sh`. | |
| 11 | + | // It records what each tool was called with, never what it returned. | |
| 12 | + | // | |
| 13 | + | // Installed by an earlier `curl -fsSL https://g1t.sh/install/claude.sh | sh`. | |
| 14 | + | // g1t's Claude Code plugin replaces it: | |
| 15 | + | // https://docs.g1t.sh/guides/claude-code-plugin/ | |
| 12 | 16 | ||
| 13 | 17 | import { execFileSync } from "node:child_process"; | |
| 14 | 18 | import { existsSync, readFileSync, writeFileSync } from "node:fs"; | |
| ⋯ | |||
| 51 | 55 | return clip(input); | |
| 52 | 56 | } | |
| 53 | 57 | ||
| 54 | − | /** The pull request this working copy belongs to, if any. Cached per copy. */ | |
| 58 | + | /** | |
| 59 | + | * The pull request this working copy belongs to, if any. Only a pull | |
| 60 | + | * request found is cached: a branch whose pull request is opened later in | |
| 61 | + | * the session is looked up again, and recorded from then on. | |
| 62 | + | */ | |
| 55 | 63 | async function pullFor(cwd, config) { | |
| 56 | 64 | const remote = git(cwd, "remote", "get-url", "origin"); | |
| 57 | 65 | const branch = git(cwd, "branch", "--show-current"); | |
| 58 | 66 | if (!remote.includes("g1t.sh/")) return null; | |
| 59 | 67 | const key = `${remote}#${branch}`; | |
| 60 | 68 | const cache = read(CACHE, {}); | |
| 61 | − | if (key in cache) return cache[key]; | |
| 69 | + | if (cache[key]) return cache[key]; | |
| 62 | 70 | const headers = { authorization: `Bearer ${config.token}` }; | |
| 63 | 71 | let found = null; | |
| 64 | 72 | const fork = /g1t\.sh\/pulls\/([a-z0-9_]+?)(?:\.git)?$/.exec(remote); | |
| ⋯ | |||
| 77 | 85 | if (pull) found = { repo: `${repo[1]}/${repo[2]}`, number: pull.number }; | |
| 78 | 86 | } | |
| 79 | 87 | } | |
| 80 | − | cache[key] = found; | |
| 81 | − | try { | |
| 82 | − | writeFileSync(CACHE, JSON.stringify(cache)); | |
| 83 | − | } catch {} | |
| 88 | + | if (found) { | |
| 89 | + | cache[key] = found; | |
| 90 | + | try { | |
| 91 | + | writeFileSync(CACHE, JSON.stringify(cache)); | |
| 92 | + | } catch {} | |
| 93 | + | } | |
| 84 | 94 | return found; | |
| 85 | 95 | } | |
| 86 | 96 | ||
| ⋯ | |||
| 116 | 126 | const entries = []; | |
| 117 | 127 | switch (event.hook_event_name) { | |
| 118 | 128 | case "UserPromptSubmit": | |
| 119 | − | if (event.prompt) entries.push({ kind: "prompt", text: clip(event.prompt) }); | |
| 129 | + | if (event.prompt && process.env.G1T_RECORD_PROMPTS !== "0") entries.push({ kind: "prompt", text: clip(event.prompt) }); | |
| 120 | 130 | break; | |
| 121 | 131 | case "PostToolUse": | |
| 122 | 132 | entries.push({ kind: "tool_call", tool: event.tool_name, text: clip(describeCall(event.tool_name, event.tool_input)) }); | |
| 123 | − | if (event.tool_response != null) { | |
| 124 | − | entries.push({ kind: "tool_result", tool: "result", text: clip(event.tool_response) }); | |
| 125 | − | } | |
| 126 | 133 | break; | |
| 127 | 134 | case "Stop": { | |
| 128 | 135 | const message = lastMessage(event.transcript_path); | |
| 124 | 124 | Or let git ask: the username is the g1t username and the password is the | |
| 125 | 125 | token. | |
| 126 | 126 | ||
| 127 | − | 8. **Record Claude Code sessions automatically** (optional). This installs | |
| 128 | − | hooks that record prompts, tool calls and replies onto the g1t pull | |
| 129 | − | request for the branch being worked on. The person runs it, because it | |
| 130 | − | signs them in through their browser: | |
| 127 | + | 8. **Record Claude Code sessions automatically** (optional). g1t's Claude | |
| 128 | + | Code plugin records each session on g1t (prompts, up to 2,000 | |
| 129 | + | characters; tool names and what they were called with, never what they | |
| 130 | + | returned; pushes), gives Claude the issue's work context when a session | |
| 131 | + | starts, and adds g1t's MCP server and the `/g1t:claim`, `/g1t:status` | |
| 132 | + | and `/g1t:handoff` commands. Its hooks use the g1t CLI | |
| 133 | + | (`curl -fsSL https://g1t.sh/install | sh`, then `g1t auth login`). The | |
| 134 | + | person installs it: | |
| 131 | 135 | ||
| 132 | 136 | ```sh | |
| 133 | − | curl -fsSL https://g1t.sh/install/claude.sh | sh | |
| 137 | + | claude plugin marketplace add https://g1t.sh/flagon-io/g1t.git | |
| 138 | + | claude plugin install g1t@g1t | |
| 134 | 139 | ``` | |
| 135 | 140 | ||
| 141 | + | `G1T_RECORD_PROMPTS=0` keeps prompts back; `G1T_RECORD=0` records | |
| 142 | + | nothing. Guide: https://docs.g1t.sh/guides/claude-code-plugin/ | |
| 143 | + | ||
| 144 | + | Other agents with a shell record the same way with the CLI: | |
| 145 | + | `g1t session start --harness codex` when they start, | |
| 146 | + | `g1t work context N` and `g1t work claim N` before working on issue N, | |
| 147 | + | `g1t session log --kind note TEXT` for decisions, `g1t session heartbeat` | |
| 148 | + | while working, `g1t work handoff N --note TEXT` if they stop early, and | |
| 149 | + | `g1t session end` at the end. | |
| 150 | + | ||
| 136 | 151 | ## Do work | |
| 137 | 152 | ||
| 138 | 153 | Issues and pull requests are addressed by repository and number, and share | |
| ⋯ | |||
| 292 | 307 | `notifications:write`). For CI, the CI preset (`repo:read`, `code:read`, | |
| 293 | 308 | `code:write`, `packages:read`, `packages:write`, `workflows:read`, | |
| 294 | 309 | `workflows:write`, `checks:read`, `checks:write`, `deployments:read`, | |
| 295 | − | `deployments:write`). A token or application given `agents:run`, | |
| 296 | − | `models:read` or `models:write` before keeps working for its other scopes; | |
| 297 | − | those three grant nothing. | |
| 310 | + | `deployments:write`). | |
| 298 | 311 | `chat:read` and `chat:write` are in no preset either: with them a person's | |
| 299 | 312 | token, OAuth or personal, uses Chat's JSON routes (`/{workspace}/-/chat/api`) | |
| 300 | 313 | and live sockets on the website without "Use the website as you", and | |