agit-ai 0.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. agit_ai-0.0.1/LICENSE +201 -0
  2. agit_ai-0.0.1/PKG-INFO +361 -0
  3. agit_ai-0.0.1/README.md +345 -0
  4. agit_ai-0.0.1/agit/__init__.py +5 -0
  5. agit_ai-0.0.1/agit/__main__.py +7 -0
  6. agit_ai-0.0.1/agit/backends/__init__.py +1 -0
  7. agit_ai-0.0.1/agit/backends/base.py +65 -0
  8. agit_ai-0.0.1/agit/backends/claude.py +121 -0
  9. agit_ai-0.0.1/agit/backends/opencode.py +224 -0
  10. agit_ai-0.0.1/agit/backends/proxy_agents.py +166 -0
  11. agit_ai-0.0.1/agit/backends/setup.py +121 -0
  12. agit_ai-0.0.1/agit/cli.py +345 -0
  13. agit_ai-0.0.1/agit/commits/__init__.py +22 -0
  14. agit_ai-0.0.1/agit/commits/actions.py +121 -0
  15. agit_ai-0.0.1/agit/commits/message.py +406 -0
  16. agit_ai-0.0.1/agit/config/__init__.py +7 -0
  17. agit_ai-0.0.1/agit/config/settings.py +172 -0
  18. agit_ai-0.0.1/agit/config/state.py +376 -0
  19. agit_ai-0.0.1/agit/git/__init__.py +25 -0
  20. agit_ai-0.0.1/agit/git/lock.py +101 -0
  21. agit_ai-0.0.1/agit/git/repo.py +315 -0
  22. agit_ai-0.0.1/agit/git/worktree.py +101 -0
  23. agit_ai-0.0.1/agit/metrics/__init__.py +18 -0
  24. agit_ai-0.0.1/agit/metrics/collect.py +771 -0
  25. agit_ai-0.0.1/agit/metrics/github.py +112 -0
  26. agit_ai-0.0.1/agit/metrics/render.py +114 -0
  27. agit_ai-0.0.1/agit/metrics/server.py +139 -0
  28. agit_ai-0.0.1/agit/metrics/web.py +845 -0
  29. agit_ai-0.0.1/agit/proxy/__init__.py +42 -0
  30. agit_ai-0.0.1/agit/proxy/commit_engine.py +665 -0
  31. agit_ai-0.0.1/agit/proxy/integration.py +630 -0
  32. agit_ai-0.0.1/agit/proxy/modal.py +173 -0
  33. agit_ai-0.0.1/agit/proxy/process.py +219 -0
  34. agit_ai-0.0.1/agit/proxy/renderer.py +683 -0
  35. agit_ai-0.0.1/agit/proxy/runner.py +4831 -0
  36. agit_ai-0.0.1/agit/proxy/sandbox.py +73 -0
  37. agit_ai-0.0.1/agit/proxy/session.py +202 -0
  38. agit_ai-0.0.1/agit/proxy/terminal.py +195 -0
  39. agit_ai-0.0.1/agit/shell/__init__.py +5 -0
  40. agit_ai-0.0.1/agit/shell/runner.py +358 -0
  41. agit_ai-0.0.1/agit/shell/ui.py +114 -0
  42. agit_ai-0.0.1/agit/summaries/__init__.py +8 -0
  43. agit_ai-0.0.1/agit/summaries/model_select.py +73 -0
  44. agit_ai-0.0.1/agit/summaries/prompts.py +44 -0
  45. agit_ai-0.0.1/agit/summaries/summarizer.py +181 -0
  46. agit_ai-0.0.1/agit/transcripts/__init__.py +12 -0
  47. agit_ai-0.0.1/agit/transcripts/claude.py +479 -0
  48. agit_ai-0.0.1/agit/transcripts/opencode.py +444 -0
  49. agit_ai-0.0.1/agit/transcripts/types.py +57 -0
  50. agit_ai-0.0.1/agit/update/__init__.py +21 -0
  51. agit_ai-0.0.1/agit/update/updater.py +328 -0
  52. agit_ai-0.0.1/agit_ai.egg-info/PKG-INFO +361 -0
  53. agit_ai-0.0.1/agit_ai.egg-info/SOURCES.txt +88 -0
  54. agit_ai-0.0.1/agit_ai.egg-info/dependency_links.txt +1 -0
  55. agit_ai-0.0.1/agit_ai.egg-info/entry_points.txt +2 -0
  56. agit_ai-0.0.1/agit_ai.egg-info/requires.txt +3 -0
  57. agit_ai-0.0.1/agit_ai.egg-info/top_level.txt +1 -0
  58. agit_ai-0.0.1/pyproject.toml +63 -0
  59. agit_ai-0.0.1/setup.cfg +4 -0
  60. agit_ai-0.0.1/tests/test_backend_commits.py +299 -0
  61. agit_ai-0.0.1/tests/test_backend_process.py +200 -0
  62. agit_ai-0.0.1/tests/test_backend_setup.py +96 -0
  63. agit_ai-0.0.1/tests/test_backends_and_config.py +245 -0
  64. agit_ai-0.0.1/tests/test_claude_session.py +480 -0
  65. agit_ai-0.0.1/tests/test_cli.py +498 -0
  66. agit_ai-0.0.1/tests/test_commit_engine.py +711 -0
  67. agit_ai-0.0.1/tests/test_commit_message.py +406 -0
  68. agit_ai-0.0.1/tests/test_commit_message_summary.py +120 -0
  69. agit_ai-0.0.1/tests/test_dashboard.py +689 -0
  70. agit_ai-0.0.1/tests/test_demo_script.py +45 -0
  71. agit_ai-0.0.1/tests/test_git_notes.py +60 -0
  72. agit_ai-0.0.1/tests/test_integration_service.py +837 -0
  73. agit_ai-0.0.1/tests/test_lock.py +137 -0
  74. agit_ai-0.0.1/tests/test_opencode_commands.py +21 -0
  75. agit_ai-0.0.1/tests/test_opencode_parse.py +55 -0
  76. agit_ai-0.0.1/tests/test_opencode_session.py +324 -0
  77. agit_ai-0.0.1/tests/test_pre_compaction.py +158 -0
  78. agit_ai-0.0.1/tests/test_proxy.py +4627 -0
  79. agit_ai-0.0.1/tests/test_proxy_modal.py +437 -0
  80. agit_ai-0.0.1/tests/test_proxy_session.py +112 -0
  81. agit_ai-0.0.1/tests/test_sandbox.py +83 -0
  82. agit_ai-0.0.1/tests/test_shell.py +154 -0
  83. agit_ai-0.0.1/tests/test_state.py +201 -0
  84. agit_ai-0.0.1/tests/test_summarizer.py +282 -0
  85. agit_ai-0.0.1/tests/test_summarizer_config.py +48 -0
  86. agit_ai-0.0.1/tests/test_summary_async.py +381 -0
  87. agit_ai-0.0.1/tests/test_summary_scratch.py +53 -0
  88. agit_ai-0.0.1/tests/test_ui.py +25 -0
  89. agit_ai-0.0.1/tests/test_update.py +359 -0
  90. agit_ai-0.0.1/tests/test_worktree.py +1057 -0
agit_ai-0.0.1/LICENSE ADDED
@@ -0,0 +1,201 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright [yyyy] [name of copyright owner]
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
agit_ai-0.0.1/PKG-INFO ADDED
@@ -0,0 +1,361 @@
1
+ Metadata-Version: 2.4
2
+ Name: agit-ai
3
+ Version: 0.0.1
4
+ Summary: Interactive agent + git commit orchestration. Requires git and a backend CLI (Claude Code or OpenCode); the GitHub CLI (gh) is optional, used for the dashboard's GitHub-ID committer view.
5
+ Author: aGiT contributors
6
+ License: Apache-2.0
7
+ Project-URL: Homepage, https://github.com/core-aix/agit
8
+ Project-URL: Repository, https://github.com/core-aix/agit
9
+ Requires-Python: >=3.10
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+ Requires-Dist: prompt_toolkit>=3.0.52
13
+ Requires-Dist: pyte>=0.8.2
14
+ Requires-Dist: watchdog>=6.0
15
+ Dynamic: license-file
16
+
17
+ # aGiT
18
+
19
+ aGiT stands for agent + git. It is an interactive Python CLI that wraps coding-agent command line tools and Git so agentic code changes are committed with traceable metadata.
20
+
21
+ aGiT supports OpenCode and Claude (Claude Code) as interchangeable backends. Every aGiT feature works the same regardless of the selected backend.
22
+
23
+ ## Dashboard
24
+
25
+ `agit --dashboard` (or `-d`) opens a **live, auto-refreshing web dashboard** of your repository — who and what wrote the code — served on `localhost` and opened in your browser. Every number is computed from commit metadata alone, so it's identical on every clone; nothing is sent anywhere.
26
+
27
+ ```bash
28
+ agit --dashboard # serve on localhost and open the browser (Ctrl-C to stop)
29
+ agit -d text # one-shot plain-text report instead (pipe it, paste it into an issue)
30
+ ```
31
+
32
+ ![The aGiT dashboard](docs/images/dashboard.png)
33
+
34
+ - **aGiT-tracked AI vs non-tracked lines** — what the agents wrote (tracked by aGiT) versus everything else; it never claims a human wrote what the model did.
35
+ - **Filter live** — narrow the whole dashboard to one committer (merged to their GitHub ID), a backend, a model, or a time range.
36
+ - **Tokens, efficiency, and loop detection**, plus a commit log you can click to read the full message and jump to the commit on GitHub.
37
+
38
+ See [Repository dashboard](#repository-dashboard) below for the full breakdown.
39
+
40
+ ## Requirements
41
+
42
+ aGiT needs **git** and at least one backend CLI — [Claude Code](https://docs.claude.com/en/docs/claude-code) or [OpenCode](https://opencode.ai) — on your `PATH`. The dashboard's committer view additionally uses the **GitHub CLI (`gh`)** to resolve commit authors to their GitHub logins: install it from [cli.github.com](https://cli.github.com) and run `gh auth login`. `gh` is optional — without it the dashboard still works and falls back to merging committer identities by email and no-reply login.
43
+
44
+ ## Install
45
+
46
+ ```bash
47
+ pip install agit-ai
48
+ ```
49
+
50
+ This installs the `agit` command and the terminal UI dependency used for status bars and contextual command hints. (The PyPI distribution is named `agit-ai` because the `agit` name is taken by an unrelated project; the command you run and the importable package are both still `agit`.) Once installed, aGiT keeps itself up to date — see [Self-update](#self-update).
51
+
52
+ For local development, install from a checkout instead:
53
+
54
+ ```bash
55
+ python3 -m pip install -e .
56
+ ```
57
+
58
+ ### Contributing
59
+
60
+ Install dependencies and the optional git hooks:
61
+
62
+ ```bash
63
+ uv sync --group dev
64
+ make install-hooks
65
+ ```
66
+
67
+ This installs two hooks:
68
+
69
+ - **commit** — `ruff` (lint + format) and basic file hygiene, so commits stay fast.
70
+ - **push** — the full CI-equivalent gate (`ruff`, `mypy` vs the baseline, tests + coverage), so a push that would break CI fails locally first.
71
+
72
+ Run the same full gate by hand at any time:
73
+
74
+ ```bash
75
+ make check # or: ./scripts/check.sh
76
+ ```
77
+
78
+ This is the definition of "done" for a change — it mirrors CI exactly (`.github/workflows/ci.yml`).
79
+
80
+ ## Usage
81
+
82
+ Run in the current repository:
83
+
84
+ ```bash
85
+ agit
86
+ ```
87
+
88
+ By default, `agit` runs in proxy mode: it launches the real backend TUI (OpenCode or Claude) in a pseudo-terminal, renders it through an internal terminal screen, and reserves a bottom status line for aGiT showing the session (and the base branch it merges into), the backend, the summarizer state, and the repository the agent is working on (the base repository path, home-abbreviated and elided from the left when space is tight). Press `Ctrl-G` to enter aGiT command mode (configurable via `menu_key` in `~/.agit/config.json` — see Configuration).
89
+
90
+ Run against another repository:
91
+
92
+ ```bash
93
+ agit --repo /path/to/repo
94
+ ```
95
+
96
+ Choose the backend (also saved as the global default for future runs):
97
+
98
+ ```bash
99
+ agit --backend claude
100
+ agit --backend opencode
101
+ ```
102
+
103
+ By default aGiT resumes the previous conversation for the repository. Start a fresh one instead with:
104
+
105
+ ```bash
106
+ agit --new-session
107
+ ```
108
+
109
+ Run without a worktree (the agent edits the current branch directly, so changes are visible live as it works):
110
+
111
+ ```bash
112
+ agit --no-worktree
113
+ ```
114
+
115
+ This is for single-session use: there's no isolation or auto-integration, and concurrent sessions are unsafe in this mode (starting a new session is blocked). Set `"use_worktrees": false` in `~/.agit/config.json` to make it the default; `--no-worktree` always wins.
116
+
117
+ ### Forwarding arguments to the backend
118
+
119
+ aGiT does not reduce the backend's own functionality: any argument it doesn't recognize is forwarded verbatim to the backend CLI (`claude` / `opencode`).
120
+
121
+ ```bash
122
+ agit --backend opencode --port 12345 # --port 12345 goes to opencode
123
+ ```
124
+
125
+ Use `--` to forward an argument that aGiT also defines (e.g. `--verbose`), or to pass a bare prompt:
126
+
127
+ ```bash
128
+ agit -- --verbose "fix the bug" # everything after -- goes to the backend
129
+ ```
130
+
131
+ aGiT's own flags (`--repo`, `--verbose`, `--mode`, `--backend`, `--new-session`, `--no-worktree`) bind to aGiT when they appear before `--`. Note that aGiT manages session selection itself, so forwarding session flags (`--resume`, `--session-id`, `--session`, `--continue`) may interfere with its session tracking — it warns when you do.
132
+
133
+ Help follows the same model: `agit --help` (or `-h`) prints aGiT's own options followed by the active backend's help, so one command documents both layers. To run only the backend's help, forward it explicitly: `agit -- --help`.
134
+
135
+ On the first run, aGiT asks which backend should be the default (listed alphabetically, with each backend's install status). If the chosen backend's CLI is not installed, aGiT shows install instructions and lets you install it or pick a different one. The choice is saved in `~/.agit/config.json` (`default_backend`) and reused for future runs. You can also switch backends mid-session with the `agent-backend` command below.
136
+
137
+ In proxy mode (default), press `Ctrl-G`, then type one of these aGiT commands:
138
+
139
+ ```text
140
+ session switch / start (own worktree) / stop a live session
141
+ agent-backend switch backend (opencode|claude); shows a picker
142
+ summarizer toggle summarization on/off, set model, show status
143
+ git-base-branch switch the branch sessions integrate into
144
+ git-status show git status
145
+ git-stage review and stage untracked files
146
+ git-unstaged show intentionally unstaged files
147
+ git-user-commit create a user commit
148
+ update check for / install an aGiT self-update
149
+ exit exit (with confirmation)
150
+ ```
151
+
152
+ aGiT tracks one session per repository and stays pinned to the session it launched (so it does not drift to other sessions you open). Use the `session` command (`Ctrl-G`, then `session`) to start a new session, switch the tracked session to another existing one, or sync tracking to the most recently active session — for example after starting a new conversation inside the backend's own TUI. This works the same for all backends.
153
+
154
+ Only `session` starts with `s`, so `Ctrl-G` then `s` + Enter jumps straight to the session picker. The session menu marks each session `running` or `idle`. Git-specific commands share a `git-` prefix.
155
+
156
+ ### Self-update
157
+
158
+ aGiT keeps itself current. On startup, and then about every five minutes while you work, it checks whether a newer aGiT is available:
159
+
160
+ - **Source-linked install** (the editable `pip install -e .` from a git checkout): it fetches the checkout's upstream branch and compares it with your current branch.
161
+ - **Package install** (a wheel from a package index): it compares the installed version with the latest published one.
162
+
163
+ If an update exists, aGiT prompts you at startup and shows a notice during a session (run the `update` command from the `Ctrl-G` menu to act on it). When you accept, aGiT waits until **every session has finished and all commits are integrated**, installs the update, then restarts itself automatically. It never interrupts a merge: while any session is resolving a merge/conflict, the notice is held back and an accepted update is deferred until the merge is done. Source updates are fast-forward-only and are skipped (with a message) if the checkout has uncommitted changes or has diverged from upstream, so an update never disturbs local development. Choose "Stop checking for updates" — or set `"check_for_updates": false` in `~/.agit/config.json` — to turn the checks off; tune the cadence with `timings.update_check_seconds`.
164
+
165
+
166
+ Proxy mode launches the backend's native TUI directly and recovers session metadata for automatic agent commits — via `opencode export` for OpenCode, or by reading the session transcript under `~/.claude/projects/` for Claude.
167
+
168
+
169
+ ## How It Works
170
+
171
+ ### Backends
172
+
173
+ aGiT drives an external coding agent rather than calling a model directly. OpenCode and Claude (Claude Code) are interchangeable backends, and every aGiT feature behaves the same regardless of which is selected. The per-repository backend is recorded in state; the user-wide default lives in `~/.agit/config.json`.
174
+
175
+ aGiT recovers what to commit from the backend's own session record: `opencode export` for OpenCode, and the session transcript under `~/.claude/projects/` for Claude. In JSON mode it instead invokes the backend non-interactively per prompt and captures the final response.
176
+
177
+ ### Session tracking
178
+
179
+ aGiT tracks exactly one backend session per repository and stays pinned to the session it launched, so it does not drift to other conversations you open in the backend. On startup it baselines the tracked session, so token metadata and the interaction trace only cover turns that happen after aGiT starts watching — resuming an old conversation does not re-commit its history.
180
+
181
+ Use the `session` command to start a new session, switch the tracked session to another existing one, or sync tracking to the most recently active session (for example after starting a fresh conversation inside the backend's own TUI). The session menu marks each session `running` or `idle`.
182
+
183
+ ### Worktrees and branches
184
+
185
+ To let sessions run without stepping on each other or on your working tree, each aGiT session runs in its own git worktree under `.agit/worktrees/<name>`, created *detached* at the base branch — a session has no branch of its own. Work within a session is committed on per-turn branches named `agit/<backend>/<name>/t<turn>`, created lazily on the first commit of each turn; once a turn is integrated its branch is deleted and the worktree is detached at the new base again. All aGiT-managed branches live under the `agit/` prefix so they are easy to recognize for cleanup and never collide with your own branches.
186
+
187
+ The base working tree (the branch you launched from) is only ever advanced by **integration**: aGiT merges a session's pending commits back into the base branch rather than committing onto it directly. A single-writer lock ensures only one aGiT process auto-commits or integrates at a time, so concurrent sessions stay consistent.
188
+
189
+ ### Integration and startup recovery
190
+
191
+ When a session's commits are merged into the base branch and the merge has conflicts, the agent backend resolves them, and the resolution is recorded as an `<aGiT-merge>` commit listing the base commits it was resolved against.
192
+
193
+ On startup, aGiT reconciles worktrees left behind by previous runs: it integrates any pending commits into the base branch and then deletes the worktree. Worktrees that cannot be integrated cleanly (a conflict, or uncommitted changes) are kept so no work is lost. The backend conversation itself persists (keyed by the worktree path) and stays resumable.
194
+
195
+ ### Commit message format
196
+
197
+ aGiT commit messages use a consistent Markdown-style structure. The first line is the subject (prefixed with `<aGiT>` for agent commits — including the cover commits placed on top of backend-made commits — `<aGiT-merge>` for agent-resolved merges, or left plain for user commits). When summarization is enabled the summary leads the message: its first line is the subject and the rest is the first paragraph of the body. The rest of the body is organized into `#` sections — `# Prompts` (when a summary takes the subject), `# Interaction Trace`, `# aGiT Metadata` — with `## User` / `## Agent` subsections inside the interaction trace. Commits are written with `git commit -F -` (no editor), so the `#` lines are preserved rather than stripped as git comments. Secrets and terminal escape sequences are masked out of subjects and trace bodies before committing.
198
+
199
+ Because the conversation is recorded in commit messages, aGiT shows a privacy warning at startup — never enter passwords, API keys, or other sensitive information in the chat — which must be acknowledged to continue (skipped when there is no terminal to acknowledge from).
200
+
201
+ ### Summarization
202
+
203
+ When summarization is enabled (the default), aGiT runs a second LLM stream alongside the coding session to preserve design context that would otherwise be lost to session compaction or terse commit subjects:
204
+
205
+ - **Commit summaries** — each agent commit gets an LLM-written summary of what changed and why. The summary leads the commit message: its first line becomes the subject and the rest follows as the first paragraph of the body (the prompts that used to head the message move to `# Prompts`); it is also stored as a git note in the `agit/commit-summary` namespace.
206
+ - **Session summaries** — a rolling narrative of the session (goals, architectural decisions, design evolution) is updated on every commit and attached as a git note in the `agit/session-summary` namespace.
207
+ - **Pre-compaction capture** — when you run `/compact` in the backend, aGiT first exports the full session transcript and folds it into the session summary, so compaction does not lose the conversation's context.
208
+
209
+ Because summaries are git notes, they travel with the repository and can be read independently of commit messages:
210
+
211
+ ```bash
212
+ git notes --ref agit/commit-summary show <commit>
213
+ git notes --ref agit/session-summary show <commit>
214
+ ```
215
+
216
+ Summarization never blocks the session: commits are created immediately with a prompt-based subject, the summary is computed on a background worker (the status line shows "aGiT is summarizing commit ..."), and the commit message is then amended in place. The amend only happens while it is safe — the commit is still the latest, unintegrated, and nothing new is staged; integration waits for the summary up to `summary_wait_seconds` and then proceeds, in which case the summary is recorded in git notes only. The metadata records the summarization cost next to the session's own usage (`summary_model`, `summary_tokens_input`, `summary_tokens_output`).
217
+
218
+ The status bar shows whether summarization is active (`sum:on` / `sum:off`). Use the `summarizer` command (`Ctrl-G`, then `summarizer`, or `:summarizer` in JSON mode) to toggle it (`summarizer on|off`), set the summarization model (`summarizer model`), or show the current status; changes persist to the repository-local `.agit/config.json` (see Configuration).
219
+
220
+ ## Commit Behavior
221
+
222
+ - Tracked modifications and deletions are staged with `git add -u`.
223
+ - New untracked files require confirmation before staging.
224
+ - Declined untracked files are remembered in repository-local `.agit/state.json`.
225
+ - Agent commits use the `<aGiT>` tag and include the full interaction trace since the last code-changing commit.
226
+ - Agent commit metadata includes context token count and generated token usage accumulated since the last code-changing commit.
227
+ - Token figures are read directly from the backend's session transcript (each assistant message's reported usage) and broken out by category: `input`, `output`, `cache_read`, `cache_write`, and (when the backend reports it) `reasoning`. For Claude, the recorded output count already includes extended-thinking and tool-call tokens. Sub-agent/sidechain turns are counted separately under the matching `subagent_*` categories rather than dropped. Each category is recorded only when the backend reports a non-zero value, so backends that omit a field (e.g. OpenCode does not expose sub-agent usage) simply have no line for it.
228
+ - The categories are **non-overlapping**: `output` counts only the main agent's generated tokens, and `subagent_output` counts only sub-agent generated tokens — neither includes the other, so nothing is double-counted. For a grand total of generated tokens, sum the matching pairs yourself (e.g. `output + subagent_output`, and `reasoning + subagent_reasoning` for OpenCode). The input side counts every token exactly once: `input` is all *fresh* input processed since the last commit — the uncached remainder plus the cache-creation tokens (so a first run's input reflects the full context instead of looking near zero next to the cache) — with `cache_write` kept as the "of which was written to the cache" breakdown. `cache_read` stays separate because those tokens were already counted as input when first processed; they are replayed from the cache and billed at a different rate.
229
+ - The figures should still be treated as a lower bound: any consumption the backend does not record in the transcript (e.g. internal compaction, retried requests, or usage a provider omits) is not captured, so actual tokens consumed may be higher than reported.
230
+ - Proxy mode baselines the continued backend session on startup so token metadata only includes turns after aGiT starts tracking new changes.
231
+ - Proxy mode preserves the backend's selected model in commit metadata when it can be read from session data.
232
+ - User commits use the user-provided subject and include aGiT metadata.
233
+ - Commits are created only when staged changes exist.
234
+ - If the backend commits on its own (e.g. the agent runs `git commit` itself, or a hook does), aGiT never rewrites those commits — their hashes stay exactly what the agent may already have reported in PR or issue comments. Instead, once the turn finishes, aGiT adds a *cover commit* on top carrying the interaction trace and metadata: a merge-shaped commit in the GitHub PR merge style, whose tree is the backend head's tree and whose parents are the turn's start and the backend's head, so `git log --first-parent` reads turn-by-turn while the backend's own commits remain reachable via the second parent. The `covered_commits` metadata line records the hashes of the backend-made commits the cover accounts for; when aGiT also has uncommitted changes to commit, its own (regular) commit carries that line instead.
235
+ ## Advanced Usage
236
+
237
+ Show aGiT diagnostic messages:
238
+
239
+ ```bash
240
+ agit --verbose
241
+ ```
242
+
243
+ Use the structured JSON fallback mode:
244
+
245
+ ```bash
246
+ agit --mode json
247
+ ```
248
+
249
+ JSON mode invokes the backend non-interactively for each prompt (`opencode run --format json` or `claude -p --output-format json`) so aGiT can capture the final response and create traceable commits.
250
+
251
+ In JSON mode, plain text is sent to the active agent backend:
252
+
253
+ ```text
254
+ > fix the parser bug
255
+ ```
256
+
257
+ JSON mode aGiT commands use `:` so backend-native `/` input is not intercepted:
258
+
259
+ ```text
260
+ :help show commands
261
+ :status show git status
262
+ :user-commit create a user commit
263
+ :stage review and stage untracked files
264
+ :unstaged show intentionally unstaged files
265
+ :agent-backend <backend> switch backend (opencode|claude)
266
+ :exit exit
267
+ ```
268
+
269
+ In JSON mode, aGiT shows a bottom status bar with the active backend, target repo, model, and unstaged-new-file count. Typing `:` shows aGiT command completions. Typing `/` shows common backend command completions, and slash commands are forwarded to the backend rather than handled by aGiT.
270
+
271
+ ### Scripted runs and the demo
272
+
273
+ `--prompt` runs JSON mode fully scripted: each prompt is sent to the backend in order (lines starting with `:` are aGiT commands), every turn that changes files becomes a commit, and aGiT exits when the prompts are done.
274
+
275
+ ```bash
276
+ agit --repo path/to/repo --backend claude \
277
+ --prompt "add input validation to parse()" \
278
+ --prompt ":status" \
279
+ --permission-mode acceptEdits
280
+ ```
281
+
282
+ Scripted runs never block on a question: the privacy warning is printed without waiting for acknowledgment, and new untracked files are staged automatically (with a notice) instead of being reviewed interactively. The same non-interactive defaults apply when prompts are piped to `agit --mode json` on stdin. Note that headless Claude needs permission to edit files — forward `--permission-mode acceptEdits` (or your preferred permission flags) through aGiT as shown above; OpenCode's `run` mode edits by default.
283
+
284
+ `scripts/demo.sh` is a self-contained showcase built on this: it creates a fresh repository in a temporary directory, has the agent write a small program and its tests through aGiT, and leaves the repository behind so you can inspect the `<aGiT>` commit history or continue interactively.
285
+
286
+ ```bash
287
+ scripts/demo.sh # drive the demo with claude
288
+ scripts/demo.sh --backend opencode # ... or with opencode
289
+ scripts/demo.sh --model haiku --dir /tmp/agit-demo
290
+ ```
291
+
292
+ ### Repository dashboard
293
+
294
+ `agit --dashboard` (or `-d`) opens a live web dashboard of repository metrics computed entirely from the aGiT metadata in commit messages — no extra state, so the numbers are identical on every clone. It is served on `localhost`, opens in your browser, and **auto-refreshes** (the page polls the server, which recomputes from `git log` on each request), so you can watch metrics update as an agent commits. Press Ctrl-C to stop.
295
+
296
+ - **Coverage**: how many commits are aGiT-tracked (agent commits, backend-made commits covered by an aGiT cover commit, agent-resolved merges, user commits, and aGiT's own integration merges) versus non-tracked.
297
+ - **Code changes**: lines added/removed split two ways — **aGiT-tracked AI** (agent commits + the backend-made commits an aGiT cover commit accounts for + agent-resolved merges) and **non-tracked** (everything else: user commits, plain commits with no aGiT metadata, and squash/PR-merge commits whose message concatenates several metadata blocks and so can't be cleanly attributed). There is deliberately no "human" category — even a user-made commit can contain lines an agent produced off the record, so the only honest claim is whether aGiT tracked the lines as AI. Cover commits are merges and contribute no line counts of their own, so a turn's lines are never double-counted.
298
+ - **aGiT-ops**: the integration merge commits aGiT makes itself (e.g. bringing base into a session branch) are shown as their own class, not lumped into non-tracked. They carry no diff, so they add no lines.
299
+ - **Squashed commits**: when several aGiT commits are squashed into one (a squash- or PR-merge concatenates their metadata blocks — git flattens this even across multiple rounds of squashing), the dashboard parses every original back out, so their tokens and per-model/backend usage are still counted instead of lost in the aggregate. In the web commit log such a commit is tagged `⧉ N squashed` and expands on click into its original commits, each itself expandable to its full message.
300
+ - **Tokens**: totals per category (input, output, reasoning, cache read/write, sub-agents, summarizer) and an efficiency ratio — AI-changed lines per 1k output tokens.
301
+ - **Breakdowns** by backend, by model (a cover commit's bucket includes the lines of the backend-made commits it covers), and by committer. Committer identities are merged to **GitHub IDs** via the `gh` CLI when available (every commit GitHub knows is keyed by its real login); without `gh` it falls back to merging by email and no-reply login. Each committer's lines are split into the aGiT-tracked AI they drove versus non-tracked.
302
+ - **Possible loops**: runs of three or more consecutive turns with near-identical prompts (or the same prompt repeated within one turn's trace), with the output tokens they consumed — a sign the conversation is going in circles.
303
+
304
+ The web page (styled like the [project page](https://github.com/core-aix/agit/tree/main/docs)) lets you **filter live** — narrow the whole dashboard to one committer or view the entire team, slice by backend or model, or restrict to a **time range** (presets or a custom from/to). The server recomputes the metrics for each filter, and the **commit log is paginated** (fetched a page at a time), so the browser never holds the whole history — memory stays bounded no matter how big the repo is. Each log line shows per-line token metrics; clicking a line opens the full commit message **rendered as Markdown** with a link to the commit on GitHub, and a squash expands into its original commits (each itself expandable). Agent commits also record when the AI-driven conversation started and ended (`agent_started_at` / `agent_ended_at` in the metadata block).
305
+
306
+ `agit --dashboard text` (or `-d text`) prints the same metrics as a one-shot plain-text report instead of serving — handy for piping or pasting into an issue.
307
+
308
+ The dashboard is read-only in either form: it never commits, never prompts, and skips the privacy acknowledgment.
309
+
310
+
311
+ ## Configuration
312
+
313
+ Repository-local configuration can be stored in `.agit/config.json`:
314
+
315
+ ```json
316
+ {
317
+ "trace_turn_limit": 5,
318
+ "summarization_enabled": true,
319
+ "summarization_model": null
320
+ }
321
+ ```
322
+
323
+ `trace_turn_limit` controls the maximum number of recent user turns included in an agent commit body. The default is `5`.
324
+
325
+ `summarization_enabled` (default `true`) toggles the LLM summarization stream (see Summarization above). `summarization_model` sets the model the summarizer asks the backend to use; leave it unset (`null`) to use the backend's default model. Both keys can also be set user-wide in `~/.agit/config.json`; the repository-local value wins, and the `summarizer` command writes its changes here.
326
+
327
+ User-wide settings live in `~/.agit/config.json` (override the directory with `AGIT_CONFIG_DIR`):
328
+
329
+ ```json
330
+ {
331
+ "default_backend": "opencode",
332
+ "menu_key": "ctrl-g",
333
+ "sandbox": true,
334
+ "use_worktrees": true,
335
+ "timings": {
336
+ "base_poll_seconds": 3.0
337
+ }
338
+ }
339
+ ```
340
+
341
+ `default_backend` (`opencode` or `claude`) is used for repositories that have no backend recorded yet. It is updated whenever you pass `--backend` or switch backends with `agent-backend`.
342
+
343
+ `sandbox` (default `true`) confines the agent's writes to its own session worktree (via `sandbox-exec` on macOS), keeping the base repository and sibling worktrees read-only to the agent. Set it to `false` to disable confinement; when sandboxing is unavailable, aGiT instead warns when the base repository is edited while a session runs.
344
+
345
+ `use_worktrees` (default `true`) controls whether sessions run in isolated worktrees. Set it to `false` to run the agent directly on the current branch by default — the same behavior as `--no-worktree` (which always wins over the config). See the `--no-worktree` notes under Usage for the trade-offs.
346
+
347
+ `menu_key` sets the key that opens aGiT's command menu in proxy mode. The default is `ctrl-g`; any `ctrl-<letter>` works except keys the terminal or aGiT already uses (`ctrl-c` exit flow, `ctrl-h` Backspace, `ctrl-i` Tab, `ctrl-j`/`ctrl-m` Enter). An invalid value falls back to `ctrl-g`, so a typo can never lock you out of the menu. The status line and aGiT's messages show whichever key is configured.
348
+
349
+ `timings` tunes aGiT's polling and debounce intervals (all in seconds). Specify only the keys you want to change; anything omitted — or set to a non-positive / non-numeric value — keeps its default:
350
+
351
+ | Key | Default | What it controls |
352
+ | --- | --- | --- |
353
+ | `base_poll_seconds` | `3.0` | How often the base branch is re-checked for commits made outside aGiT (so worktrees pick them up). |
354
+ | `background_poll_seconds` | `2.0` | How often an idle background session is serviced (committed / integrated). |
355
+ | `file_stable_seconds` | `8.0` | Quiet period after a file change before an auto-commit. |
356
+ | `child_idle_seconds` | `4.0` | No backend output for this long counts as idle. |
357
+ | `parse_cooldown_seconds` | `10.0` | Minimum gap between agent-turn parses. |
358
+ | `base_edit_check_seconds` | `3.0` | How often aGiT warns about edits to the base repo when the sandbox is unavailable. |
359
+ | `cwd_check_seconds` | `3.0` | How often aGiT checks for the Claude resume-cwd drift bug. |
360
+ | `base_drift_check_seconds` | `2.0` | How often aGiT checks whether the base repo was switched to another branch outside aGiT. |
361
+ | `summary_wait_seconds` | `45.0` | How long integration waits for a background commit summary before proceeding without it. |