gitputra 0.2.2__tar.gz → 0.2.4__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gitputra
3
- Version: 0.2.2
3
+ Version: 0.2.4
4
4
  Summary: AI-powered GitHub repo analyzer CLI — analyze, chat, and visualize any codebase. Run 'gitputra info' to see all commands and features.
5
5
  Author-email: Adityava Gangopadhyay <adityava49cse@gmail.com>
6
6
  License: MIT
@@ -15,19 +15,23 @@ Requires-Dist: chromadb>=1.0
15
15
  Requires-Dist: matplotlib<4.0,>=3.8
16
16
  Requires-Dist: networkx<4.0,>=3.2
17
17
  Requires-Dist: reportlab<5.0,>=4.0
18
- Requires-Dist: google-generativeai<1.0,>=0.5
18
+ Requires-Dist: google-generativeai>=0.5
19
19
  Requires-Dist: openai<2.0,>=1.0
20
- Requires-Dist: anthropic<1.0,>=0.25
21
20
  Requires-Dist: pdfplumber<1.0,>=0.9
21
+ Requires-Dist: rich<14.0,>=13.0
22
22
 
23
23
  # 🔍 GitPutra
24
24
 
25
+ <p align="center">
26
+ <img src="https://github.com/user-attachments/assets/e1385a24-e92a-479b-ba79-742173c0f567" alt="GitPutra Logo" width="200"/>
27
+ </p>
28
+
25
29
  <p align="center">
26
30
  <img src="https://img.shields.io/pypi/v/gitputra?color=blue&label=PyPI&logo=pypi&logoColor=white" alt="PyPI Version">
27
31
  <img src="https://img.shields.io/pypi/pyversions/gitputra?color=blue&logo=python&logoColor=white" alt="Python Versions">
28
32
  <img src="https://img.shields.io/pypi/dm/gitputra?color=green&label=Downloads&logo=pypi&logoColor=white" alt="Downloads">
29
33
  <img src="https://img.shields.io/pypi/l/gitputra?color=yellow" alt="License">
30
- <img src="https://img.shields.io/badge/AI-Gemini%20%7C%20OpenAI%20%7C%20Claude-blueviolet?logo=openai&logoColor=white" alt="AI Providers">
34
+ <img src="https://img.shields.io/badge/AI-Gemini%20%7C%20OpenAI-blueviolet?logo=openai&logoColor=white" alt="AI Providers">
31
35
  </p>
32
36
 
33
37
  <p align="center">
@@ -41,7 +45,7 @@ Requires-Dist: pdfplumber<1.0,>=0.9
41
45
 
42
46
  - 🔍 **Deep Repo Analysis** — AI-generated structured report covering Summary, Architecture, Tech Stack, Issues, and Suggested Improvements
43
47
  - 💬 **RAG Chat** — Ask questions about any codebase using Retrieval-Augmented Generation (ChromaDB + embeddings)
44
- - 🤖 **Multi-AI Support** — Works with Google Gemini, OpenAI, and Anthropic Claude
48
+ - 🤖 **Multi-AI Support** — Works with Google Gemini & OpenAI
45
49
  - 🌿 **Branch Support** — Analyze or chat with any specific branch of a repo
46
50
  - 📊 **Dependency Diagrams** — Auto-generates NetworkX graph diagram + Mermaid flowchart
47
51
  - 📄 **Multilingual PDF Reports** — Exports analysis as a styled PDF in ~110 languages
@@ -80,9 +84,6 @@ With options:
80
84
  # Use OpenAI, output in Bengali, skip diagram
81
85
  gitputra analyze https://github.com/user/repo --ai openai --key YOUR_KEY --lang Bengali --no-diagram
82
86
 
83
- # Use Claude, skip PDF
84
- gitputra analyze https://github.com/user/repo --ai claude --key YOUR_KEY --no-pdf
85
-
86
87
  # Analyze a specific branch
87
88
  gitputra analyze https://github.com/user/repo --branch dev --ai gemini --key YOUR_API_KEY
88
89
  ```
@@ -125,7 +126,7 @@ gitputra chat https://github.com/user/repo --branch feature/my-branch --ai gemin
125
126
 
126
127
  ### Export Codebase Context
127
128
 
128
- Export your entire codebase as a single Markdown file you can paste into any AI tool (Claude, ChatGPT, Gemini…) to continue work without re-explaining the project.
129
+ Export your entire codebase as a single Markdown file you can paste into any AI tool (ChatGPT, Gemini…) to continue work without re-explaining the project.
129
130
 
130
131
  ```bash
131
132
  # Local codebase — fast, no API key needed (no AI summaries)
@@ -133,7 +134,6 @@ gitputra export-context ./my-project
133
134
 
134
135
  # With AI summaries (requires --use-ai and an API key)
