-
-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathstop.py
More file actions
200 lines (163 loc) · 6.19 KB
/
Copy pathstop.py
File metadata and controls
200 lines (163 loc) · 6.19 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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
#!/usr/bin/env python3
"""CodingBuddy Stop Hook — finalize operational stats (#825).
Outputs a systemMessage with the session summary on Stop event.
"""
import json
import os
import sys
# Resolve hooks/lib and add to path
_hooks_dir = os.path.dirname(os.path.abspath(__file__))
_lib_dir = os.path.join(_hooks_dir, "lib")
if _lib_dir not in sys.path:
sys.path.insert(0, _lib_dir)
from safe_main import safe_main
@safe_main
def handle_stop(data: dict):
"""Entry point for Stop hook.
Finalizes session stats and returns a systemMessage summary.
"""
try:
from stats import SessionStats
from session_utils import get_session_id
session_id = get_session_id()
# Clean up companion TUI pane (#970)
try:
from tui_launcher import cleanup as cleanup_tui
cleanup_tui(session_id)
except Exception:
pass # Never block session stop
stats = SessionStats(session_id=session_id)
# Flush pending in-memory stats before finalize (#931)
stats.flush()
summary = stats.format_summary()
final_data = stats.finalize()
# Render buddy session summary to stderr (#972)
try:
from buddy_renderer import render_session_summary
from config import get_config
cwd = os.environ.get("CLAUDE_PROJECT_DIR", os.getcwd())
cfg = get_config(cwd)
tone = cfg.get("tone", "casual")
language = cfg.get("language", "en")
tool_names = final_data.get("tool_names", {})
render_stats = {
"duration_minutes": int(final_data.get("duration_seconds", 0) // 60),
"tool_count": final_data.get("tool_count", 0),
"files_changed": tool_names.get("Edit", 0) + tool_names.get("Write", 0),
}
agents = []
active_agent = os.environ.get("CODINGBUDDY_ACTIVE_AGENT", "")
if active_agent:
agents.append({
"name": active_agent,
"eye": "\u25cf",
"colorAnsi": "cyan",
})
rendered = render_session_summary(
render_stats, agents, tone, language,
tool_names=tool_names,
)
if rendered:
print(rendered, file=sys.stderr)
except Exception:
pass # Never block session stop
# End session in history database (#823)
try:
from history_db import HistoryDB
db = HistoryDB()
db.end_session(session_id, outcome="completed")
# Close singleton connection (#931)
HistoryDB.close_instance()
db.close()
except Exception:
pass # Never block session stop
# Auto-learning: analyze session patterns (#929)
try:
from pattern_detector import PatternDetector
from history_db import HistoryDB
al_db = HistoryDB()
detector = PatternDetector(db=al_db)
patterns = detector.detect_patterns()
if patterns:
from rule_suggester import RuleSuggester
suggester = RuleSuggester()
suggestions = suggester.suggest_rules(patterns)
if suggestions:
summary += "\n\n--- Auto-Learning Suggestions ---\n"
for s in suggestions:
summary += f"- {s['title']}\n"
try:
al_db.close()
except Exception:
pass
except Exception:
pass # Never block session stop
# Agent memory: record session agent activity (#947)
try:
from agent_memory import AgentMemory
agent_name = os.environ.get("CODINGBUDDY_ACTIVE_AGENT", "")
if agent_name:
mem = AgentMemory()
# Record session summary as a finding
if summary:
mem.add_finding(agent_name, {
"session_id": session_id,
"summary": summary[:200],
})
except Exception:
pass # Never block session stop
# Check achievements on session stop (#1008)
try:
from achievement_tracker import (
AchievementTracker,
render_batch_celebration,
render_achievement_badges,
)
tracker = AchievementTracker()
tracker.record_session()
# Record agent usage if active
active_agent = os.environ.get("CODINGBUDDY_ACTIVE_AGENT", "")
if active_agent:
tracker.record_agent_usage(active_agent)
newly_unlocked = tracker.check_achievements()
if newly_unlocked:
celebration = render_batch_celebration(
newly_unlocked, language
)
if celebration:
print(celebration, file=sys.stderr)
# Show badge summary if any unlocked
all_unlocked = tracker.get_unlocked()
if all_unlocked:
badges = render_achievement_badges(all_unlocked, language)
if badges:
print(badges, file=sys.stderr)
except Exception:
pass # Never block session stop
# Notify on session end (#829)
try:
_maybe_notify_session_end(summary)
except Exception:
pass # Never block session stop
if summary:
return {
"systemMessage": summary,
}
except Exception:
pass # Never block session stop
return None
def _maybe_notify_session_end(summary: str):
"""Send session summary notification if configured."""
if not summary:
return
from config import get_config
from notifications import NotificationEvent, notify
config = get_config(os.getcwd())
event = NotificationEvent(
event_type="session_end",
title="Session Complete",
message=summary[:500], # Truncate for webhook limits
)
notify(event, config)
if __name__ == "__main__":
handle_stop()