git-copilot-commit 0.3.7__tar.gz → 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {git_copilot_commit-0.3.7 → git_copilot_commit-0.4.0}/PKG-INFO +2 -2
- {git_copilot_commit-0.3.7 → git_copilot_commit-0.4.0}/pyproject.toml +1 -1
- {git_copilot_commit-0.3.7 → git_copilot_commit-0.4.0}/src/git_copilot_commit/cli.py +17 -86
- git_copilot_commit-0.4.0/src/git_copilot_commit/github_copilot.py +824 -0
- {git_copilot_commit-0.3.7 → git_copilot_commit-0.4.0}/src/git_copilot_commit/settings.py +1 -1
- git_copilot_commit-0.4.0/uv.lock +205 -0
- git_copilot_commit-0.3.7/uv.lock +0 -1174
- {git_copilot_commit-0.3.7 → git_copilot_commit-0.4.0}/.github/workflows/ci.yml +0 -0
- {git_copilot_commit-0.3.7 → git_copilot_commit-0.4.0}/.gitignore +0 -0
- {git_copilot_commit-0.3.7 → git_copilot_commit-0.4.0}/.justfile +0 -0
- {git_copilot_commit-0.3.7 → git_copilot_commit-0.4.0}/.python-version +0 -0
- {git_copilot_commit-0.3.7 → git_copilot_commit-0.4.0}/LICENSE +0 -0
- {git_copilot_commit-0.3.7 → git_copilot_commit-0.4.0}/README.md +0 -0
- {git_copilot_commit-0.3.7 → git_copilot_commit-0.4.0}/src/git_copilot_commit/__init__.py +0 -0
- {git_copilot_commit-0.3.7 → git_copilot_commit-0.4.0}/src/git_copilot_commit/git.py +0 -0
- {git_copilot_commit-0.3.7 → git_copilot_commit-0.4.0}/src/git_copilot_commit/prompts/commit-message-generator-prompt.md +0 -0
- {git_copilot_commit-0.3.7 → git_copilot_commit-0.4.0}/src/git_copilot_commit/py.typed +0 -0
- {git_copilot_commit-0.3.7 → git_copilot_commit-0.4.0}/src/git_copilot_commit/version.py +0 -0
- {git_copilot_commit-0.3.7 → git_copilot_commit-0.4.0}/vhs/demo.vhs +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: git-copilot-commit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Automatically generate and commit changes using copilot
|
|
5
5
|
Author-email: Dheepak Krishnamurthy <1813121+kdheepak@users.noreply.github.com>
|
|
6
6
|
License-File: LICENSE
|
|
7
7
|
Requires-Python: >=3.12
|
|
8
|
-
Requires-Dist:
|
|
8
|
+
Requires-Dist: httpx>=0.28.0
|
|
9
9
|
Requires-Dist: platformdirs>=4.0.0
|
|
10
10
|
Requires-Dist: rich>=14.0.0
|
|
11
11
|
Requires-Dist: typer>=0.16.0
|
|
@@ -2,18 +2,18 @@
|
|
|
2
2
|
git-copilot-commit - AI-powered Git commit assistant
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
import rich
|
|
6
8
|
import typer
|
|
7
9
|
from rich.console import Console
|
|
8
|
-
from rich.prompt import Confirm
|
|
9
10
|
from rich.panel import Panel
|
|
10
|
-
import
|
|
11
|
-
from pathlib import Path
|
|
11
|
+
from rich.prompt import Confirm
|
|
12
12
|
|
|
13
|
-
from litellm import completion
|
|
14
13
|
from .git import GitRepository, GitError, NotAGitRepositoryError
|
|
15
14
|
from .settings import Settings
|
|
16
15
|
from .version import __version__
|
|
16
|
+
from . import github_copilot
|
|
17
17
|
|
|
18
18
|
console = Console()
|
|
19
19
|
app = typer.Typer(help=__doc__, add_completion=False)
|
|
@@ -84,29 +84,6 @@ def load_system_prompt() -> str:
|
|
|
84
84
|
raise typer.Exit(1)
|
|
85
85
|
|
|
86
86
|
|
|
87
|
-
def ask(prompt, model) -> str:
|
|
88
|
-
response = completion(
|
|
89
|
-
model=model,
|
|
90
|
-
messages=[
|
|
91
|
-
{"role": "system", "content": load_system_prompt()},
|
|
92
|
-
{"role": "user", "content": prompt},
|
|
93
|
-
],
|
|
94
|
-
extra_headers={
|
|
95
|
-
"editor-version": "vscode/1.85.1",
|
|
96
|
-
"Copilot-Integration-Id": "vscode-chat",
|
|
97
|
-
},
|
|
98
|
-
)
|
|
99
|
-
text = response.choices[0].message.content
|
|
100
|
-
text = text.strip()
|
|
101
|
-
# Remove triple backticks if they wrap the entire text
|
|
102
|
-
if text.startswith("```") and text.endswith("```"):
|
|
103
|
-
text = text[3:-3].strip()
|
|
104
|
-
# Otherwise remove single backticks if they wrap the entire text
|
|
105
|
-
elif text.startswith("`") and text.endswith("`"):
|
|
106
|
-
text = text[1:-1].strip()
|
|
107
|
-
return text
|
|
108
|
-
|
|
109
|
-
|
|
110
87
|
def generate_commit_message(
|
|
111
88
|
repo: GitRepository, model: str | None = None, context: str = ""
|
|
112
89
|
) -> str:
|
|
@@ -134,35 +111,12 @@ def generate_commit_message(
|
|
|
134
111
|
prompt = "\n".join(prompt_parts)
|
|
135
112
|
|
|
136
113
|
if model is None:
|
|
137
|
-
model = "
|
|
114
|
+
model = "gpt-5.1-codex"
|
|
138
115
|
|
|
139
|
-
if
|
|
140
|
-
model =
|
|
116
|
+
if model.startswith("github_copilot/"):
|
|
117
|
+
model = model.replace("github_copilot/", "")
|
|
141
118
|
|
|
142
|
-
|
|
143
|
-
return ask(prompt, model=model)
|
|
144
|
-
except Exception as _:
|
|
145
|
-
console.print(
|
|
146
|
-
"Prompt failed, falling back to simpler commit message generation."
|
|
147
|
-
)
|
|
148
|
-
|
|
149
|
-
fallback_prompt_parts = [
|
|
150
|
-
"`git status`:\n",
|
|
151
|
-
f"```\n{status.get_porcelain_output()}\n```",
|
|
152
|
-
]
|
|
153
|
-
|
|
154
|
-
if context.strip():
|
|
155
|
-
fallback_prompt_parts.insert(
|
|
156
|
-
0, f"User-provided context:\n\n{context.strip()}\n\n"
|
|
157
|
-
)
|
|
158
|
-
|
|
159
|
-
fallback_prompt_parts.append(
|
|
160
|
-
"\nGenerate a conventional commit message based on the git status above:"
|
|
161
|
-
)
|
|
162
|
-
|
|
163
|
-
fallback_prompt = "\n".join(fallback_prompt_parts)
|
|
164
|
-
|
|
165
|
-
return ask(fallback_prompt, model=model)
|
|
119
|
+
return github_copilot.ask(prompt, model=model)
|
|
166
120
|
|
|
167
121
|
|
|
168
122
|
def commit_with_retry_no_verify(
|
|
@@ -213,6 +167,14 @@ def commit(
|
|
|
213
167
|
console.print("[red]Error: Not in a git repository[/red]")
|
|
214
168
|
raise typer.Exit(1)
|
|
215
169
|
|
|
170
|
+
try:
|
|
171
|
+
existing_credentials = github_copilot.load_credentials()
|
|
172
|
+
except Exception as _:
|
|
173
|
+
existing_credentials = None
|
|
174
|
+
|
|
175
|
+
if existing_credentials is None:
|
|
176
|
+
github_copilot.login()
|
|
177
|
+
|
|
216
178
|
# Load settings and use default model if none provided
|
|
217
179
|
settings = Settings()
|
|
218
180
|
if model is None:
|
|
@@ -304,36 +266,5 @@ def commit(
|
|
|
304
266
|
console.print(f"[green]✓ Successfully committed: {commit_sha[:8]}[/green]")
|
|
305
267
|
|
|
306
268
|
|
|
307
|
-
@app.command()
|
|
308
|
-
def config(
|
|
309
|
-
set_default_model: str | None = typer.Option(
|
|
310
|
-
None, "--set-default-model", help="Set default model for commit messages"
|
|
311
|
-
),
|
|
312
|
-
show: bool = typer.Option(False, "--show", help="Show current configuration"),
|
|
313
|
-
):
|
|
314
|
-
"""Manage application configuration."""
|
|
315
|
-
settings = Settings()
|
|
316
|
-
|
|
317
|
-
if set_default_model:
|
|
318
|
-
settings.default_model = set_default_model
|
|
319
|
-
console.print(f"[green]✓ Default model set to: {set_default_model}[/green]")
|
|
320
|
-
|
|
321
|
-
if show or (not set_default_model):
|
|
322
|
-
console.print("\n[bold]Current Configuration:[/bold]")
|
|
323
|
-
default_model = settings.default_model
|
|
324
|
-
if default_model:
|
|
325
|
-
console.print(f"Default model: [cyan]{default_model}[/cyan]")
|
|
326
|
-
else:
|
|
327
|
-
console.print("Default model: [dim]not set[/dim]")
|
|
328
|
-
|
|
329
|
-
active_prompt = get_active_prompt_path()
|
|
330
|
-
if active_prompt:
|
|
331
|
-
console.print(f"Active prompt file: [cyan]{active_prompt}[/cyan]")
|
|
332
|
-
else:
|
|
333
|
-
console.print("Active prompt file: [red]not found[/red]")
|
|
334
|
-
|
|
335
|
-
console.print(f"Config file: [dim]{settings.config_file}[/dim]")
|
|
336
|
-
|
|
337
|
-
|
|
338
269
|
if __name__ == "__main__":
|
|
339
270
|
app()
|