devgen-cli 0.2.3__tar.gz → 0.2.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.
Files changed (69) hide show
  1. devgen_cli-0.2.5/PKG-INFO +187 -0
  2. devgen_cli-0.2.5/README.md +150 -0
  3. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/devgen/ai.py +11 -2
  4. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/devgen/cli/commit.py +53 -1
  5. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/devgen/cli/config.py +55 -2
  6. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/devgen/cli/main.py +12 -4
  7. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/devgen/cli/setup.py +20 -1
  8. devgen_cli-0.2.5/devgen/modules/changelog_generator.py +155 -0
  9. devgen_cli-0.2.5/devgen/modules/changelog_sections.py +79 -0
  10. devgen_cli-0.2.5/devgen/modules/commit_generator.py +392 -0
  11. devgen_cli-0.2.5/devgen/modules/diff_builder.py +220 -0
  12. devgen_cli-0.2.5/devgen/modules/git_ops.py +144 -0
  13. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/devgen/modules/license_generator.py +1 -3
  14. devgen_cli-0.2.5/devgen/modules/release_note_generator.py +56 -0
  15. devgen_cli-0.2.5/devgen/providers/__init__.py +0 -0
  16. devgen_cli-0.2.5/devgen/providers/anthropic.py +19 -0
  17. devgen_cli-0.2.5/devgen/providers/base.py +90 -0
  18. devgen_cli-0.2.5/devgen/providers/gemini.py +63 -0
  19. devgen_cli-0.2.5/devgen/providers/huggingface.py +54 -0
  20. devgen_cli-0.2.5/devgen/providers/ollama.py +51 -0
  21. devgen_cli-0.2.5/devgen/providers/openai.py +20 -0
  22. devgen_cli-0.2.5/devgen/providers/openrouter.py +25 -0
  23. devgen_cli-0.2.5/devgen/templates/commit/commit_message.tpl +14 -0
  24. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/devgen/utils.py +118 -10
  25. devgen_cli-0.2.5/devgen_cli.egg-info/PKG-INFO +187 -0
  26. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/devgen_cli.egg-info/SOURCES.txt +6 -1
  27. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/devgen_cli.egg-info/requires.txt +1 -1
  28. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/pyproject.toml +2 -2
  29. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/setup.py +1 -1
  30. devgen_cli-0.2.3/PKG-INFO +0 -177
  31. devgen_cli-0.2.3/README.md +0 -140
  32. devgen_cli-0.2.3/devgen/modules/changelog_generator.py +0 -178
  33. devgen_cli-0.2.3/devgen/modules/commit_generator.py +0 -308
  34. devgen_cli-0.2.3/devgen/modules/release_note_generator.py +0 -66
  35. devgen_cli-0.2.3/devgen/providers/__init__.py +0 -24
  36. devgen_cli-0.2.3/devgen/providers/anthropic.py +0 -23
  37. devgen_cli-0.2.3/devgen/providers/gemini.py +0 -24
  38. devgen_cli-0.2.3/devgen/providers/huggingface.py +0 -45
  39. devgen_cli-0.2.3/devgen/providers/openai.py +0 -51
  40. devgen_cli-0.2.3/devgen/providers/openrouter.py +0 -36
  41. devgen_cli-0.2.3/devgen/templates/commit/commit_message.j2 +0 -15
  42. devgen_cli-0.2.3/devgen_cli.egg-info/PKG-INFO +0 -177
  43. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/LICENSE +0 -0
  44. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/MANIFEST.in +0 -0
  45. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/devgen/__init__.py +0 -0
  46. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/devgen/cli/__init__.py +0 -0
  47. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/devgen/cli/changelog.py +0 -0
  48. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/devgen/cli/gitignore.py +0 -0
  49. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/devgen/cli/license.py +0 -0
  50. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/devgen/cli/release.py +0 -0
  51. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/devgen/modules/__init__.py +0 -0
  52. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/devgen/modules/gitignore_generator.py +0 -0
  53. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/devgen/templates/licenses/agpl-3.0.json +0 -0
  54. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/devgen/templates/licenses/apache-2.0.json +0 -0
  55. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/devgen/templates/licenses/bsd-2-clause.json +0 -0
  56. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/devgen/templates/licenses/bsd-3-clause.json +0 -0
  57. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/devgen/templates/licenses/bsl-1.0.json +0 -0
  58. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/devgen/templates/licenses/cc0-1.0.json +0 -0
  59. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/devgen/templates/licenses/epl-2.0.json +0 -0
  60. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/devgen/templates/licenses/gpl-2.0.json +0 -0
  61. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/devgen/templates/licenses/gpl-3.0.json +0 -0
  62. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/devgen/templates/licenses/lgpl-2.1.json +0 -0
  63. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/devgen/templates/licenses/mit.json +0 -0
  64. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/devgen/templates/licenses/mpl-2.0.json +0 -0
  65. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/devgen/templates/licenses/unlicense.json +0 -0
  66. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/devgen_cli.egg-info/dependency_links.txt +0 -0
  67. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/devgen_cli.egg-info/entry_points.txt +0 -0
  68. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/devgen_cli.egg-info/top_level.txt +0 -0
  69. {devgen_cli-0.2.3 → devgen_cli-0.2.5}/setup.cfg +0 -0