135
136
  gitputra export-context ./my-project --use-ai --ai gemini --key YOUR_API_KEY
136
- gitputra export-context ./my-project --use-ai --ai claude --key YOUR_API_KEY
137
137
 
138
138
  # Remote GitHub repo
139
139
  gitputra export-context https://github.com/user/repo --remote --ai gemini --key YOUR_API_KEY
@@ -152,7 +152,7 @@ Output saved to `./output/context_<project_name>_<timestamp>.md`
152
152
 
153
153
  **How to use the exported file:**
154
154
  1. Open the `.md` file
155
- 2. Paste it into any AI chat (Claude, ChatGPT, Gemini…)
155
+ 2. Paste it into any AI chat (ChatGPT, Gemini…)
156
156
  3. Say: *"Here is my codebase context. Read it and help me continue."*
157
157
 
158
158
  ---
@@ -178,9 +178,8 @@ gitputra --version
178
178
  |------|----------|------------|-----------------|
179
179
  | `--ai gemini` | Google Gemini | gemini-2.5-flash | text-embedding-004 |
180
180
  | `--ai openai` | OpenAI | gpt-4o-mini | text-embedding-3-large |
181
- | `--ai claude` | Anthropic Claude | claude-sonnet-4-5 | via `GEMINI_API_KEY` fallback |
182
181
 
183
- > **Note:** Claude has no embedding API. For RAG/chat with `--ai claude`, set `GEMINI_API_KEY` in your `.env` file to enable embeddings.
182
+
184
183
 
185
184
  ### Setting up your API Key
186
185
 
@@ -188,7 +187,6 @@ gitputra --version
188
187
 
189
188
  ```env
190
189
  API_KEY=your_api_key_here
191
- GEMINI_API_KEY=your_gemini_key # only needed for --ai claude with chat/RAG
192
190
  ```
193
191
 
194
192
  **Option 2 — CLI flag:**
@@ -222,7 +220,7 @@ gitputra analyze https://github.com/user/repo --ai gemini --key KEY --lang Benga
222
220
 
223
221
  ---
224
222
 
225
- ## 📁 Supported File Extensions (48 types)
223
+ ## 📁 Supported File Extensions (49 types)
226
224
 
227
225
  | Category | Extensions |
228
226
  |----------|-----------|
@@ -233,7 +231,7 @@ gitputra analyze https://github.com/user/repo --ai gemini --key KEY --lang Benga
233
231
  | Systems | `.go`, `.rs`, `.swift`, `.dart` |
234
232
  | Scripting | `.sh`, `.bat`, `.ps1`, `.pl`, `.lua`, `.r`, `.m`, `.rb`, `.php`, `.coffee`, `.elm` |
235
233
  | Config | `.json`, `.yaml`, `.yml`, `.xml`, `.ini`, `.cfg`, `.conf`, `.gradle`, `.makefile` |
236
- | Docs | `.md`, `.txt`, `.log`, `.sql` |
234
+ | Docs | `.md`, `.txt`, `.log`, `.sql`, `.pdf` |
237
235
  | Special | `Dockerfile`, `Makefile` |
238
236
 
239
237
  ---
@@ -1,11 +1,15 @@
1
1
  # 🔍 GitPutra
2
2
 
3
+ <p align="center">
4
+ <img src="https://github.com/user-attachments/assets/e1385a24-e92a-479b-ba79-742173c0f567" alt="GitPutra Logo" width="200"/>
5
+ </p>
6
+
3
7
  <p align="center">
4
8
  <img src="https://img.shields.io/pypi/v/gitputra?color=blue&label=PyPI&logo=pypi&logoColor=white" alt="PyPI Version">
5
9
  <img src="https://img.shields.io/pypi/pyversions/gitputra?color=blue&logo=python&logoColor=white" alt="Python Versions">
6
10
  <img src="https://img.shields.io/pypi/dm/gitputra?color=green&label=Downloads&logo=pypi&logoColor=white" alt="Downloads">
7
11
  <img src="https://img.shields.io/pypi/l/gitputra?color=yellow" alt="License">
8
- <img src="https://img.shields.io/badge/AI-Gemini%20%7C%20OpenAI%20%7C%20Claude-blueviolet?logo=openai&logoColor=white" alt="AI Providers">
12
+ <img src="https://img.shields.io/badge/AI-Gemini%20%7C%20OpenAI-blueviolet?logo=openai&logoColor=white" alt="AI Providers">
9
13
  </p>
10
14
 
11
15
  <p align="center">
@@ -19,7 +23,7 @@
19
23
 
20
24
  - 🔍 **Deep Repo Analysis** — AI-generated structured report covering Summary, Architecture, Tech Stack, Issues, and Suggested Improvements
