messygit 0.2.0__tar.gz → 0.2.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 (28) hide show
  1. messygit-0.2.1/.github/workflows/publish.yml +27 -0
  2. messygit-0.2.1/PKG-INFO +146 -0
  3. messygit-0.2.1/README.md +136 -0
  4. {messygit-0.2.0/.claude/worktrees/frosty-montalcini-03d71b → messygit-0.2.1}/pyproject.toml +2 -2
  5. messygit-0.2.0/.claude/worktrees/frosty-montalcini-03d71b/.claude/settings.local.json +0 -7
  6. messygit-0.2.0/.claude/worktrees/frosty-montalcini-03d71b/.git +0 -1
  7. messygit-0.2.0/.claude/worktrees/frosty-montalcini-03d71b/README.md +0 -105
  8. messygit-0.2.0/.claude/worktrees/frosty-montalcini-03d71b/messygit/cli.py +0 -112
  9. messygit-0.2.0/.claude/worktrees/frosty-montalcini-03d71b/messygit/git.py +0 -240
  10. messygit-0.2.0/.claude/worktrees/frosty-montalcini-03d71b/messygit/prompts.py +0 -70
  11. messygit-0.2.0/.gitignore +0 -5
  12. messygit-0.2.0/PKG-INFO +0 -115
  13. messygit-0.2.0/README.md +0 -105
  14. messygit-0.2.0/messygit/__init__.py +0 -0
  15. messygit-0.2.0/messygit/config.py +0 -104
  16. messygit-0.2.0/messygit/llm.py +0 -112
  17. messygit-0.2.0/pyproject.toml +0 -18
  18. {messygit-0.2.0/.claude/worktrees/frosty-montalcini-03d71b → messygit-0.2.1}/.gitignore +0 -0
  19. {messygit-0.2.0 → messygit-0.2.1}/ARCHITECTURE.md +0 -0
  20. {messygit-0.2.0/.claude/worktrees/frosty-montalcini-03d71b → messygit-0.2.1}/messygit/__init__.py +0 -0
  21. {messygit-0.2.0 → messygit-0.2.1}/messygit/agent/agent.py +0 -0
  22. {messygit-0.2.0 → messygit-0.2.1}/messygit/agent/tool.py +0 -0
  23. {messygit-0.2.0 → messygit-0.2.1}/messygit/agent/tools.py +0 -0
  24. {messygit-0.2.0 → messygit-0.2.1}/messygit/cli.py +0 -0
  25. {messygit-0.2.0/.claude/worktrees/frosty-montalcini-03d71b → messygit-0.2.1}/messygit/config.py +0 -0
  26. {messygit-0.2.0 → messygit-0.2.1}/messygit/git.py +0 -0
  27. {messygit-0.2.0/.claude/worktrees/frosty-montalcini-03d71b → messygit-0.2.1}/messygit/llm.py +0 -0
  28. {messygit-0.2.0 → messygit-0.2.1}/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,146 @@
