-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
107 lines (89 loc) · 3.09 KB
/
app.py
File metadata and controls
107 lines (89 loc) · 3.09 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
"""
Floom wrapper for hook-stats.
The CLI version reads ~/.claude/bash-commands.log. In the Floom sandbox
the user pastes or uploads the log content, and this wrapper parses it
with the same logic.
"""
import re
from collections import Counter
from datetime import datetime, timezone
from floom import app, save_artifact
LINE_RE = re.compile(r"^\[(?P<ts>[^\]]+)\]\s*(?P<cmd>.*)$")
def _parse(log_text: str):
"""Parse only lines that start with a [timestamp] prefix."""
entries = []
for line in log_text.splitlines():
match = LINE_RE.match(line)
if not match:
continue
ts_raw = match.group("ts")
cmd = match.group("cmd").strip()
# Extract just the date portion (YYYY-MM-DD) for day buckets.
day = ts_raw[:10] if len(ts_raw) >= 10 else ts_raw
head = cmd.split()[0] if cmd else ""
entries.append({"ts": ts_raw, "day": day, "cmd": cmd, "head": head})
return entries
@app.action
def analyze(log_content: str) -> dict:
"""
Parse a Claude Code bash-commands.log file and return usage stats.
log_content: the full text contents of ~/.claude/bash-commands.log
"""
if not log_content or not log_content.strip():
return {
"total": 0,
"today": 0,
"top_commands": [],
"git": {"pushes": 0, "commits": 0, "diffs": 0},
"per_day": [],
"report": "No log content provided.",
}
entries = _parse(log_content)
total = len(entries)
today = datetime.now(timezone.utc).strftime("%Y-%m-%d")
today_count = sum(1 for e in entries if e["day"] == today)
head_counts = Counter(e["head"] for e in entries if e["head"])
top_commands = [
{"command": cmd, "count": n}
for cmd, n in head_counts.most_common(15)
]
pushes = sum(1 for e in entries if "git push" in e["cmd"])
commits = sum(1 for e in entries if "git commit" in e["cmd"])
diffs = sum(1 for e in entries if "git diff" in e["cmd"])
day_counts = Counter(e["day"] for e in entries)
per_day = [
{"day": day, "count": n}
for day, n in sorted(day_counts.items())[-7:]
]
# Build a human-readable text report that mirrors the CLI output.
lines = [
"Bash Command Stats",
"===================",
f"Total commands: {total}",
f"Today: {today_count}",
"",
"Top 15 commands:",
]
for item in top_commands:
lines.append(f" {item['count']:>4} {item['command']}")
lines.extend([
"",
"Git operations:",
f" pushes: {pushes}",
f" commits: {commits}",
f" diffs: {diffs}",
"",
"Commands per day (last 7):",
])
for item in per_day:
lines.append(f" {item['day']}: {item['count']}")
report_text = "\n".join(lines)
save_artifact("hook-stats.txt", report_text)
return {
"total": total,
"today": today_count,
"top_commands": top_commands,
"git": {"pushes": pushes, "commits": commits, "diffs": diffs},
"per_day": per_day,
"report": report_text,
}