21
25
  - 💬 **RAG Chat** — Ask questions about any codebase using Retrieval-Augmented Generation (ChromaDB + embeddings)
22
- - 🤖 **Multi-AI Support** — Works with Google Gemini, OpenAI, and Anthropic Claude
26
+ - 🤖 **Multi-AI Support** — Works with Google Gemini & OpenAI
23
27
  - 🌿 **Branch Support** — Analyze or chat with any specific branch of a repo
24
28
  - 📊 **Dependency Diagrams** — Auto-generates NetworkX graph diagram + Mermaid flowchart
25
29
  - 📄 **Multilingual PDF Reports** — Exports analysis as a styled PDF in ~110 languages
@@ -58,9 +62,6 @@ With options:
58
62
  # Use OpenAI, output in Bengali, skip diagram
59
63
  gitputra analyze https://github.com/user/repo --ai openai --key YOUR_KEY --lang Bengali --no-diagram
60
64
 
61
- # Use Claude, skip PDF
62
- gitputra analyze https://github.com/user/repo --ai claude --key YOUR_KEY --no-pdf
63
-
64
65
  # Analyze a specific branch
65
66
  gitputra analyze https://github.com/user/repo --branch dev --ai gemini --key YOUR_API_KEY
66
67
  ```
@@ -103,7 +104,7 @@ gitputra chat https://github.com/user/repo --branch feature/my-branch --ai gemin
103
104
 
104
105
  ### Export Codebase Context
105
106
 
106
- Export your entire codebase as a single Markdown file you can paste into any AI tool (Claude, ChatGPT, Gemini…) to continue work without re-explaining the project.
107
+ Export your entire codebase as a single Markdown file you can paste into any AI tool (ChatGPT, Gemini…) to continue work without re-explaining the project.
107
108
 
108
109
  ```bash
109
110
  # Local codebase — fast, no API key needed (no AI summaries)
@@ -111,7 +112,6 @@ gitputra export-context ./my-project
111
112
 
112
113
  # With AI summaries (requires --use-ai and an API key)
113
114
  gitputra export-context ./my-project --use-ai --ai gemini --key YOUR_API_KEY
114
- gitputra export-context ./my-project --use-ai --ai claude --key YOUR_API_KEY
115
115
 
116
116
  # Remote GitHub repo
117
117
  gitputra export-context https://github.com/user/repo --remote --ai gemini --key YOUR_API_KEY
@@ -130,7 +130,7 @@ Output saved to `./output/context_<project_name>_<timestamp>.md`
130
130
 
131
131
  **How to use the exported file:**
132
132
  1. Open the `.md` file
133
- 2. Paste it into any AI chat (Claude, ChatGPT, Gemini…)
133
+ 2. Paste it into any AI chat (ChatGPT, Gemini…)
134
134
  3. Say: *"Here is my codebase context. Read it and help me continue."*
135
135
 
136
136
  ---
@@ -156,9 +156,8 @@ gitputra --version
156
156
  |------|----------|------------|-----------------|
157
157
  | `--ai gemini` | Google Gemini | gemini-2.5-flash | text-embedding-004 |
158
158
  | `--ai openai` | OpenAI | gpt-4o-mini | text-embedding-3-large |
159
- | `--ai claude` | Anthropic Claude | claude-sonnet-4-5 | via `GEMINI_API_KEY` fallback |
160
159
 
161
- > **Note:** Claude has no embedding API. For RAG/chat with `--ai claude`, set `GEMINI_API_KEY` in your `.env` file to enable embeddings.
160
+
162
161
 
163
162
  ### Setting up your API Key
164
163
 
@@ -166,7 +165,6 @@ gitputra --version
166
165
 
167
166
  ```env
168
167
  API_KEY=your_api_key_here
169
- GEMINI_API_KEY=your_gemini_key # only needed for --ai claude with chat/RAG
170
168
  ```
171
169
 
172
170
  **Option 2 — CLI flag:**
@@ -200,7 +198,7 @@ gitputra analyze https://github.com/user/repo --ai gemini --key KEY --lang Benga
200
198
 
201
199
  ---
202
200
 
203
- ## 📁 Supported File Extensions (48 types)
201
+ ## 📁 Supported File Extensions (49 types)
204
202
 
205
203
  | Category | Extensions |
206
204
  |----------|-----------|
@@ -211,7 +209,7 @@ gitputra analyze https://github.com/user/repo --ai gemini --key KEY --lang Benga
211
209
  | Systems | `.go`, `.rs`, `.swift`, `.dart` |
212
210
  | Scripting | `.sh`, `.bat`, `.ps1`, `.pl`, `.lua`, `.r`, `.m`, `.rb`, `.php`, `.coffee`, `.elm` |
