messygit 0.3.2__tar.gz → 0.4.5__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.4.5/ARCHITECTURE.md +93 -0
- messygit-0.4.5/CHANGELOG.md +40 -0
- {messygit-0.3.2 → messygit-0.4.5}/PKG-INFO +102 -6
- {messygit-0.3.2 → messygit-0.4.5}/README.md +101 -5
- messygit-0.4.5/evals/README.md +90 -0
- messygit-0.4.5/evals/__init__.py +11 -0
- messygit-0.4.5/evals/changelog_eval.py +310 -0
- messygit-0.4.5/evals/commit_eval.py +258 -0
- messygit-0.4.5/evals/core.py +248 -0
- messygit-0.4.5/evals/fixtures.py +99 -0
- messygit-0.4.5/evals/incremental_suggest_eval.py +342 -0
- messygit-0.4.5/evals/results/changelog/2026-07-01_22-15-24.md +25 -0
- messygit-0.4.5/evals/results/commit/2026-06-26_23-26-23.md +45 -0
- messygit-0.4.5/evals/results/suggest/2026-07-01_22-16-20.md +25 -0
- messygit-0.4.5/evals/results/suggest/2026-07-01_22-32-01.md +25 -0
- messygit-0.4.5/evals/results/suggest/2026-07-01_22-36-50.md +25 -0
- messygit-0.4.5/evals/results/suggest-incremental/2026-07-05_21-47-23.md +30 -0
- messygit-0.4.5/evals/results/suggest-incremental/2026-07-05_21-56-31.md +30 -0
- messygit-0.4.5/evals/suggest_eval.py +259 -0
- {messygit-0.3.2 → messygit-0.4.5}/messygit/agent/agent.py +66 -21
- {messygit-0.3.2 → messygit-0.4.5}/messygit/agent/tools.py +111 -1
- messygit-0.4.5/messygit/cli.py +218 -0
- messygit-0.4.5/messygit/commands/__init__.py +0 -0
- messygit-0.4.5/messygit/commands/account_cmds.py +128 -0
- messygit-0.4.5/messygit/commands/agent_cmds.py +179 -0
- messygit-0.4.5/messygit/commands/app_cmds.py +86 -0
- messygit-0.4.5/messygit/commands/git_cmds.py +134 -0
- messygit-0.4.5/messygit/commands/trace.py +115 -0
- messygit-0.4.5/messygit/commands/usage.py +60 -0
- {messygit-0.3.2 → messygit-0.4.5}/messygit/config.py +55 -0
- {messygit-0.3.2 → messygit-0.4.5}/messygit/git.py +75 -0
- messygit-0.4.5/messygit/prompts.py +278 -0
- messygit-0.4.5/messygit/ui/__init__.py +0 -0
- messygit-0.4.5/messygit/ui/banner.py +54 -0
- messygit-0.4.5/messygit/ui/output.py +29 -0
- messygit-0.4.5/messygit/ui/spinner.py +94 -0
- messygit-0.4.5/messygit/ui/theme.py +59 -0
- {messygit-0.3.2 → messygit-0.4.5}/pyproject.toml +1 -1
- {messygit-0.3.2 → messygit-0.4.5}/tests/config_test.py +34 -0
- messygit-0.4.5/tests/suggest_test.py +60 -0
- messygit-0.4.5/tests/trace_test.py +115 -0
- messygit-0.4.5/tests/verbose_test.py +145 -0
- messygit-0.3.2/ARCHITECTURE.md +0 -64
- messygit-0.3.2/messygit/cli.py +0 -762
- messygit-0.3.2/messygit/prompts.py +0 -108
- {messygit-0.3.2 → messygit-0.4.5}/.github/workflows/publish.yml +0 -0
- {messygit-0.3.2 → messygit-0.4.5}/.github/workflows/test.yml +0 -0
- {messygit-0.3.2 → messygit-0.4.5}/.gitignore +0 -0
- {messygit-0.3.2 → messygit-0.4.5}/.vscode/settings.json +0 -0
- {messygit-0.3.2 → messygit-0.4.5}/messygit/__init__.py +0 -0
- {messygit-0.3.2 → messygit-0.4.5}/messygit/agent/tool.py +0 -0
- {messygit-0.3.2 → messygit-0.4.5}/messygit/llm.py +0 -0
- {messygit-0.3.2 → messygit-0.4.5}/messygit/models.py +0 -0
- {messygit-0.3.2 → messygit-0.4.5}/messygit/usage.py +0 -0
- {messygit-0.3.2 → messygit-0.4.5}/tests/agent_test.py +0 -0
- {messygit-0.3.2 → messygit-0.4.5}/tests/git_test.py +0 -0
- {messygit-0.3.2 → messygit-0.4.5}/tests/llm_test.py +0 -0
- {messygit-0.3.2 → messygit-0.4.5}/tests/tool_schema_test.py +0 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
This document describes the purpose of each file in the `messygit` project.
|
|
4
|
+
|
|
5
|
+
The package is organized in layers. `ui/` is the shared presentation foundation
|
|
6
|
+
(console, theme, spinner, banner). `commands/` holds the command handlers grouped
|
|
7
|
+
the same way the `help` screen groups them. `agent/` is a self-contained tool-use
|
|
8
|
+
loop. `cli.py` is a thin shell that wires everything together. Dependencies flow
|
|
9
|
+
one way — `ui/` knows nothing about `commands/`, and `commands/` knows nothing
|
|
10
|
+
about `cli` — so there are no import cycles.
|
|
11
|
+
|
|
12
|
+
## Root
|
|
13
|
+
|
|
14
|
+
| File | Purpose |
|
|
15
|
+
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
|
|
16
|
+
| `pyproject.toml` | Package metadata, dependencies (`anthropic`, `click`, `rich`), build system (hatchling), and the `messygit` console script. |
|
|
17
|
+
| `README.md` | User-facing documentation: install, usage, commands, and development instructions. |
|
|
18
|
+
| `ARCHITECTURE.md` | This file — a per-module map of the codebase. |
|
|
19
|
+
| `CHANGELOG.md` | Release notes, generated/updated by the `changelog` command. |
|
|
20
|
+
| `.gitignore` | Keeps `.venv/`, `__pycache__/`, `dist/`, and `*.egg-info/` out of version control. |
|
|
21
|
+
| `.github/workflows/test.yml` | Runs `pytest` on every push/PR across Python 3.10–3.13. |
|
|
22
|
+
| `.github/workflows/publish.yml` | Builds and publishes to PyPI via trusted publishing on release. |
|
|
23
|
+
|
|
24
|
+
## `messygit/` (core package)
|
|
25
|
+
|
|
26
|
+
| File | Purpose |
|
|
27
|
+
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
28
|
+
| `__init__.py` | Marks the directory as a Python package. |
|
|
29
|
+
| `cli.py` | The REPL shell: prints the startup dashboard, runs the prompt loop, owns the `COMMANDS` dispatch table and the `help` screen, and applies the saved theme on launch. Delegates all real work to `commands/`. |
|
|
30
|
+
| `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 changed files), and runs `add`/`commit`/`push`. Also exposes the primitives incremental `suggest` needs: `get_head_hash`, `get_repo_root`, `is_ancestor` (validate a saved checkpoint), and `get_commits_since`/`get_range_context` (the `saved_hash..HEAD` delta). |
|
|
31
|
+
| `llm.py` | Anthropic SDK integration for the (non-agentic) `commit` path. Creates the client, calls `messages.create`, extracts text, and maps SDK exceptions (auth, permission, billing/402) into user-friendly error classes. Exposes helpers reused by `agent/agent.py`. |
|
|
32
|
+
| `config.py` | Reads/writes `~/.messygit/config.json`: API key (plus `ANTHROPIC_API_KEY` env resolution), theme, model, todo, the `verbose` flag, and per-repo `suggest` checkpoints (`{head, suggestions, incremental_runs}`, keyed by repo root). Masks keys for display and defines user-facing error messages and exception classes. |
|
|
33
|
+
| `models.py` | The selectable Claude models, their labels, and approximate per-million-token pricing; resolves the active model from config. |
|
|
34
|
+
| `usage.py` | Session-local token-usage tracker (`SESSION_USAGE`) and the billing URL. The API exposes no balance endpoint, so usage/cost are accumulated per session. |
|
|
35
|
+
| `prompts.py` | The system prompts — `COMMIT_SYSTEM_PROMPT`, `SUGGESTION_SYSTEM_PROMPT`, `SUGGESTION_INCREMENTAL_SYSTEM_PROMPT` (delta-only "update the existing list" variant), `CHANGELOG_SYSTEM_PROMPT` — plus `build_user_prompt`. Each prompt includes anti-hallucination and untrusted-input guardrails. |
|
|
36
|
+
|
|
37
|
+
## `messygit/ui/` (shared presentation)
|
|
38
|
+
|
|
39
|
+
| File | Purpose |
|
|
40
|
+
| ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
41
|
+
| `theme.py` | Color palette and theme state. `BRAND`/`BRAND_RGB`/`BANNER_COLOR` are reassigned at runtime by `apply_theme()`, so other modules read them as `theme.BRAND` (never import the name directly). Also `brand_ansi()` and `active_theme()`. |
|
|
42
|
+
| `output.py` | The shared `console`/`err_console` objects and the small print helpers (`print_error`, `success`, `warn`, `field`). |
|
|
43
|
+
| `spinner.py` | The threaded `_CharSpinner` loading animation and the `spinner()` factory. |
|
|
44
|
+
| `banner.py` | The ASCII banner art and its boot animation (`animate_banner`). |
|
|
45
|
+
|
|
46
|
+
## `messygit/commands/` (command handlers)
|
|
47
|
+
|
|
48
|
+
| File | Purpose |
|
|
49
|
+
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
50
|
+
| `git_cmds.py` | The git group: `add`, `commit` (AI message + Y/n/e prompt), `push`, `outbox`. |
|
|
51
|
+
| `agent_cmds.py` | The agent group: `suggest` and `changelog`. `_drive()` runs an agent either under a spinner or streaming live (verbose), and records the run's trace. `suggest` is incremental: `_choose_mode` picks a full scan (first run, stale/diverged checkpoint, `suggest full`, or a periodic re-audit every `AUTO_FULL_SCAN_EVERY` runs) vs an incremental run that feeds the prior suggestions plus only the `saved_hash..HEAD` delta (`_incremental_prompt`), then advances the per-repo checkpoint. |
|
|
52
|
+
| `account_cmds.py` | The account group: `config`, `show`, `model`, `tokens`. |
|
|
53
|
+
| `app_cmds.py` | The app group: `todo`, `theme`, `verbose`. |
|
|
54
|
+
| `usage.py` | Token-usage/cost *display* helpers (`usage_summary`, `print_usage_delta`, `model_pricing`, the high-usage warning). Distinct from the root `usage.py` tracker. |
|
|
55
|
+
| `trace.py` | The `trace` command. Stores the last agent run's steps and renders them as a panel; also provides `live_reporter()`, the per-step formatter that verbose mode streams. |
|
|
56
|
+
|
|
57
|
+
## `messygit/agent/` (agentic tool-use subpackage)
|
|
58
|
+
|
|
59
|
+
| File | Purpose |
|
|
60
|
+
| ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
61
|
+
| `tool.py` | `Tool` dataclass wrapping a Python callable with a name, description, and parameter schema. `run()` invokes the function; `to_schema()` emits an Anthropic-compatible tool definition. |
|
|
62
|
+
| `tools.py` | Concrete tools: `run_git_tool` (allowlisted read-only git, including tag ranges), `read_file_tool`, `list_directory_tool`, `search_code_tool` (`git grep`), `write_file_tool` (full overwrite), and `edit_file_tool` (unique-match string replace). All file tools reject paths outside the repo root. |
|
|
63
|
+
| `agent.py` | The agentic loop. Sends messages to Claude with tool definitions, dispatches `tool_use` blocks to matching `Tool`s, feeds results back, and iterates up to `max_iterations`. Records each step as a `TraceStep` (optionally streamed via an `on_step` callback) and warns when the iteration cap is hit before finishing. |
|
|
64
|
+
|
|
65
|
+
## Data flow
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
User runs `messygit` → cli.py REPL (dispatch table)
|
|
69
|
+
│
|
|
70
|
+
├── "add <files>" / "push" ─────► commands/git_cmds.py ─► git.py
|
|
71
|
+
├── "config" / "show" / "model" / "tokens" ─► commands/account_cmds.py ─► config.py / usage.py
|
|
72
|
+
├── "todo" / "theme" / "verbose" ─────► commands/app_cmds.py ─► config.py
|
|
73
|
+
├── "trace" ─────────────────────► commands/trace.py (render last run)
|
|
74
|
+
│
|
|
75
|
+
├── "commit" ──► commands/git_cmds.py
|
|
76
|
+
│ │ ├── git.py (staged diff + token budget)
|
|
77
|
+
│ │ └── llm.py ─► prompts.COMMIT_SYSTEM_PROMPT, config.py (key)
|
|
78
|
+
│ ▼
|
|
79
|
+
│ Y/n/e prompt ─► git.py (git commit)
|
|
80
|
+
│
|
|
81
|
+
└── "suggest" / "changelog" ──► commands/agent_cmds.py
|
|
82
|
+
│ ├── config.py: load/save suggest checkpoint (suggest only)
|
|
83
|
+
│ │ └── full scan on first run / stale hash / `suggest full`
|
|
84
|
+
│ │ / every AUTO_FULL_SCAN_EVERY runs; else incremental
|
|
85
|
+
│ │ (git.py: saved_hash..HEAD delta → _incremental_prompt)
|
|
86
|
+
│ └── agent/agent.py (tool-use loop)
|
|
87
|
+
│ ├── config.py (key) + models.py
|
|
88
|
+
│ ├── prompts.{SUGGESTION,SUGGESTION_INCREMENTAL,CHANGELOG}_SYSTEM_PROMPT
|
|
89
|
+
│ └── agent/tools.py (run_git, read_file, list_directory,
|
|
90
|
+
│ write_file, edit_file)
|
|
91
|
+
▼
|
|
92
|
+
spinner OR live step stream (verbose); steps saved for `trace`
|
|
93
|
+
```
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
## [Unreleased]
|
|
2
|
+
### Added
|
|
3
|
+
- Comprehensive evaluation framework (`evals/`) for testing AI model outputs, including:
|
|
4
|
+
- Generic evaluation harness supporting multiple eval types with deterministic scorers and optional LLM-as-judge grading
|
|
5
|
+
- Commit message evaluation with test cases for format, semantic accuracy, and adversarial prompt injection
|
|
6
|
+
- Agentic evaluators for `suggest` and `changelog` commands that build throwaway git repos and grade both output quality and agent process (tool usage, iteration budget, hallucination detection)
|
|
7
|
+
- Evaluation result reporting with markdown scorecards and aggregated pass rates
|
|
8
|
+
|
|
9
|
+
## [v0.4.0] - 2026-06-23
|
|
10
|
+
### Added
|
|
11
|
+
- `trace` command to inspect and display the detailed steps of the last agent run (show what tools were called, their inputs, and results)
|
|
12
|
+
- `verbose` mode toggle to stream agent steps live as they execute (replaces the spinner with real-time output during `suggest` and `changelog` operations)
|
|
13
|
+
- `edit_file` tool for the agent to make precise edits to existing files by replacing specific text spans (complements `write_file` for partial updates)
|
|
14
|
+
- `changelog` command to automatically generate and update a CHANGELOG.md file by analyzing git history between tags
|
|
15
|
+
- Iteration limit warning that displays when an agent run hits the maximum iteration limit before completing, alerting users that the task may be incomplete
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
- CLI code reorganized from a single monolithic module into separate command modules (account_cmds, git_cmds, agent_cmds, app_cmds) and UI modules (banner, spinner, theme, output) for better maintainability
|
|
19
|
+
|
|
20
|
+
## [v0.3.2] - 2026-06-20
|
|
21
|
+
### Added
|
|
22
|
+
- Error handling for unknown tools—agent now returns an error result instead of crashing when the model requests a non-existent tool
|
|
23
|
+
- Exception handling for tool execution—tool errors are caught and reported back to the model as error results
|
|
24
|
+
- `outbox` command to display committed but unpushed commits, showing how many commits are ahead of the upstream branch
|
|
25
|
+
- Input validation and security checks for `read_file` and `list_directory` tools to prevent directory traversal attacks
|
|
26
|
+
- Enhanced tool descriptions with detailed documentation of parameters and usage examples
|
|
27
|
+
- Support for `required` field in tool schemas for better validation
|
|
28
|
+
- Comprehensive pytest test suite covering agent tool execution, config management, git diff parsing, LLM error handling, and tool schemas
|
|
29
|
+
- GitHub Actions CI workflow for automated testing across Python 3.10–3.13
|
|
30
|
+
|
|
31
|
+
### Changed
|
|
32
|
+
- Tool schema generation now includes required field declarations
|
|
33
|
+
- Improved error messages throughout the CLI for better user guidance
|
|
34
|
+
- Tool functions now validate inputs for security and proper error reporting
|
|
35
|
+
|
|
36
|
+
## [v0.3.1] - 2026-06-20
|
|
37
|
+
|
|
38
|
+
## [v0.3.0] - 2026-06-20
|
|
39
|
+
|
|
40
|
+
## [v0.2.1] - 2026-06-20
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: messygit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.5
|
|
4
4
|
Summary: An AI-powered interactive git CLI with agentic tools for commits, code suggestions, and workflow automation.
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -13,16 +13,18 @@ Description-Content-Type: text/markdown
|
|
|
13
13
|
|
|
14
14
|
# messygit
|
|
15
15
|
|
|
16
|
-
**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).
|
|
16
|
+
**messygit** is an interactive CLI that turns messy git workflows into clean Conventional Commits — stage, commit, push, generate changelogs, and get AI-powered project suggestions, all from one interface powered by [Claude](https://www.anthropic.com/api).
|
|
17
17
|
|
|
18
18
|
## Why use it
|
|
19
19
|
|
|
20
20
|
- **Interactive REPL** — one command drops you into a persistent session where you can stage, commit, push, and more without leaving.
|
|
21
21
|
- **AI commit messages** — sends your staged diff to Claude and suggests a clean Conventional Commits subject line.
|
|
22
|
-
- **Project suggestions** — an AI agent inspects your repo and recommends concrete next steps.
|
|
22
|
+
- **Project suggestions** — an AI agent inspects your repo and recommends concrete next steps. After the first run it only re-analyzes what changed (cheaper) while carrying its previous list forward, and periodically re-audits the whole repo on its own.
|
|
23
|
+
- **Changelog generation** — an agent reads the commits between your two latest tags, drills into unclear ones, categorizes the changes, and writes/updates `CHANGELOG.md`.
|
|
24
|
+
- **See what the agent did** — runs are clean by default; type `trace` to expand the last run's tool calls, or flip `verbose` on to stream each step live.
|
|
23
25
|
- **Token usage & cost** — tracks the tokens each session uses and shows a rough cost estimate, with a one-command jump to billing.
|
|
24
26
|
- **Themed UI** — a colored startup animation and prompt you can recolor with the `theme` command.
|
|
25
|
-
- **Safe by default** — only the staged diff is sent
|
|
27
|
+
- **Safe by default** — only the staged diff is sent for `commit`; agents use read-only git plus repo-scoped file tools that reject paths outside the repository. Your API key is never printed in full.
|
|
26
28
|
|
|
27
29
|
## Requirements
|
|
28
30
|
|
|
@@ -96,12 +98,16 @@ Commands are grouped on the `help` screen:
|
|
|
96
98
|
| `add <file>` or `add .` | Stage files for commit |
|
|
97
99
|
| `commit` | Generate an AI commit message from staged changes, then commit / cancel / edit |
|
|
98
100
|
| `push` | Push commits to remote |
|
|
101
|
+
| `outbox` | Show commits made locally but not yet pushed to the upstream branch |
|
|
99
102
|
|
|
100
103
|
**messyagent**
|
|
101
104
|
|
|
102
105
|
| Command | Description |
|
|
103
106
|
|---------|-------------|
|
|
104
|
-
| `suggest` | Get AI-powered next-step suggestions for your project |
|
|
107
|
+
| `suggest` | Get AI-powered next-step suggestions for your project (incremental after the first run) |
|
|
108
|
+
| `suggest full` | Force a fresh full-repo review, ignoring the saved checkpoint |
|
|
109
|
+
| `changelog` | Generate or update `CHANGELOG.md` from the commits between your two latest tags (requires at least one tag) |
|
|
110
|
+
| `trace` | Show what the last agent run actually did — its tool calls and results |
|
|
105
111
|
|
|
106
112
|
**account**
|
|
107
113
|
|
|
@@ -118,6 +124,7 @@ Commands are grouped on the `help` screen:
|
|
|
118
124
|
|---------|-------------|
|
|
119
125
|
| `todo` | Open your todo list in `$EDITOR` (saved to `~/.messygit/todo.md`) |
|
|
120
126
|
| `theme` or `theme <name>` | Change the UI color (run `theme` to list presets) |
|
|
127
|
+
| `verbose` or `verbose on\|off` | Toggle live streaming of agent steps (persists; off by default) |
|
|
121
128
|
| `help` | List available commands |
|
|
122
129
|
| `quit` / `exit` | Exit messygit |
|
|
123
130
|
|
|
@@ -136,6 +143,66 @@ messygit > push
|
|
|
136
143
|
|
|
137
144
|
> Tip: run `suggest` for AI next-step ideas, or `theme` to recolor the UI.
|
|
138
145
|
|
|
146
|
+
### Agent commands & transparency
|
|
147
|
+
|
|
148
|
+
`suggest` and `changelog` are backed by an agent that uses tools (read-only git,
|
|
149
|
+
file reads, and — for `changelog` — repo-scoped file writes) over several steps.
|
|
150
|
+
|
|
151
|
+
By default a run shows only a spinner and the final result. Two commands let you
|
|
152
|
+
see inside:
|
|
153
|
+
|
|
154
|
+
```
|
|
155
|
+
messygit > changelog # generates/updates CHANGELOG.md
|
|
156
|
+
messygit > trace # expand what that run just did
|
|
157
|
+
|
|
158
|
+
╭─ trace · changelog · 4 tool calls ─────────────╮
|
|
159
|
+
│ 1. run_git tag --sort=-creatordate │
|
|
160
|
+
│ └ v0.4.0 (+3 more lines) │
|
|
161
|
+
│ 2. run_git log v0.3.2..v0.4.0 │
|
|
162
|
+
│ └ commit a1b2c3 feat: … (+12 more lines) │
|
|
163
|
+
│ 3. read_file CHANGELOG.md │
|
|
164
|
+
│ └ ## [v0.3.2] - 2026-06-20 │
|
|
165
|
+
│ 4. edit_file CHANGELOG.md │
|
|
166
|
+
│ └ File edited successfully. │
|
|
167
|
+
╰─────────────────────────────────────────────────╯
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Prefer to watch it happen live? Turn on `verbose` — the same steps stream as the
|
|
171
|
+
agent works (no spinner). The setting persists in `~/.messygit/config.json`:
|
|
172
|
+
|
|
173
|
+
```
|
|
174
|
+
messygit > verbose on
|
|
175
|
+
Verbose on — agent runs will stream their steps live (no spinner)
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
`changelog` requires at least one git tag; it documents the range between your two
|
|
179
|
+
most recent tags (or the latest tag to `HEAD` when only one exists).
|
|
180
|
+
|
|
181
|
+
### Incremental suggestions
|
|
182
|
+
|
|
183
|
+
The first time you run `suggest` in a repo, the agent does a full scan and saves a
|
|
184
|
+
checkpoint — the current `HEAD` hash plus the list it produced — to
|
|
185
|
+
`~/.messygit/config.json`, keyed by repository. Every run after that is
|
|
186
|
+
**incremental**: instead of re-reading the whole tree, the agent is handed only the
|
|
187
|
+
`saved_hash..HEAD` delta (new commits + changed lines) alongside its previous
|
|
188
|
+
suggestions, and updates the list — dropping items the changes resolved, keeping
|
|
189
|
+
standing gaps, and adding follow-ups from what changed. Then it advances the
|
|
190
|
+
checkpoint. This makes repeat runs much cheaper and keeps the advice coherent
|
|
191
|
+
across runs instead of resetting each time.
|
|
192
|
+
|
|
193
|
+
Because delta-only analysis never re-reads untouched files, a standing issue in a
|
|
194
|
+
corner nothing has touched could otherwise drift out of view. Two things guard
|
|
195
|
+
against that:
|
|
196
|
+
|
|
197
|
+
- **Automatic re-audit** — after several incremental runs, `suggest` falls back to
|
|
198
|
+
a full scan on its own to refresh whole-repo coverage.
|
|
199
|
+
- **`suggest full`** — force a fresh full-repo review at any time.
|
|
200
|
+
|
|
201
|
+
`suggest` also falls back to a full scan automatically when there's no checkpoint
|
|
202
|
+
yet, or when the saved commit is no longer an ancestor of `HEAD` (after a rebase,
|
|
203
|
+
amend, squash, or branch switch), so a stale checkpoint never produces a nonsense
|
|
204
|
+
delta.
|
|
205
|
+
|
|
139
206
|
### Commit message style
|
|
140
207
|
|
|
141
208
|
The model follows **Conventional Commits**: `type(scope): description`
|
|
@@ -144,7 +211,7 @@ Allowed types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`. Subj
|
|
|
144
211
|
|
|
145
212
|
### Token usage & cost
|
|
146
213
|
|
|
147
|
-
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:
|
|
214
|
+
messygit tracks the tokens used by AI commands (`commit`, `suggest`, `changelog`) 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:
|
|
148
215
|
|
|
149
216
|
```
|
|
150
217
|
messygit > tokens
|
|
@@ -176,6 +243,35 @@ Switch anyway? [y/N]:
|
|
|
176
243
|
|
|
177
244
|
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.
|
|
178
245
|
|
|
246
|
+
## Development & testing
|
|
247
|
+
|
|
248
|
+
Install the package with its dev dependencies (pytest), then run the suite:
|
|
249
|
+
|
|
250
|
+
```bash
|
|
251
|
+
pip install -e ".[dev]"
|
|
252
|
+
pytest -q
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
The tests live in `tests/` and are pure unit tests — no network calls and no
|
|
256
|
+
API key required (the Anthropic client is simulated). They cover:
|
|
257
|
+
|
|
258
|
+
| File | What it covers |
|
|
259
|
+
|------|----------------|
|
|
260
|
+
| `tests/config_test.py` | API-key resolution order (env → file), key save/load, theme/model/todo persistence, per-repo `suggest` checkpoints, malformed-config handling |
|
|
261
|
+
| `tests/suggest_test.py` | `suggest` mode selection — full-scan vs incremental, and the periodic auto re-audit cycle |
|
|
262
|
+
| `tests/git_test.py` | The diff parser — noise-file filtering and the compact changed-lines format |
|
|
263
|
+
| `tests/llm_test.py` | Insufficient-balance / billing-error detection and user messaging |
|
|
264
|
+
| `tests/tool_schema_test.py` | Agent tool schemas match the shape the Anthropic Messages API expects |
|
|
265
|
+
| `tests/agent_test.py` | The agent's tool-use loop, driven by a simulated Anthropic client with scripted responses |
|
|
266
|
+
| `tests/trace_test.py` | The `trace` renderer — step numbering, result truncation, empty state, and markup-safety of raw tool output |
|
|
267
|
+
| `tests/verbose_test.py` | The `verbose` setting, the toggle command, and `_drive` choosing live-stream vs. spinner |
|
|
268
|
+
|
|
269
|
+
### Continuous integration
|
|
270
|
+
|
|
271
|
+
`.github/workflows/test.yml` runs `pytest` on every push to `main` and on every
|
|
272
|
+
pull request, across Python 3.10–3.13. No secrets are required because the tests
|
|
273
|
+
mock the Anthropic client.
|
|
274
|
+
|
|
179
275
|
## Publishing to PyPI
|
|
180
276
|
|
|
181
277
|
This project uses GitHub Actions with [PyPI trusted publishing](https://docs.pypi.org/trusted-publishers/) — no API tokens needed in your repo.
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
# messygit
|
|
2
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).
|
|
3
|
+
**messygit** is an interactive CLI that turns messy git workflows into clean Conventional Commits — stage, commit, push, generate changelogs, and get AI-powered project suggestions, all from one interface powered by [Claude](https://www.anthropic.com/api).
|
|
4
4
|
|
|
5
5
|
## Why use it
|
|
6
6
|
|
|
7
7
|
- **Interactive REPL** — one command drops you into a persistent session where you can stage, commit, push, and more without leaving.
|
|
8
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.
|
|
9
|
+
- **Project suggestions** — an AI agent inspects your repo and recommends concrete next steps. After the first run it only re-analyzes what changed (cheaper) while carrying its previous list forward, and periodically re-audits the whole repo on its own.
|
|
10
|
+
- **Changelog generation** — an agent reads the commits between your two latest tags, drills into unclear ones, categorizes the changes, and writes/updates `CHANGELOG.md`.
|
|
11
|
+
- **See what the agent did** — runs are clean by default; type `trace` to expand the last run's tool calls, or flip `verbose` on to stream each step live.
|
|
10
12
|
- **Token usage & cost** — tracks the tokens each session uses and shows a rough cost estimate, with a one-command jump to billing.
|
|
11
13
|
- **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
|
|
14
|
+
- **Safe by default** — only the staged diff is sent for `commit`; agents use read-only git plus repo-scoped file tools that reject paths outside the repository. Your API key is never printed in full.
|
|
13
15
|
|
|
14
16
|
## Requirements
|
|
15
17
|
|
|
@@ -83,12 +85,16 @@ Commands are grouped on the `help` screen:
|
|
|
83
85
|
| `add <file>` or `add .` | Stage files for commit |
|
|
84
86
|
| `commit` | Generate an AI commit message from staged changes, then commit / cancel / edit |
|
|
85
87
|
| `push` | Push commits to remote |
|
|
88
|
+
| `outbox` | Show commits made locally but not yet pushed to the upstream branch |
|
|
86
89
|
|
|
87
90
|
**messyagent**
|
|
88
91
|
|
|
89
92
|
| Command | Description |
|
|
90
93
|
|---------|-------------|
|
|
91
|
-
| `suggest` | Get AI-powered next-step suggestions for your project |
|
|
94
|
+
| `suggest` | Get AI-powered next-step suggestions for your project (incremental after the first run) |
|
|
95
|
+
| `suggest full` | Force a fresh full-repo review, ignoring the saved checkpoint |
|
|
96
|
+
| `changelog` | Generate or update `CHANGELOG.md` from the commits between your two latest tags (requires at least one tag) |
|
|
97
|
+
| `trace` | Show what the last agent run actually did — its tool calls and results |
|
|
92
98
|
|
|
93
99
|
**account**
|
|
94
100
|
|
|
@@ -105,6 +111,7 @@ Commands are grouped on the `help` screen:
|
|
|
105
111
|
|---------|-------------|
|
|
106
112
|
| `todo` | Open your todo list in `$EDITOR` (saved to `~/.messygit/todo.md`) |
|
|
107
113
|
| `theme` or `theme <name>` | Change the UI color (run `theme` to list presets) |
|
|
114
|
+
| `verbose` or `verbose on\|off` | Toggle live streaming of agent steps (persists; off by default) |
|
|
108
115
|
| `help` | List available commands |
|
|
109
116
|
| `quit` / `exit` | Exit messygit |
|
|
110
117
|
|
|
@@ -123,6 +130,66 @@ messygit > push
|
|
|
123
130
|
|
|
124
131
|
> Tip: run `suggest` for AI next-step ideas, or `theme` to recolor the UI.
|
|
125
132
|
|
|
133
|
+
### Agent commands & transparency
|
|
134
|
+
|
|
135
|
+
`suggest` and `changelog` are backed by an agent that uses tools (read-only git,
|
|
136
|
+
file reads, and — for `changelog` — repo-scoped file writes) over several steps.
|
|
137
|
+
|
|
138
|
+
By default a run shows only a spinner and the final result. Two commands let you
|
|
139
|
+
see inside:
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
messygit > changelog # generates/updates CHANGELOG.md
|
|
143
|
+
messygit > trace # expand what that run just did
|
|
144
|
+
|
|
145
|
+
╭─ trace · changelog · 4 tool calls ─────────────╮
|
|
146
|
+
│ 1. run_git tag --sort=-creatordate │
|
|
147
|
+
│ └ v0.4.0 (+3 more lines) │
|
|
148
|
+
│ 2. run_git log v0.3.2..v0.4.0 │
|
|
149
|
+
│ └ commit a1b2c3 feat: … (+12 more lines) │
|
|
150
|
+
│ 3. read_file CHANGELOG.md │
|
|
151
|
+
│ └ ## [v0.3.2] - 2026-06-20 │
|
|
152
|
+
│ 4. edit_file CHANGELOG.md │
|
|
153
|
+
│ └ File edited successfully. │
|
|
154
|
+
╰─────────────────────────────────────────────────╯
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Prefer to watch it happen live? Turn on `verbose` — the same steps stream as the
|
|
158
|
+
agent works (no spinner). The setting persists in `~/.messygit/config.json`:
|
|
159
|
+
|
|
160
|
+
```
|
|
161
|
+
messygit > verbose on
|
|
162
|
+
Verbose on — agent runs will stream their steps live (no spinner)
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
`changelog` requires at least one git tag; it documents the range between your two
|
|
166
|
+
most recent tags (or the latest tag to `HEAD` when only one exists).
|
|
167
|
+
|
|
168
|
+
### Incremental suggestions
|
|
169
|
+
|
|
170
|
+
The first time you run `suggest` in a repo, the agent does a full scan and saves a
|
|
171
|
+
checkpoint — the current `HEAD` hash plus the list it produced — to
|
|
172
|
+
`~/.messygit/config.json`, keyed by repository. Every run after that is
|
|
173
|
+
**incremental**: instead of re-reading the whole tree, the agent is handed only the
|
|
174
|
+
`saved_hash..HEAD` delta (new commits + changed lines) alongside its previous
|
|
175
|
+
suggestions, and updates the list — dropping items the changes resolved, keeping
|
|
176
|
+
standing gaps, and adding follow-ups from what changed. Then it advances the
|
|
177
|
+
checkpoint. This makes repeat runs much cheaper and keeps the advice coherent
|
|
178
|
+
across runs instead of resetting each time.
|
|
179
|
+
|
|
180
|
+
Because delta-only analysis never re-reads untouched files, a standing issue in a
|
|
181
|
+
corner nothing has touched could otherwise drift out of view. Two things guard
|
|
182
|
+
against that:
|
|
183
|
+
|
|
184
|
+
- **Automatic re-audit** — after several incremental runs, `suggest` falls back to
|
|
185
|
+
a full scan on its own to refresh whole-repo coverage.
|
|
186
|
+
- **`suggest full`** — force a fresh full-repo review at any time.
|
|
187
|
+
|
|
188
|
+
`suggest` also falls back to a full scan automatically when there's no checkpoint
|
|
189
|
+
yet, or when the saved commit is no longer an ancestor of `HEAD` (after a rebase,
|
|
190
|
+
amend, squash, or branch switch), so a stale checkpoint never produces a nonsense
|
|
191
|
+
delta.
|
|
192
|
+
|
|
126
193
|
### Commit message style
|
|
127
194
|
|
|
128
195
|
The model follows **Conventional Commits**: `type(scope): description`
|
|
@@ -131,7 +198,7 @@ Allowed types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`. Subj
|
|
|
131
198
|
|
|
132
199
|
### Token usage & cost
|
|
133
200
|
|
|
134
|
-
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:
|
|
201
|
+
messygit tracks the tokens used by AI commands (`commit`, `suggest`, `changelog`) 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:
|
|
135
202
|
|
|
136
203
|
```
|
|
137
204
|
messygit > tokens
|
|
@@ -163,6 +230,35 @@ Switch anyway? [y/N]:
|
|
|
163
230
|
|
|
164
231
|
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.
|
|
165
232
|
|
|
233
|
+
## Development & testing
|
|
234
|
+
|
|
235
|
+
Install the package with its dev dependencies (pytest), then run the suite:
|
|
236
|
+
|
|
237
|
+
```bash
|
|
238
|
+
pip install -e ".[dev]"
|
|
239
|
+
pytest -q
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
The tests live in `tests/` and are pure unit tests — no network calls and no
|
|
243
|
+
API key required (the Anthropic client is simulated). They cover:
|
|
244
|
+
|
|
245
|
+
| File | What it covers |
|
|
246
|
+
|------|----------------|
|
|
247
|
+
| `tests/config_test.py` | API-key resolution order (env → file), key save/load, theme/model/todo persistence, per-repo `suggest` checkpoints, malformed-config handling |
|
|
248
|
+
| `tests/suggest_test.py` | `suggest` mode selection — full-scan vs incremental, and the periodic auto re-audit cycle |
|
|
249
|
+
| `tests/git_test.py` | The diff parser — noise-file filtering and the compact changed-lines format |
|
|
250
|
+
| `tests/llm_test.py` | Insufficient-balance / billing-error detection and user messaging |
|
|
251
|
+
| `tests/tool_schema_test.py` | Agent tool schemas match the shape the Anthropic Messages API expects |
|
|
252
|
+
| `tests/agent_test.py` | The agent's tool-use loop, driven by a simulated Anthropic client with scripted responses |
|
|
253
|
+
| `tests/trace_test.py` | The `trace` renderer — step numbering, result truncation, empty state, and markup-safety of raw tool output |
|
|
254
|
+
| `tests/verbose_test.py` | The `verbose` setting, the toggle command, and `_drive` choosing live-stream vs. spinner |
|
|
255
|
+
|
|
256
|
+
### Continuous integration
|
|
257
|
+
|
|
258
|
+
`.github/workflows/test.yml` runs `pytest` on every push to `main` and on every
|
|
259
|
+
pull request, across Python 3.10–3.13. No secrets are required because the tests
|
|
260
|
+
mock the Anthropic client.
|
|
261
|
+
|
|
166
262
|
## Publishing to PyPI
|
|
167
263
|
|
|
168
264
|
This project uses GitHub Actions with [PyPI trusted publishing](https://docs.pypi.org/trusted-publishers/) — no API tokens needed in your repo.
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Evals
|
|
2
|
+
|
|
3
|
+
Evals measure the **quality of real model output** — distinct from the unit
|
|
4
|
+
tests in `tests/`, which simulate the model and run offline. Evals call the live
|
|
5
|
+
API, so they cost tokens and need an `ANTHROPIC_API_KEY`. They are intentionally
|
|
6
|
+
**not** collected by `pytest`.
|
|
7
|
+
|
|
8
|
+
## Run it
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
export ANTHROPIC_API_KEY=sk-ant-... # or: messygit > config <key>
|
|
12
|
+
python -m evals.commit_eval # diff -> commit subject
|
|
13
|
+
python -m evals.suggest_eval # repo state -> next-steps list (agentic)
|
|
14
|
+
python -m evals.changelog_eval # tagged repo -> written CHANGELOG.md (agentic)
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The agentic evals (`suggest`, `changelog`) build a throwaway git repo per case,
|
|
18
|
+
run the real agent inside it, and grade both the output and the trace — so they
|
|
19
|
+
call the API many times over several iterations and take a few minutes each.
|
|
20
|
+
|
|
21
|
+
Each run writes a markdown report to `evals/results/<eval>/<timestamp>.md`
|
|
22
|
+
(one file per run, grouped by eval) — the terminal only prints the file path.
|
|
23
|
+
Exit code is `0` if the format-check pass rate ≥ `EVAL_PASS_BAR` (default `0.90`),
|
|
24
|
+
else `1` — so it can gate a CI job.
|
|
25
|
+
|
|
26
|
+
Env knobs:
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
| Var | Default | Meaning |
|
|
30
|
+
| ------------------ | ------------------ | ----------------------------------------------------------------------------------------------------------- |
|
|
31
|
+
| `EVAL_JUDGE_MODEL` | `claude-haiku-4-5` | Model used for LLM-as-judge scoring (set a stronger one like `claude-sonnet-4-6` for more reliable grading) |
|
|
32
|
+
| `EVAL_PASS_BAR` | `0.9` | Fraction of applicable checks that must pass |
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
The model *under test* is whatever `model` is configured in messygit (default
|
|
36
|
+
Haiku) — switch it with `model <name>` to compare models on the same dataset.
|
|
37
|
+
|
|
38
|
+
## How it's built
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
| File | Role |
|
|
42
|
+
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
43
|
+
| `core.py` | The **generic harness**, shared by every eval: `run_eval`, `render`, the `ScoreResult`/`CaseResult` types, and `make_llm_judge`. Knows nothing about any specific eval. |
|
|
44
|
+
| `commit_eval.py` | **One self-contained eval**: the `CommitCase` dataset, the bespoke scorers, `generate()`, the judge rubric, and `main()`. The reference shape to copy. |
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
## Adding a new eval — just write one file
|
|
48
|
+
|
|
49
|
+
Create `evals/<name>_eval.py` with four things and let `core` do the rest:
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
from .core import run_eval, write_report, make_llm_judge, ScoreResult, PASS_BAR
|
|
53
|
+
|
|
54
|
+
CASES = [...] # 1. objects with a `.name`
|
|
55
|
+
def generate(case) -> str: ... # 2. run the thing under test
|
|
56
|
+
SCORERS = [my_scorer, ...] # 3. (case, output) -> ScoreResult
|
|
57
|
+
judge = make_llm_judge(system, render_user) # 4. optional
|
|
58
|
+
|
|
59
|
+
def main():
|
|
60
|
+
results = run_eval(CASES, generate, SCORERS, judge=judge)
|
|
61
|
+
rate = write_report(results, eval_name="<name>") # writes results/<name>/<ts>.md
|
|
62
|
+
return 0 if rate >= PASS_BAR else 1
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
The harness (running cases, catching generation errors, aggregating, the
|
|
66
|
+
scoreboard) is reused as-is. Only the dataset, `generate`, and scorers are
|
|
67
|
+
bespoke — which is inherent: each eval defines its own "what good looks like".
|
|
68
|
+
|
|
69
|
+
## Adapting this to the agentic evals (`suggest` / `changelog`)
|
|
70
|
+
|
|
71
|
+
Same one-file shape; only two things grow:
|
|
72
|
+
|
|
73
|
+
1. **Input/output.** Instead of a diff → subject line, an agentic case is a
|
|
74
|
+
*repo state + task* → the agent's effect (final text, files written, and the
|
|
75
|
+
`TraceStep` list the agent already records on `agent.steps`). Run the agent in
|
|
76
|
+
a throwaway git repo (see how `tests/` build temp repos) so file writes are
|
|
77
|
+
safe to inspect and discard.
|
|
78
|
+
2. **Scorers get richer.** Beyond output-quality scorers, evaluate the *process*
|
|
79
|
+
using the trace:
|
|
80
|
+
- did it call the expected tools (e.g. `changelog` should `git log` a tag
|
|
81
|
+
range and `git show` at least one commit)?
|
|
82
|
+
- did it stay within `max_iterations` / a tool-call budget?
|
|
83
|
+
- did it avoid hallucinated numbers (assert no unverified figures appear) —
|
|
84
|
+
the exact failure the changelog prompt guardrail targets?
|
|
85
|
+
- did the written `CHANGELOG.md` parse, and prepend rather than clobber?
|
|
86
|
+
|
|
87
|
+
Keep deterministic scorers first (cheap, sharp), and reserve the LLM judge for
|
|
88
|
+
the genuinely subjective properties. Make the judge return structured JSON and
|
|
89
|
+
give it a rubric, as `scorers.llm_judge` does.
|
|
90
|
+
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""Model-output evals for messygit.
|
|
2
|
+
|
|
3
|
+
Unlike the unit tests in `tests/` (which simulate the model and run offline),
|
|
4
|
+
evals call the REAL model and score its output. They cost tokens and need an
|
|
5
|
+
ANTHROPIC_API_KEY, so they are NOT part of the `pytest` run — launch them
|
|
6
|
+
explicitly with `python -m evals.commit_eval`.
|
|
7
|
+
|
|
8
|
+
`commit_eval` is the worked reference: a graded dataset, programmatic scorers,
|
|
9
|
+
an LLM-as-judge, and an aggregated scoreboard — the same shape you can reuse to
|
|
10
|
+
evaluate the agentic `suggest`/`changelog` commands.
|
|
11
|
+
"""
|