@@ -0,0 +1,187 @@
1
+ Metadata-Version: 2.4
2
+ Name: devgen-cli
3
+ Version: 0.2.5
4
+ Summary: A collection of developer tools
5
+ Home-page: https://github.com/S4NKALP/devgen
6
+ Author: Sankalp Tharu
7
+ Author-email: Sankalp Tharu <sankalptharu50028@gmail.com>
8
+ License: GPL-3.0-or-later
9
+ Project-URL: Homepage, https://github.com/S4NKALP/devgen
10
+ Keywords: devgen,cli,git,changelog,gitignore,license,commit-generator,commit
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.7
17
+ Classifier: Programming Language :: Python :: 3.8
18
+ Classifier: Programming Language :: Python :: 3.9
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Requires-Python: >=3.10
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: anthropic>=0.75.0
24
+ Requires-Dist: google-genai>=0.1.0
25
+ Requires-Dist: jinja2>=3.1.6
26
+ Requires-Dist: openai>=2.11.0
27
+ Requires-Dist: pyyaml>=6.0.3
28
+ Requires-Dist: questionary>=2.1.1
29
+ Requires-Dist: requests>=2.32.5
30
+ Requires-Dist: rich>=14.2.0
31
+ Requires-Dist: toml>=0.10.2
32
+ Requires-Dist: typer>=0.20.0
33
+ Dynamic: author
34
+ Dynamic: home-page
35
+ Dynamic: license-file
36
+ Dynamic: requires-python
37
+
38
+ # DevGen
39
+
40
+ <div align="center">
41
+
42
+ **AI-Powered Git & Project Workflows in One CLI**
43
+
44
+ Stop wasting time on repetitive tasks. DevGen automates commits, changelogs, `.gitignore`, and license files using AI — from cloud providers or a local Ollama model.
45
+
46
+ > PyPI didn't allow the original name, so you'll find it as **devgen-cli** on PyPI
47
+
48
+ > <a href="https://pypi.org/project/devgen-cli"><img src="https://img.shields.io/pypi/v/devgen-cli?color=blue&label=PyPI&logo=pypi&logoColor=white" alt="PyPI"></a>
49
+ > <img src="https://img.shields.io/badge/Python-3.10%2B-3776AB?logo=python&logoColor=white" alt="Python">
50
+ > <a href="https://github.com/S4NKALP/DevGen/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-GPL--3.0--or--later-blue.svg" alt="License"></a>
51
+ > <a href="https://github.com/S4NKALP/DevGen/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/S4NKALP/DevGen/ci.yml?branch=main&label=CI" alt="CI"></a>
52
+ > <a href="https://github.com/S4NKALP/DevGen/actions/workflows/pre-commit.yml"><img src="https://img.shields.io/github/actions/workflow/status/S4NKALP/DevGen/pre-commit.yml?branch=main&label=Pre-Commit" alt="Pre-Commit"></a>
53
+
54
+ </div>
55
+
56
+ ## Why DevGen
57
+
58
+ DevGen is a CLI for the parts of development that should be invisible. It writes Conventional Commits from your diff, drafts SemVer changelogs, fetches `.gitignore` and license templates, and routes everything through whichever AI provider you prefer — including a fully local Ollama model if you don't want to send code to the cloud.
59
+
60
+ ## Features
61
+
62
+ - **AI-Powered Commits** — Conventional Commit messages generated from your staged diff, grouped by directory, with optional emoji prefixes.
63
+ - **Multiple Providers** — Google Gemini, OpenAI, Anthropic, OpenRouter, HuggingFace, and local Ollama, all behind one CLI.
64
+ - **Smart Caching** — `.gitignore` and license templates are cached for offline use; AI responses are de-duplicated.
65
+ - **Conventional Changelogs** — `feat`, `fix`, `refactor`, `perf`, `docs`, `test`, `build`, `ci`, `chore`, `style`, and a `BREAKING CHANGES` section.
66
+ - **Project Scaffolding** — Pull `.gitignore` from GitHub's collection and drop in SPDX license files (MIT, Apache-2.0, GPL-3.0, AGPL-3.0, BSD, MPL-2.0, …).
67
+ - **Custom Templates** — Override the commit-message prompt via a `.tpl` file in your config.
68
+ - **Interactive Setup** — `devgen setup` walks you through provider + API key + options.
69
+ - **Undo Support** — `devgen commit undo` rolls back the last AI commit while keeping changes staged.
70
+ - **Token-Limit Aware** — When a diff exceeds a model's context window, you get a single actionable error with `--max-groups` and `--max-diff-size` hints.
71
+
72
+ ## Supported AI Providers
73
+
74
+ | Provider | Notes |
75
+ | ----------------- | ---------------------------------------------------- |
76
+ | **Google Gemini** | Default-friendly, generous free tier |
77
+ | **OpenAI** | GPT-4o, GPT-4.1, o-series |
78
+ | **Anthropic** | Claude 3.5 / 3.7 / 4 |
79
+ | **OpenRouter** | Single key, many models |
80
+ | **HuggingFace** | Inference API |
81
+ | **Ollama** | Fully local, no API key, no data leaves your machine |
82
+
83
+ ## Installation
84
+
85
+ ```bash
86
+ # Recommended: isolated environment
87
+ pipx install devgen-cli
88
+
89
+ # Or use uv for speed
90
+ uv tool install devgen-cli
91
+
92
+ # Or plain pip
93
+ pip install devgen-cli
94
+
95
+ # Shell completion (bash/zsh/fish)
96
+ devgen --install-completion
97
+ ```
98
+
99
+ Requires **Python 3.10 or newer**.
100
+
101
+ ## Quick Start
102
+
103
+ ```bash
104
+ # 1. Configure a provider and API key
105
+ devgen setup config
106
+
107
+ # 2. Stage your work as usual
108
+ git add .
109
+
110
+ # 3. Let DevGen write the commit message
111
+ devgen commit run
112
+
113
+ # 4. Or preview first, then commit
114
+ devgen commit run --dry-run
115
+ devgen commit run --push
116
+ ```
117
+
118
+ ## Commands
119
+
120
+ | Command | Description |
121
+ | ------------------------------- | ----------------------------------------------------------------------------- |
122
+ | `devgen setup config` | Interactive provider / API key / options wizard |
123
+ | `devgen commit run` | Stage, generate message, commit (optionally `--push`, `--check`, `--dry-run`) |
124
+ | `devgen commit undo` | Undo the last AI commit, keep changes staged |
125
+ | `devgen changelog` | Generate a Conventional Commits changelog from recent history |
126
+ | `devgen release-notes` | Generate release notes for a version range |
127
+ | `devgen gitignore list` | List available GitHub `.gitignore` templates |
128
+ | `devgen gitignore add <name> …` | Add `.gitignore` entries to the current project |
129
+ | `devgen license list` | List available SPDX licenses |
130
+ | `devgen license add <spdx>` | Add a LICENSE file to the current project |
131
+
132
+ Run `devgen <command> --help` for full options on any subcommand.
133
+
134
+ ## Custom Templates
135
+
136
+ DevGen uses `.tpl` files for its commit prompt. To override the default, set `custom_template` in your config (see `devgen config info`) and point it at a `.tpl` file with `{{ diff_text }}`, `{{ context }}`, `{{ group_name }}`, and the conditional `{% if use_emoji %}` block.
137
+
138
+ Example minimal template:
139
+
140
+ ```
141
+ {{ diff_text }}
142
+ Summarize the change above in one Conventional Commit line.
143
+ ```
144
+
145
+ ## Architecture
146
+
147
+ DevGen is built around a small set of composable components:
148
+
149
+ - **`BaseProvider`** — abstract base for every AI provider; handles API-key validation, token-limit detection, and error wrapping. Adding a new provider is one subclass with a single `_generate()` method.
150
+ - **`GitOperator`** — all `subprocess` calls to `git` live here, behind a `GitError` exception.
151
+ - **`DiffBuilder` / `FileGrouper` / `ManifestInspector`** — split a staged diff into per-directory groups with compact project context, so the model sees a focused slice instead of a wall of text.
152
+ - **`Section` enum** — single source of truth for changelog ordering and emoji, shared by `ChangelogGenerator` and `ReleaseNotesGenerator`.
153
+
154
+ The CLI entry point is `devgen.cli.main:app` (Typer), exposed as the `devgen` script.
155
+
156
+ ## Development
157
+
158
+ ```bash
159
+ git clone https://github.com/S4NKALP/DevGen.git
160
+ cd DevGen
161
+ uv sync --all-extras --dev # install runtime + dev deps
162
+ uv run pre-commit run --all-files
163
+ uv run devgen --help
164
+ ```
165
+
166
+ The project uses `uv` for dependency management, `ruff` for lint + format, and `pyright` for type checking. CI runs all three on Python 3.10 through 3.13 (see `.github/workflows/ci.yml`).
167
+
168
+ ## Contributing
169
+
170
+ Issues and PRs welcome. Please run `uv run pre-commit run --all-files` before opening a PR so CI stays green.
171
+
172
+ ## License
173
+
174
+ GPL-3.0-or-later. See [LICENSE](LICENSE).
175
+
176
+ ## Acknowledgments
177
+
178
+ Built on the shoulders of:
179
+
180
+ - **Typer** & **Rich** — CLI and terminal UI
181
+ - **Questionary** — interactive prompts
182
+ - **Google Gemini**, **OpenAI**, **Anthropic**, **OpenRouter**, **HuggingFace**, and **Ollama** — AI providers
183
+ - **Ruff** — lint and format
184
+
185
+ <div align="center">
186
+ Made with ❤️ by <a href="https://github.com/S4NKALP">Sankalp</a>
187
+ </div>
@@ -0,0 +1,150 @@
1
+ # DevGen
2
+
3
+ <div align="center">
4
+
5
+ **AI-Powered Git & Project Workflows in One CLI**
6
+
7
+ Stop wasting time on repetitive tasks. DevGen automates commits, changelogs, `.gitignore`, and license files using AI — from cloud providers or a local Ollama model.
8
+
9
+ > PyPI didn't allow the original name, so you'll find it as **devgen-cli** on PyPI
10
+
11
+ > <a href="https://pypi.org/project/devgen-cli"><img src="https://img.shields.io/pypi/v/devgen-cli?color=blue&label=PyPI&logo=pypi&logoColor=white" alt="PyPI"></a>
12
+ > <img src="https://img.shields.io/badge/Python-3.10%2B-3776AB?logo=python&logoColor=white" alt="Python">
13
+ > <a href="https://github.com/S4NKALP/DevGen/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-GPL--3.0--or--later-blue.svg" alt="License"></a>
14
+ > <a href="https://github.com/S4NKALP/DevGen/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/S4NKALP/DevGen/ci.yml?branch=main&label=CI" alt="CI"></a>
15
+ > <a href="https://github.com/S4NKALP/DevGen/actions/workflows/pre-commit.yml"><img src="https://img.shields.io/github/actions/workflow/status/S4NKALP/DevGen/pre-commit.yml?branch=main&label=Pre-Commit" alt="Pre-Commit"></a>
16
+
17
+ </div>
18
+
19
+ ## Why DevGen
20
+
21
+ DevGen is a CLI for the parts of development that should be invisible. It writes Conventional Commits from your diff, drafts SemVer changelogs, fetches `.gitignore` and license templates, and routes everything through whichever AI provider you prefer — including a fully local Ollama model if you don't want to send code to the cloud.
22
+
23
+ ## Features
24
+
25
+ - **AI-Powered Commits** — Conventional Commit messages generated from your staged diff, grouped by directory, with optional emoji prefixes.
26
+ - **Multiple Providers** — Google Gemini, OpenAI, Anthropic, OpenRouter, HuggingFace, and local Ollama, all behind one CLI.
27
+ - **Smart Caching** — `.gitignore` and license templates are cached for offline use; AI responses are de-duplicated.
28
+ - **Conventional Changelogs** — `feat`, `fix`, `refactor`, `perf`, `docs`, `test`, `build`, `ci`, `chore`, `style`, and a `BREAKING CHANGES` section.
29
+ - **Project Scaffolding** — Pull `.gitignore` from GitHub's collection and drop in SPDX license files (MIT, Apache-2.0, GPL-3.0, AGPL-3.0, BSD, MPL-2.0, …).
30
+ - **Custom Templates** — Override the commit-message prompt via a `.tpl` file in your config.
31
+ - **Interactive Setup** — `devgen setup` walks you through provider + API key + options.
32
+ - **Undo Support** — `devgen commit undo` rolls back the last AI commit while keeping changes staged.
33
+ - **Token-Limit Aware** — When a diff exceeds a model's context window, you get a single actionable error with `--max-groups` and `--max-diff-size` hints.
34
+
35
+ ## Supported AI Providers
36
+
37
+ | Provider | Notes |
38
+ | ----------------- | ---------------------------------------------------- |
39
+ | **Google Gemini** | Default-friendly, generous free tier |
40
+ | **OpenAI** | GPT-4o, GPT-4.1, o-series |
41
+ | **Anthropic** | Claude 3.5 / 3.7 / 4 |
42
+ | **OpenRouter** | Single key, many models |
43
+ | **HuggingFace** | Inference API |
44
+ | **Ollama** | Fully local, no API key, no data leaves your machine |
45
+
46
+ ## Installation
47
+
48
+ ```bash
49
+ # Recommended: isolated environment
50
+ pipx install devgen-cli
51
+
52
+ # Or use uv for speed
53
+ uv tool install devgen-cli
54
+
55
+ # Or plain pip
56
+ pip install devgen-cli
57
+
58
+ # Shell completion (bash/zsh/fish)
59
+ devgen --install-completion
60
+ ```
61
+
62
+ Requires **Python 3.10 or newer**.
63
+
64
+ ## Quick Start
65
+
66
+ ```bash
67
+ # 1. Configure a provider and API key
68
+ devgen setup config
69
+
70
+ # 2. Stage your work as usual
71
+ git add .
72
+
73
+ # 3. Let DevGen write the commit message
74
+ devgen commit run
75
+
76
+ # 4. Or preview first, then commit
77
+ devgen commit run --dry-run
78
+ devgen commit run --push
79
+ ```
80
+
81
+ ## Commands
82
+
83
+ | Command | Description |
84
+ | ------------------------------- | ----------------------------------------------------------------------------- |
85
+ | `devgen setup config` | Interactive provider / API key / options wizard |
86
+ | `devgen commit run` | Stage, generate message, commit (optionally `--push`, `--check`, `--dry-run`) |
87
+ | `devgen commit undo` | Undo the last AI commit, keep changes staged |
88
+ | `devgen changelog` | Generate a Conventional Commits changelog from recent history |
89
+ | `devgen release-notes` | Generate release notes for a version range |
90
+ | `devgen gitignore list` | List available GitHub `.gitignore` templates |
91
+ | `devgen gitignore add <name> …` | Add `.gitignore` entries to the current project |
92
+ | `devgen license list` | List available SPDX licenses |
93
+ | `devgen license add <spdx>` | Add a LICENSE file to the current project |
94
+
95
+ Run `devgen <command> --help` for full options on any subcommand.
96
+
97
+ ## Custom Templates
98
+
99
+ DevGen uses `.tpl` files for its commit prompt. To override the default, set `custom_template` in your config (see `devgen config info`) and point it at a `.tpl` file with `{{ diff_text }}`, `{{ context }}`, `{{ group_name }}`, and the conditional `{% if use_emoji %}` block.
100
+
101
+ Example minimal template:
102
+
103
+ ```
104
+ {{ diff_text }}
105
+ Summarize the change above in one Conventional Commit line.
106
+ ```
107
+
108
+ ## Architecture
109
+
110
+ DevGen is built around a small set of composable components:
111
+
112
+ - **`BaseProvider`** — abstract base for every AI provider; handles API-key validation, token-limit detection, and error wrapping. Adding a new provider is one subclass with a single `_generate()` method.
113
+ - **`GitOperator`** — all `subprocess` calls to `git` live here, behind a `GitError` exception.
114
+ - **`DiffBuilder` / `FileGrouper` / `ManifestInspector`** — split a staged diff into per-directory groups with compact project context, so the model sees a focused slice instead of a wall of text.
115
+ - **`Section` enum** — single source of truth for changelog ordering and emoji, shared by `ChangelogGenerator` and `ReleaseNotesGenerator`.
116
+
117
+ The CLI entry point is `devgen.cli.main:app` (Typer), exposed as the `devgen` script.
118
+
119
+ ## Development
120
+
121
+ ```bash
122
+ git clone https://github.com/S4NKALP/DevGen.git
123
+ cd DevGen
124
+ uv sync --all-extras --dev # install runtime + dev deps
125
+ uv run pre-commit run --all-files
126
+ uv run devgen --help
127
+ ```
128
+
129
+ The project uses `uv` for dependency management, `ruff` for lint + format, and `pyright` for type checking. CI runs all three on Python 3.10 through 3.13 (see `.github/workflows/ci.yml`).
130
+
131
+ ## Contributing
132
+
133
+ Issues and PRs welcome. Please run `uv run pre-commit run --all-files` before opening a PR so CI stays green.
134
+
135
+ ## License
136
+
137
+ GPL-3.0-or-later. See [LICENSE](LICENSE).
138
+
139
+ ## Acknowledgments
140
+
141
+ Built on the shoulders of:
142
+
143
+ - **Typer** & **Rich** — CLI and terminal UI
144
+ - **Questionary** — interactive prompts
145
+ - **Google Gemini**, **OpenAI**, **Anthropic**, **OpenRouter**, **HuggingFace**, and **Ollama** — AI providers
146
+ - **Ruff** — lint and format
147
+
148
+ <div align="center">
149
+ Made with ❤️ by <a href="https://github.com/S4NKALP">Sankalp</a>
150
+ </div>
@@ -21,8 +21,17 @@ def generate_with_ai(
21
21
  provider_module = import_module(f"devgen.providers.{provider}")
22
22
  class_name = "".join([x.capitalize() for x in provider.split("_")]) + "Provider"
23
23
  provider_class = getattr(provider_module, class_name)
24
- except (ModuleNotFoundError, AttributeError) as e:
25
- raise ImportError(f"Provider `{provider}` not found or invalid: {e}") from e
24
+ except ModuleNotFoundError as e:
25
+ raise ImportError(
26
+ f"Provider `{provider}` is not a built-in module: {e}. "
27
+ f"Available providers: gemini, openai, anthropic, huggingface, "
28
+ f"openrouter, ollama."
29
+ ) from e
30
+ except AttributeError as e:
31
+ raise ImportError(
32
+ f"Provider `{provider}` exists but does not expose a "
33
+ f"`{class_name}` class. This is a packaging bug."
34
+ ) from e
26
35
 
27
36
  provider_instance = provider_class()
28
37
  return provider_instance.generate(prompt, api_key=api_key, model=model, **kwargs)
@@ -1,5 +1,6 @@
1
1
  from typing import Annotated
2
2
 
3
+ import questionary
3
4
  import typer
4
5
 
5
6
  from devgen.modules.commit_generator import run_commit_engine
@@ -50,12 +51,35 @@ def run_commit(
50
51
  help="Force regeneration of commit messages.",
51
52
  ),
52
53
  ] = False,