1
+ Metadata-Version: 2.4
2
+ Name: messygit
3
+ Version: 0.2.1
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
+ Description-Content-Type: text/markdown
10
+
11
+ # messygit
12
+
13
+ **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).
14
+
15
+ ## Why use it
16
+
17
+ - **Interactive REPL** — one command drops you into a persistent session where you can stage, commit, push, and more without leaving.
18
+ - **AI commit messages** — sends your staged diff to Claude and suggests a clean Conventional Commits subject line.
19
+ - **Project suggestions** — an AI agent inspects your repo and recommends concrete next steps.
20
+ - **Safe by default** — only the staged diff is sent to the model. Your API key is never printed in full.
21
+
22
+ ## Requirements
23
+
24
+ - **Python** 3.10 or newer
25
+ - **Git** (run inside a repository)
26
+ - An **Anthropic API key** with access to the Messages API
27
+
28
+ ## Installation
29
+
30
+ ```bash
31
+ pip install messygit
32
+ ```
33
+
34
+ ### Install from source
35
+
36
+ ```bash
37
+ cd messygit
38
+ python -m venv .venv
39
+ source .venv/bin/activate # Windows: .venv\Scripts\activate
40
+ pip install -e .
41
+ ```
42
+
43
+ ## API key
44
+
45
+ messygit resolves the key in this order:
46
+
47
+ 1. Environment variable **`ANTHROPIC_API_KEY`**
48
+ 2. Config file **`~/.messygit/config.json`**
49
+
50
+ You can set the key from within the messygit interface:
51
+
52
+ ```
53
+ messygit > config YOUR_ANTHROPIC_API_KEY
54
+ ```
55
+
56
+ ## Usage
57
+
58
+ ```bash
59
+ messygit
60
+ ```
61
+
62
+ This drops you into the interactive interface:
63
+
64
+ ```
65
+ mmm mmm eeeeeee sssssss sssssss yy yy ggggggg ii tttttttt
66
+ mm mm mm m ee ss ss yy yy gg ii tt
67
+ mm mmm m eeeee sssssss sssssss yyy gg ggg ii tt
68
+ mm m ee ss ss yy gg gg ii tt
69
+ mm m eeeeeee sssssss sssssss yy ggggg ii tt
70
+
71
+ Type 'help' for commands, 'quit' to exit.
72
+
73
+ messygit >
74
+ ```
75
+
76
+ ### Commands
77
+
78
+ | Command | Description |
79
+ |---------|-------------|
80
+ | `add <file>` or `add .` | Stage files for commit |
81
+ | `commit` | Generate an AI commit message from staged changes, then commit / cancel / edit |
82
+ | `push` | Push commits to remote |
83
+ | `suggestion` | Get AI-powered next-step suggestions for your project |
84
+ | `config <key>` | Save your Anthropic API key to `~/.messygit/config.json` |
85
+ | `show` | Display a masked API key and its source |
86
+ | `help` | List available commands |
87
+ | `quit` / `exit` | Exit messygit |
88
+
89
+ ### Typical flow
90
+
91
+ ```
92
+ messygit > add .
93
+ Staged everything
94
+
95
+ messygit > commit
96
+ feat(cli): add interactive REPL with ASCII banner
97
+ Commit with this message? [y/n/e] y
98
+
99
+ messygit > push
100
+ ```
101
+
102
+ ### Commit message style
103
+
104
+ The model follows **Conventional Commits**: `type(scope): description`
105
+
106
+ Allowed types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`. Subjects are one line, imperative, lowercase, no trailing period.
107
+
108
+ ## Publishing to PyPI
109
+
110
+ This project uses GitHub Actions with [PyPI trusted publishing](https://docs.pypi.org/trusted-publishers/) — no API tokens needed in your repo.
111
+
112
+ ### One-time setup
113
+
114
+ 1. Go to your project on [pypi.org](https://pypi.org/manage/project/messygit/settings/publishing/)
115
+ 2. Add a **Trusted Publisher**:
116
+ - **Owner:** your GitHub username
117
+ - **Repository:** `messygit`
118
+ - **Workflow name:** `publish.yml`
119
+ - **Environment:** leave blank
120
+
121
+ ### To release a new version
122
+
123
+ 1. Bump `version` in `pyproject.toml`
124
+ 2. Commit and push
125
+ 3. Create a GitHub release:
126
+
127
+ ```bash
128
+ git tag v0.2.0
129
+ git push origin v0.2.0
130
+ ```
131
+
132
+ 4. Go to GitHub → Releases → Draft a new release → select the tag → Publish
133
+
134
+ The workflow at `.github/workflows/publish.yml` will automatically build and upload to PyPI.
135
+
136
+ ### Manual publish (without CI)
137
+
138
+ ```bash
139
+ rm -rf dist/
140
+ python -m build
141
+ twine upload dist/*
142
+ ```
143
+
144
+ ## License
145
+
146
+ MIT (see `pyproject.toml`).
@@ -0,0 +1,136 @@
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
+ - **Safe by default** — only the staged diff is sent to the model. Your API key is never printed in full.
11
+
12
+ ## Requirements
13
+
14
+ - **Python** 3.10 or newer
15
+ - **Git** (run inside a repository)
16
+ - An **Anthropic API key** with access to the Messages API
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ pip install messygit
22
+ ```
23
+
24
+ ### Install from source
25
+
26
+ ```bash
27
+ cd messygit
28
+ python -m venv .venv
29
+ source .venv/bin/activate # Windows: .venv\Scripts\activate
30
+ pip install -e .
31
+ ```
32
+
33
+ ## API key
34
+
35
+ messygit resolves the key in this order:
36
+
37
+ 1. Environment variable **`ANTHROPIC_API_KEY`**
38
+ 2. Config file **`~/.messygit/config.json`**
39
+
40
+ You can set the key from within the messygit interface:
41
+
42
+ ```
43
+ messygit > config YOUR_ANTHROPIC_API_KEY
44
+ ```
45
+
46
+ ## Usage
47
+
48
+ ```bash
49
+ messygit
50
+ ```
51
+
52
+ This drops you into the interactive interface:
53
+
54
+ ```
55
+ mmm mmm eeeeeee sssssss sssssss yy yy ggggggg ii tttttttt
56
+ mm mm mm m ee ss ss yy yy gg ii tt
57
+ mm mmm m eeeee sssssss sssssss yyy gg ggg ii tt
58
+ mm m ee ss ss yy gg gg ii tt
59
+ mm m eeeeeee sssssss sssssss yy ggggg ii tt
60
+
61
+ Type 'help' for commands, 'quit' to exit.
62
+
63
+ messygit >
64
+ ```
65
+
66
+ ### Commands
67
+
68
+ | Command | Description |
69
+ |---------|-------------|
70
+ | `add <file>` or `add .` | Stage files for commit |
71
+ | `commit` | Generate an AI commit message from staged changes, then commit / cancel / edit |
72
+ | `push` | Push commits to remote |
73
+ | `suggestion` | Get AI-powered next-step suggestions for your project |
74
+ | `config <key>` | Save your Anthropic API key to `~/.messygit/config.json` |
75
+ | `show` | Display a masked API key and its source |
76
+ | `help` | List available commands |
77
+ | `quit` / `exit` | Exit messygit |
78
+
79
+ ### Typical flow
80
+
81
+ ```
82
+ messygit > add .
83
+ Staged everything
84
+
85
+ messygit > commit
86
+ feat(cli): add interactive REPL with ASCII banner
87
+ Commit with this message? [y/n/e] y
88
+
89
+ messygit > push
90
+ ```
91
+
92
+ ### Commit message style
93
+
94
+ The model follows **Conventional Commits**: `type(scope): description`
95
+
96
+ Allowed types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`. Subjects are one line, imperative, lowercase, no trailing period.
97
+
98
+ ## Publishing to PyPI
99
+
100
+ This project uses GitHub Actions with [PyPI trusted publishing](https://docs.pypi.org/trusted-publishers/) — no API tokens needed in your repo.
101
+
102
+ ### One-time setup
103
+
104
+ 1. Go to your project on [pypi.org](https://pypi.org/manage/project/messygit/settings/publishing/)
105
+ 2. Add a **Trusted Publisher**:
106
+ - **Owner:** your GitHub username
107
+ - **Repository:** `messygit`
108
+ - **Workflow name:** `publish.yml`
109
+ - **Environment:** leave blank
110
+
111
+ ### To release a new version
112
+
113
+ 1. Bump `version` in `pyproject.toml`
114
+ 2. Commit and push
115
+ 3. Create a GitHub release:
116
+
117
+ ```bash
118
+ git tag v0.2.0
119
+ git push origin v0.2.0
120
+ ```
121
+
122
+ 4. Go to GitHub → Releases → Draft a new release → select the tag → Publish
123
+
124
+ The workflow at `.github/workflows/publish.yml` will automatically build and upload to PyPI.
125
+
126
+ ### Manual publish (without CI)
127
+
128
+ ```bash
129
+ rm -rf dist/
130
+ python -m build
131
+ twine upload dist/*
132
+ ```
133
+
134
+ ## License
135
+
136
+ MIT (see `pyproject.toml`).
@@ -4,8 +4,8 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "messygit"
7
- version = "0.1.4"
8
- description = "CLI that drafts Conventional Commits from staged git diffs with Claude, then commit, cancel, or edit."
7
+ version = "0.2.1"
8
+ description = "An AI-powered interactive git CLI with agentic tools for commits, code suggestions, and workflow automation."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
11
11
  license = "MIT"
@@ -1,7 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "Bash(find /Users/jaydentan/Desktop/projects/messygit -name \"agent.py\" 2>/dev/null)"
5
- ]
6
- }
7
- }
@@ -1 +0,0 @@
1
- gitdir: /Users/jaydentan/Desktop/projects/messygit/.git/worktrees/frosty-montalcini-03d71b
@@ -1,105 +0,0 @@
1
- # messygit
2
-
3
- **messygit** is a command-line tool that reads your **staged** Git changes, asks **Claude** (via the [Anthropic API](https://www.anthropic.com/api)) to suggest a **Conventional Commits** subject line, and then lets you **commit**, **cancel**, or **edit** the message before running `git commit`.
4
-
5
- ## Why use it
6
-
7
- - Keeps commit subjects consistent (`feat(scope): describe the change`) without thinking up wording from scratch.
8
- - Only the **staged** diff is sent to the model—what you `git add` is what gets summarized.
9
- - The API key is never printed in full; `show` uses a masked preview.
10
- - Clear errors for missing keys, rejected keys, and billing or zero-balance situations.
11
-
12
- ## Requirements
13
-
14
- - **Python** 3.10 or newer
15
- - **Git** (run inside a repository)
16
- - An **Anthropic API key** with access to the Messages API
17
-
18
- ## Installation
19
-
20
- ```bash
21
- pip install messygit
22
- ```
23
-
24
- This installs the `messygit` command (see `[project.scripts]` in `pyproject.toml`).
25
-
26
- ### Install from source
27
-
28
- From a checkout of this project:
29
-
30
- ```bash
31
- cd messygit
32
- python -m venv .venv
33
- source .venv/bin/activate # Windows: .venv\Scripts\activate
34
- pip install -e .
35
- ```
36
-
37
- ## API key
38
-
39
- messygit resolves the key in this order:
40
-
41
- 1. Environment variable **`ANTHROPIC_API_KEY`**
42
- 2. Config file **`~/.messygit/config.json`** (written by `messygit config`)
43
-
44
- If neither is set, the default command exits with a short message explaining how to fix it.
45
-
46
- **Save a key to the config file:**
47
-
48
- ```bash
49
- messygit config --key YOUR_ANTHROPIC_API_KEY
50
- ```
51
-
52
- **Show a masked key** (which source is active, without revealing the secret):
53
-
54
- ```bash
55
- messygit show
56
- ```
57
-
58
- ## Usage
59
-
60
- Typical flow:
61
-
62
- ```bash
63
- git add .
64
- messygit
65
- ```
66
-
67
- 1. If there is nothing staged, messygit tells you to run `git add` first.
68
- 2. Otherwise it sends the staged diff to Claude and prints a suggested one-line message.
69
- 3. You are prompted: **commit** (default), **no** (cancel), or **edit** (open `$EDITOR` to change the message).
70
- 4. On confirmation, it runs `git commit -m "..."` with your chosen text.
71
-
72
- ### Commands
73
-
74
- | Command | Description |
75
- |--------|-------------|
76
- | `messygit` | Generate a message from `git diff --staged`, then prompt to commit / cancel / edit. |
77
- | `messygit config --key KEY` | Store the Anthropic API key under `~/.messygit/config.json`. |
78
- | `messygit show` | Print a masked API key and whether it comes from the environment or config file. |
79
-
80
- ### Commit message style
81
-
82
- The model is instructed to follow **Conventional Commits**, for example:
83
-
84
- `feat(auth): validate refresh tokens`
85
-
86
- Allowed types include: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`. Subjects are one line, imperative, lowercase, no trailing period, and kept within a reasonable length (see your prompts in the package if you customize behavior).
87
-
88
- ## Development
89
-
90
- Without installing the package, from the **repository root** (the directory that contains the `messygit` package folder):
91
-
92
- ```bash
93
- .venv/bin/python -m messygit.cli
94
- ```
95
-
96
- Subcommands:
97
-
98
- ```bash
99
- python -m messygit.cli config --key YOUR_KEY
100
- python -m messygit.cli show
101
- ```
102
-
103
- ## License
104
-
105
- MIT (see `pyproject.toml`).
@@ -1,112 +0,0 @@
1
- import os
2
-
3
- import click
4
-
5
- from .config import (
6
- ANTHROPIC_ENV_VAR,
7
- CONFIG_FILE,
8
- AnthropicInsufficientBalanceError,
9
- InvalidAnthropicCredentialsError,
10
- MissingApiKeyError,
11
- load_api_key,
12
- mask_api_key,
13
- save_api_key,
14
- )
15
- from .git import get_staged_diff, git_commit
16
- from .llm import generate_commit_message
17
-
18
- def _prompt_commit_action(message: str) -> None:
19
- """Ask [Y/n/e]: commit, cancel, or edit in $EDITOR."""
20
- current = message
21
- while True:
22
- click.echo(current)
23
- choice = click.prompt(
24
- "Commit with this message? [y/n/e]",
25
- default="Y",
26
- show_default=False,
27
- ).strip().lower()
28
-
29
- if choice in ("", "y", "yes"):
30
- result = git_commit(current)
31
- if result.stdout:
32
- click.echo(result.stdout, nl=False)
33
- if result.stderr:
34
- click.echo(result.stderr, nl=False, err=True)
35
- if result.returncode != 0:
36
- raise click.ClickException("git commit failed.")
37
- return
38
-
39
- if choice in ("n", "no"):
40
- click.echo("Commit cancelled.")
41
- return
42
-
43
- if choice in ("e", "edit"):
44
- edited = click.edit(current)
45
- if edited is None:
46
- click.echo("Editor exited without saving; message unchanged.")
47
- continue
48
- stripped = edited.strip()
49
- if not stripped:
50
- click.echo("Empty message ignored; message unchanged.")
51
- continue
52
- current = stripped
53
- continue
54
-
55
- click.echo("Please answer y (yes), n (no), or e (edit).")
56
-
57
- @click.group(invoke_without_command=True)
58
- @click.pass_context
59
- def main(ctx):
60
- """Messy Git is a tool that analyzes your updated code and generates clean commit messages. Let's keep your "messy" messages in check!"""
61
- if ctx.invoked_subcommand is None:
62
- diff = get_staged_diff()
63
- if not diff.strip():
64
- raise click.ClickException(
65
- "No staged changes found. Run 'git add' first."
66
- )
67
- try:
68
- message = generate_commit_message(diff)
69
- except MissingApiKeyError as e:
70
- raise click.ClickException(str(e)) from e
71
- except InvalidAnthropicCredentialsError as e:
72
- raise click.ClickException(str(e)) from e
73
- except AnthropicInsufficientBalanceError as e:
74
- raise click.ClickException(str(e)) from e
75
- _prompt_commit_action(message)
76
-
77
- @main.command("config")
78
- @click.option("--key", type=str, required=True, help="Anthropic API key")
79
- def config_cmd(key):
80
- """Configure your Anthropic API key."""
81
- try:
82
- save_api_key(key)
83
- except ValueError as e:
84
- raise click.ClickException(str(e)) from e
85
- click.echo(f"API key saved successfully ({mask_api_key(key.strip())})")
86
-
87
- @main.command("show")
88
- def show():
89
- """Display masked API key (env takes precedence over config file)."""
90
- env_set = ANTHROPIC_ENV_VAR in os.environ
91
- env_key = (os.environ.get(ANTHROPIC_ENV_VAR) or "").strip()
92
- if env_key:
93
- click.echo(f"API key: {mask_api_key(env_key)} (from ANTHROPIC_API_KEY)")
94
- return
95
- file_key = load_api_key()
96
- if file_key:
97
- if env_set:
98
- click.echo(
99
- f"{ANTHROPIC_ENV_VAR} is set but empty; showing key from {CONFIG_FILE}."
100
- )
101
- click.echo(f"API key: {mask_api_key(file_key)} (from {CONFIG_FILE})")
102
- return
103
- if env_set:
104
- click.echo(
105
- f"{ANTHROPIC_ENV_VAR} is set but empty or whitespace-only, and no usable key "
106
- f"is stored in {CONFIG_FILE}. Unset the variable or run messygit config --key."
107
- )
108
- return
109
- click.echo("No API key found. Set ANTHROPIC_API_KEY or run messygit config --key.")
110
-
111
- if __name__ == "__main__":
112
- main()