213
211
  | Config | `.json`, `.yaml`, `.yml`, `.xml`, `.ini`, `.cfg`, `.conf`, `.gradle`, `.makefile` |
214
- | Docs | `.md`, `.txt`, `.log`, `.sql` |
212
+ | Docs | `.md`, `.txt`, `.log`, `.sql`, `.pdf` |
215
213
  | Special | `Dockerfile`, `Makefile` |
216
214
 
217
215
  ---
@@ -2,12 +2,19 @@ import click
2
2
  from dotenv import load_dotenv
3
3
  from . import corelogic as core
4
4
  from . import context_export as ctx
5
+ from rich.console import Console
6
+ from rich.table import Table
7
+ from rich.panel import Panel
8
+ from rich.progress import track
9
+ from rich import print as rprint
10
+
11
+ console = Console()
5
12
 
6
13
  load_dotenv()
7
14
 
8
15
 
9
16
  @click.group()
10
- @click.version_option("0.2.2", prog_name="gitputra")
17
+ @click.version_option("0.2.4", prog_name="gitputra")
11
18
  def main():
12
19
  """🔍 Gitputra — AI-powered GitHub repo analyzer."""
13
20
  pass
@@ -21,7 +28,7 @@ def main():
21
28
  @click.option("--branch", default=None, help="Branch to clone (default: repo default branch). Ignored with --local.")
22
29
  @click.option(
23
30
  "--ai", "ai_choice",
24
- type=click.Choice(["gemini", "openai", "claude"], case_sensitive=False),
31
+ type=click.Choice(["gemini", "openai"], case_sensitive=False),
25
32
  default="gemini", show_default=True,
26
33
  help="AI provider to use."
27
34
  )
@@ -67,27 +74,27 @@ def analyze(url, branch, ai_choice, key, lang, no_pdf, no_diagram, local):
67
74
  repo_path = os.path.abspath(url.strip())
68
75
  repo_name = os.path.basename(repo_path)
69
76
  if not os.path.isdir(repo_path):
70
- click.secho(f"❌ Directory not found: {repo_path}", fg="red")
77
+ console.print(f"❌ Directory not found: {repo_path}", style="bold red")
71
78
  raise SystemExit(1)
72
- click.secho(f"📂 Analyzing local directory: {repo_path}", fg="cyan")
79
+ console.print(f"📂 Analyzing local directory: {repo_path}", style="bold cyan")
73
80
  else:
74
81
  repo_path, repo_name = core.clone_repo(url, branch)
75
82
 
76
83
  files = core.load_files(repo_path)
77
84
 
78
85
  if not files:
79
- click.secho("❌ No supported source files found.", fg="red")
86
+ console.print("❌ No supported source files found.", style="bold red")
80
87
  raise SystemExit(1)
81
88
 
82
89
  collection = core.get_collection(repo_name, branch)
83
90
  if collection.count() == 0:
84
91
  core.store_chunks(files, repo_name, branch)
85
92
  else:
86
- click.secho("ℹ️ Using existing index (run 'clear-db' to re-index).", fg="cyan")
93
+ console.print("ℹ️ Using existing index (run 'clear-db' to re-index).", style="bold cyan")
87
94
 
88
95
  analysis = core.analyze_repo(files)
89
96
 
90
- click.echo("\n" + analysis + "\n")
97
+ console.print(Panel.fit(analysis, title="🔍 Analysis Report", border_style="green"))
91
98
 
92
99
  if not no_diagram:
93
100
  core.generate_diagram(files)
@@ -96,7 +103,7 @@ def analyze(url, branch, ai_choice, key, lang, no_pdf, no_diagram, local):
96
103
  if not no_pdf:
97
104
  core.generate_pdf(analysis)
98
105
 
99
- click.secho("✅ Done! Outputs saved in ./output/", fg="green")
106
+ console.print("✅ Done! Outputs saved in ./output/", style="bold green")
100
107
 
101
108
 
102
109
  # ─────────────────────────────────────────────
@@ -107,7 +114,7 @@ def analyze(url, branch, ai_choice, key, lang, no_pdf, no_diagram, local):
107
114
  @click.option("--branch", default=None, help="Branch to clone (default: repo default branch). Ignored with --local.")
108
115
  @click.option(
109
116
  "--ai", "ai_choice",
110
- type=click.Choice(["gemini", "openai", "claude"], case_sensitive=False),
117
+ type=click.Choice(["gemini", "openai"], case_sensitive=False),
111
118
  default="gemini", show_default=True,
112
119
  )
113
120
  @click.option(
@@ -140,39 +147,39 @@ def chat(url, branch, ai_choice, key, lang, local):
140
147
  repo_path = os.path.abspath(url.strip())
141
148
  repo_name = os.path.basename(repo_path)
142
149
  if not os.path.isdir(repo_path):
143
- click.secho(f"❌ Directory not found: {repo_path}", fg="red")
150
+ console.print(f"❌ Directory not found: {repo_path}", style="bold red")
144
151
  raise SystemExit(1)
145
- click.secho(f"📂 Using local directory: {repo_path}", fg="cyan")
152
+ console.print(f"📂 Using local directory: {repo_path}", style="bold cyan")
146
153
  else:
147
154
  repo_path, repo_name = core.clone_repo(url, branch)
148
155
 
149
156
  collection = core.get_collection(repo_name, branch)
150
157
  if collection.count() == 0:
151
- click.secho("📂 No existing index found — indexing now...", fg="yellow")
158
+ console.print("📂 No existing index found — indexing now...", style="bold yellow")
152
159
  files = core.load_files(repo_path)
153
160
  if not files:
154
- click.secho("❌ No supported source files found.", fg="red")
161
+ console.print("❌ No supported source files found.", style="bold red")
155
162
  raise SystemExit(1)
156
163
  core.store_chunks(files, repo_name, branch)
157
- click.secho("✅ Indexed.", fg="green")
164
+ console.print("✅ Indexed.", style="bold green")
158
165
  else:
159
- click.secho("✅ Using existing index.", fg="cyan")
166
+ console.print("✅ Using existing index.", style="bold cyan")
160
167
 
161
- click.secho(f"\n💬 Chat mode [{repo_name}] — ask anything about the codebase. Type 'exit' to quit.\n", fg="cyan")
168
+ console.print(f"\n💬 Chat mode [{repo_name}] — ask anything about the codebase. Type 'exit' to quit.\n", style="bold cyan")
162
169
 
163
170
  while True:
164
171
  try:
165
- question = click.prompt(">>", prompt_suffix=" ")
172
+ question = console.input("[bold cyan]>> [/]")
166
173
  except (KeyboardInterrupt, EOFError):
167
- click.echo("\nBye!")
174
+ console.print("\n NAMASKAR", style="bold magenta")
168
175
  break
169
176
 
170
177
  if question.strip().lower() in ("exit", "quit", "q"):
171
- click.echo("Bye!")
178
+ console.print("\n NAMASKAR", style="bold magenta")
172
179
  break
173
180
 
174
181
  answer = core.query_rag(question, repo_name, branch)
175
- click.echo(f"\n{answer}\n")
182
+ console.print(Panel(answer, title="🤖 Answer", border_style="blue"))
176
183
 
177
184
 
178
185
  # ─────────────────────────────────────────────
@@ -185,7 +192,7 @@ def chat(url, branch, ai_choice, key, lang, local):
185
192
 
186
193
  @click.option(
187
194
  "--ai", "ai_choice",
188
- type=click.Choice(["gemini", "openai", "claude"], case_sensitive=False),
195
+ type=click.Choice(["gemini", "openai"], case_sensitive=False),
189
196
  default="gemini", show_default=True,
190
197
  help="AI provider to use for summaries."
191
198
  )
@@ -207,7 +214,7 @@ def export_context_cmd(project_path, branch, remote, ai_choice, key, lang, no_ai
207
214
 
208
215
  Scans PROJECT_PATH (defaults to current directory), generates AI summaries
209
216
  of every file, and writes a single Markdown file you can paste into any AI
210
- tool (Claude, ChatGPT, Gemini ...) to continue work without re-explaining
217
+ tool (ChatGPT, Gemini ...) to continue work without re-explaining
211
218
  the project.
212
219
 
213
220
  \b
@@ -219,7 +226,7 @@ def export_context_cmd(project_path, branch, remote, ai_choice, key, lang, no_ai
219
226
  gitputra export-context ./my-project (fast, no key needed)
220
227
  gitputra export-context "C:\\path\\with spaces\\project"
221
228
  gitputra export-context ./my-project --use-ai --ai gemini --key AIza...
222
- gitputra export-context ./my-project --use-ai --ai claude --key sk-ant-...
229
+ gitputra export-context ./my-project --use-ai --ai openai --key sk-ant-...
223
230
  gitputra export-context (scans current dir)
224
231
  """
225
232
  if remote:
@@ -251,7 +258,7 @@ def clear_db():
251
258
  client = chromadb.PersistentClient(path="./chroma_db")
252
259
  for col in client.list_collections():
253
260
  client.delete_collection(col.name)
254
- click.secho("🗑️ ChromaDB cleared.", fg="yellow")
261
+ console.print("🗑️ ChromaDB cleared.", style="bold yellow")
255
262
 
256
263
  # ─────────────────────────────────────────────
257
264
  # INFORMATION
@@ -259,17 +266,32 @@ def clear_db():
259
266
  @main.command()
260
267
  def info():
261
268
  """Show supported AIs, languages, extensions, and commands."""
262
- click.secho("\n 🔍 GitPutra — AI-powered GitHub Repo Analyzer", fg="cyan", bold=True)
263
- click.secho(" 🤖 Chat with your codebase using Gemini, OpenAI or Claude", fg="bright_cyan")
264
- click.secho(" 🏷️ Version: 0.2.2", fg="cyan")
265
- click.secho(" 👨‍💻 Author: Adityava Gangopadhyay", fg="magenta")
266
- click.secho(" 💼 Email: adityava49cse@gmail.com", fg="bright_magenta")
267
- click.secho(" 🔗 LinkedIn: https://www.linkedin.com/in/adityava-gangopadhyay/", fg="blue")
268
- click.secho(" 📦 Project URL: https://pypi.org/project/gitputra/", fg="bright_yellow")
269
+ console.print("\n")
270
+ console.print(" ██████╗ ██╗████████╗██████╗ ██╗ ██╗████████╗██████╗ █████╗ ", style="bold red")
271
+ console.print(" ██╔════╝ ██║╚══██╔══╝██╔══██╗██║ ██║╚══██╔══╝██╔══██╗██╔══██╗", style="bold red")
272
+ console.print(" ██║ ███╗██║ ██║ ██████╔╝██║ ██║ ██║ ██████╔╝███████║", style="bold yellow")
273
+ console.print(" ██║ ██║██║ ██║ ██╔═══╝ ██║ ██║ ██║ ██╔══██╗██╔══██║", style="bold blue")
274
+ console.print(" ╚██████╔╝██║ ██║ ██║ ╚██████╔╝ ██║ ██║ ██║██║ ██║", style="bold blue")
275
+ console.print(" ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝", style="bold yellow")
276
+ console.print("\n ◈ GitPutra — Analyze • Visualize • Synthesize ", style="bold cyan")
277
+
278
+ table = Table(title="📦 GitPutra Info", show_lines=True)
279
+
280
+ table.add_column("Field", style="cyan", no_wrap=True)
281
+ table.add_column("Details", style="yellow")
282
+
283
+ table.add_row("🤖 Description", "[bold magenta]Chat with your codebase using Gemini or OpenAI[/bold magenta]")
284
+ table.add_row("🏷️ Version", "[bold magenta]0.2.4[/bold magenta]")
285
+ table.add_row("👨‍💻 Author", "[bold bright_blue]Adityava Gangopadhyay[/bold bright_blue]")
286
+ table.add_row("💼 Email", "[bold bright_blue]adityava49cse@gmail.com[/bold bright_blue]")
287
+ table.add_row("🔗 LinkedIn", "[bold #FFA500]https://www.linkedin.com/in/adityava-gangopadhyay/[/bold #FFA500]")
288
+ table.add_row("📦 Project URL", "[bold #FFA500]https://pypi.org/project/gitputra/[/bold #FFA500]")
289
+
290
+ console.print(table)
269
291
 
270
- click.secho(" 💬 Special Message-> Feel free to contact for any suggestion or issues\n", fg="bright_blue")
292
+ console.print(" 💬 Special Message-> Feel free to contact for any suggestion or issues\n", style="bold blue")
271
293
 
272
- click.secho("📦 Commands:", fg="yellow", bold=True)
294
+ console.print("📦 Commands:", style="bold yellow")
273
295
  commands = [
274
296
  ("analyze <url>", "Clone & analyze a remote GitHub repo"),
275
297
  ("analyze <path> --local","Analyze a local codebase (no cloning)"),
@@ -282,21 +304,37 @@ def info():
282
304
  ("info", "Show this info screen"),
283
305
 
284
306
  ]
307
+ table = Table(title="📦 Commands")
308
+
309
+ table.add_column("Command", style="cyan", no_wrap=True)
310
+ table.add_column("Description", style="white")
311
+
285
312
  for cmd, desc in commands:
286
- click.echo(f" {'gitputra ' + cmd:<40} {desc}")
313
+ table.add_row(f"gitputra {cmd}", desc)
314
+
315
+ console.print(table)
287
316
 
288
- click.secho("\n🤖 Supported AI Providers:", fg="yellow", bold=True)
317
+ console.print("\n🤖 Supported AI Providers:", style="bold yellow")
289
318
  ais = [
290
- ("gemini", "Google Gemini 2.5 Flash", "text-embedding-004"),
319
+ ("gemini", "Google Gemini 2.5 Flash", "gemini-embedding-001"),
291
320
  ("openai", "OpenAI GPT-4o Mini", "text-embedding-3-large"),
292
- ("claude", "Anthropic Claude Sonnet 4.5", "via GEMINI_API_KEY fallback"),
293
321
  ]
322
+ ai_table = Table(title="🤖 Supported AI Providers")
323
+
324
+ ai_table.add_column("Flag", style="cyan")
325
+ ai_table.add_column("Model", style="green")
326
+ ai_table.add_column("Embedding", style="magenta")
327
+
294
328
  for flag, model, embed in ais:
295
- click.echo(f" --ai {flag:<10} model: {model:<35} embed: {embed}")
329
+ ai_table.add_row(flag, model, embed)
330
+
331
+ console.print(ai_table)
296
332
 
297
- click.secho("\n🌍 PDF Output Languages (~110 supported):", fg="yellow", bold=True)
333
+ table = Table(title="🌍 PDF Output Languages (~110 supported)", show_lines=True)
334
+
335
+ table.add_column("Script", style="bold cyan", no_wrap=True)
336
+ table.add_column("Languages", style="white")
298
337
 
299
- click.secho(" Latin script:", fg="white", bold=True)
300
338
  latin = [
301
339
  "English", "French", "Spanish", "Portuguese", "Italian", "German",
302
340
  "Dutch", "Swedish", "Norwegian", "Danish", "Finnish", "Polish",
@@ -309,38 +347,27 @@ def info():
309
347
  "Icelandic", "Faroese", "Vietnamese", "Hawaiian", "Maori",
310
348
  "Tok Pisin", "Tswana", "Shona", "Sesotho",
311
349
  ]
312
- row = []
313
- for i, lang in enumerate(latin):
314
- row.append(f"{lang:<22}")
315
- if (i + 1) % 4 == 0:
316
- click.echo(" " + "".join(row))
317
- row = []
318
- if row:
319
- click.echo(" " + "".join(row))
320
-
321
- click.secho(" Bengali script:", fg="white", bold=True)
350
+
322
351
  bengali = ["Bengali", "Assamese"]
323
- click.echo(" " + " | ".join(bengali))
324
352
 
325
- click.secho(" Devanagari script:", fg="white", bold=True)
326
353
  devanagari = ["Hindi", "Marathi", "Nepali", "Sanskrit", "Maithili", "Konkani", "Bodo", "Dogri"]
327
- click.echo(" " + " | ".join(devanagari))
328
-
329
- click.echo()
330
- click.echo(" (AI response language depends on the chosen model's capability)")
331
-
332
- click.secho(f"\n📁 Supported File Extensions ({len(core.SUPPORTED_EXT)} types):", fg="yellow", bold=True)
333
- exts = sorted(core.SUPPORTED_EXT)
334
- row = []
335
- for i, ext in enumerate(exts):
336
- row.append(f"{ext:<12}")
337
- if (i + 1) % 8 == 0:
338
- click.echo(" " + "".join(row))
339
- row = []
340
- if row:
341
- click.echo(" " + "".join(row))
342
-
343
- click.secho("\n📂 Supported Special Files:", fg="yellow", bold=True)
344
- click.echo(" " + " | ".join(core.SUPPORTED_NAMES))
354
+
355
+ # Join nicely instead of manual spacing gymnastics
356
+ table.add_row("Latin script", ", ".join(latin))
357
+ table.add_row("Bengali script", " | ".join(bengali))
358
+ table.add_row("Devanagari script", " | ".join(devanagari))
359
+
360
+ console.print(table)
361
+
362
+ console.print("\n(AI response language depends on the chosen model's capability)", style="dim")
363
+
364
+ ext_table = Table(title=f"📁 Supported File Extensions ({len(core.SUPPORTED_EXT)} types)")
365
+ ext_table.add_column("Extensions", style="cyan", overflow="fold")
366
+ exts = sorted(core.SUPPORTED_EXT)
367
+ chunk_size = 10
368
+ for i in range(0, len(exts), chunk_size):
369
+ ext_table.add_row(", ".join(exts[i:i+chunk_size]))
370
+
371
+ console.print(ext_table)
345
372
 
346
373
  click.echo()
@@ -1,25 +1,18 @@
1
- """
2
- context_export.py — GitPutra Context Export
3
- ────────────────────────────────────────────
4
- Scans a local codebase and produces a single portable Markdown file
5
- that captures the full project context. Paste it into any AI tool
6
- (Claude, ChatGPT, Gemini, etc.) to continue work without re-explaining.
7
-
8
- Usage (standalone):
9
- gitputra --export-context /path/to/project --ai gemini --key YOUR_KEY
10
-
11
- Output:
12
- ./output/context_<project_name>_<timestamp>.md
13
- """
14
-
15
1
  import os
16
2
  import json
17
3
  import datetime
4
+ from rich.console import Console
5
+ from rich.table import Table
6
+ from rich.panel import Panel
7
+ from rich.progress import track
8
+ from rich import print as rprint
9
+
10
+ console = Console()
18
11
 
19
12
  # ── Re-use the same extension filter as corelogic.py ──────────────────────────
20
13
  SUPPORTED_EXT = (
21
- ".py", ".c", ".h", ".cpp", ".js", ".ts", ".md", ".txt",
22
- ".java", ".go", ".rs", ".php", ".rb", ".swift",
14
+ ".py", ".c", ".h", ".cpp", ".js", ".ts", ".md", ".pdf",
15
+ ".txt", ".java", ".go", ".rs", ".php", ".rb", ".swift",
23
16
  ".cs", ".html", ".css", ".json", ".yaml", ".yml", ".xml",
24
17
  ".sh", ".bat", ".ps1", ".gradle", ".makefile",
25
18
  ".ini", ".cfg", ".conf", ".log", ".sql", ".ipynb",
@@ -88,12 +81,12 @@ def scan_project(root: str) -> list[dict]:
88
81
  "size_bytes": os.path.getsize(abs_path),
89
82
  "content": content,
90
83
  })
91
- except Exception:
92
- pass
84
+ except Exception as e:
85
+ console.log(f"⚠️ Error reading {abs_path}: {e}")
93
86
 
94
87
  # Stable, deterministic order
95
88
  results.sort(key=lambda f: f["path"])
96
- print(f"📂 Found {len(results)} source files in '{os.path.basename(root)}'")
89
+ console.log(f"📂 Found {len(results)} source files in '{os.path.basename(root)}'")
97
90
  return results
98
91
 
99
92
 
@@ -139,7 +132,7 @@ _TECH_HINTS = {
139
132
  ".rs": "Rust",
140
133
  ".java": "Java",
141
134
  ".cpp": "C++",
142
- ".c": "C",
135
+ ".c": "C",
143
136
  ".cs": "C#",
144
137
  ".rb": "Ruby",
145
138
  ".php": "PHP",
@@ -280,7 +273,7 @@ def assemble_markdown(
280
273
  f"| **Files:** {len(files)} | **Root:** `{root}`\n\n",
281
274
  "---\n\n",
282
275
  "<!-- HOW TO USE THIS FILE\n"
283
- "Paste this entire file into any AI chat (Claude, ChatGPT, Gemini …)\n"
276
+ "Paste this entire file into any AI chat (ChatGPT, Gemini …)\n"
284
277
  "and say: 'I am sharing my codebase context. Read it and help me continue.'\n"
285
278
  "-->\n\n",
286
279
  ]
@@ -384,16 +377,15 @@ def export_context(
384
377
 
385
378
  # 2. Tech stack (heuristic, instant)
386
379
  tech = detect_tech_stack(files)
387
- print(f"🔍 Languages: {', '.join(tech['languages']) or 'none detected'}")
380
+ console.log(f"🔍 Languages: {', '.join(tech['languages']) or 'none detected'}")
388
381
 
389
382
  # 3. Per-file AI summaries
390
383
  file_summaries: list[dict] = []
391
384
  if skip_ai:
392
- print("⚡ --no-ai: skipping LLM summaries")
385
+ console.log("⚡ --no-ai: skipping LLM summaries")
393
386
  else:
394
387
  total = len(files)
395
- for i, f in enumerate(files, 1):
396
- print(f" 📝 Summarising [{i}/{total}] {f['path']}")
388
+ for f in track(files, description="🧠 Summarizing files..."):
397
389
  summary = _summarise_file(f["path"], f["content"], language, safe_generate_fn)
398
390
  file_summaries.append({
399
391
  "path": f["path"],
@@ -402,7 +394,7 @@ def export_context(
402
394
  })
403
395
 
404
396
  # 4. Project-level synthesis
405
- print("🧩 Synthesising project overview...")
397
+ console.log("🧩 Synthesising project overview...")
406
398
  if skip_ai or not file_summaries:
407
399
  project_summary = (
408
400
  f"*AI summaries were skipped (`--no-ai`). "
@@ -433,11 +425,11 @@ def export_context(
433
425
  fh.write(md)
434
426
 
435
427
  size_kb = os.path.getsize(out_path) / 1024
436
- print(f"\n✅ Context exported → {out_path} ({size_kb:.1f} KB)")
437
- print(
428
+ console.log(f"\n✅ Context exported → {out_path} ({size_kb:.1f} KB)")
429
+ console.log(
438
430
  "\n💡 How to use:\n"
439
431
  " 1. Open the .md file\n"
440
- " 2. Paste it into any AI chat (Claude, ChatGPT, Gemini …)\n"
432
+ " 2. Paste it into any AI chat (ChatGPT, Gemini …)\n"
441
433
  ' 3. Say: "Here is my codebase context. Read it and help me continue."\n'
442
434
  )
443
435