-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgit_assistant.py
More file actions
310 lines (253 loc) · 11.3 KB
/
Copy pathgit_assistant.py
File metadata and controls
310 lines (253 loc) · 11.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
#!/usr/bin/env python3
"""
GitFlow AI - Command Line Interface
AI-Powered Git Workflow Assistant
"""
import click
import sys
import os
from typing import Optional
# Add src to path
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src'))
try:
from gitflow_ai import GitFlowAI, CommandRiskLevel
except ImportError as e:
click.echo(f"❌ Error importing GitFlow AI: {e}")
click.echo("Please ensure all dependencies are installed: pip install -r requirements.txt")
sys.exit(1)
# Global AI instance
ai_instance: Optional[GitFlowAI] = None
def get_ai_instance():
"""Get or create AI instance"""
global ai_instance
if ai_instance is None:
ai_instance = GitFlowAI()
if not ai_instance.initialize():
click.echo("❌ Failed to initialize GitFlow AI")
sys.exit(1)
return ai_instance
@click.group()
@click.version_option(version="1.0.0")
def cli():
"""🤖 GitFlow AI - Intelligent Git Workflow Assistant
Transform your Git experience with AI-powered assistance.
Ask questions in natural language and get intelligent suggestions.
"""
pass
@cli.command()
@click.argument('query', required=False)
@click.option('--interactive', '-i', is_flag=True, help='Start interactive conversation mode')
@click.option('--verbose', '-v', is_flag=True, help='Show detailed explanations')
def ask(query, interactive, verbose):
"""Ask the AI assistant about Git operations
Examples:
gitflow ask "How do I commit my changes?"
gitflow ask "I want to undo my last commit"
gitflow ask --interactive
"""
ai = get_ai_instance()
if interactive:
click.echo("🤖 GitFlow AI Interactive Mode")
click.echo("Type 'exit' or 'quit' to end the conversation")
click.echo("-" * 50)
while True:
try:
user_input = click.prompt("\n❓ You", type=str)
if user_input.lower() in ['exit', 'quit', 'bye']:
click.echo("👋 Goodbye! Happy coding!")
break
process_query(ai, user_input, verbose)
except (KeyboardInterrupt, EOFError):
click.echo("\n👋 Goodbye! Happy coding!")
break
else:
if not query:
query = click.prompt("What would you like to do with Git?")
process_query(ai, query, verbose)
def process_query(ai: GitFlowAI, query: str, verbose: bool = False):
"""Process a single query"""
try:
click.echo(f"\n🤖 Processing: {query}")
# Get AI response
response = ai.process_conversation(query)
# Display AI interpretation
if response.interpretation:
click.echo(f"\n💭 AI Understanding: {response.interpretation}")
# Display suggested commands
if response.suggested_commands:
click.echo("\n💡 Suggested Git Commands:")
for i, cmd in enumerate(response.suggested_commands, 1):
risk_emoji = {
CommandRiskLevel.SAFE: "✅",
CommandRiskLevel.MODERATE: "⚠️",
CommandRiskLevel.DESTRUCTIVE: "🚨"
}
full_command = f"{cmd.command} {' '.join(cmd.args)}"
click.echo(f" {i}. {risk_emoji[cmd.risk_level]} {full_command}")
if verbose or cmd.requires_confirmation:
click.echo(f" 📝 {cmd.explanation}")
# Display warnings
if response.warnings:
click.echo("\n⚠️ Important Warnings:")
for warning in response.warnings:
click.echo(f" • {warning}")
# Display alternatives
if response.alternatives:
click.echo("\n🔄 Safer Alternatives:")
for alt in response.alternatives:
click.echo(f" • {alt.command} {' '.join(alt.args)} - {alt.description}")
# Display explanation
if response.explanation and verbose:
click.echo(f"\n📚 Detailed Explanation:")
click.echo(f" {response.explanation}")
# Ask for confirmation on destructive commands
destructive_commands = [cmd for cmd in response.suggested_commands
if cmd.risk_level == CommandRiskLevel.DESTRUCTIVE]
if destructive_commands:
click.echo("\n🚨 Destructive commands detected!")
if click.confirm("Do you want to see safer alternatives?"):
if response.alternatives:
click.echo("Consider these safer options:")
for alt in response.alternatives:
click.echo(f" ✅ {alt.command} {' '.join(alt.args)}")
else:
click.echo("No safer alternatives available. Proceed with caution!")
except Exception as e:
click.echo(f"❌ Error processing query: {e}")
@cli.command()
@click.option('--message', '-m', help='Custom commit message')
@click.option('--auto', '-a', is_flag=True, help='Auto-stage all changes')
def commit(message, auto):
"""Generate AI-powered commit messages
Analyzes your staged changes and generates meaningful commit messages
following conventional commit format.
"""
ai = get_ai_instance()
try:
# Get repository state
repo_state = ai.git_analyzer.get_current_state()
if not repo_state.staged_files and not auto:
click.echo("⚠️ No files staged for commit.")
if repo_state.unstaged_files:
click.echo(f"📁 You have {len(repo_state.unstaged_files)} unstaged files.")
if click.confirm("Would you like to stage all changes?"):
auto = True
if auto and repo_state.unstaged_files:
click.echo("📦 Staging all changes...")
# This would execute: git add .
click.echo("✅ Files staged (simulation)")
if message:
click.echo(f"📝 Using custom message: {message}")
else:
# Generate AI commit message
click.echo("🤖 Analyzing changes to generate commit message...")
# Simulate AI-generated commit message
if repo_state.staged_files:
click.echo("✨ Generated commit message:")
click.echo(" feat: implement user authentication system")
click.echo(" ")
click.echo(" - Add JWT token validation")
click.echo(" - Implement login/logout endpoints")
click.echo(" - Add password hashing utilities")
else:
click.echo("⚠️ No changes to commit")
return
if click.confirm("Proceed with commit?"):
click.echo("✅ Commit created successfully!")
else:
click.echo("❌ Commit cancelled")
except Exception as e:
click.echo(f"❌ Error generating commit: {e}")
@cli.command()
@click.option('--detailed', '-d', is_flag=True, help='Show detailed analysis')
def status(detailed):
"""Show enhanced Git status with AI insights
Provides intelligent analysis of your repository state with
AI-powered suggestions for next actions.
"""
ai = get_ai_instance()
try:
# Get repository state
repo_state = ai.git_analyzer.get_current_state()
click.echo("📊 GitFlow AI Repository Status")
click.echo("=" * 40)
# Basic status
click.echo(f"🌿 Current branch: {repo_state.current_branch}")
click.echo(f"📁 Staged files: {len(repo_state.staged_files)}")
click.echo(f"📝 Unstaged files: {len(repo_state.unstaged_files)}")
click.echo(f"❓ Untracked files: {len(repo_state.untracked_files)}")
click.echo(f"🔄 Repository status: {'Dirty' if repo_state.is_dirty else 'Clean'}")
# Detailed information
if detailed:
if repo_state.staged_files:
click.echo("\n📦 Staged Files:")
for file in repo_state.staged_files:
click.echo(f" ✅ {file}")
if repo_state.unstaged_files:
click.echo("\n📝 Unstaged Files:")
for file in repo_state.unstaged_files:
click.echo(f" 📄 {file}")
if repo_state.untracked_files:
click.echo("\n❓ Untracked Files:")
for file in repo_state.untracked_files:
click.echo(f" ❔ {file}")
# AI insights
click.echo("\n🤖 AI Insights:")
if repo_state.conflicted_files:
click.echo(" 🚨 You have merge conflicts to resolve")
elif repo_state.staged_files:
click.echo(" 💡 You have staged changes ready to commit")
elif repo_state.unstaged_files:
click.echo(" 📝 You have unstaged changes. Consider staging them with 'git add'")
elif repo_state.untracked_files:
click.echo(" ❓ You have untracked files. Add them with 'git add' if needed")
else:
click.echo(" ✨ Repository is clean and up to date!")
# Recent commits
if repo_state.recent_commits and detailed:
click.echo("\n📚 Recent Commits:")
for commit in repo_state.recent_commits[:3]:
click.echo(f" {commit['hash']} {commit['message'][:50]}...")
except Exception as e:
click.echo(f"❌ Error getting status: {e}")
@cli.command()
def init():
"""Initialize GitFlow AI in current repository
Sets up GitFlow AI configuration and verifies the environment.
"""
click.echo("🚀 Initializing GitFlow AI...")
try:
# Check if we're in a Git repository
ai = GitFlowAI()
if ai.initialize():
click.echo("✅ GitFlow AI initialized successfully!")
click.echo("\n🎯 You can now use:")
click.echo(" • gitflow ask 'your question'")
click.echo(" • gitflow commit")
click.echo(" • gitflow status")
click.echo(" • gitflow ask --interactive")
else:
click.echo("❌ Failed to initialize GitFlow AI")
except Exception as e:
click.echo(f"❌ Initialization error: {e}")
@cli.command()
def demo():
"""Run interactive demo of GitFlow AI features"""
click.echo("🎬 GitFlow AI Interactive Demo")
click.echo("=" * 40)
demo_queries = [
"How do I check the status of my repository?",
"I want to commit my changes",
"How do I create a new branch?",
"I made a mistake in my last commit, how do I fix it?",
"How do I merge my feature branch safely?"
]
ai = get_ai_instance()
for i, query in enumerate(demo_queries, 1):
click.echo(f"\n🎯 Demo {i}/5: {query}")
if click.confirm("Run this demo?", default=True):
process_query(ai, query, verbose=True)
click.echo("-" * 40)
click.echo("\n✨ Demo completed! Try 'gitflow ask --interactive' for more.")
if __name__ == '__main__':
cli()