gitglimpse 0.1.1__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.
- {gitglimpse-0.1.1 → gitglimpse-0.1.2}/PKG-INFO +1 -1
- {gitglimpse-0.1.1 → gitglimpse-0.1.2}/pyproject.toml +1 -1
- gitglimpse-0.1.2/src/gitglimpse/__init__.py +1 -0
- {gitglimpse-0.1.1 → gitglimpse-0.1.2}/src/gitglimpse/cli.py +14 -10
- {gitglimpse-0.1.1 → gitglimpse-0.1.2}/src/gitglimpse/formatters/template.py +26 -20
- gitglimpse-0.1.1/src/gitglimpse/__init__.py +0 -1
- {gitglimpse-0.1.1 → gitglimpse-0.1.2}/.gitignore +0 -0
- {gitglimpse-0.1.1 → gitglimpse-0.1.2}/LICENSE +0 -0
- {gitglimpse-0.1.1 → gitglimpse-0.1.2}/src/gitglimpse/commands/__init__.py +0 -0
- {gitglimpse-0.1.1 → gitglimpse-0.1.2}/src/gitglimpse/commands/report.md +0 -0
- {gitglimpse-0.1.1 → gitglimpse-0.1.2}/src/gitglimpse/commands/standup.md +0 -0
- {gitglimpse-0.1.1 → gitglimpse-0.1.2}/src/gitglimpse/commands/week.md +0 -0
- {gitglimpse-0.1.1 → gitglimpse-0.1.2}/src/gitglimpse/config.py +0 -0
- {gitglimpse-0.1.1 → gitglimpse-0.1.2}/src/gitglimpse/estimation.py +0 -0
- {gitglimpse-0.1.1 → gitglimpse-0.1.2}/src/gitglimpse/formatters/__init__.py +0 -0
- {gitglimpse-0.1.1 → gitglimpse-0.1.2}/src/gitglimpse/formatters/json.py +0 -0
- {gitglimpse-0.1.1 → gitglimpse-0.1.2}/src/gitglimpse/formatters/markdown.py +0 -0
- {gitglimpse-0.1.1 → gitglimpse-0.1.2}/src/gitglimpse/git.py +0 -0
- {gitglimpse-0.1.1 → gitglimpse-0.1.2}/src/gitglimpse/grouping.py +0 -0
- {gitglimpse-0.1.1 → gitglimpse-0.1.2}/src/gitglimpse/onboarding.py +0 -0
- {gitglimpse-0.1.1 → gitglimpse-0.1.2}/src/gitglimpse/providers/__init__.py +0 -0
- {gitglimpse-0.1.1 → gitglimpse-0.1.2}/src/gitglimpse/providers/base.py +0 -0
- {gitglimpse-0.1.1 → gitglimpse-0.1.2}/src/gitglimpse/providers/claude.py +0 -0
- {gitglimpse-0.1.1 → gitglimpse-0.1.2}/src/gitglimpse/providers/gemini.py +0 -0
- {gitglimpse-0.1.1 → gitglimpse-0.1.2}/src/gitglimpse/providers/local.py +0 -0
- {gitglimpse-0.1.1 → gitglimpse-0.1.2}/src/gitglimpse/providers/openai.py +0 -0
- {gitglimpse-0.1.1 → gitglimpse-0.1.2}/src/gitglimpse/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gitglimpse
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: Analyze git history and generate standup updates, daily reports, and weekly summaries.
|
|
5
5
|
Project-URL: Homepage, https://github.com/dino/gitglimpse
|
|
6
6
|
Project-URL: Repository, https://github.com/dino/gitglimpse
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "gitglimpse"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.2"
|
|
8
8
|
description = "Analyze git history and generate standup updates, daily reports, and weekly summaries."
|
|
9
9
|
authors = [{ name = "Dino" }]
|
|
10
10
|
license = { text = "MIT" }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.2"
|
|
@@ -426,11 +426,13 @@ def standup(
|
|
|
426
426
|
llm_output = provider.summarize_standup(tasks, report_date, diff_snippets)
|
|
427
427
|
|
|
428
428
|
_print_status_line(resolved_author, active_provider, ctx_mode)
|
|
429
|
-
|
|
430
|
-
llm_output
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
429
|
+
if llm_output:
|
|
430
|
+
console.print(llm_output, markup=False, highlight=False)
|
|
431
|
+
else:
|
|
432
|
+
console.print(
|
|
433
|
+
format_standup(tasks, report_date, group_by=group_by if multi else "project"),
|
|
434
|
+
highlight=False,
|
|
435
|
+
)
|
|
434
436
|
|
|
435
437
|
|
|
436
438
|
# ---------------------------------------------------------------------------
|
|
@@ -630,11 +632,13 @@ def week(
|
|
|
630
632
|
llm_output = provider.summarize_week(tasks, start_date, end_date, diff_snippets)
|
|
631
633
|
|
|
632
634
|
_print_status_line(resolved_author, active_provider, ctx_mode)
|
|
633
|
-
|
|
634
|
-
llm_output
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
635
|
+
if llm_output:
|
|
636
|
+
console.print(llm_output, markup=False, highlight=False)
|
|
637
|
+
else:
|
|
638
|
+
console.print(
|
|
639
|
+
format_week_template(tasks, start_date, end_date),
|
|
640
|
+
highlight=False,
|
|
641
|
+
)
|
|
638
642
|
|
|
639
643
|
|
|
640
644
|
# ---------------------------------------------------------------------------
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
from collections import defaultdict
|
|
4
4
|
from datetime import date, timedelta
|
|
5
5
|
|
|
6
|
+
from rich.markup import escape as _escape
|
|
7
|
+
|
|
6
8
|
from gitglimpse.estimation import format_duration
|
|
7
9
|
from gitglimpse.grouping import Task
|
|
8
10
|
|
|
@@ -19,24 +21,28 @@ def _day_label(day: date, today: date) -> str:
|
|
|
19
21
|
|
|
20
22
|
def _render_task_bullet(task: Task, inline_project: bool = False) -> str:
|
|
21
23
|
duration = format_duration(task.estimated_minutes)
|
|
24
|
+
summary = _escape(task.summary)
|
|
25
|
+
branch = _escape(task.branch) if task.branch else None
|
|
26
|
+
project = _escape(task.project) if task.project else None
|
|
27
|
+
|
|
22
28
|
parts = []
|
|
23
|
-
if inline_project and
|
|
24
|
-
parts.append(f"{
|
|
25
|
-
elif
|
|
26
|
-
parts.append(
|
|
29
|
+
if inline_project and project:
|
|
30
|
+
parts.append(f"[bold magenta]{project}[/bold magenta]/{branch}" if branch else f"[bold magenta]{project}[/bold magenta]")
|
|
31
|
+
elif branch:
|
|
32
|
+
parts.append(branch)
|
|
27
33
|
parts.append(duration)
|
|
28
34
|
meta = f" ({', '.join(parts)})"
|
|
29
|
-
return f" \u2022 {
|
|
35
|
+
return f" [yellow]\u2022[/yellow] {summary}[dim]{meta}[/dim]"
|
|
30
36
|
|
|
31
37
|
|
|
32
38
|
def format_standup(tasks: list[Task], report_date: date, group_by: str = "project") -> str:
|
|
33
39
|
"""Render a plain-text standup update."""
|
|
34
40
|
date_str = f"{report_date.strftime('%B')} {report_date.day}, {report_date.year}"
|
|
35
|
-
lines: list[str] = [f"Standup \u2014 {date_str}", ""]
|
|
41
|
+
lines: list[str] = [f"[bold yellow]Standup \u2014 {date_str}[/bold yellow]", ""]
|
|
36
42
|
|
|
37
43
|
if not tasks:
|
|
38
44
|
lines.append("(no commits found)")
|
|
39
|
-
lines.extend(["", "Total estimated time: 0.0h"])
|
|
45
|
+
lines.extend(["", "[dim]Total estimated time:[/dim] [green]0.0h[/green]"])
|
|
40
46
|
return "\n".join(lines)
|
|
41
47
|
|
|
42
48
|
projects = sorted({t.project for t in tasks if t.project})
|
|
@@ -51,13 +57,13 @@ def format_standup(tasks: list[Task], report_date: date, group_by: str = "projec
|
|
|
51
57
|
|
|
52
58
|
for day in sorted(by_day):
|
|
53
59
|
label = _day_label(day, today)
|
|
54
|
-
lines.append(f"{label}:")
|
|
60
|
+
lines.append(f"[blue]{label}:[/blue]")
|
|
55
61
|
for task in by_day[day]:
|
|
56
62
|
lines.append(_render_task_bullet(task, inline_project=True))
|
|
57
63
|
lines.append("")
|
|
58
64
|
|
|
59
65
|
total_hours = sum(t.estimated_minutes for t in tasks) / 60
|
|
60
|
-
lines.append(f"Total estimated time: {total_hours:.1f}h across {len(projects)} projects")
|
|
66
|
+
lines.append(f"[dim]Total estimated time:[/dim] [green]{total_hours:.1f}h[/green] [dim]across {len(projects)} projects[/dim]")
|
|
61
67
|
elif multi:
|
|
62
68
|
# Group by project (default).
|
|
63
69
|
by_project: dict[str, list[Task]] = defaultdict(list)
|
|
@@ -65,14 +71,14 @@ def format_standup(tasks: list[Task], report_date: date, group_by: str = "projec
|
|
|
65
71
|
by_project[task.project].append(task)
|
|
66
72
|
|
|
67
73
|
for project in projects:
|
|
68
|
-
lines.append(f"{project}:")
|
|
74
|
+
lines.append(f"[bold magenta]{_escape(project)}:[/bold magenta]")
|
|
69
75
|
by_day = defaultdict(list)
|
|
70
76
|
for task in by_project[project]:
|
|
71
77
|
by_day[task.first_commit_time.date()].append(task)
|
|
72
78
|
for day in sorted(by_day):
|
|
73
79
|
if len(by_day) > 1:
|
|
74
80
|
label = _day_label(day, today)
|
|
75
|
-
lines.append(f" {label}:")
|
|
81
|
+
lines.append(f" [blue]{label}:[/blue]")
|
|
76
82
|
for task in by_day[day]:
|
|
77
83
|
lines.append(f" {_render_task_bullet(task)}")
|
|
78
84
|
else:
|
|
@@ -81,7 +87,7 @@ def format_standup(tasks: list[Task], report_date: date, group_by: str = "projec
|
|
|
81
87
|
lines.append("")
|
|
82
88
|
|
|
83
89
|
total_hours = sum(t.estimated_minutes for t in tasks) / 60
|
|
84
|
-
lines.append(f"Total estimated time: {total_hours:.1f}h across {len(projects)} projects")
|
|
90
|
+
lines.append(f"[dim]Total estimated time:[/dim] [green]{total_hours:.1f}h[/green] [dim]across {len(projects)} projects[/dim]")
|
|
85
91
|
else:
|
|
86
92
|
by_day = defaultdict(list)
|
|
87
93
|
for task in tasks:
|
|
@@ -89,13 +95,13 @@ def format_standup(tasks: list[Task], report_date: date, group_by: str = "projec
|
|
|
89
95
|
|
|
90
96
|
for day in sorted(by_day):
|
|
91
97
|
label = _day_label(day, today)
|
|
92
|
-
lines.append(f"{label}:")
|
|
98
|
+
lines.append(f"[blue]{label}:[/blue]")
|
|
93
99
|
for task in by_day[day]:
|
|
94
100
|
lines.append(_render_task_bullet(task))
|
|
95
101
|
lines.append("")
|
|
96
102
|
|
|
97
103
|
total_hours = sum(t.estimated_minutes for t in tasks) / 60
|
|
98
|
-
lines.append(f"Total estimated time: {total_hours:.1f}h")
|
|
104
|
+
lines.append(f"[dim]Total estimated time:[/dim] [green]{total_hours:.1f}h[/green]")
|
|
99
105
|
|
|
100
106
|
return "\n".join(lines)
|
|
101
107
|
|
|
@@ -112,11 +118,11 @@ def format_week_template(tasks: list[Task], start_date: date, end_date: date) ->
|
|
|
112
118
|
e = f"{end_date.strftime('%B')} {end_date.day}, {end_date.year}"
|
|
113
119
|
header_date = f"{s} \u2013 {e}"
|
|
114
120
|
|
|
115
|
-
lines: list[str] = [f"Weekly Summary \u2014 {header_date}", ""]
|
|
121
|
+
lines: list[str] = [f"[bold yellow]Weekly Summary \u2014 {header_date}[/bold yellow]", ""]
|
|
116
122
|
|
|
117
123
|
if not tasks:
|
|
118
124
|
lines.append(" (no commits found)")
|
|
119
|
-
lines.extend(["", "Week total: 0.0h across 0 tasks"])
|
|
125
|
+
lines.extend(["", "[dim]Week total:[/dim] [green]0.0h[/green] [dim]across 0 tasks[/dim]"])
|
|
120
126
|
return "\n".join(lines)
|
|
121
127
|
|
|
122
128
|
by_day: dict[date, list[Task]] = defaultdict(list)
|
|
@@ -128,14 +134,14 @@ def format_week_template(tasks: list[Task], start_date: date, end_date: date) ->
|
|
|
128
134
|
for day in sorted(by_day):
|
|
129
135
|
day_tasks = by_day[day]
|
|
130
136
|
day_label = f"{day.strftime('%A')} ({day.strftime('%B')} {day.day})"
|
|
131
|
-
lines.append(f"{day_label}:")
|
|
137
|
+
lines.append(f"[blue]{day_label}:[/blue]")
|
|
132
138
|
for task in day_tasks:
|
|
133
139
|
duration = format_duration(task.estimated_minutes)
|
|
134
|
-
lines.append(f" \u2022 {task.summary} ({duration})")
|
|
140
|
+
lines.append(f" [yellow]\u2022[/yellow] {_escape(task.summary)} [dim]({duration})[/dim]")
|
|
135
141
|
day_hours = sum(t.estimated_minutes for t in day_tasks) / 60
|
|
136
|
-
lines.append(f" Day total: {day_hours:.1f}h")
|
|
142
|
+
lines.append(f" [dim]Day total:[/dim] [green]{day_hours:.1f}h[/green]")
|
|
137
143
|
lines.append("")
|
|
138
144
|
|
|
139
145
|
n = len(tasks)
|
|
140
|
-
lines.append(f"Week total: {week_minutes / 60:.1f}h across {n} task{'s' if n != 1 else ''}")
|
|
146
|
+
lines.append(f"[dim]Week total:[/dim] [green]{week_minutes / 60:.1f}h[/green] [dim]across {n} task{'s' if n != 1 else ''}[/dim]")
|
|
141
147
|
return "\n".join(lines)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.1.1"
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|