messygit 0.2.0__tar.gz → 0.3.0__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.
- messygit-0.3.0/.github/workflows/publish.yml +27 -0
- messygit-0.3.0/.vscode/settings.json +1 -0
- messygit-0.3.0/ARCHITECTURE.md +64 -0
- messygit-0.3.0/PKG-INFO +214 -0
- messygit-0.3.0/README.md +203 -0
- {messygit-0.2.0 → messygit-0.3.0}/messygit/agent/agent.py +5 -2
- messygit-0.3.0/messygit/cli.py +709 -0
- {messygit-0.2.0/.claude/worktrees/frosty-montalcini-03d71b → messygit-0.3.0}/messygit/config.py +47 -8
- {messygit-0.2.0 → messygit-0.3.0}/messygit/git.py +60 -0
- {messygit-0.2.0 → messygit-0.3.0}/messygit/llm.py +5 -2
- messygit-0.3.0/messygit/models.py +43 -0
- messygit-0.3.0/messygit/usage.py +50 -0
- {messygit-0.2.0/.claude/worktrees/frosty-montalcini-03d71b → messygit-0.3.0}/pyproject.toml +3 -2
- messygit-0.2.0/.claude/worktrees/frosty-montalcini-03d71b/.claude/settings.local.json +0 -7
- messygit-0.2.0/.claude/worktrees/frosty-montalcini-03d71b/.git +0 -1
- messygit-0.2.0/.claude/worktrees/frosty-montalcini-03d71b/README.md +0 -105
- messygit-0.2.0/.claude/worktrees/frosty-montalcini-03d71b/messygit/cli.py +0 -112
- messygit-0.2.0/.claude/worktrees/frosty-montalcini-03d71b/messygit/git.py +0 -240
- messygit-0.2.0/.claude/worktrees/frosty-montalcini-03d71b/messygit/llm.py +0 -112
- messygit-0.2.0/.claude/worktrees/frosty-montalcini-03d71b/messygit/prompts.py +0 -70
- messygit-0.2.0/.gitignore +0 -5
- messygit-0.2.0/ARCHITECTURE.md +0 -48
- messygit-0.2.0/PKG-INFO +0 -115
- messygit-0.2.0/README.md +0 -105
- messygit-0.2.0/messygit/__init__.py +0 -0
- messygit-0.2.0/messygit/cli.py +0 -283
- messygit-0.2.0/messygit/config.py +0 -104
- messygit-0.2.0/pyproject.toml +0 -18
- {messygit-0.2.0/.claude/worktrees/frosty-montalcini-03d71b → messygit-0.3.0}/.gitignore +0 -0
- {messygit-0.2.0/.claude/worktrees/frosty-montalcini-03d71b → messygit-0.3.0}/messygit/__init__.py +0 -0
- {messygit-0.2.0 → messygit-0.3.0}/messygit/agent/tool.py +0 -0
- {messygit-0.2.0 → messygit-0.3.0}/messygit/agent/tools.py +0 -0
- {messygit-0.2.0 → messygit-0.3.0}/messygit/prompts.py +0 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
publish:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
permissions:
|
|
11
|
+
id-token: write
|
|
12
|
+
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
|
|
16
|
+
- uses: actions/setup-python@v5
|
|
17
|
+
with:
|
|
18
|
+
python-version: "3.13"
|
|
19
|
+
|
|
20
|
+
- name: Install build tools
|
|
21
|
+
run: pip install build
|
|
22
|
+
|
|
23
|
+
- name: Build package
|
|
24
|
+
run: python -m build
|
|
25
|
+
|
|
26
|
+
- name: Publish to PyPI
|
|
27
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
This document describes the purpose of each file in the `messygit` project.
|
|
4
|
+
|
|
5
|
+
## Root
|
|
6
|
+
|
|
7
|
+
| File | Purpose |
|
|
8
|
+
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
|
|
9
|
+
| `pyproject.toml` | Package metadata, dependencies (`anthropic`, `click`), build system (hatchling), and the `messygit` console script entrypoint. |
|
|
10
|
+
| `README.md` | User-facing documentation: install, usage, commands, and development instructions. |
|
|
11
|
+
| `.gitignore` | Keeps `.venv/`, `__pycache__/`, `dist/`, and `*.egg-info/` out of version control. |
|
|
12
|
+
| `.github/workflows/publish.yml` | GitHub Actions workflow for publishing the package. |
|
|
13
|
+
|
|
14
|
+
## `messygit/` (Python package)
|
|
15
|
+
|
|
16
|
+
| File | Purpose |
|
|
17
|
+
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
18
|
+
| `__init__.py` | Marks the directory as a Python package (empty). |
|
|
19
|
+
| `cli.py` | Interactive REPL entrypoint. Displays an ASCII banner, runs a prompt loop, and dispatches commands: `add`, `commit`, `push`, `config`, `show`, `suggest`, `help`, `quit`/`exit`. Orchestrates all other modules. Includes a threaded `Spinner` for loading animations. |
|
|
20
|
+
| `git.py` | All subprocess calls to `git`. Reads staged diffs (`git diff --cached -U0`), parses them into a compact changed-lines format, filters noise files, handles the large-diff fallback (stat summary + top-N most-changed files), and runs `git add`, `git commit`, and `git push`. |
|
|
21
|
+
| `llm.py` | Anthropic SDK integration. Creates the client with the resolved API key, calls `messages.create`, extracts the text response, and maps SDK exceptions (`AuthenticationError`, `PermissionDeniedError`, `BadRequestError`, billing 402) into user-friendly error classes. Also exposes helpers reused by `agent/agent.py`. |
|
|
22
|
+
| `config.py` | API key storage and resolution. Reads/writes `~/.messygit/config.json`, checks the `ANTHROPIC_API_KEY` env var, validates keys are non-empty, masks keys for display, and defines all user-facing error messages and exception classes. |
|
|
23
|
+
| `prompts.py` | System prompts and user prompt builder. Contains the Conventional Commits instructions (`COMMIT_SYSTEM_PROMPT`), the suggestion agent instructions (`SUGGESTION_SYSTEM_PROMPT`), and `build_user_prompt` which wraps staged changes into the user message sent to Claude. |
|
|
24
|
+
|
|
25
|
+
## `messygit/agent/` (agentic tool-use subpackage)
|
|
26
|
+
|
|
27
|
+
| File | Purpose |
|
|
28
|
+
| ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
29
|
+
| `tool.py` | `Tool` dataclass wrapping a Python callable with a name, description, and parameter schema. Provides `run()` to invoke the function and `to_schema()` to emit an Anthropic-compatible tool definition. |
|
|
30
|
+
| `tools.py` | Concrete tool instances available to agents: `run_git_tool` (allowlisted read-only git commands), `read_file_tool`, `list_directory_tool`, and `search_code_tool` (`git grep`). |
|
|
31
|
+
| `agent.py` | Generic agentic loop. Sends messages to Claude with tool definitions, processes `tool_use` response blocks by dispatching to matching `Tool` instances, appends results, and iterates up to `max_iterations`. Handles API errors identically to `llm.py`. |
|
|
32
|
+
|
|
33
|
+
## Data flow
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
User runs `messygit` → interactive REPL
|
|
37
|
+
│
|
|
38
|
+
├── "add <files>" ──► git.py (git add)
|
|
39
|
+
├── "push" ──► git.py (git push)
|
|
40
|
+
├── "config <key>" ──► config.py (save API key)
|
|
41
|
+
├── "show" ──► config.py (display masked key)
|
|
42
|
+
│
|
|
43
|
+
├── "commit" ──► git.py (read staged diff, apply token budget)
|
|
44
|
+
│ │
|
|
45
|
+
│ ▼
|
|
46
|
+
│ llm.py (send context to Claude)
|
|
47
|
+
│ │ │
|
|
48
|
+
│ │ ├── config.py (resolve API key)
|
|
49
|
+
│ │ └── prompts.py (COMMIT_SYSTEM_PROMPT + user prompt)
|
|
50
|
+
│ ▼
|
|
51
|
+
│ cli.py (display message, prompt Y/n/e)
|
|
52
|
+
│ │
|
|
53
|
+
│ ▼
|
|
54
|
+
│ git.py (git commit -m "...")
|
|
55
|
+
│
|
|
56
|
+
└── "suggest" ──► agent/agent.py (agentic loop)
|
|
57
|
+
│ │
|
|
58
|
+
│ ├── config.py (resolve API key)
|
|
59
|
+
│ ├── prompts.py (SUGGESTION_SYSTEM_PROMPT)
|
|
60
|
+
│ └── agent/tools.py (run_git, read_file, list_directory)
|
|
61
|
+
▼
|
|
62
|
+
cli.py (display suggestion)
|
|
63
|
+
```
|
|
64
|
+
|
messygit-0.3.0/PKG-INFO
ADDED
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: messygit
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: An AI-powered interactive git CLI with agentic tools for commits, code suggestions, and workflow automation.
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
Requires-Python: >=3.10
|
|
7
|
+
Requires-Dist: anthropic>=0.39.0
|
|
8
|
+
Requires-Dist: click>=8.0
|
|
9
|
+
Requires-Dist: rich>=13.0
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
|
|
12
|
+
# messygit
|
|
13
|
+
|
|
14
|
+
**messygit** is an interactive CLI that turns messy git workflows into clean Conventional Commits — stage, commit, push, and get AI-powered project suggestions, all from one interface powered by [Claude](https://www.anthropic.com/api).
|
|
15
|
+
|
|
16
|
+
## Why use it
|
|
17
|
+
|
|
18
|
+
- **Interactive REPL** — one command drops you into a persistent session where you can stage, commit, push, and more without leaving.
|
|
19
|
+
- **AI commit messages** — sends your staged diff to Claude and suggests a clean Conventional Commits subject line.
|
|
20
|
+
- **Project suggestions** — an AI agent inspects your repo and recommends concrete next steps.
|
|
21
|
+
- **Token usage & cost** — tracks the tokens each session uses and shows a rough cost estimate, with a one-command jump to billing.
|
|
22
|
+
- **Themed UI** — a colored startup animation and prompt you can recolor with the `theme` command.
|
|
23
|
+
- **Safe by default** — only the staged diff is sent to the model. Your API key is never printed in full.
|
|
24
|
+
|
|
25
|
+
## Requirements
|
|
26
|
+
|
|
27
|
+
- **Python** 3.10 or newer
|
|
28
|
+
- **Git** (run inside a repository)
|
|
29
|
+
- An **Anthropic API key** with access to the Messages API
|
|
30
|
+
|
|
31
|
+
## Installation
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pip install messygit
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Install from source
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
cd messygit
|
|
41
|
+
python -m venv .venv
|
|
42
|
+
source .venv/bin/activate # Windows: .venv\Scripts\activate
|
|
43
|
+
pip install -e .
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## API key
|
|
47
|
+
|
|
48
|
+
messygit resolves the key in this order:
|
|
49
|
+
|
|
50
|
+
1. Environment variable **`ANTHROPIC_API_KEY`**
|
|
51
|
+
2. Config file **`~/.messygit/config.json`**
|
|
52
|
+
|
|
53
|
+
You can set the key from within the messygit interface:
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
messygit > config YOUR_ANTHROPIC_API_KEY
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Usage
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
messygit
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
This drops you into the interactive interface — an animated banner followed by a
|
|
66
|
+
status dashboard, then the prompt:
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
mmm mmmm eeeeeee sssssss sssssss yy yy ggggggg ii tttttttt
|
|
70
|
+
mm mm mm mm ee ss ss yy yy gg ii tt
|
|
71
|
+
mm mmm mm eeeee sssssss sssssss yy gg ggg ii tt
|
|
72
|
+
mm mm ee ss ss yy gg gg ii tt
|
|
73
|
+
mm mm eeeeeee sssssss sssssss yy ggggg ii tt
|
|
74
|
+
|
|
75
|
+
repo messygit ⎇ main
|
|
76
|
+
status 3 staged · 2 modified
|
|
77
|
+
api key sk-ant-a...x3f2 (config)
|
|
78
|
+
model Haiku 4.5 $1 in · $5 out / 1M
|
|
79
|
+
tokens 0 used this session
|
|
80
|
+
────────────────────────────────────────────────────────────
|
|
81
|
+
Type help for commands · quit to exit
|
|
82
|
+
|
|
83
|
+
messygit (main) ❯
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Commands
|
|
87
|
+
|
|
88
|
+
Commands are grouped on the `help` screen:
|
|
89
|
+
|
|
90
|
+
**git**
|
|
91
|
+
|
|
92
|
+
| Command | Description |
|
|
93
|
+
|---------|-------------|
|
|
94
|
+
| `add <file>` or `add .` | Stage files for commit |
|
|
95
|
+
| `commit` | Generate an AI commit message from staged changes, then commit / cancel / edit |
|
|
96
|
+
| `push` | Push commits to remote |
|
|
97
|
+
|
|
98
|
+
**messyagent**
|
|
99
|
+
|
|
100
|
+
| Command | Description |
|
|
101
|
+
|---------|-------------|
|
|
102
|
+
| `suggest` | Get AI-powered next-step suggestions for your project |
|
|
103
|
+
|
|
104
|
+
**account**
|
|
105
|
+
|
|
106
|
+
| Command | Description |
|
|
107
|
+
|---------|-------------|
|
|
108
|
+
| `config <key>` | Save your Anthropic API key to `~/.messygit/config.json` |
|
|
109
|
+
| `show` | Display a masked API key and its source |
|
|
110
|
+
| `model` or `model <name>` | Switch the Claude model (run `model` to list models and pricing) |
|
|
111
|
+
| `tokens` | Show this session's token usage and estimated cost, and open the billing console |
|
|
112
|
+
|
|
113
|
+
**app**
|
|
114
|
+
|
|
115
|
+
| Command | Description |
|
|
116
|
+
|---------|-------------|
|
|
117
|
+
| `theme` or `theme <name>` | Change the UI color (run `theme` to list presets) |
|
|
118
|
+
| `help` | List available commands |
|
|
119
|
+
| `quit` / `exit` | Exit messygit |
|
|
120
|
+
|
|
121
|
+
### Typical flow
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
messygit > add .
|
|
125
|
+
Staged everything
|
|
126
|
+
|
|
127
|
+
messygit > commit
|
|
128
|
+
feat(cli): add interactive REPL with ASCII banner
|
|
129
|
+
Commit with this message? [y/n/e] y
|
|
130
|
+
|
|
131
|
+
messygit > push
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
> Tip: run `suggest` for AI next-step ideas, or `theme` to recolor the UI.
|
|
135
|
+
|
|
136
|
+
### Commit message style
|
|
137
|
+
|
|
138
|
+
The model follows **Conventional Commits**: `type(scope): description`
|
|
139
|
+
|
|
140
|
+
Allowed types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`. Subjects are one line, imperative, lowercase, no trailing period.
|
|
141
|
+
|
|
142
|
+
### Token usage & cost
|
|
143
|
+
|
|
144
|
+
messygit tracks the tokens used by AI commands (`commit`, `suggest`) for the current session and shows a running total after each call. Run `tokens` for a breakdown and a one-key jump to the Anthropic billing console:
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
messygit > tokens
|
|
148
|
+
╭─ token usage ─────────────────────────────╮
|
|
149
|
+
│ used 8,420 tokens │
|
|
150
|
+
│ 6,200 in · 2,220 out │
|
|
151
|
+
│ requests 2 │
|
|
152
|
+
│ est cost ≈ $0.02 │
|
|
153
|
+
╰───────────────────────────────────────────╯
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
The cost is a **rough estimate** at the selected model's [pricing](https://www.anthropic.com/pricing). The Anthropic API does not expose remaining account credits, so usage and cost are measured per session only.
|
|
157
|
+
|
|
158
|
+
### Choosing a model
|
|
159
|
+
|
|
160
|
+
messygit defaults to **Claude Haiku 4.5** (fast and cheap). Use `model` to list the available models and their token pricing, or `model <name>` to switch (your choice persists in `~/.messygit/config.json`):
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
messygit > model
|
|
164
|
+
Available models — usage: model <name>
|
|
165
|
+
● haiku Haiku 4.5 $1 in · $5 out / 1M (current)
|
|
166
|
+
sonnet Sonnet 4.6 $3 in · $15 out / 1M
|
|
167
|
+
opus Opus 4.8 $5 in · $25 out / 1M
|
|
168
|
+
|
|
169
|
+
messygit > model opus
|
|
170
|
+
! Opus 4.8 costs more than Haiku 4.5 ($5 in · $25 out / 1M vs $1 in · $5 out / 1M). Token usage will be billed at the higher rate.
|
|
171
|
+
Switch anyway? [y/N]:
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Switching to a **more expensive** model prompts for confirmation first. The session cost estimate prices each request at the model used for it, so it stays accurate even if you switch mid-session.
|
|
175
|
+
|
|
176
|
+
## Publishing to PyPI
|
|
177
|
+
|
|
178
|
+
This project uses GitHub Actions with [PyPI trusted publishing](https://docs.pypi.org/trusted-publishers/) — no API tokens needed in your repo.
|
|
179
|
+
|
|
180
|
+
### One-time setup
|
|
181
|
+
|
|
182
|
+
1. Go to your project on [pypi.org](https://pypi.org/manage/project/messygit/settings/publishing/)
|
|
183
|
+
2. Add a **Trusted Publisher**:
|
|
184
|
+
- **Owner:** your GitHub username
|
|
185
|
+
- **Repository:** `messygit`
|
|
186
|
+
- **Workflow name:** `publish.yml`
|
|
187
|
+
- **Environment:** leave blank
|
|
188
|
+
|
|
189
|
+
### To release a new version
|
|
190
|
+
|
|
191
|
+
1. Bump `version` in `pyproject.toml`
|
|
192
|
+
2. Commit and push
|
|
193
|
+
3. Create a GitHub release:
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
git tag v0.2.0
|
|
197
|
+
git push origin v0.2.0
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
4. Go to GitHub → Releases → Draft a new release → select the tag → Publish
|
|
201
|
+
|
|
202
|
+
The workflow at `.github/workflows/publish.yml` will automatically build and upload to PyPI.
|
|
203
|
+
|
|
204
|
+
### Manual publish (without CI)
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
rm -rf dist/
|
|
208
|
+
python -m build
|
|
209
|
+
twine upload dist/*
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## License
|
|
213
|
+
|
|
214
|
+
MIT (see `pyproject.toml`).
|
messygit-0.3.0/README.md
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
# messygit
|
|
2
|
+
|
|
3
|
+
**messygit** is an interactive CLI that turns messy git workflows into clean Conventional Commits — stage, commit, push, and get AI-powered project suggestions, all from one interface powered by [Claude](https://www.anthropic.com/api).
|
|
4
|
+
|
|
5
|
+
## Why use it
|
|
6
|
+
|
|
7
|
+
- **Interactive REPL** — one command drops you into a persistent session where you can stage, commit, push, and more without leaving.
|
|
8
|
+
- **AI commit messages** — sends your staged diff to Claude and suggests a clean Conventional Commits subject line.
|
|
9
|
+
- **Project suggestions** — an AI agent inspects your repo and recommends concrete next steps.
|
|
10
|
+
- **Token usage & cost** — tracks the tokens each session uses and shows a rough cost estimate, with a one-command jump to billing.
|
|
11
|
+
- **Themed UI** — a colored startup animation and prompt you can recolor with the `theme` command.
|
|
12
|
+
- **Safe by default** — only the staged diff is sent to the model. Your API key is never printed in full.
|
|
13
|
+
|
|
14
|
+
## Requirements
|
|
15
|
+
|
|
16
|
+
- **Python** 3.10 or newer
|
|
17
|
+
- **Git** (run inside a repository)
|
|
18
|
+
- An **Anthropic API key** with access to the Messages API
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install messygit
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Install from source
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
cd messygit
|
|
30
|
+
python -m venv .venv
|
|
31
|
+
source .venv/bin/activate # Windows: .venv\Scripts\activate
|
|
32
|
+
pip install -e .
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## API key
|
|
36
|
+
|
|
37
|
+
messygit resolves the key in this order:
|
|
38
|
+
|
|
39
|
+
1. Environment variable **`ANTHROPIC_API_KEY`**
|
|
40
|
+
2. Config file **`~/.messygit/config.json`**
|
|
41
|
+
|
|
42
|
+
You can set the key from within the messygit interface:
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
messygit > config YOUR_ANTHROPIC_API_KEY
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Usage
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
messygit
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
This drops you into the interactive interface — an animated banner followed by a
|
|
55
|
+
status dashboard, then the prompt:
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
mmm mmmm eeeeeee sssssss sssssss yy yy ggggggg ii tttttttt
|
|
59
|
+
mm mm mm mm ee ss ss yy yy gg ii tt
|
|
60
|
+
mm mmm mm eeeee sssssss sssssss yy gg ggg ii tt
|
|
61
|
+
mm mm ee ss ss yy gg gg ii tt
|
|
62
|
+
mm mm eeeeeee sssssss sssssss yy ggggg ii tt
|
|
63
|
+
|
|
64
|
+
repo messygit ⎇ main
|
|
65
|
+
status 3 staged · 2 modified
|
|
66
|
+
api key sk-ant-a...x3f2 (config)
|
|
67
|
+
model Haiku 4.5 $1 in · $5 out / 1M
|
|
68
|
+
tokens 0 used this session
|
|
69
|
+
────────────────────────────────────────────────────────────
|
|
70
|
+
Type help for commands · quit to exit
|
|
71
|
+
|
|
72
|
+
messygit (main) ❯
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Commands
|
|
76
|
+
|
|
77
|
+
Commands are grouped on the `help` screen:
|
|
78
|
+
|
|
79
|
+
**git**
|
|
80
|
+
|
|
81
|
+
| Command | Description |
|
|
82
|
+
|---------|-------------|
|
|
83
|
+
| `add <file>` or `add .` | Stage files for commit |
|
|
84
|
+
| `commit` | Generate an AI commit message from staged changes, then commit / cancel / edit |
|
|
85
|
+
| `push` | Push commits to remote |
|
|
86
|
+
|
|
87
|
+
**messyagent**
|
|
88
|
+
|
|
89
|
+
| Command | Description |
|
|
90
|
+
|---------|-------------|
|
|
91
|
+
| `suggest` | Get AI-powered next-step suggestions for your project |
|
|
92
|
+
|
|
93
|
+
**account**
|
|
94
|
+
|
|
95
|
+
| Command | Description |
|
|
96
|
+
|---------|-------------|
|
|
97
|
+
| `config <key>` | Save your Anthropic API key to `~/.messygit/config.json` |
|
|
98
|
+
| `show` | Display a masked API key and its source |
|
|
99
|
+
| `model` or `model <name>` | Switch the Claude model (run `model` to list models and pricing) |
|
|
100
|
+
| `tokens` | Show this session's token usage and estimated cost, and open the billing console |
|
|
101
|
+
|
|
102
|
+
**app**
|
|
103
|
+
|
|
104
|
+
| Command | Description |
|
|
105
|
+
|---------|-------------|
|
|
106
|
+
| `theme` or `theme <name>` | Change the UI color (run `theme` to list presets) |
|
|
107
|
+
| `help` | List available commands |
|
|
108
|
+
| `quit` / `exit` | Exit messygit |
|
|
109
|
+
|
|
110
|
+
### Typical flow
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
messygit > add .
|
|
114
|
+
Staged everything
|
|
115
|
+
|
|
116
|
+
messygit > commit
|
|
117
|
+
feat(cli): add interactive REPL with ASCII banner
|
|
118
|
+
Commit with this message? [y/n/e] y
|
|
119
|
+
|
|
120
|
+
messygit > push
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
> Tip: run `suggest` for AI next-step ideas, or `theme` to recolor the UI.
|
|
124
|
+
|
|
125
|
+
### Commit message style
|
|
126
|
+
|
|
127
|
+
The model follows **Conventional Commits**: `type(scope): description`
|
|
128
|
+
|
|
129
|
+
Allowed types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`. Subjects are one line, imperative, lowercase, no trailing period.
|
|
130
|
+
|
|
131
|
+
### Token usage & cost
|
|
132
|
+
|
|
133
|
+
messygit tracks the tokens used by AI commands (`commit`, `suggest`) for the current session and shows a running total after each call. Run `tokens` for a breakdown and a one-key jump to the Anthropic billing console:
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
messygit > tokens
|
|
137
|
+
╭─ token usage ─────────────────────────────╮
|
|
138
|
+
│ used 8,420 tokens │
|
|
139
|
+
│ 6,200 in · 2,220 out │
|
|
140
|
+
│ requests 2 │
|
|
141
|
+
│ est cost ≈ $0.02 │
|
|
142
|
+
╰───────────────────────────────────────────╯
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
The cost is a **rough estimate** at the selected model's [pricing](https://www.anthropic.com/pricing). The Anthropic API does not expose remaining account credits, so usage and cost are measured per session only.
|
|
146
|
+
|
|
147
|
+
### Choosing a model
|
|
148
|
+
|
|
149
|
+
messygit defaults to **Claude Haiku 4.5** (fast and cheap). Use `model` to list the available models and their token pricing, or `model <name>` to switch (your choice persists in `~/.messygit/config.json`):
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
messygit > model
|
|
153
|
+
Available models — usage: model <name>
|
|
154
|
+
● haiku Haiku 4.5 $1 in · $5 out / 1M (current)
|
|
155
|
+
sonnet Sonnet 4.6 $3 in · $15 out / 1M
|
|
156
|
+
opus Opus 4.8 $5 in · $25 out / 1M
|
|
157
|
+
|
|
158
|
+
messygit > model opus
|
|
159
|
+
! Opus 4.8 costs more than Haiku 4.5 ($5 in · $25 out / 1M vs $1 in · $5 out / 1M). Token usage will be billed at the higher rate.
|
|
160
|
+
Switch anyway? [y/N]:
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Switching to a **more expensive** model prompts for confirmation first. The session cost estimate prices each request at the model used for it, so it stays accurate even if you switch mid-session.
|
|
164
|
+
|
|
165
|
+
## Publishing to PyPI
|
|
166
|
+
|
|
167
|
+
This project uses GitHub Actions with [PyPI trusted publishing](https://docs.pypi.org/trusted-publishers/) — no API tokens needed in your repo.
|
|
168
|
+
|
|
169
|
+
### One-time setup
|
|
170
|
+
|
|
171
|
+
1. Go to your project on [pypi.org](https://pypi.org/manage/project/messygit/settings/publishing/)
|
|
172
|
+
2. Add a **Trusted Publisher**:
|
|
173
|
+
- **Owner:** your GitHub username
|
|
174
|
+
- **Repository:** `messygit`
|
|
175
|
+
- **Workflow name:** `publish.yml`
|
|
176
|
+
- **Environment:** leave blank
|
|
177
|
+
|
|
178
|
+
### To release a new version
|
|
179
|
+
|
|
180
|
+
1. Bump `version` in `pyproject.toml`
|
|
181
|
+
2. Commit and push
|
|
182
|
+
3. Create a GitHub release:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
git tag v0.2.0
|
|
186
|
+
git push origin v0.2.0
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
4. Go to GitHub → Releases → Draft a new release → select the tag → Publish
|
|
190
|
+
|
|
191
|
+
The workflow at `.github/workflows/publish.yml` will automatically build and upload to PyPI.
|
|
192
|
+
|
|
193
|
+
### Manual publish (without CI)
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
rm -rf dist/
|
|
197
|
+
python -m build
|
|
198
|
+
twine upload dist/*
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## License
|
|
202
|
+
|
|
203
|
+
MIT (see `pyproject.toml`).
|
|
@@ -15,8 +15,9 @@ from ..config import (
|
|
|
15
15
|
resolve_api_key,
|
|
16
16
|
)
|
|
17
17
|
from ..llm import _is_insufficient_balance_or_billing, _insufficient_balance_user_message, _text_from_message
|
|
18
|
+
from ..models import current_model
|
|
19
|
+
from ..usage import SESSION_USAGE
|
|
18
20
|
|
|
19
|
-
DEFAULT_MODEL = "claude-haiku-4-5-20251001"
|
|
20
21
|
DEFAULT_MAX_TOKENS = 4096
|
|
21
22
|
|
|
22
23
|
class Agent:
|
|
@@ -29,19 +30,21 @@ class Agent:
|
|
|
29
30
|
def run(self, user_input: str) -> str:
|
|
30
31
|
"""Run the agent."""
|
|
31
32
|
client = Anthropic(api_key=resolve_api_key())
|
|
33
|
+
model = current_model()
|
|
32
34
|
messages = []
|
|
33
35
|
try:
|
|
34
36
|
messages.append({"role": "user", "content": user_input})
|
|
35
37
|
response = None
|
|
36
38
|
for i in range(self.max_iterations):
|
|
37
39
|
response = client.messages.create(
|
|
38
|
-
model=
|
|
40
|
+
model=model.id,
|
|
39
41
|
max_tokens=DEFAULT_MAX_TOKENS,
|
|
40
42
|
tools=[t.to_schema() for t in self.tools],
|
|
41
43
|
tool_choice={"type": "auto"},
|
|
42
44
|
system=self.system_prompt,
|
|
43
45
|
messages=messages,
|
|
44
46
|
)
|
|
47
|
+
SESSION_USAGE.record(response.usage, model)
|
|
45
48
|
messages.append({"role": "assistant", "content": response.content})
|
|
46
49
|
|
|
47
50
|
tool_use_blocks = [b for b in response.content if b.type == "tool_use"]
|