claude-comms 1.0.10 → 1.0.12

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.
@@ -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.*
@@ -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
 
@@ -4,6 +4,9 @@ import json
4
4
  import sys
5
5
  import requests
6
6
  import argparse
7
+ import os
8
+ sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
9
+ from utils.server_config import get_server_url
7
10
 
8
11
  def get_unread_messages(subagent_name):
9
12
  """
@@ -17,7 +20,7 @@ def get_unread_messages(subagent_name):
17
20
  """
18
21
  try:
19
22
  response = requests.post(
20
- 'http://localhost:4000/subagents/unread',
23
+ f'{get_server_url()}/subagents/unread',
21
24
  json={
22
25
  'subagent_name': subagent_name
23
26
  },
@@ -32,7 +35,7 @@ def get_unread_messages(subagent_name):
32
35
  return []
33
36
 
34
37
  except requests.exceptions.ConnectionError:
35
- print("Error: Could not connect to observability server at localhost:4000", file=sys.stderr)
38
+ print(f"Error: Could not connect to observability server at {get_server_url()}", file=sys.stderr)
36
39
  return []
37
40
  except requests.exceptions.Timeout:
38
41
  print("Error: Request timed out", file=sys.stderr)
@@ -9,6 +9,9 @@
9
9
  import json
10
10
  import sys
11
11
  import requests
12
+ import os
13
+ sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
14
+ from utils.server_config import get_server_url
12
15
 
13
16
 
14
17
  def main():
@@ -34,7 +37,7 @@ def main():
34
37
  # Register the subagent with the server
35
38
  try:
36
39
  response = requests.post(
37
- 'http://localhost:4000/subagents/register',
40
+ f'{get_server_url()}/subagents/register',
38
41
  json={
39
42
  'session_id': session_id,
40
43
  'name': nickname,
@@ -48,7 +51,7 @@ def main():
48
51
  # Now update with initial prompt using PATCH endpoint
49
52
  if initial_prompt:
50
53
  prompt_response = requests.patch(
51
- f'http://localhost:4000/subagents/{session_id}/{nickname}',
54
+ f'{get_server_url()}/subagents/{session_id}/{nickname}',
52
55
  json={'initial_prompt': initial_prompt},
53
56
  timeout=2
54
57
  )
@@ -4,6 +4,9 @@ import json
4
4
  import sys
5
5
  import requests
6
6
  import argparse
7
+ import os
8
+ sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
9
+ from utils.server_config import get_server_url
7
10
 
8
11
  def send_message(sender_name, message):
9
12
  """
@@ -26,7 +29,7 @@ def send_message(sender_name, message):
26
29
  pass
27
30
 
28
31
  response = requests.post(
29
- 'http://localhost:4000/subagents/message',
32
+ f'{get_server_url()}/subagents/message',
30
33
  json={
31
34
  'sender': sender_name,
32
35
  'message': message
@@ -41,7 +44,7 @@ def send_message(sender_name, message):
41
44
  return False
42
45
 
43
46
  except requests.exceptions.ConnectionError:
44
- print("Error: Could not connect to observability server at localhost:4000", file=sys.stderr)
47
+ print(f"Error: Could not connect to observability server at {get_server_url()}", file=sys.stderr)
45
48
  return False
46
49
  except requests.exceptions.Timeout:
47
50
  print("Error: Request timed out", file=sys.stderr)
@@ -9,6 +9,9 @@
9
9
  import json
10
10
  import sys
11
11
  import requests
12
+ import os
13
+ sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
14
+ from utils.server_config import get_server_url
12
15
 
13
16
 
14
17
  def main():
@@ -86,7 +89,7 @@ def main():
86
89
  # Update subagent completion status
87
90
  try:
88
91
  response = requests.post(
89
- 'http://localhost:4000/subagents/update-completion',
92
+ f'{get_server_url()}/subagents/update-completion',
90
93
  json={
91
94
  'session_id': session_id,
92
95
  'name': agent_name,
@@ -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()
@@ -16,8 +16,15 @@ import urllib.request
16
16
  import urllib.error
17
17
  from datetime import datetime
18
18
 
19
- def send_event_to_server(event_data, server_url='http://localhost:4000/events'):
19
+ # Add parent directory to path for imports
20
+ sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
21
+ from utils.server_config import get_server_url
22
+
23
+ def send_event_to_server(event_data, server_url=None):
20
24
  """Send event data to the observability server."""
25
+ if server_url is None:
26
+ server_url = f'{get_server_url()}/events'
27
+
21
28
  try:
22
29
  # Prepare the request
23
30
  req = urllib.request.Request(
@@ -49,7 +56,6 @@ def main():
49
56
  parser = argparse.ArgumentParser(description='Send Claude Code hook events to observability server')
50
57
  parser.add_argument('--source-app', required=True, help='Source application name')
51
58
  parser.add_argument('--event-type', required=True, help='Hook event type (PreToolUse, PostToolUse, etc.)')
52
- parser.add_argument('--server-url', default='http://localhost:4000/events', help='Server URL')
53
59
  parser.add_argument('--add-chat', action='store_true', help='Include chat transcript if available')
54
60
  parser.add_argument('--summarize', action='store_true', help='Generate AI summary of the event')
55
61
 
@@ -94,7 +100,8 @@ def main():
94
100
 
95
101
 
96
102
  # Send to server
97
- success = send_event_to_server(event_data, args.server_url)
103
+ server_url = f'{get_server_url()}/events'
104
+ success = send_event_to_server(event_data, server_url)
98
105
 
99
106
  # Always exit with 0 to not block Claude Code operations
100
107
  sys.exit(0)
@@ -0,0 +1,261 @@
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
+ import os
18
+ sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
19
+ from utils.server_config import get_server_url
20
+
21
+ # Maximum tokens per page (easily configurable)
22
+ MAX_TOKENS_PER_PAGE = 6000
23
+
24
+ try:
25
+ import tiktoken
26
+ except ImportError:
27
+ print("Error: tiktoken not installed. Run: pip install tiktoken", file=sys.stderr)
28
+ sys.exit(1)
29
+
30
+
31
+ def count_tokens(json_object, encoding):
32
+ """
33
+ Count tokens for a JSON object.
34
+ Converts object to JSON string and counts tokens.
35
+ """
36
+ json_str = json.dumps(json_object, separators=(',', ':'))
37
+ return len(encoding.encode(json_str))
38
+
39
+
40
+ def paginate_timeline(timeline, page, max_tokens=MAX_TOKENS_PER_PAGE):
41
+ """
42
+ Paginate timeline messages into chunks that fit within max_tokens.
43
+ Returns the messages for the requested page or None if out of range.
44
+ Uses tiktoken for accurate token counting, including JSON structure overhead.
45
+ """
46
+ if not timeline:
47
+ return timeline if page == 1 else None
48
+
49
+ # Get the encoding for token counting (cl100k_base for GPT-3.5/4)
50
+ try:
51
+ encoding = tiktoken.get_encoding("cl100k_base")
52
+ except Exception as e:
53
+ print(f"Error initializing tiktoken: {e}", file=sys.stderr)
54
+ # Fallback to character-based if tiktoken fails
55
+ return paginate_timeline_fallback(timeline, page)
56
+
57
+ # Calculate overhead for the JSON structure
58
+ # {"sessionId": "...", "timeline": [...], "page": N}
59
+ session_id = "8d90abf7-bd33-4367-985c-b5acb886a63a" # Example ID for overhead calculation
60
+ overhead_json = {
61
+ "sessionId": session_id,
62
+ "timeline": [],
63
+ "page": 1
64
+ }
65
+ overhead_tokens = len(encoding.encode(json.dumps(overhead_json, separators=(',', ':'))))
66
+
67
+ pages = []
68
+ current_page = []
69
+ current_tokens = overhead_tokens # Start with JSON structure overhead
70
+
71
+ for message in timeline:
72
+ message_tokens = count_tokens(message, encoding)
73
+ # Add tokens for comma separator if not first message
74
+ separator_tokens = 1 if current_page else 0
75
+
76
+ # Check if adding this message would exceed the limit
77
+ total_with_message = current_tokens + separator_tokens + message_tokens
78
+
79
+ if total_with_message > max_tokens:
80
+ if current_page:
81
+ # Save current page and start new one
82
+ pages.append(current_page)
83
+ current_page = [message]
84
+ current_tokens = overhead_tokens + message_tokens
85
+ else:
86
+ # Single message exceeds limit, but we need to include it
87
+ current_page = [message]
88
+ current_tokens = overhead_tokens + message_tokens
89
+ else:
90
+ # Add to current page (within limit)
91
+ current_page.append(message)
92
+ current_tokens = total_with_message
93
+
94
+ # Add the last page if it has content
95
+ if current_page:
96
+ pages.append(current_page)
97
+
98
+ # Return requested page or None if out of range
99
+ if page > 0 and page <= len(pages):
100
+ return pages[page - 1]
101
+ else:
102
+ return None
103
+
104
+
105
+ def get_total_pages(timeline, max_tokens=MAX_TOKENS_PER_PAGE):
106
+ """
107
+ Calculate total number of pages by checking when paginate returns None.
108
+ """
109
+ if not timeline:
110
+ return 1
111
+
112
+ page = 1
113
+ while paginate_timeline(timeline, page, max_tokens) is not None:
114
+ page += 1
115
+
116
+ return page - 1
117
+
118
+
119
+ def paginate_timeline_fallback(timeline, page, max_chars=30000):
120
+ """
121
+ Fallback character-based pagination if tiktoken is unavailable.
122
+ """
123
+ if not timeline:
124
+ return timeline if page == 1 else None
125
+
126
+ pages = []
127
+ current_page = []
128
+ current_size = 100
129
+
130
+ for message in timeline:
131
+ message_json = json.dumps(message, indent=2)
132
+ message_size = len(message_json) + 5
133
+
134
+ if current_size + message_size > max_chars and current_page:
135
+ pages.append(current_page)
136
+ current_page = [message]
137
+ current_size = 100 + message_size
138
+ else:
139
+ current_page.append(message)
140
+ current_size += message_size
141
+
142
+ if current_page:
143
+ pages.append(current_page)
144
+
145
+ if page > 0 and page <= len(pages):
146
+ return pages[page - 1]
147
+ else:
148
+ return None
149
+
150
+
151
+ def main():
152
+ """Main entry point - fetch and return paginated JSON."""
153
+ parser = argparse.ArgumentParser(
154
+ description='Fetch session data from Claude Code observability API with pagination'
155
+ )
156
+
157
+ parser.add_argument(
158
+ '--session-id',
159
+ required=True,
160
+ help='Session ID to fetch data for'
161
+ )
162
+
163
+ parser.add_argument(
164
+ '--page',
165
+ type=int,
166
+ default=1,
167
+ help='Page number to fetch (default: 1)'
168
+ )
169
+
170
+ parser.add_argument(
171
+ '--total-pages',
172
+ action='store_true',
173
+ help='Return only the total number of pages instead of page data'
174
+ )
175
+
176
+ args = parser.parse_args()
177
+
178
+ # Wait 100ms per page before hitting the DB (as requested)
179
+ if args.page > 1:
180
+ time.sleep(args.page * 0.1)
181
+
182
+ try:
183
+ # Fetch the data from API
184
+ api_base = args.api_base if args.api_base else get_server_url()
185
+ url = f"{api_base}/api/sessions/{args.session_id}/introspect"
186
+ response = requests.get(url, timeout=10)
187
+
188
+ if response.status_code == 200:
189
+ data = response.json()
190
+
191
+ # If --total-pages flag is set, return only the total page count
192
+ if args.total_pages:
193
+ if 'timeline' in data and data['timeline']:
194
+ total = get_total_pages(data['timeline'])
195
+ print(total)
196
+ else:
197
+ print(1)
198
+ sys.exit(0)
199
+
200
+ # Handle pagination if timeline exists
201
+ if 'timeline' in data and data['timeline']:
202
+ paginated_timeline = paginate_timeline(data['timeline'], args.page)
203
+
204
+ if paginated_timeline is None:
205
+ # Page out of range
206
+ print("//end")
207
+ sys.exit(0)
208
+ else:
209
+ # Return paginated data
210
+ paginated_data = {
211
+ 'sessionId': data.get('sessionId'),
212
+ 'timeline': paginated_timeline,
213
+ 'page': args.page
214
+ }
215
+ print(json.dumps(paginated_data, indent=2))
216
+ sys.exit(0)
217
+ else:
218
+ # No timeline or empty timeline
219
+ if args.page == 1:
220
+ print(json.dumps(data, indent=2))
221
+ else:
222
+ print("//end")
223
+ sys.exit(0)
224
+ else:
225
+ # Error case
226
+ error_data = {
227
+ 'error': f'API returned status {response.status_code}',
228
+ 'status_code': response.status_code,
229
+ 'session_id': args.session_id
230
+ }
231
+ print(json.dumps(error_data, indent=2), file=sys.stderr)
232
+ sys.exit(1)
233
+
234
+ except requests.exceptions.ConnectionError:
235
+ api_base = get_server_url()
236
+ error_data = {
237
+ 'error': f'Could not connect to API server at {api_base}',
238
+ 'status_code': 0
239
+ }
240
+ print(json.dumps(error_data, indent=2), file=sys.stderr)
241
+ sys.exit(1)
242
+
243
+ except requests.exceptions.Timeout:
244
+ error_data = {
245
+ 'error': 'Request timeout',
246
+ 'status_code': 0
247
+ }
248
+ print(json.dumps(error_data, indent=2), file=sys.stderr)
249
+ sys.exit(1)
250
+
251
+ except Exception as e:
252
+ error_data = {
253
+ 'error': f'Unexpected error: {str(e)}',
254
+ 'status_code': 0
255
+ }
256
+ print(json.dumps(error_data, indent=2), file=sys.stderr)
257
+ sys.exit(1)
258
+
259
+
260
+ if __name__ == '__main__':
261
+ 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()
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Utility module to get the communication server URL from environment variable.
4
+ Falls back to default if not set.
5
+ """
6
+
7
+ import os
8
+
9
+ def get_server_url():
10
+ """
11
+ Get the communication server URL from CLAUDE_COMMS_SERVER environment variable.
12
+ Falls back to http://localhost:4000 if not set.
13
+
14
+ Returns:
15
+ str: The server URL
16
+ """
17
+ return os.environ.get('CLAUDE_COMMS_SERVER', 'http://localhost:4000')
@@ -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
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-comms",
3
- "version": "1.0.10",
3
+ "version": "1.0.12",
4
4
  "description": "NPX installer for Claude Code hooks and observability setup",
5
5
  "main": "src/index.js",
6
6
  "bin": {