54
+ check: Annotated[
55
+ bool,
56
+ typer.Option(
57
+ "--check",
58
+ help="Review/edit commit message before committing.",
59
+ ),
60
+ ] = False,
61
+ max_groups: Annotated[
62
+ int | None,
63
+ typer.Option(
64
+ "--max-groups",
65
+ help="Maximum number of commit groups. Lower this if you hit token-limit errors.",
66
+ ),
67
+ ] = None,
68
+ max_diff_size: Annotated[
69
+ int | None,
70
+ typer.Option(
71
+ "--max-diff-size",
72
+ help="Maximum diff size in chars per group (default 8000). "
73
+ "Lower this if you hit token-limit errors.",
74
+ ),
75
+ ] = None,
53
76
  ) -> None:
54
77
  log_file = get_main_log_path()
55
78
  logger = configure_logger("devgen.cli.commit", log_file, console=debug)
56
79
  logger.info(f"Log file: {log_file}")
57
80
  logger.info(
58
- f"Options: dry_run={dry_run}, push={push}, debug={debug}, force={force_rebuild}"
81
+ f"Options: dry_run={dry_run}, push={push}, debug={debug}, force={force_rebuild}, "
82
+ f"check={check}, max_groups={max_groups}, max_diff_size={max_diff_size}"
59
83
  )
