gitview 0.1.0__tar.gz → 0.1.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 (32) hide show
  1. {gitview-0.1.0/gitview.egg-info → gitview-0.1.1}/PKG-INFO +1 -1
  2. {gitview-0.1.0 → gitview-0.1.1}/gitview/cli.py +240 -49
  3. {gitview-0.1.0 → gitview-0.1.1}/gitview/writer.py +4 -4
  4. {gitview-0.1.0 → gitview-0.1.1/gitview.egg-info}/PKG-INFO +1 -1
  5. {gitview-0.1.0 → gitview-0.1.1}/pyproject.toml +1 -1
  6. {gitview-0.1.0 → gitview-0.1.1}/setup.py +1 -1
  7. {gitview-0.1.0 → gitview-0.1.1}/INSTALL.md +0 -0
  8. {gitview-0.1.0 → gitview-0.1.1}/LICENSE +0 -0
  9. {gitview-0.1.0 → gitview-0.1.1}/MANIFEST.in +0 -0
  10. {gitview-0.1.0 → gitview-0.1.1}/README.md +0 -0
  11. {gitview-0.1.0 → gitview-0.1.1}/bin/gitview +0 -0
  12. {gitview-0.1.0 → gitview-0.1.1}/examples/basic_usage.py +0 -0
  13. {gitview-0.1.0 → gitview-0.1.1}/gitview/__init__.py +0 -0
  14. {gitview-0.1.0 → gitview-0.1.1}/gitview/backends/__init__.py +0 -0
  15. {gitview-0.1.0 → gitview-0.1.1}/gitview/backends/anthropic_backend.py +0 -0
  16. {gitview-0.1.0 → gitview-0.1.1}/gitview/backends/base.py +0 -0
  17. {gitview-0.1.0 → gitview-0.1.1}/gitview/backends/ollama_backend.py +0 -0
  18. {gitview-0.1.0 → gitview-0.1.1}/gitview/backends/openai_backend.py +0 -0
  19. {gitview-0.1.0 → gitview-0.1.1}/gitview/backends/router.py +0 -0
  20. {gitview-0.1.0 → gitview-0.1.1}/gitview/chunker.py +0 -0
  21. {gitview-0.1.0 → gitview-0.1.1}/gitview/extractor.py +0 -0
  22. {gitview-0.1.0 → gitview-0.1.1}/gitview/storyteller.py +0 -0
  23. {gitview-0.1.0 → gitview-0.1.1}/gitview/summarizer.py +0 -0
  24. {gitview-0.1.0 → gitview-0.1.1}/gitview.egg-info/SOURCES.txt +0 -0
  25. {gitview-0.1.0 → gitview-0.1.1}/gitview.egg-info/dependency_links.txt +0 -0
  26. {gitview-0.1.0 → gitview-0.1.1}/gitview.egg-info/entry_points.txt +0 -0
  27. {gitview-0.1.0 → gitview-0.1.1}/gitview.egg-info/not-zip-safe +0 -0
  28. {gitview-0.1.0 → gitview-0.1.1}/gitview.egg-info/requires.txt +0 -0
  29. {gitview-0.1.0 → gitview-0.1.1}/gitview.egg-info/top_level.txt +0 -0
  30. {gitview-0.1.0 → gitview-0.1.1}/requirements.txt +0 -0
  31. {gitview-0.1.0 → gitview-0.1.1}/setup.cfg +0 -0
  32. {gitview-0.1.0 → gitview-0.1.1}/verify_installation.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gitview
3
- Version: 0.1.0
3
+ Version: 0.1.1
4
4
  Summary: Git history analyzer with LLM-powered narrative generation
5
5
  Home-page: https://github.com/carstenbund/gitview
6
6
  Author: GitView Contributors
@@ -23,27 +23,142 @@ console = Console()
23
23
  def cli():
24
24
  """GitView - Git history analyzer with LLM-powered narrative generation.
25
25
 
26
- Extract, analyze, and generate compelling narratives from your git repository's history.
26
+ \b
27
+ Extract, chunk, and use LLMs to generate compelling narratives from your
28
+ git repository's history.
29
+
30
+ \b
31
+ Quick Start:
32
+ # Using Anthropic Claude (default)
33
+ export ANTHROPIC_API_KEY="your-key"
34
+ gitview analyze
35
+
36
+ # Using OpenAI GPT
37
+ export OPENAI_API_KEY="your-key"
38
+ gitview analyze --backend openai
39
+
40
+ # Using local Ollama (no API key needed)
41
+ gitview analyze --backend ollama --model llama3
42
+
43
+ \b
44
+ See 'gitview analyze --help' for detailed LLM configuration options.
27
45
  """
28
46
  pass
29
47
 
30
48
 
31
- @cli.command()
32
- @click.option('--repo', '-r', default=".", help="Path to git repository")
33
- @click.option('--output', '-o', default="output", help="Output directory")
49
+ ANALYZE_HELP = """Analyze git repository and generate narrative history.
50
+
51
+ \b
52
+ This command runs the full pipeline:
53
+ 1. Extract git history with detailed metadata
54
+ 2. Chunk commits into meaningful phases/epochs
55
+ 3. Summarize each phase using LLM
56
+ 4. Generate global narrative stories
57
+ 5. Write markdown reports and JSON data
58
+
59
+ \b
60
+ LLM BACKEND CONFIGURATION:
61
+
62
+ GitView supports three LLM backends:
63
+
64
+ \b
65
+ 1. Anthropic Claude (default, requires API key):
66
+ export ANTHROPIC_API_KEY="your-key"
67
+ gitview analyze
68
+
69
+ Or: gitview analyze --backend anthropic --api-key "your-key"
70
+
71
+ Default model: claude-sonnet-4-5-20250929
72
+ Other models: claude-3-opus-20240229, claude-3-haiku-20240307
73
+
74
+ \b
75
+ 2. OpenAI GPT (requires API key):
76
+ export OPENAI_API_KEY="your-key"
77
+ gitview analyze --backend openai
78
+
79
+ Default model: gpt-4
80
+ Other models: gpt-4-turbo-preview, gpt-3.5-turbo
81
+
82
+ \b
83
+ 3. Ollama (local, FREE, no API key needed):
84
+ # Start Ollama server first: ollama serve
85
+ # Pull a model: ollama pull llama3
86
+ gitview analyze --backend ollama --model llama3
87
+
88
+ Popular models: llama3, mistral, codellama, mixtral
89
+ Default URL: http://localhost:11434
90
+
91
+ \b
92
+ Backend auto-detection:
93
+ If no --backend is specified, GitView checks environment variables:
94
+ - If ANTHROPIC_API_KEY is set → uses Anthropic
95
+ - If OPENAI_API_KEY is set → uses OpenAI
96
+ - Otherwise → uses Ollama (local)
97
+
98
+ \b
99
+ EXAMPLES:
100
+
101
+ # Analyze current directory with Claude (auto-detected)
102
+ export ANTHROPIC_API_KEY="sk-ant-..."
103
+ gitview analyze
104
+
105
+ # Use OpenAI GPT-4 with custom model
106
+ gitview analyze --backend openai --model gpt-4-turbo-preview
107
+
108
+ # Use local Ollama (no API costs!)
109
+ gitview analyze --backend ollama --model llama3
110
+
111
+ # Analyze specific repository
112
+ gitview analyze --repo /path/to/repo --output ./analysis
113
+
114
+ # Quick analysis without LLM (just extract and chunk)
115
+ gitview analyze --skip-llm
116
+
117
+ # Analyze last 100 commits only
118
+ gitview analyze --max-commits 100
119
+
120
+ # Adaptive chunking (default, splits on significant changes)
121
+ gitview analyze --strategy adaptive
122
+
123
+ # Fixed-size chunks (50 commits per phase)
124
+ gitview analyze --strategy fixed --chunk-size 50
125
+
126
+ # Use custom Ollama server
127
+ gitview analyze --backend ollama --ollama-url http://192.168.1.100:11434
128
+ """
129
+
130
+
131
+ @cli.command(help=ANALYZE_HELP)
132
+ @click.option('--repo', '-r', default=".",
133
+ help="Path to git repository (default: current directory)")
134
+ @click.option('--output', '-o', default="output",
135
+ help="Output directory for reports and data")
34
136
  @click.option('--strategy', '-s', type=click.Choice(['fixed', 'time', 'adaptive']),
35
- default='adaptive', help="Chunking strategy")
137
+ default='adaptive',
138
+ help="Chunking strategy: 'adaptive' (default, splits on significant changes), "
139
+ "'fixed' (N commits per phase), 'time' (by time period)")
36
140
  @click.option('--chunk-size', type=int, default=50,
37
- help="Chunk size for fixed strategy")
38
- @click.option('--max-commits', type=int, help="Maximum commits to analyze")
39
- @click.option('--branch', default='HEAD', help="Branch to analyze")
141
+ help="Commits per chunk when using 'fixed' strategy")
142
+ @click.option('--max-commits', type=int,
143
+ help="Maximum commits to analyze (default: all commits)")
144
+ @click.option('--branch', default='HEAD',
145
+ help="Branch to analyze (default: HEAD/current branch)")
40
146
  @click.option('--backend', '-b', type=click.Choice(['anthropic', 'openai', 'ollama']),
41
- help="LLM backend (auto-detected from environment if not specified)")
42
- @click.option('--model', '-m', help="Model identifier (uses backend defaults if not specified)")
43
- @click.option('--api-key', help="API key for the backend (defaults to env var)")
44
- @click.option('--ollama-url', default='http://localhost:11434', help="Ollama API URL")
45
- @click.option('--repo-name', help="Repository name for output")
46
- @click.option('--skip-llm', is_flag=True, help="Skip LLM summarization (extract and chunk only)")
147
+ help="LLM backend: 'anthropic' (Claude), 'openai' (GPT), 'ollama' (local). "
148
+ "Auto-detected from env vars if not specified.")
149
+ @click.option('--model', '-m',
150
+ help="Model identifier. Defaults: claude-sonnet-4-5-20250929 (Anthropic), "
151
+ "gpt-4 (OpenAI), llama3 (Ollama)")
152
+ @click.option('--api-key',
153
+ help="API key for Anthropic/OpenAI. Defaults to ANTHROPIC_API_KEY or "
154
+ "OPENAI_API_KEY environment variable")
155
+ @click.option('--ollama-url', default='http://localhost:11434',
156
+ help="Ollama server URL (only for --backend ollama)")
157
+ @click.option('--repo-name',
158
+ help="Repository name for output (default: directory name)")
159
+ @click.option('--skip-llm', is_flag=True,
160
+ help="Skip LLM summarization - only extract and chunk history "
161
+ "(useful for quick analysis without API costs)")
47
162
  def analyze(repo, output, strategy, chunk_size, max_commits, branch, backend,
48
163
  model, api_key, ollama_url, repo_name, skip_llm):
49
164
  """Analyze git repository and generate narrative history.
@@ -94,7 +209,7 @@ def analyze(repo, output, strategy, chunk_size, max_commits, branch, backend,
94
209
  records = extractor.extract_history(max_commits=max_commits, branch=branch)
95
210
  progress.update(task, completed=True)
96
211
 
97
- console.print(f"[green]Extracted {len(records)} commits[/green]\n")
212
+ console.print(f"[green]Extracted {len(records)} commits[/green]\n")
98
213
 
99
214
  # Save raw history
100
215
  history_file = Path(output) / "repo_history.jsonl"
@@ -109,7 +224,7 @@ def analyze(repo, output, strategy, chunk_size, max_commits, branch, backend,
109
224
  kwargs['chunk_size'] = chunk_size
110
225
 
111
226
  phases = chunker.chunk(records, **kwargs)
112
- console.print(f"[green]Created {len(phases)} phases[/green]\n")
227
+ console.print(f"[green]Created {len(phases)} phases[/green]\n")
113
228
 
114
229
  # Display phase overview
115
230
  _display_phase_overview(phases)
@@ -122,7 +237,7 @@ def analyze(repo, output, strategy, chunk_size, max_commits, branch, backend,
122
237
  console.print("\n[yellow]Skipping LLM summarization. Writing basic timeline...[/yellow]")
123
238
  timeline_file = Path(output) / "timeline.md"
124
239
  OutputWriter.write_simple_timeline(phases, str(timeline_file))
125
- console.print(f"[green]Wrote timeline to {timeline_file}[/green]\n")
240
+ console.print(f"[green]Wrote timeline to {timeline_file}[/green]\n")
126
241
  return
127
242
 
128
243
  # Step 3: Summarize phases with LLM
@@ -158,7 +273,7 @@ def analyze(repo, output, strategy, chunk_size, max_commits, branch, backend,
158
273
  summarizer._save_phase_with_summary(phase, str(phases_dir))
159
274
  progress.update(task, advance=1)
160
275
 
161
- console.print(f"[green]Summarized all phases[/green]\n")
276
+ console.print(f"[green]Summarized all phases[/green]\n")
162
277
 
163
278
  # Step 4: Generate global story
164
279
  console.print("[bold]Step 4: Generating global narrative...[/bold]")
@@ -178,7 +293,7 @@ def analyze(repo, output, strategy, chunk_size, max_commits, branch, backend,
178
293
  stories = storyteller.generate_global_story(phases, repo_name)
179
294
  progress.update(task, completed=True)
180
295
 
181
- console.print(f"[green]Generated global narrative[/green]\n")
296
+ console.print(f"[green]Generated global narrative[/green]\n")
182
297
 
183
298
  # Step 5: Write output
184
299
  console.print("[bold]Step 5: Writing output files...[/bold]")
@@ -187,22 +302,22 @@ def analyze(repo, output, strategy, chunk_size, max_commits, branch, backend,
187
302
  # Write markdown report
188
303
  markdown_path = output_path / "history_story.md"
189
304
  OutputWriter.write_markdown(stories, phases, str(markdown_path), repo_name)
190
- console.print(f"[green]Wrote {markdown_path}[/green]")
305
+ console.print(f"[green]Wrote {markdown_path}[/green]")
191
306
 
192
307
  # Write JSON data
193
308
  json_path = output_path / "history_data.json"
194
309
  OutputWriter.write_json(stories, phases, str(json_path))
195
- console.print(f"[green]Wrote {json_path}[/green]")
310
+ console.print(f"[green]Wrote {json_path}[/green]")
196
311
 
197
312
  # Write timeline
198
313
  timeline_path = output_path / "timeline.md"
199
314
  OutputWriter.write_simple_timeline(phases, str(timeline_path))
200
- console.print(f"[green]Wrote {timeline_path}[/green]\n")
315
+ console.print(f"[green]Wrote {timeline_path}[/green]\n")
201
316
 
202
317
  # Success summary
203
- console.print("[bold green]Analysis complete![/bold green]\n")
204
- console.print(f"📊 Analyzed {len(records)} commits across {len(phases)} phases")
205
- console.print(f"📝 Output written to: {output_path.resolve()}\n")
318
+ console.print("[bold green]Analysis complete![/bold green]\n")
319
+ console.print(f"Analyzed {len(records)} commits across {len(phases)} phases")
320
+ console.print(f"Output written to: {output_path.resolve()}\n")
206
321
 
207
322
  except Exception as e:
208
323
  console.print(f"\n[red]Error: {e}[/red]")
@@ -211,17 +326,54 @@ def analyze(repo, output, strategy, chunk_size, max_commits, branch, backend,
211
326
  sys.exit(1)
212
327
 
213
328
 
214
- @cli.command()
215
- @click.option('--repo', '-r', default=".", help="Path to git repository")
329
+ EXTRACT_HELP = """Extract git history to JSONL file (no LLM needed).
330
+
331
+ \b
332
+ This command extracts detailed metadata from git commits without using an LLM.
333
+ Useful for:
334
+ - Quick history extraction
335
+ - Pre-processing for later analysis
336
+ - Exploring repository metrics
337
+
338
+ \b
339
+ Extracted data includes:
340
+ - Commit metadata (hash, author, date, message)
341
+ - Lines of code changes (insertions/deletions)
342
+ - Language breakdown per commit
343
+ - README evolution
344
+ - Comment density analysis
345
+ - Detection of large changes and refactors
346
+
347
+ \b
348
+ EXAMPLES:
349
+
350
+ # Extract full history to default location
351
+ gitview extract
352
+
353
+ # Extract to custom file
354
+ gitview extract --output my_history.jsonl
355
+
356
+ # Extract only last 100 commits
357
+ gitview extract --max-commits 100
358
+
359
+ # Extract from specific branch
360
+ gitview extract --branch develop
361
+
362
+ # Extract from different repository
363
+ gitview extract --repo /path/to/repo --output repo_data.jsonl
364
+ """
365
+
366
+
367
+ @cli.command(help=EXTRACT_HELP)
368
+ @click.option('--repo', '-r', default=".",
369
+ help="Path to git repository (default: current directory)")
216
370
  @click.option('--output', '-o', default="output/repo_history.jsonl",
217
- help="Output JSONL file")
218
- @click.option('--max-commits', type=int, help="Maximum commits to extract")
219
- @click.option('--branch', default='HEAD', help="Branch to extract from")
371
+ help="Output JSONL file path")
372
+ @click.option('--max-commits', type=int,
373
+ help="Maximum commits to extract (default: all commits)")
374
+ @click.option('--branch', default='HEAD',
375
+ help="Branch to extract from (default: HEAD/current branch)")
220
376
  def extract(repo, output, max_commits, branch):
221
- """Extract git history to JSONL file.
222
-
223
- This command only extracts the git history without chunking or summarization.
224
- """
225
377
  console.print("\n[bold blue]Extracting Git History[/bold blue]\n")
226
378
 
227
379
  repo_path = Path(repo).resolve()
@@ -243,24 +395,63 @@ def extract(repo, output, max_commits, branch):
243
395
 
244
396
  extractor.save_to_jsonl(records, output)
245
397
 
246
- console.print(f"\n[green]Extracted {len(records)} commits to {output}[/green]\n")
398
+ console.print(f"\n[green]Extracted {len(records)} commits to {output}[/green]\n")
247
399
 
248
400
  except Exception as e:
249
401
  console.print(f"\n[red]Error: {e}[/red]")
250
402
  sys.exit(1)
251
403
 
252
404
 
253
- @cli.command()
405
+ CHUNK_HELP = """Chunk extracted history into meaningful phases (no LLM needed).
406
+
407
+ \b
408
+ Takes a JSONL file from 'gitview extract' and splits it into phases/epochs
409
+ based on the chosen strategy. No LLM or API key required.
410
+
411
+ \b
412
+ CHUNKING STRATEGIES:
413
+
414
+ 1. Adaptive (recommended):
415
+ Automatically splits when significant changes occur:
416
+ - LOC changes by >30%
417
+ - Large deletions or additions (>1000 lines)
418
+ - README rewrites
419
+ - Major refactorings
420
+
421
+ 2. Fixed:
422
+ Split into fixed-size chunks (e.g., 50 commits per phase)
423
+
424
+ 3. Time:
425
+ Split by time periods (week, month, quarter, year)
426
+
427
+ \b
428
+ EXAMPLES:
429
+
430
+ # Chunk with adaptive strategy (recommended)
431
+ gitview chunk repo_history.jsonl
432
+
433
+ # Chunk with fixed size (25 commits per phase)
434
+ gitview chunk repo_history.jsonl --strategy fixed --chunk-size 25
435
+
436
+ # Save phases to custom directory
437
+ gitview chunk repo_history.jsonl --output ./my_phases
438
+
439
+ # First extract, then chunk separately
440
+ gitview extract --output data.jsonl
441
+ gitview chunk data.jsonl --output phases/
442
+ """
443
+
444
+
445
+ @cli.command(help=CHUNK_HELP)
254
446
  @click.argument('history_file', type=click.Path(exists=True))
255
- @click.option('--output', '-o', default="output/phases", help="Output directory for phases")
447
+ @click.option('--output', '-o', default="output/phases",
448
+ help="Output directory for phase JSON files")
256
449
  @click.option('--strategy', '-s', type=click.Choice(['fixed', 'time', 'adaptive']),
257
- default='adaptive', help="Chunking strategy")
258
- @click.option('--chunk-size', type=int, default=50, help="Chunk size for fixed strategy")
450
+ default='adaptive',
451
+ help="Chunking strategy: 'adaptive' (default), 'fixed', 'time'")
452
+ @click.option('--chunk-size', type=int, default=50,
453
+ help="Commits per chunk when using 'fixed' strategy")
259
454
  def chunk(history_file, output, strategy, chunk_size):
260
- """Chunk extracted history into phases.
261
-
262
- Takes a JSONL file from the extract command and chunks it into phases.
263
- """
264
455
  console.print("\n[bold blue]Chunking History into Phases[/bold blue]\n")
265
456
 
266
457
  try:
@@ -279,12 +470,12 @@ def chunk(history_file, output, strategy, chunk_size):
279
470
 
280
471
  phases = chunker.chunk(records, **kwargs)
281
472
 
282
- console.print(f"[green]Created {len(phases)} phases[/green]\n")
473
+ console.print(f"[green]Created {len(phases)} phases[/green]\n")
283
474
  _display_phase_overview(phases)
284
475
 
285
476
  # Save
286
477
  chunker.save_phases(phases, output)
287
- console.print(f"\n[green]Saved phases to {output}[/green]\n")
478
+ console.print(f"\n[green]Saved phases to {output}[/green]\n")
288
479
 
289
480
  except Exception as e:
290
481
  console.print(f"\n[red]Error: {e}[/red]")
@@ -304,13 +495,13 @@ def _display_phase_overview(phases):
304
495
  for phase in phases:
305
496
  events = []
306
497
  if phase.has_large_deletion:
307
- events.append("🗑️")
498
+ events.append("x")
308
499
  if phase.has_large_addition:
309
- events.append("")
500
+ events.append("+")
310
501
  if phase.has_refactor:
311
- events.append("♻️")
502
+ events.append(">>")
312
503
  if phase.readme_changed:
313
- events.append("📝")
504
+ events.append(">")
314
505
 
315
506
  table.add_row(
316
507
  str(phase.phase_number),
@@ -90,13 +90,13 @@ class OutputWriter:
90
90
  # Events
91
91
  events = []
92
92
  if phase.has_large_deletion:
93
- events.append("🗑️ Large Deletion")
93
+ events.append("Large Deletion")
94
94
  if phase.has_large_addition:
95
- events.append("Large Addition")
95
+ events.append("Large Addition")
96
96
  if phase.has_refactor:
97
- events.append("♻️ Refactoring")
97
+ events.append("Refactoring")
98
98
  if phase.readme_changed:
99
- events.append("📝 README Changed")
99
+ events.append("README Changed")
100
100
 
101
101
  if events:
102
102
  f.write(f"**Events:** {' | '.join(events)}\n\n")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gitview
3
- Version: 0.1.0
3
+ Version: 0.1.1
4
4
  Summary: Git history analyzer with LLM-powered narrative generation
5
5
  Home-page: https://github.com/carstenbund/gitview
6
6
  Author: GitView Contributors
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "gitview"
7
- version = "0.1.0"
7
+ version = "0.1.1"
8
8
  description = "Git history analyzer with LLM-powered narrative generation"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
@@ -13,7 +13,7 @@ with open("requirements.txt", "r", encoding="utf-8") as fh:
13
13
 
14
14
  setup(
15
15
  name="gitview",
16
- version="0.1.0",
16
+ version="0.1.1",
17
17
  author="GitView Contributors",
18
18
  author_email="", # Add if publishing
19
19
  description="Git history analyzer with LLM-powered narrative generation",
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes