git2report 0.1.0__tar.gz → 0.1.2__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 (37) hide show
  1. {git2report-0.1.0 → git2report-0.1.2}/PKG-INFO +28 -7
  2. {git2report-0.1.0 → git2report-0.1.2}/README.md +27 -6
  3. {git2report-0.1.0 → git2report-0.1.2}/git2report/__init__.py +1 -1
  4. {git2report-0.1.0 → git2report-0.1.2}/git2report/report.py +0 -3
  5. {git2report-0.1.0 → git2report-0.1.2}/git2report/web.py +61 -7
  6. {git2report-0.1.0 → git2report-0.1.2}/git2report.egg-info/PKG-INFO +28 -7
  7. {git2report-0.1.0 → git2report-0.1.2}/pyproject.toml +1 -1
  8. {git2report-0.1.0 → git2report-0.1.2}/LICENSE +0 -0
  9. {git2report-0.1.0 → git2report-0.1.2}/git2report/__main__.py +0 -0
  10. {git2report-0.1.0 → git2report-0.1.2}/git2report/branches.py +0 -0
  11. {git2report-0.1.0 → git2report-0.1.2}/git2report/cache.py +0 -0
  12. {git2report-0.1.0 → git2report-0.1.2}/git2report/charts.py +0 -0
  13. {git2report-0.1.0 → git2report-0.1.2}/git2report/chunker.py +0 -0
  14. {git2report-0.1.0 → git2report-0.1.2}/git2report/cli.py +0 -0
  15. {git2report-0.1.0 → git2report-0.1.2}/git2report/clustering.py +0 -0
  16. {git2report-0.1.0 → git2report-0.1.2}/git2report/config.py +0 -0
  17. {git2report-0.1.0 → git2report-0.1.2}/git2report/eval_tools.py +0 -0
  18. {git2report-0.1.0 → git2report-0.1.2}/git2report/extractor.py +0 -0
  19. {git2report-0.1.0 → git2report-0.1.2}/git2report/filtering.py +0 -0
  20. {git2report-0.1.0 → git2report-0.1.2}/git2report/metrics.py +0 -0
  21. {git2report-0.1.0 → git2report-0.1.2}/git2report/models.py +0 -0
  22. {git2report-0.1.0 → git2report-0.1.2}/git2report/pipeline.py +0 -0
  23. {git2report-0.1.0 → git2report-0.1.2}/git2report/rules.py +0 -0
  24. {git2report-0.1.0 → git2report-0.1.2}/git2report/summarizer.py +0 -0
  25. {git2report-0.1.0 → git2report-0.1.2}/git2report/timeutil.py +0 -0
  26. {git2report-0.1.0 → git2report-0.1.2}/git2report.egg-info/SOURCES.txt +0 -0
  27. {git2report-0.1.0 → git2report-0.1.2}/git2report.egg-info/dependency_links.txt +0 -0
  28. {git2report-0.1.0 → git2report-0.1.2}/git2report.egg-info/entry_points.txt +0 -0
  29. {git2report-0.1.0 → git2report-0.1.2}/git2report.egg-info/requires.txt +0 -0
  30. {git2report-0.1.0 → git2report-0.1.2}/git2report.egg-info/top_level.txt +0 -0
  31. {git2report-0.1.0 → git2report-0.1.2}/setup.cfg +0 -0
  32. {git2report-0.1.0 → git2report-0.1.2}/tests/test_chunker.py +0 -0
  33. {git2report-0.1.0 → git2report-0.1.2}/tests/test_end_to_end.py +0 -0
  34. {git2report-0.1.0 → git2report-0.1.2}/tests/test_eval_tools.py +0 -0
  35. {git2report-0.1.0 → git2report-0.1.2}/tests/test_filter_cluster_metrics.py +0 -0
  36. {git2report-0.1.0 → git2report-0.1.2}/tests/test_rules.py +0 -0
  37. {git2report-0.1.0 → git2report-0.1.2}/tests/test_summarizer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: git2report
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: Turn Git history into a plain-language, evidence-linked progress report with visual charts and Terminal Web Studio.
5
5
  Author-email: Vijay <vijaykd04@users.noreply.github.com>
6
6
  License: MIT
@@ -31,21 +31,42 @@ Dynamic: license-file
31
31
 
32
32
  # Git2Report
33
33
 
34
+ [![PyPI version](https://img.shields.io/pypi/v/git2report.svg)](https://pypi.org/project/git2report/)
35
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
36
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
37
+
34
38
  Turn a Git repository's history into a plain-language weekly progress report, where **every number is
35
- counted by code** and **every line carries commit IDs as proof**. The AI (optional, local) only writes
39
+ counted by code** and **every line carries commit IDs as proof**. The AI (optional, local Ollama or Google Gemini) only writes
36
40
  sentences.
37
41
 
42
+ ---
43
+
44
+ ## ⚡ Quick 1-Command Run (No Cloning Required!)
45
+
46
+ Anyone with Python can install and run Git2Report globally in one command:
47
+
48
+ ```bash
49
+ pip install git2report
50
+ git2report --ui
51
+ # Or if your PATH isn't updated:
52
+ python -m git2report --ui
38
53
  ```
39
- git2report --repo . --since 7d --audience guide --out report.pdf
54
+
55
+ Or run directly without installing using `pipx`:
56
+ ```bash
57
+ pipx run git2report --ui
40
58
  ```
41
59
 
42
- ## Install
60
+ ---
43
61
 
44
- ```
62
+ ## Install for Development
63
+
64
+ ```bash
65
+ git clone https://github.com/vijaykd04/Git2Report.git
66
+ cd Git2Report
45
67
  python -m venv .venv
46
68
  .venv\Scripts\activate # Windows (Linux/macOS: source .venv/bin/activate)
47
- pip install -e ".[dev]" # core + pytest
48
- pip install -e ".[ollama]" # only if you want AI sentences (also install Ollama from ollama.com)
69
+ pip install -e ".[dev]" # includes test suite
49
70
  ```
50
71
 
51
72
  ## Use
@@ -1,20 +1,41 @@
1
1
  # Git2Report
2
2
 
3
+ [![PyPI version](https://img.shields.io/pypi/v/git2report.svg)](https://pypi.org/project/git2report/)
4
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+
3
7
  Turn a Git repository's history into a plain-language weekly progress report, where **every number is
4
- counted by code** and **every line carries commit IDs as proof**. The AI (optional, local) only writes
8
+ counted by code** and **every line carries commit IDs as proof**. The AI (optional, local Ollama or Google Gemini) only writes
5
9
  sentences.
6
10
 
11
+ ---
12
+
13
+ ## ⚡ Quick 1-Command Run (No Cloning Required!)
14
+
15
+ Anyone with Python can install and run Git2Report globally in one command:
16
+
17
+ ```bash
18
+ pip install git2report
19
+ git2report --ui
20
+ # Or if your PATH isn't updated:
21
+ python -m git2report --ui
7
22
  ```
8
- git2report --repo . --since 7d --audience guide --out report.pdf
23
+
24
+ Or run directly without installing using `pipx`:
25
+ ```bash
26
+ pipx run git2report --ui
9
27
  ```
10
28
 
11
- ## Install
29
+ ---
12
30
 
13
- ```
31
+ ## Install for Development
32
+
33
+ ```bash
34
+ git clone https://github.com/vijaykd04/Git2Report.git
35
+ cd Git2Report
14
36
  python -m venv .venv
15
37
  .venv\Scripts\activate # Windows (Linux/macOS: source .venv/bin/activate)
16
- pip install -e ".[dev]" # core + pytest
17
- pip install -e ".[ollama]" # only if you want AI sentences (also install Ollama from ollama.com)
38
+ pip install -e ".[dev]" # includes test suite
18
39
  ```
19
40
 
20
41
  ## Use
@@ -1,2 +1,2 @@
1
1
  """Git2Report: turn Git history into a plain-language, evidence-linked progress report."""
2
- __version__ = "0.1.0"
2
+ __version__ = "0.1.2"
@@ -777,9 +777,6 @@ HTML_TEMPLATE = """\
777
777
  <div class="summary-box">
778
778
  {{ s.text }}
779
779
  </div>
780
- {% if s.note %}
781
- <div style="font-size: 0.8rem; color: var(--warning); margin-bottom: 10px;">⚠️ {{ s.note }}</div>
782
- {% endif %}
783
780
 
784
781
  {% if s.commits %}
785
782
  <table class="commit-table">
@@ -606,7 +606,7 @@ TERMINAL_HTML = """<!DOCTYPE html>
606
606
  <span class="p-user">root</span><span class="p-at">@</span><span class="p-host">git2report</span><span class="p-colon">:</span><span class="p-path">~</span><span class="p-dollar">$</span>
607
607
  </div>
608
608
  <div class="command-display" id="commandPreview">
609
- git2report --repo cloned_repos/CampusThrift --since 2025-01-01 --audience guide --llm gemini --all
609
+ git2report --repo cloned_repos/CampusThrift --since 2025-01-01 --audience guide --all
610
610
  </div>
611
611
  <span class="cursor-blink"></span>
612
612
  </div>
@@ -677,12 +677,24 @@ TERMINAL_HTML = """<!DOCTYPE html>
677
677
  <span class="arg-desc">&lt;gemini | ollama | offline&gt;</span>
678
678
  </label>
679
679
  <select id="llmSelect" class="term-select" onchange="onLlmChange()">
680
- <option value="gemini" selected>gemini (Google Gemini + Smart Cache)</option>
680
+ <option value="offline" selected>offline (Instant / 100% Deterministic / No Keys)</option>
681
681
  <option value="ollama">ollama (Local Private AI / Offline Model)</option>
682
- <option value="offline">offline (Deterministic Heuristic / Zero AI)</option>
682
+ <option value="gemini">gemini (Google Gemini Cloud AI)</option>
683
683
  </select>
684
684
  </div>
685
685
 
686
+ <!-- Gemini API Key Input (Shows only when gemini is selected) -->
687
+ <div class="arg-group" id="apiKeyGroup" style="display: none;">
688
+ <div style="display: flex; justify-content: space-between; align-items: center;">
689
+ <label class="arg-label" for="apiKeyInput">
690
+ <span>--api-key</span>
691
+ <span class="arg-desc">&lt;gemini key&gt;</span>
692
+ </label>
693
+ <span id="apiKeyStatusBadge" style="font-size: 0.68rem; color: var(--text-muted);"></span>
694
+ </div>
695
+ <input type="password" id="apiKeyInput" class="term-input" placeholder="Paste your GEMINI_API_KEY here..." oninput="updateCliPreview()">
696
+ </div>
697
+
686
698
  <!-- Model Selection (Shows for Ollama & Gemini) -->
687
699
  <div class="arg-group" id="modelGroup" style="display: none;">
688
700
  <div style="display: flex; justify-content: space-between; align-items: center;">
@@ -819,6 +831,14 @@ TERMINAL_HTML = """<!DOCTYPE html>
819
831
  }
820
832
  updateCliPreview();
821
833
  checkOllamaStatus();
834
+ try {
835
+ const cfgRes = await fetch('/api/config');
836
+ const cfg = await cfgRes.json();
837
+ if (cfg.has_gemini_key) {
838
+ document.getElementById('apiKeyInput').placeholder = '●●●●●●●● (API key detected on system)';
839
+ document.getElementById('apiKeyStatusBadge').innerHTML = '<span style="color: var(--accent-green);">● KEY ACTIVE</span>';
840
+ }
841
+ } catch (e) {}
822
842
  });
823
843
 
824
844
  async function checkOllamaStatus() {
@@ -852,12 +872,18 @@ TERMINAL_HTML = """<!DOCTYPE html>
852
872
  function onLlmChange() {
853
873
  const llm = document.getElementById('llmSelect').value;
854
874
  const modelGroup = document.getElementById('modelGroup');
875
+ const apiKeyGroup = document.getElementById('apiKeyGroup');
855
876
  if (llm === 'ollama') {
856
877
  modelGroup.style.display = 'flex';
878
+ apiKeyGroup.style.display = 'none';
857
879
  document.getElementById('modelLabelDesc').innerText = '<ollama model, e.g. llama3:8b>';
858
880
  checkOllamaStatus();
881
+ } else if (llm === 'gemini') {
882
+ modelGroup.style.display = 'none';
883
+ apiKeyGroup.style.display = 'flex';
859
884
  } else {
860
885
  modelGroup.style.display = 'none';
886
+ apiKeyGroup.style.display = 'none';
861
887
  }
862
888
  updateCliPreview();
863
889
  }
@@ -882,12 +908,19 @@ TERMINAL_HTML = """<!DOCTYPE html>
882
908
  const audience = document.getElementById('audienceSelect').value;
883
909
  const llm = document.getElementById('llmSelect').value;
884
910
  const model = document.getElementById('modelInput').value.trim();
911
+ const apiKey = document.getElementById('apiKeyInput').value.trim();
885
912
  const next = document.getElementById('nextGoalInput').value.trim();
886
913
 
887
- let cmd = `git2report --repo ${repo} --since ${since} --audience ${audience} --llm ${llm}`;
914
+ let cmd = `git2report --repo ${repo} --since ${since} --audience ${audience}`;
915
+ if (llm !== 'offline') {
916
+ cmd += ` --llm ${llm}`;
917
+ }
888
918
  if (llm === 'ollama' && model) {
889
919
  cmd += ` --model ${model}`;
890
920
  }
921
+ if (llm === 'gemini' && apiKey) {
922
+ cmd += ` --api-key "●●●●"`;
923
+ }
891
924
  if (next) {
892
925
  cmd += ` --next "${next}"`;
893
926
  }
@@ -900,12 +933,12 @@ TERMINAL_HTML = """<!DOCTYPE html>
900
933
  document.getElementById('repoInput').value = 'cloned_repos/CampusThrift';
901
934
  document.getElementById('sinceInput').value = '2025-01-01';
902
935
  document.getElementById('audienceSelect').value = 'guide';
903
- document.getElementById('llmSelect').value = 'gemini';
936
+ document.getElementById('llmSelect').value = 'offline';
904
937
  } else if (type === 'current') {
905
938
  document.getElementById('repoInput').value = '.';
906
939
  document.getElementById('sinceInput').value = '7d';
907
940
  document.getElementById('audienceSelect').value = 'team';
908
- document.getElementById('llmSelect').value = 'gemini';
941
+ document.getElementById('llmSelect').value = 'offline';
909
942
  } else if (type === 'offline') {
910
943
  document.getElementById('llmSelect').value = 'offline';
911
944
  }
@@ -957,6 +990,7 @@ TERMINAL_HTML = """<!DOCTYPE html>
957
990
  const audience = document.getElementById('audienceSelect').value;
958
991
  const llm = document.getElementById('llmSelect').value;
959
992
  const model = document.getElementById('modelInput').value.trim();
993
+ const apiKey = document.getElementById('apiKeyInput').value.trim();
960
994
  const nextGoal = document.getElementById('nextGoalInput').value.trim();
961
995
 
962
996
  const payload = {
@@ -965,6 +999,7 @@ TERMINAL_HTML = """<!DOCTYPE html>
965
999
  audience,
966
1000
  llm,
967
1001
  model: (llm === 'ollama') ? model : '',
1002
+ api_key: (llm === 'gemini') ? apiKey : '',
968
1003
  next_goals: nextGoal ? [nextGoal] : [],
969
1004
  formats: {
970
1005
  pdf: document.getElementById('fmtPdf').checked,
@@ -1060,6 +1095,16 @@ class WebStudioHandler(BaseHTTPRequestHandler):
1060
1095
  self.wfile.write(json.dumps({"online": len(models) > 0, "models": models}).encode("utf-8"))
1061
1096
  return
1062
1097
 
1098
+ if path == "/api/config":
1099
+ from git2report.summarizer import _load_env_file
1100
+ _load_env_file()
1101
+ has_key = bool(os.environ.get("GEMINI_API_KEY") or os.environ.get("GOOGLE_API_KEY"))
1102
+ self.send_response(HTTPStatus.OK)
1103
+ self.send_header("Content-Type", "application/json")
1104
+ self.end_headers()
1105
+ self.wfile.write(json.dumps({"has_gemini_key": has_key}).encode("utf-8"))
1106
+ return
1107
+
1063
1108
  if path == "/api/preview":
1064
1109
  html_path = self.last_generated_files.get("html")
1065
1110
  if html_path and html_path.exists():
@@ -1110,8 +1155,17 @@ class WebStudioHandler(BaseHTTPRequestHandler):
1110
1155
  audience = data.get("audience", "guide")
1111
1156
  llm = data.get("llm", "gemini")
1112
1157
  model = data.get("model", "")
1158
+ user_api_key = data.get("api_key", "").strip()
1113
1159
  planned = data.get("next_goals", [])
1114
1160
 
1161
+ if user_api_key:
1162
+ os.environ["GEMINI_API_KEY"] = user_api_key
1163
+ try:
1164
+ env_file = Path.home() / ".git2report_env"
1165
+ env_file.write_text(f"GEMINI_API_KEY={user_api_key}\n", encoding="utf-8")
1166
+ except Exception:
1167
+ pass
1168
+
1115
1169
  repo_path = Path(repo_str)
1116
1170
  if repo_str.startswith(("http://", "https://", "git@")):
1117
1171
  repo_name = repo_str.rstrip("/").split("/")[-1]
@@ -1135,7 +1189,7 @@ class WebStudioHandler(BaseHTTPRequestHandler):
1135
1189
  )
1136
1190
 
1137
1191
  chosen_model = model or ("gemini-2.5-flash" if llm == "gemini" else ("llama3:8b" if llm == "ollama" else ""))
1138
- summarizer = get_summarizer(llm, chosen_model)
1192
+ summarizer = get_summarizer(llm, chosen_model, api_key=user_api_key or None)
1139
1193
  report_data = run_pipeline(opts, summarizer, log=log_fn)
1140
1194
 
1141
1195
  reports_dir = Path("reports")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: git2report
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: Turn Git history into a plain-language, evidence-linked progress report with visual charts and Terminal Web Studio.
5
5
  Author-email: Vijay <vijaykd04@users.noreply.github.com>
6
6
  License: MIT
@@ -31,21 +31,42 @@ Dynamic: license-file
31
31
 
32
32
  # Git2Report
33
33
 
34
+ [![PyPI version](https://img.shields.io/pypi/v/git2report.svg)](https://pypi.org/project/git2report/)
35
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
36
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
37
+
34
38
  Turn a Git repository's history into a plain-language weekly progress report, where **every number is
35
- counted by code** and **every line carries commit IDs as proof**. The AI (optional, local) only writes
39
+ counted by code** and **every line carries commit IDs as proof**. The AI (optional, local Ollama or Google Gemini) only writes
36
40
  sentences.
37
41
 
42
+ ---
43
+
44
+ ## ⚡ Quick 1-Command Run (No Cloning Required!)
45
+
46
+ Anyone with Python can install and run Git2Report globally in one command:
47
+
48
+ ```bash
49
+ pip install git2report
50
+ git2report --ui
51
+ # Or if your PATH isn't updated:
52
+ python -m git2report --ui
38
53
  ```
39
- git2report --repo . --since 7d --audience guide --out report.pdf
54
+
55
+ Or run directly without installing using `pipx`:
56
+ ```bash
57
+ pipx run git2report --ui
40
58
  ```
41
59
 
42
- ## Install
60
+ ---
43
61
 
44
- ```
62
+ ## Install for Development
63
+
64
+ ```bash
65
+ git clone https://github.com/vijaykd04/Git2Report.git
66
+ cd Git2Report
45
67
  python -m venv .venv
46
68
  .venv\Scripts\activate # Windows (Linux/macOS: source .venv/bin/activate)
47
- pip install -e ".[dev]" # core + pytest
48
- pip install -e ".[ollama]" # only if you want AI sentences (also install Ollama from ollama.com)
69
+ pip install -e ".[dev]" # includes test suite
49
70
  ```
50
71
 
51
72
  ## Use
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "git2report"
7
- version = "0.1.0"
7
+ version = "0.1.2"
8
8
  description = "Turn Git history into a plain-language, evidence-linked progress report with visual charts and Terminal Web Studio."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
File without changes
File without changes
File without changes