60
84
 
61
85
  run_commit_engine(
@@ -63,7 +87,10 @@ def run_commit(
63
87
  push=push,
64
88
  debug=debug,
65
89
  force_rebuild=force_rebuild,
90
+ check=check,
66
91
  logger=logger,
92
+ max_groups=max_groups,
93
+ max_diff_size=max_diff_size,
67
94
  )
68
95
 
69
96
 
@@ -94,3 +121,28 @@ def validate() -> None:
94
121
  typer.echo(f"- {f}")
95
122
  else:
96
123
  typer.secho("[i] No staged files.", fg=typer.colors.RED)
124
+
125
+
126
+ @app.command("undo")
127
+ def undo_commit() -> None:
128
+ """Undoes the last commit but keeps changes staged."""
129
+ from devgen.utils import run_git_command
130
+
131
+ try:
132
+ # Check if there's at least one commit
133
+ run_git_command(["git", "rev-parse", "HEAD"])
134
+ except Exception:
135
+ typer.secho("No commits found to undo.", fg=typer.colors.RED)
136
+ return
137
+
138
+ if questionary.confirm(
139
+ "Are you sure you want to undo the last commit? (Changes will remain staged)",
140
+ default=False,
141
+ ).ask():
142
+ try:
143
+ run_git_command(["git", "reset", "--soft", "HEAD~1"])
144
+ typer.secho(
145
+ "Last commit undone. Changes are still staged.", fg=typer.colors.GREEN
146
+ )
147
+ except Exception as e:
148
+ typer.secho(f"Failed to undo commit: {e}", fg=typer.colors.RED)
@@ -62,7 +62,14 @@ def edit_config(
62
62
  if key == "provider":
63
63
  value = questionary.select(
64
64
  "Select AI Provider:",
65
- choices=["gemini", "openai", "huggingface", "openrouter", "anthropic"],
65
+ choices=[
66
+ "gemini",
67
+ "openai",
68
+ "huggingface",
69
+ "openrouter",
70
+ "anthropic",
71
+ "ollama",
72
+ ],
66
73
  default=str(current_val) if current_val else "gemini",
67
74
  style=style,
68
75
  ).ask()
@@ -117,7 +124,14 @@ def set_config() -> None:
117
124
  # Questions
118
125
  provider = questionary.select(
119
126
  "Select AI Provider:",
120
- choices=["gemini", "openai", "huggingface", "openrouter", "anthropic"],
127
+ choices=[
128
+ "gemini",
129
+ "openai",
130
+ "huggingface",
131
+ "openrouter",
132
+ "anthropic",
133
+ "ollama",
134
+ ],
121
135
  default=config.get("provider", "gemini"),
122
136
  style=style,
123
137
  ).ask()
@@ -151,12 +165,24 @@ def set_config() -> None:
151
165
  raise typer.Exit(code=130)
152
166
  emoji = emoji_choice == "Yes"
153
167
 
168
+ ollama_host = config.get("ollama_host", "http://localhost:11434")
169
+ if provider == "ollama":
170
+ ollama_host_input = questionary.text(
171
+ "Ollama server URL:",
172
+ default=ollama_host,
173
+ style=style,
174
+ ).ask()
175
+ if ollama_host_input is None:
176
+ raise typer.Exit(code=130)
177
+ ollama_host = ollama_host_input.strip() or ollama_host
178
+
154
179
  # Save Config
155
180
  new_config = {
156
181
  "provider": provider,
157
182
  "model": model,
158
183
  "api_key": api_key,
159
184
  "emoji": emoji,
185
+ "ollama_host": ollama_host,
160
186
  }
161
187
 
162
188
  # Merge with existing config to preserve other keys?
@@ -167,3 +193,30 @@ def set_config() -> None:
167
193
  _save_config(config)
168
194
  typer.secho("\nConfiguration saved.", fg=typer.colors.GREEN)
169
195
  typer.echo(yaml.dump(new_config, default_flow_style=False))
196
+
197
+
198
+ @app.command("info")
199
+ def config_info() -> None:
200
+ """Show information about configuration options and templates."""
201
+ from rich.console import Console
202
+ from rich.table import Table
203
+
204
+ console = Console()
205
+ table = Table(title="Custom Template Variables", box=None)
206
+ table.add_column("Variable", style="cyan")
207
+ table.add_column("Description", style="white")
208
+
209
+ table.add_row("{{ group_name }}", "The folder name being committed (or 'root').")
210
+ table.add_row("{{ diff_text }}", "The git diff of the changes.")
211
+ table.add_row("{{ context }}", "Project context (manifest files content).")
212
+
213
+ console.print(table)
214
+ console.print(
215
+ "\n[bold]Tip:[/bold] If you hardcode emojis in your template, the AI will likely include them regardless of the 'emoji' setting.",
216
+ style="yellow",
217
+ )
218
+ console.print("\n[bold]Example Template:[/bold]")
219
+ console.print(
220
+ "custom_template: |\n [type]: [desc]\n \n Diff: {{ diff_text }}\n",
221
+ style="dim",
222
+ )
@@ -15,7 +15,7 @@ from devgen.cli.setup import app as setup_app
15
15
  app = typer.Typer(
16
16
  name="devgen",
17
17
  help="devgen-py: AI-Powered Git Commit & Release Automation.",
18
- add_completion=False,
18
+ add_completion=True,
19
19
  no_args_is_help=True,
20
20
  rich_markup_mode="markdown",
21
21
  )
@@ -48,13 +48,21 @@ def _version_callback(value: bool) -> None:
48
48
  typer.echo(f"devgen version: {version}")
49
49
  else:
50
50
  typer.secho(
51
- "Error: Version not found in pyproject.toml",
51
+ "Could not determine version: no `project.version` or "
52
+ "`tool.poetry.version` found in pyproject.toml.",
52
53
  fg=typer.colors.RED,
53
54
  err=True,
54
55
  )
55
- except (FileNotFoundError, KeyError, Exception) as e:
56
+ except FileNotFoundError:
56
57
  typer.secho(
57
- f"Error: Could not determine version: {e}",
58
+ f"pyproject.toml not found at {pyproject_path}. "
59
+ "The installation may be corrupt.",
60
+ fg=typer.colors.RED,
61
+ err=True,
62
+ )
63
+ except toml.TomlDecodeError as e:
64
+ typer.secho(
65
+ f"pyproject.toml is not valid TOML: {e}",
58
66
  fg=typer.colors.RED,
59
67
  err=True,
60
68
  )
@@ -33,7 +33,14 @@ def setup_config() -> None:
33
33
  # Questions
34
34
  provider = questionary.select(
35
35
  "Select AI Provider:",
36
- choices=["gemini", "openai", "huggingface", "openrouter", "anthropic"],
36
+ choices=[
37
+ "gemini",
38
+ "openai",
39
+ "huggingface",
40
+ "openrouter",
41
+ "anthropic",
42
+ "ollama",
43
+ ],
37
44
  default=current_config.get("provider", "gemini"),
38
45
  style=style,
39
46
  ).ask()
@@ -67,12 +74,24 @@ def setup_config() -> None:
67
74
  raise typer.Exit(code=130)
68
75
  emoji = emoji_choice == "Yes"
69
76
 
77
+ ollama_host = current_config.get("ollama_host", "http://localhost:11434")
78
+ if provider == "ollama":
79
+ ollama_host_input = questionary.text(
80
+ "Ollama server URL:",
81
+ default=ollama_host,
82
+ style=style,
83
+ ).ask()
84
+ if ollama_host_input is None:
85
+ raise typer.Exit(code=130)
86
+ ollama_host = ollama_host_input.strip() or ollama_host
87
+
70
88
  # Save Config
71
89
  new_config = {
72
90
  "provider": provider,
73
91
  "model": model,
74
92
  "api_key": api_key,
75
93
  "emoji": emoji,
94
+ "ollama_host": ollama_host,
76
95
  }
77
96
 
78
97
  try: