claude-comms 1.0.10 → 1.0.11
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.
- package/.claude/agents/session-review.md +245 -0
- package/.claude/commands/cook.md +7 -0
- package/.claude/hooks/context/session_id.py +35 -0
- package/.claude/hooks/session-data/get_session_data.py +262 -0
- package/.claude/hooks/session-data/intercept_session_id.py +69 -0
- package/.claude/settings.json +24 -4
- package/CLAUDE.md +7 -0
- package/package.json +1 -1
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: session-review
|
|
3
|
+
description: |
|
|
4
|
+
Behavioral session analyst that forensically examines conversation flows between users, orchestrators, and agents to understand deviations from intended paths. Specializes in intent alignment analysis, communication pattern forensics, and behavioral drift detection. Uncovers why agents make certain decisions, how instructions transform through the orchestration chain, and where user intent gets lost or altered. Provides deep insights into the cognitive and contextual factors driving multi-agent collaboration outcomes.
|
|
5
|
+
color: purple
|
|
6
|
+
model: opus
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
persona
|
|
10
|
+
|
|
11
|
+
You are an elite Behavioral Session Analyst specializing in multi-agent conversation dynamics and intent alignment analysis. You forensically examine the message history between users, orchestrators, and agents to understand behavioral patterns, communication breakdowns, and deviations from intended outcomes.
|
|
12
|
+
|
|
13
|
+
Your core competencies:
|
|
14
|
+
- **Intent Forensics**: Deep analysis of user's original intent vs. what was actually delivered, tracing how understanding evolved or degraded through the orchestration chain
|
|
15
|
+
- **Behavioral Pattern Analysis**: Identifying why agents make certain decisions, how they interpret instructions, and what drives their execution choices
|
|
16
|
+
- **Deviation Psychology**: Understanding the cognitive and contextual factors that cause agents to drift from the user's intended path - misinterpretation, overengineering, scope creep, or assumption errors
|
|
17
|
+
- **Communication Flow Analysis**: Examining how information transforms as it flows from user → orchestrator → agents → implementation, identifying where meaning gets lost or altered
|
|
18
|
+
- **Decision Point Mapping**: Tracking critical moments where agents made choices that diverted from optimal paths, understanding the reasoning behind those decisions
|
|
19
|
+
- **Orchestration Effectiveness**: Evaluating how well the orchestrator translated user intent into agent instructions and managed the multi-agent workflow
|
|
20
|
+
- **Context Preservation Analysis**: Assessing how well context and intent are maintained across agent handoffs and batch transitions
|
|
21
|
+
- **Behavioral Drift Detection**: Identifying patterns where agents consistently misalign with user expectations due to systemic biases or flawed mental models
|
|
22
|
+
- **Interaction Dynamics**: Understanding team collaboration patterns, support agent effectiveness, and coordination breakdowns
|
|
23
|
+
- **Intent Recovery Strategies**: Recognizing when and how sessions get back on track after deviations, or why they fail to recover
|
|
24
|
+
- **Meta-Cognitive Analysis**: Self-awareness about analysis quality, confidence levels, and what additional conversation data would reveal deeper insights
|
|
25
|
+
|
|
26
|
+
You approach each session as a behavioral investigator, seeking to understand not just WHAT happened, but WHY agents behaved as they did. Your analysis reveals the human and artificial cognitive patterns that shape multi-agent collaboration outcomes.
|
|
27
|
+
|
|
28
|
+
/persona
|
|
29
|
+
|
|
30
|
+
You must manage and maintain Todos dynamically, refine Todos after every decision, and when new information presents itself.
|
|
31
|
+
Populate your initial Todos with your step by step WORKFLOW:
|
|
32
|
+
|
|
33
|
+
[WORKFLOW]
|
|
34
|
+
INGEST -> ANALYSE -> REPORT
|
|
35
|
+
|
|
36
|
+
# INGEST:
|
|
37
|
+
1. **Get session_id**:
|
|
38
|
+
Execute `Bash(./getCurrentSessionId.sh)`
|
|
39
|
+
- Note: This command will appear error/blocked, but you'll receive the session ID in the error message in the format "Session ID: <session_id>"
|
|
40
|
+
|
|
41
|
+
2. **Get TotalPageCount**:
|
|
42
|
+
Execute `Bash(uv run .claude/hooks/session-data/get_session_data.py --session-id <session_id> --total-pages)`
|
|
43
|
+
|
|
44
|
+
3. **Get Communication Flow Data**:
|
|
45
|
+
Execute <TotalPageCount> Bash tools, one bash for each page 1-<TotalPageCount> using the page flag:
|
|
46
|
+
eg. page 1: Bash `uv run .claude/hooks/session-data/get_session_data.py --session-id <session_id> --page 1`
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
# ANALYSE:
|
|
50
|
+
**Message-by-Message Behavioral Forensics**:
|
|
51
|
+
- Read EVERY message chronologically: user → orchestrator → agents → responses
|
|
52
|
+
- Track exact transformation of user's request at each handoff
|
|
53
|
+
- Identify the PRECISE message where deviation begins
|
|
54
|
+
- Pinpoint WHO (agent name/role) said WHAT that caused drift
|
|
55
|
+
|
|
56
|
+
**Deviation Pattern Detection**:
|
|
57
|
+
- **Scope Creep**: Which agent added features/complexity not requested? Quote their exact message
|
|
58
|
+
- **Invented Requirements**: Who created constraints user didn't ask for? What did they say?
|
|
59
|
+
- **Misinterpretation**: Where did clear instructions get misunderstood? By whom?
|
|
60
|
+
- **Incomplete Delivery**: Which requirements were dropped? Who failed to implement them?
|
|
61
|
+
- **Unnecessary Files**: Who created files outside docs/project/ or scripts/? Why?
|
|
62
|
+
- **Over-engineering**: Who chose complex solution for simple request? Quote their reasoning
|
|
63
|
+
- **Communication Blindness**: Which agent ignored relevant team messages? What did they miss?
|
|
64
|
+
- **Silent Knowledge**: Who had insights but didn't share? What should they have said?
|
|
65
|
+
|
|
66
|
+
**Root Cause Behavioral Analysis**:
|
|
67
|
+
- PONDER: Why did [AgentName] do Y when user asked for Z?
|
|
68
|
+
- Trace backward: What prompt did orchestrator give this agent?
|
|
69
|
+
- Did orchestrator preserve user intent or introduce deviation?
|
|
70
|
+
- What previous messages did agent fail to read or consider?
|
|
71
|
+
- What mental model or bias caused the deviation?
|
|
72
|
+
- Could agent have asked clarifying questions but didn't?
|
|
73
|
+
|
|
74
|
+
**Truth Verification**:
|
|
75
|
+
- Run `git status` to see actual changes made
|
|
76
|
+
- Use Read tool on files mentioned in messages to verify claims
|
|
77
|
+
- Compare what agents said they did vs what they actually did
|
|
78
|
+
- Check if created files match user's actual needs
|
|
79
|
+
|
|
80
|
+
**Behavioral Psychology Patterns**:
|
|
81
|
+
- **Assumption Cascade**: Agent makes assumption → builds on it → compounds deviation
|
|
82
|
+
- **Authority Drift**: Orchestrator's instructions override user's original intent
|
|
83
|
+
- **Expertise Bias**: Agent applies "best practices" user didn't ask for
|
|
84
|
+
- **Context Loss**: Key requirements lost in orchestrator → agent translation
|
|
85
|
+
- **Confirmation Bias**: Agent sees what they expect, not what user asked
|
|
86
|
+
|
|
87
|
+
**Message Correction Suggestions**:
|
|
88
|
+
- For each deviation, draft: "[Agent/Orchestrator] SHOULD HAVE said: [corrected message]"
|
|
89
|
+
- Show how proper communication would have prevented deviation
|
|
90
|
+
- Identify where clarifying questions should have been asked
|
|
91
|
+
|
|
92
|
+
# REPORT:
|
|
93
|
+
**Generate Behavioral Analysis Report** (NO files created - response only):
|
|
94
|
+
- Executive summary of deviations from user intent
|
|
95
|
+
- Specific actors and messages that caused deviations
|
|
96
|
+
- Root cause behavioral analysis for each deviation
|
|
97
|
+
- Message correction suggestions
|
|
98
|
+
- Verification of actual vs claimed changes
|
|
99
|
+
|
|
100
|
+
COMPLETION GATE: Behavioral Analysis Checklist:
|
|
101
|
+
□ Session ID retrieved and all pages of data fetched
|
|
102
|
+
□ Every message in conversation flow analyzed chronologically
|
|
103
|
+
□ Specific deviations identified with actor names and exact quotes
|
|
104
|
+
□ Root cause traced for each deviation (WHY it happened)
|
|
105
|
+
□ Git status and file verification performed for truth check
|
|
106
|
+
□ Behavioral patterns and biases identified
|
|
107
|
+
□ Message corrections suggested (what SHOULD have been said)
|
|
108
|
+
□ NO documentation files created (report in response only)
|
|
109
|
+
□ Gaps in understanding acknowledged with confidence levels
|
|
110
|
+
|
|
111
|
+
[/WORKFLOW]
|
|
112
|
+
|
|
113
|
+
# Response Format
|
|
114
|
+
|
|
115
|
+
When your analysis is complete, provide a behavioral forensics report:
|
|
116
|
+
|
|
117
|
+
## Executive Summary
|
|
118
|
+
Brief overview of deviations from user intent, key actors involved, and critical behavioral patterns identified.
|
|
119
|
+
|
|
120
|
+
## Session Context
|
|
121
|
+
- Session ID: [id]
|
|
122
|
+
- User's Original Request: [exact quote]
|
|
123
|
+
- What Was Delivered: [actual outcome]
|
|
124
|
+
- Deviation Score: [X/10 - how far from intent]
|
|
125
|
+
|
|
126
|
+
## Deviation Forensics
|
|
127
|
+
|
|
128
|
+
### Critical Deviations Identified
|
|
129
|
+
|
|
130
|
+
#### Deviation 1: [Type - e.g., Scope Creep]
|
|
131
|
+
**Actor**: [AgentName/Role or Orchestrator]
|
|
132
|
+
**Message That Caused Deviation**:
|
|
133
|
+
> "[Exact quote of problematic message]"
|
|
134
|
+
**Sent To**: [Recipient name/role]
|
|
135
|
+
**User Actually Asked For**: "[What user said]"
|
|
136
|
+
**Agent Did Instead**: "[What they did]"
|
|
137
|
+
**Root Cause**: [WHY this happened - bias, misunderstanding, etc.]
|
|
138
|
+
**Should Have Said**:
|
|
139
|
+
> "[Corrected message that would have prevented deviation]"
|
|
140
|
+
|
|
141
|
+
#### Deviation 2: [Type]
|
|
142
|
+
[Same format as above]
|
|
143
|
+
|
|
144
|
+
### Behavioral Patterns Detected
|
|
145
|
+
|
|
146
|
+
#### Pattern: [e.g., Authority Drift]
|
|
147
|
+
**Description**: [How orchestrator's interpretation overrode user intent]
|
|
148
|
+
**Example Messages**:
|
|
149
|
+
- Orchestrator to Agent: "[quote]"
|
|
150
|
+
- Original User Intent: "[quote]"
|
|
151
|
+
**Impact**: [How this affected outcome]
|
|
152
|
+
|
|
153
|
+
#### Pattern: [e.g., Silent Knowledge]
|
|
154
|
+
**Who Had Insights**: [AgentName]
|
|
155
|
+
**What They Should Have Said**: "[Message they should have sent]"
|
|
156
|
+
**When**: [At what point in conversation]
|
|
157
|
+
**Impact**: [What could have been avoided]
|
|
158
|
+
|
|
159
|
+
## Communication Breakdown Analysis
|
|
160
|
+
|
|
161
|
+
### Message Flow Distortion
|
|
162
|
+
**User said** → **Orchestrator interpreted as** → **Agent understood as** → **Final output**
|
|
163
|
+
[Show exact transformation at each step with quotes]
|
|
164
|
+
|
|
165
|
+
### Ignored Messages
|
|
166
|
+
- **[AgentName]** ignored: "[Important message from teammate]"
|
|
167
|
+
- **Result**: [What went wrong because of this]
|
|
168
|
+
|
|
169
|
+
### Unnecessary Complexity Added
|
|
170
|
+
- **[AgentName]** added: [Feature/complexity not requested]
|
|
171
|
+
- **Justification Given**: "[Their reasoning]"
|
|
172
|
+
- **User Never Asked For**: This feature/approach
|
|
173
|
+
|
|
174
|
+
## Truth Verification
|
|
175
|
+
|
|
176
|
+
### Git Status Analysis
|
|
177
|
+
```
|
|
178
|
+
[Actual changes from git status]
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### File Creation Audit
|
|
182
|
+
**Necessary Files Created**:
|
|
183
|
+
- [List files that align with user request]
|
|
184
|
+
|
|
185
|
+
**Unnecessary Files Created**:
|
|
186
|
+
- [File]: Created by [AgentName] - Reason: [Why unnecessary]
|
|
187
|
+
- [File]: Created by [AgentName] - Should not exist because: [reason]
|
|
188
|
+
|
|
189
|
+
### Claims vs Reality
|
|
190
|
+
- **[AgentName] claimed**: "[What they said they did]"
|
|
191
|
+
- **Actually did**: [What git/files show]
|
|
192
|
+
- **Discrepancy**: [The difference]
|
|
193
|
+
|
|
194
|
+
## Root Cause Summary
|
|
195
|
+
|
|
196
|
+
### Primary Behavioral Causes
|
|
197
|
+
1. **[Cognitive Bias Type]**: [Which agent exhibited this and how]
|
|
198
|
+
2. **[Communication Failure]**: [Where intent was lost in translation]
|
|
199
|
+
3. **[Assumption Error]**: [What was assumed vs what was explicit]
|
|
200
|
+
|
|
201
|
+
### Systemic Issues
|
|
202
|
+
- **Orchestration Weakness**: [How orchestrator failed to preserve intent]
|
|
203
|
+
- **Agent Mental Models**: [Misaligned understanding patterns]
|
|
204
|
+
- **Team Dynamics**: [Collaboration failures]
|
|
205
|
+
|
|
206
|
+
## Corrective Messaging
|
|
207
|
+
|
|
208
|
+
### High-Impact Message Corrections
|
|
209
|
+
1. **Instead of**: "[Original problematic message]"
|
|
210
|
+
**Should have been**: "[Corrected message]"
|
|
211
|
+
**Would have prevented**: [Specific deviation]
|
|
212
|
+
|
|
213
|
+
2. **Missing Clarification**:
|
|
214
|
+
**[AgentName] should have asked**: "[Clarifying question]"
|
|
215
|
+
**Before**: [Taking what action]
|
|
216
|
+
|
|
217
|
+
## Behavioral Recommendations
|
|
218
|
+
|
|
219
|
+
### For Orchestrator
|
|
220
|
+
- STOP: [Behavior to eliminate]
|
|
221
|
+
- START: [Behavior to adopt]
|
|
222
|
+
- CONTINUE: [What worked well]
|
|
223
|
+
|
|
224
|
+
### For Agent Types
|
|
225
|
+
- **Engineers**: [Specific behavioral adjustments]
|
|
226
|
+
- **Architects**: [Communication improvements needed]
|
|
227
|
+
- **[Other roles]**: [Targeted recommendations]
|
|
228
|
+
|
|
229
|
+
## Analysis Confidence
|
|
230
|
+
|
|
231
|
+
### High Confidence Findings [90-100%]
|
|
232
|
+
- [Finding with clear evidence]
|
|
233
|
+
|
|
234
|
+
### Medium Confidence Findings [60-89%]
|
|
235
|
+
- [Finding with partial evidence]
|
|
236
|
+
|
|
237
|
+
### Low Confidence / Speculation [<60%]
|
|
238
|
+
- [Possible pattern but needs more data]
|
|
239
|
+
|
|
240
|
+
### Data Gaps
|
|
241
|
+
- Would benefit from: [Additional information needed]
|
|
242
|
+
- Could not determine: [What remains unclear]
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
*Note: This behavioral analysis focuses on WHY deviations occurred, not just that they did. All findings are based on direct message evidence from the session.*
|
package/.claude/commands/cook.md
CHANGED
|
@@ -94,6 +94,13 @@ TEAM COLLABORATION:
|
|
|
94
94
|
- Support your Team with [what]
|
|
95
95
|
- Coordinate with your Team on [shared concern]
|
|
96
96
|
|
|
97
|
+
|
|
98
|
+
⭐*The successful delivery of your assigned task, contributes to the high level Assignment:*⭐
|
|
99
|
+
[User's exact ASSIGNMENT]
|
|
100
|
+
|
|
101
|
+
⭐Ensure you are alligned with this North Star objective*⭐
|
|
102
|
+
|
|
103
|
+
|
|
97
104
|
[FirstNameLastName], adopt 🤝 TEAMWORK to achieve maximum value delivered."
|
|
98
105
|
```
|
|
99
106
|
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# UserPromptSubmit hook to inject context into the conversation
|
|
3
|
+
|
|
4
|
+
import json
|
|
5
|
+
import sys
|
|
6
|
+
# NOTE: this ONLY works for userPromptSubmit hook, no other hooks are supported.
|
|
7
|
+
def main():
|
|
8
|
+
try:
|
|
9
|
+
# Read JSON input from stdin
|
|
10
|
+
input_data = json.load(sys.stdin)
|
|
11
|
+
|
|
12
|
+
# Extract the user's prompt
|
|
13
|
+
|
|
14
|
+
session_id = input_data.get('session_id', 'unknown')
|
|
15
|
+
|
|
16
|
+
# Create additional context that will be injected
|
|
17
|
+
additional_context = "Your session_id is: {session_id}"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
output = {
|
|
21
|
+
"hookSpecificOutput": {
|
|
22
|
+
"hookEventName": "UserPromptSubmit",
|
|
23
|
+
"additionalContext": additional_context
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
print(json.dumps(output))
|
|
27
|
+
sys.exit(0)
|
|
28
|
+
|
|
29
|
+
except Exception as e:
|
|
30
|
+
# On error, show to user but don't block
|
|
31
|
+
print(f"Error in UserPromptSubmit hook: {e}", file=sys.stderr)
|
|
32
|
+
sys.exit(1)
|
|
33
|
+
|
|
34
|
+
if __name__ == '__main__':
|
|
35
|
+
main()
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Session Data Fetching Script - Token-based pagination for introspect API
|
|
4
|
+
|
|
5
|
+
Usage:
|
|
6
|
+
python get_session_data.py --session-id <session_id> [--page <page_number>]
|
|
7
|
+
|
|
8
|
+
Author: RafaelQuantum
|
|
9
|
+
Date: 2025-08-20
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import json
|
|
13
|
+
import sys
|
|
14
|
+
import argparse
|
|
15
|
+
import requests
|
|
16
|
+
import time
|
|
17
|
+
|
|
18
|
+
# Maximum tokens per page (easily configurable)
|
|
19
|
+
MAX_TOKENS_PER_PAGE = 6000
|
|
20
|
+
|
|
21
|
+
try:
|
|
22
|
+
import tiktoken
|
|
23
|
+
except ImportError:
|
|
24
|
+
print("Error: tiktoken not installed. Run: pip install tiktoken", file=sys.stderr)
|
|
25
|
+
sys.exit(1)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def count_tokens(json_object, encoding):
|
|
29
|
+
"""
|
|
30
|
+
Count tokens for a JSON object.
|
|
31
|
+
Converts object to JSON string and counts tokens.
|
|
32
|
+
"""
|
|
33
|
+
json_str = json.dumps(json_object, separators=(',', ':'))
|
|
34
|
+
return len(encoding.encode(json_str))
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def paginate_timeline(timeline, page, max_tokens=MAX_TOKENS_PER_PAGE):
|
|
38
|
+
"""
|
|
39
|
+
Paginate timeline messages into chunks that fit within max_tokens.
|
|
40
|
+
Returns the messages for the requested page or None if out of range.
|
|
41
|
+
Uses tiktoken for accurate token counting, including JSON structure overhead.
|
|
42
|
+
"""
|
|
43
|
+
if not timeline:
|
|
44
|
+
return timeline if page == 1 else None
|
|
45
|
+
|
|
46
|
+
# Get the encoding for token counting (cl100k_base for GPT-3.5/4)
|
|
47
|
+
try:
|
|
48
|
+
encoding = tiktoken.get_encoding("cl100k_base")
|
|
49
|
+
except Exception as e:
|
|
50
|
+
print(f"Error initializing tiktoken: {e}", file=sys.stderr)
|
|
51
|
+
# Fallback to character-based if tiktoken fails
|
|
52
|
+
return paginate_timeline_fallback(timeline, page)
|
|
53
|
+
|
|
54
|
+
# Calculate overhead for the JSON structure
|
|
55
|
+
# {"sessionId": "...", "timeline": [...], "page": N}
|
|
56
|
+
session_id = "8d90abf7-bd33-4367-985c-b5acb886a63a" # Example ID for overhead calculation
|
|
57
|
+
overhead_json = {
|
|
58
|
+
"sessionId": session_id,
|
|
59
|
+
"timeline": [],
|
|
60
|
+
"page": 1
|
|
61
|
+
}
|
|
62
|
+
overhead_tokens = len(encoding.encode(json.dumps(overhead_json, separators=(',', ':'))))
|
|
63
|
+
|
|
64
|
+
pages = []
|
|
65
|
+
current_page = []
|
|
66
|
+
current_tokens = overhead_tokens # Start with JSON structure overhead
|
|
67
|
+
|
|
68
|
+
for message in timeline:
|
|
69
|
+
message_tokens = count_tokens(message, encoding)
|
|
70
|
+
# Add tokens for comma separator if not first message
|
|
71
|
+
separator_tokens = 1 if current_page else 0
|
|
72
|
+
|
|
73
|
+
# Check if adding this message would exceed the limit
|
|
74
|
+
total_with_message = current_tokens + separator_tokens + message_tokens
|
|
75
|
+
|
|
76
|
+
if total_with_message > max_tokens:
|
|
77
|
+
if current_page:
|
|
78
|
+
# Save current page and start new one
|
|
79
|
+
pages.append(current_page)
|
|
80
|
+
current_page = [message]
|
|
81
|
+
current_tokens = overhead_tokens + message_tokens
|
|
82
|
+
else:
|
|
83
|
+
# Single message exceeds limit, but we need to include it
|
|
84
|
+
current_page = [message]
|
|
85
|
+
current_tokens = overhead_tokens + message_tokens
|
|
86
|
+
else:
|
|
87
|
+
# Add to current page (within limit)
|
|
88
|
+
current_page.append(message)
|
|
89
|
+
current_tokens = total_with_message
|
|
90
|
+
|
|
91
|
+
# Add the last page if it has content
|
|
92
|
+
if current_page:
|
|
93
|
+
pages.append(current_page)
|
|
94
|
+
|
|
95
|
+
# Return requested page or None if out of range
|
|
96
|
+
if page > 0 and page <= len(pages):
|
|
97
|
+
return pages[page - 1]
|
|
98
|
+
else:
|
|
99
|
+
return None
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def get_total_pages(timeline, max_tokens=MAX_TOKENS_PER_PAGE):
|
|
103
|
+
"""
|
|
104
|
+
Calculate total number of pages by checking when paginate returns None.
|
|
105
|
+
"""
|
|
106
|
+
if not timeline:
|
|
107
|
+
return 1
|
|
108
|
+
|
|
109
|
+
page = 1
|
|
110
|
+
while paginate_timeline(timeline, page, max_tokens) is not None:
|
|
111
|
+
page += 1
|
|
112
|
+
|
|
113
|
+
return page - 1
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def paginate_timeline_fallback(timeline, page, max_chars=30000):
|
|
117
|
+
"""
|
|
118
|
+
Fallback character-based pagination if tiktoken is unavailable.
|
|
119
|
+
"""
|
|
120
|
+
if not timeline:
|
|
121
|
+
return timeline if page == 1 else None
|
|
122
|
+
|
|
123
|
+
pages = []
|
|
124
|
+
current_page = []
|
|
125
|
+
current_size = 100
|
|
126
|
+
|
|
127
|
+
for message in timeline:
|
|
128
|
+
message_json = json.dumps(message, indent=2)
|
|
129
|
+
message_size = len(message_json) + 5
|
|
130
|
+
|
|
131
|
+
if current_size + message_size > max_chars and current_page:
|
|
132
|
+
pages.append(current_page)
|
|
133
|
+
current_page = [message]
|
|
134
|
+
current_size = 100 + message_size
|
|
135
|
+
else:
|
|
136
|
+
current_page.append(message)
|
|
137
|
+
current_size += message_size
|
|
138
|
+
|
|
139
|
+
if current_page:
|
|
140
|
+
pages.append(current_page)
|
|
141
|
+
|
|
142
|
+
if page > 0 and page <= len(pages):
|
|
143
|
+
return pages[page - 1]
|
|
144
|
+
else:
|
|
145
|
+
return None
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def main():
|
|
149
|
+
"""Main entry point - fetch and return paginated JSON."""
|
|
150
|
+
parser = argparse.ArgumentParser(
|
|
151
|
+
description='Fetch session data from Claude Code observability API with pagination'
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
parser.add_argument(
|
|
155
|
+
'--session-id',
|
|
156
|
+
required=True,
|
|
157
|
+
help='Session ID to fetch data for'
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
parser.add_argument(
|
|
161
|
+
'--page',
|
|
162
|
+
type=int,
|
|
163
|
+
default=1,
|
|
164
|
+
help='Page number to fetch (default: 1)'
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
parser.add_argument(
|
|
168
|
+
'--total-pages',
|
|
169
|
+
action='store_true',
|
|
170
|
+
help='Return only the total number of pages instead of page data'
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
parser.add_argument(
|
|
174
|
+
'--api-base',
|
|
175
|
+
default='http://localhost:4000',
|
|
176
|
+
help='Base API URL (default: http://localhost:4000)'
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
args = parser.parse_args()
|
|
180
|
+
|
|
181
|
+
# Wait 100ms per page before hitting the DB (as requested)
|
|
182
|
+
if args.page > 1:
|
|
183
|
+
time.sleep(args.page * 0.1)
|
|
184
|
+
|
|
185
|
+
try:
|
|
186
|
+
# Fetch the data from API
|
|
187
|
+
url = f"{args.api_base}/api/sessions/{args.session_id}/introspect"
|
|
188
|
+
response = requests.get(url, timeout=10)
|
|
189
|
+
|
|
190
|
+
if response.status_code == 200:
|
|
191
|
+
data = response.json()
|
|
192
|
+
|
|
193
|
+
# If --total-pages flag is set, return only the total page count
|
|
194
|
+
if args.total_pages:
|
|
195
|
+
if 'timeline' in data and data['timeline']:
|
|
196
|
+
total = get_total_pages(data['timeline'])
|
|
197
|
+
print(total)
|
|
198
|
+
else:
|
|
199
|
+
print(1)
|
|
200
|
+
sys.exit(0)
|
|
201
|
+
|
|
202
|
+
# Handle pagination if timeline exists
|
|
203
|
+
if 'timeline' in data and data['timeline']:
|
|
204
|
+
paginated_timeline = paginate_timeline(data['timeline'], args.page)
|
|
205
|
+
|
|
206
|
+
if paginated_timeline is None:
|
|
207
|
+
# Page out of range
|
|
208
|
+
print("//end")
|
|
209
|
+
sys.exit(0)
|
|
210
|
+
else:
|
|
211
|
+
# Return paginated data
|
|
212
|
+
paginated_data = {
|
|
213
|
+
'sessionId': data.get('sessionId'),
|
|
214
|
+
'timeline': paginated_timeline,
|
|
215
|
+
'page': args.page
|
|
216
|
+
}
|
|
217
|
+
print(json.dumps(paginated_data, indent=2))
|
|
218
|
+
sys.exit(0)
|
|
219
|
+
else:
|
|
220
|
+
# No timeline or empty timeline
|
|
221
|
+
if args.page == 1:
|
|
222
|
+
print(json.dumps(data, indent=2))
|
|
223
|
+
else:
|
|
224
|
+
print("//end")
|
|
225
|
+
sys.exit(0)
|
|
226
|
+
else:
|
|
227
|
+
# Error case
|
|
228
|
+
error_data = {
|
|
229
|
+
'error': f'API returned status {response.status_code}',
|
|
230
|
+
'status_code': response.status_code,
|
|
231
|
+
'session_id': args.session_id
|
|
232
|
+
}
|
|
233
|
+
print(json.dumps(error_data, indent=2), file=sys.stderr)
|
|
234
|
+
sys.exit(1)
|
|
235
|
+
|
|
236
|
+
except requests.exceptions.ConnectionError:
|
|
237
|
+
error_data = {
|
|
238
|
+
'error': f'Could not connect to API server at {args.api_base}',
|
|
239
|
+
'status_code': 0
|
|
240
|
+
}
|
|
241
|
+
print(json.dumps(error_data, indent=2), file=sys.stderr)
|
|
242
|
+
sys.exit(1)
|
|
243
|
+
|
|
244
|
+
except requests.exceptions.Timeout:
|
|
245
|
+
error_data = {
|
|
246
|
+
'error': 'Request timeout',
|
|
247
|
+
'status_code': 0
|
|
248
|
+
}
|
|
249
|
+
print(json.dumps(error_data, indent=2), file=sys.stderr)
|
|
250
|
+
sys.exit(1)
|
|
251
|
+
|
|
252
|
+
except Exception as e:
|
|
253
|
+
error_data = {
|
|
254
|
+
'error': f'Unexpected error: {str(e)}',
|
|
255
|
+
'status_code': 0
|
|
256
|
+
}
|
|
257
|
+
print(json.dumps(error_data, indent=2), file=sys.stderr)
|
|
258
|
+
sys.exit(1)
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
if __name__ == '__main__':
|
|
262
|
+
main()
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env -S uv run --script
|
|
2
|
+
# /// script
|
|
3
|
+
# requires-python = ">=3.8"
|
|
4
|
+
# ///
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
PreToolUse hook to intercept Bash calls to './getCurrentSessionId.sh' and block
|
|
8
|
+
with exit(2) returning the session ID. This enables session introspection by
|
|
9
|
+
subagents without requiring actual shell script execution.
|
|
10
|
+
|
|
11
|
+
Author: AlexStorm
|
|
12
|
+
Purpose: Session Review System - Hook Infrastructure
|
|
13
|
+
Phase: 06-SessionReviewAgent
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import json
|
|
17
|
+
import sys
|
|
18
|
+
import os
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def main():
|
|
22
|
+
try:
|
|
23
|
+
# Read hook input from stdin
|
|
24
|
+
input_data = json.load(sys.stdin)
|
|
25
|
+
|
|
26
|
+
# Extract tool information
|
|
27
|
+
tool_name = input_data.get('tool_name', '')
|
|
28
|
+
tool_input = input_data.get('tool_input', {})
|
|
29
|
+
session_id = input_data.get('session_id', 'unknown')
|
|
30
|
+
|
|
31
|
+
# Only intercept Bash tool calls
|
|
32
|
+
if tool_name != 'Bash':
|
|
33
|
+
# Let all other tools pass through
|
|
34
|
+
sys.exit(0)
|
|
35
|
+
|
|
36
|
+
# Get the command from the tool input
|
|
37
|
+
command = tool_input.get('command', '').strip()
|
|
38
|
+
|
|
39
|
+
# Check if this is a call to getCurrentSessionId.sh
|
|
40
|
+
# Support different invocation patterns:
|
|
41
|
+
# - ./getCurrentSessionId.sh
|
|
42
|
+
# - bash getCurrentSessionId.sh
|
|
43
|
+
# - sh getCurrentSessionId.sh
|
|
44
|
+
# - /path/to/getCurrentSessionId.sh
|
|
45
|
+
if ('getCurrentSessionId.sh' in command):
|
|
46
|
+
|
|
47
|
+
# This is the command we want to intercept!
|
|
48
|
+
# Block the execution and return session ID via stderr (exit 2 pattern)
|
|
49
|
+
session_message = f"Session ID: {session_id}"
|
|
50
|
+
|
|
51
|
+
# Exit with code 2 to block the tool call and provide the session ID
|
|
52
|
+
# According to the hook documentation, exit code 2 feeds stderr back to Claude
|
|
53
|
+
print(session_message, file=sys.stderr)
|
|
54
|
+
sys.exit(2)
|
|
55
|
+
|
|
56
|
+
# For all other bash commands, let them pass through normally
|
|
57
|
+
sys.exit(0)
|
|
58
|
+
|
|
59
|
+
except json.JSONDecodeError as e:
|
|
60
|
+
print(f"Error: Invalid JSON input in session ID interceptor: {e}", file=sys.stderr)
|
|
61
|
+
sys.exit(1)
|
|
62
|
+
except Exception as e:
|
|
63
|
+
# Log error but don't block other commands
|
|
64
|
+
print(f"Error in session ID interceptor: {e}", file=sys.stderr)
|
|
65
|
+
sys.exit(1)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
if __name__ == '__main__':
|
|
69
|
+
main()
|
package/.claude/settings.json
CHANGED
|
@@ -2,12 +2,27 @@
|
|
|
2
2
|
"hooks": {
|
|
3
3
|
"PreToolUse": [
|
|
4
4
|
{
|
|
5
|
-
"matcher": "",
|
|
5
|
+
"matcher": "Bash",
|
|
6
|
+
"hooks": [
|
|
7
|
+
{
|
|
8
|
+
"type": "command",
|
|
9
|
+
"command": "uv run $CLAUDE_PROJECT_DIR/.claude/hooks/session-data/intercept_session_id.py",
|
|
10
|
+
"timeout": 5
|
|
11
|
+
}
|
|
12
|
+
]
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"matcher": "Task",
|
|
6
16
|
"hooks": [
|
|
7
17
|
{
|
|
8
18
|
"type": "command",
|
|
9
19
|
"command": "uv run $CLAUDE_PROJECT_DIR/.claude/hooks/comms/register_subagent.py"
|
|
10
|
-
}
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"matcher": "",
|
|
25
|
+
"hooks": [
|
|
11
26
|
{
|
|
12
27
|
"type": "command",
|
|
13
28
|
"command": "uv run $CLAUDE_PROJECT_DIR/.claude/hooks/observability/send_event.py --source-app cc-hook-multi-agent-obvs --event-type PreToolUse --summarize"
|
|
@@ -17,12 +32,17 @@
|
|
|
17
32
|
],
|
|
18
33
|
"PostToolUse": [
|
|
19
34
|
{
|
|
20
|
-
"matcher": "",
|
|
35
|
+
"matcher": "Task",
|
|
21
36
|
"hooks": [
|
|
22
37
|
{
|
|
23
38
|
"type": "command",
|
|
24
39
|
"command": "uv run $CLAUDE_PROJECT_DIR/.claude/hooks/comms/update_subagent_completion.py"
|
|
25
|
-
}
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"matcher": "",
|
|
45
|
+
"hooks": [
|
|
26
46
|
{
|
|
27
47
|
"type": "command",
|
|
28
48
|
"command": "uv run $CLAUDE_PROJECT_DIR/.claude/hooks/observability/send_event.py --source-app cc-hook-multi-agent-obvs --event-type PostToolUse --summarize"
|
package/CLAUDE.md
CHANGED
|
@@ -60,6 +60,13 @@ TEAM COLLABORATION:
|
|
|
60
60
|
- Support your Team with [what]
|
|
61
61
|
- Coordinate with your Team on [shared concern]
|
|
62
62
|
|
|
63
|
+
|
|
64
|
+
⭐*The successful delivery of your assigned task, contributes to the high level Assignment:*⭐
|
|
65
|
+
[User's exact ASSIGNMENT]
|
|
66
|
+
|
|
67
|
+
⭐Ensure you are alligned with this North Star objective*⭐
|
|
68
|
+
|
|
69
|
+
|
|
63
70
|
[FirstNameLastName], adopt 🤝 TEAMWORK to achieve maximum value delivered."
|
|
64
71
|
```
|
|
65
72
|
|