Setting the file. One moment.
Extract Data · Extracting Session Data · bitwarden/ai-plugins · Skills Docs
ContentsBack to the top of the page 19
Running Work Transitions
scripts/ extract-data.sh
Shell · 246 lines · 8 KB
jq
&
>
/dev/null;
then
13 echo "Error: jq is required but not installed. Install with: brew install jq" >&2
14 exit 1
15 fi
16
17 # Default options
18 EXTRACT_TYPE = ""
19 SESSION_ID = ""
20 PROJECT_DIR = "${ PWD }"
21 OUTPUT_FORMAT = "text"
22 LIMIT = ""
23
24 # Parse arguments
25 while [[ $# -gt 0 ]]; do
26 case $1 in
27 --type )
28 EXTRACT_TYPE = " $2 "
29 shift 2
30 ;;
31 --session )
32 SESSION_ID = " $2 "
33 shift 2
34 ;;
35 --project )
36 PROJECT_DIR = " $2 "
37 shift 2
38 ;;
39 --format )
40 OUTPUT_FORMAT = " $2 "
41 shift 2
42 ;;
43 --limit )
44 LIMIT = " $2 "
45 shift 2
46 ;;
47 --help )
48 echo "Usage: $0 --type TYPE [options]"
49 echo ""
50 echo "Required:"
51 echo " --type TYPE Data to extract: metadata, user-prompts, tool-usage,"
52 echo " errors, thinking, text-responses, statistics, all"
53 echo ""
54 echo "Options:"
55 echo " --session ID Extract from specific session (default: all sessions)"
56 echo " --project DIR Project directory (default: current directory)"
57 echo " --format FORMAT Output format: text (default), json, csv"
58 echo " --limit N Limit output to first N items"
59 echo " --help Show this help message"
60 echo ""
61 echo "Examples:"
62 echo " $0 --type statistics # Stats for all sessions"
63 echo " $0 --type errors --session abc123 # Errors from specific session"
64 echo " $0 --type tool-usage --format json # Tool usage in JSON format"
65 exit 0
66 ;;
67 *)
68 echo "Error: Unknown argument: $1 " >&2
69 exit 1
70 ;;
71 esac
72 done
73
74 # Validate required arguments
75 if [ -z "${ EXTRACT_TYPE }" ]; then
76 echo "Error: --type is required" >&2
77 echo "Run ' $0 --help' for usage information" >&2
78 exit 1
79 fi
80
81 # Get session files
82 if [ -n "${ SESSION_ID }" ]; then
83 # Single session
84 SESSION_FILE = $( "${ SCRIPT_DIR }/locate-logs.sh" "${ PROJECT_DIR }" "${ SESSION_ID }" )
85 if [ ! -f "${ SESSION_FILE }" ]; then
86 echo "Error: Session file not found: ${ SESSION_FILE }" >&2
87 exit 1
88 fi
89 SESSION_FILES = ( "${ SESSION_FILE }" )
90 else
91 # All sessions
92 LOGS_DIR = $( "${ SCRIPT_DIR }/locate-logs.sh" "${ PROJECT_DIR }" )
93 if [ ! -d "${ LOGS_DIR }" ]; then
94 echo "Error: Logs directory not found: ${ LOGS_DIR }" >&2
95 exit 1
96 fi
97
98 SESSION_FILES = ()
99 while IFS = read -r file ; do
100 SESSION_FILES += ( " $file " )
101 done < <( find "${ LOGS_DIR }" -maxdepth 1 -name "*.jsonl" -type f)
102
103 if [ ${ # SESSION_FILES[ @ ]} -eq 0 ]; then
104 echo "Error: No session files found in: ${ LOGS_DIR }" >&2
105 exit 1
106 fi
107 fi
108
109 # Apply limit if specified
110 apply_limit () {
111 if [ -n "${ LIMIT }" ]; then
112 head -n "${ LIMIT }"
113 else
114 cat
115 fi
116 }
117
118 # Extract metadata
119 extract_metadata () {
120 local file = " $1 "
121 local session_id = $( basename "${ file }" .jsonl )
122
123 local first_line = $( head -1 "${ file }" )
124 local last_line = $( tail -1 "${ file }" )
125
126 echo "Session ID: ${ session_id }"
127 echo "First Timestamp: $( echo "${ first_line }" | jq -r '.timestamp // "unknown"')"
128 echo "Last Timestamp: $( echo "${ last_line }" | jq -r '.timestamp // "unknown"')"
129 echo "Git Branch: $( echo "${ first_line }" | jq -r '.gitBranch // "unknown"')"
130 echo "Working Directory: $( echo "${ first_line }" | jq -r '.cwd // "unknown"')"
131 echo "Total Lines: $( wc -l < "${ file }" | tr -d ' ')"
132 echo ""
133 }
134
135 # Extract user prompts
136 extract_user_prompts () {
137 local file = " $1 "
138 grep '"type":"user"' "${ file }" | jq -r '.message.content' | apply_limit
139 }
140
141 # Extract tool usage statistics
142 extract_tool_usage () {
143 local file = " $1 "
144 grep '"type":"assistant"' "${ file }" | \
145 jq -r '.message.content[]? | select(.type=="tool_use") | .name' | \
146 sort | uniq -c | sort -rn | \
147 awk '{printf "%-30s %d\n", $2, $1}' | \
148 apply_limit
149 }
150
151 # Extract errors
152 extract_errors () {
153 local file = " $1 "
154 grep '"is_error":true' "${ file }" | \
155 jq -r '[.timestamp, .message.content[]? | select(.is_error==true) | .content] | @tsv' | \
156 apply_limit
157 }
158
159 # Extract thinking blocks
160 extract_thinking () {
161 local file = " $1 "
162 grep '"type":"assistant"' "${ file }" | \
163 jq -r '.message.content[]? | select(.type=="thinking") | .thinking' | \
164 apply_limit
165 }
166
167 # Extract text responses
168 extract_text_responses () {
169 local file = " $1 "
170 grep '"type":"assistant"' "${ file }" | \
171 jq -r '.message.content[]? | select(.type=="text") | .text' | \
172 apply_limit
173 }
174
175 # Extract statistics
176 extract_statistics () {
177 local file = " $1 "
178 local session_id = $( basename "${ file }" .jsonl )
179 local total_lines = $( wc -l < "${ file }" | tr -d ' ' )
180 local user_msgs = $( grep -c '"type":"user"' "${ file }" 2> /dev/null || echo "0" )
181 local assistant_msgs = $( grep -c '"type":"assistant"' "${ file }" 2> /dev/null || echo "0" )
182 local tool_calls = $( grep '"type":"assistant"' "${ file }" | jq -r '.message.content[]? | select(.type=="tool_use") | .name' 2> /dev/null | wc -l | tr -d ' ' )
183 local errors = $( grep -c '"is_error":true' "${ file }" 2> /dev/null || echo "0" )
184 local thinking_blocks = $( grep '"type":"assistant"' "${ file }" | jq -r '.message.content[]? | select(.type=="thinking")' 2> /dev/null | wc -l | tr -d ' ' )
185
186 echo "Session: ${ session_id }"
187 echo " Total Lines: ${ total_lines }"
188 echo " User Messages: ${ user_msgs }"
189 echo " Assistant Messages: ${ assistant_msgs }"
190 echo " Tool Calls: ${ tool_calls }"
191 echo " Errors: ${ errors }"
192 echo " Thinking Blocks: ${ thinking_blocks }"
193 echo ""
194 }
195
196 # Process each session file
197 for session_file in "${ SESSION_FILES [ @ ]}" ; do
198 case ${EXTRACT_TYPE} in
199 metadata )
200 extract_metadata "${ session_file }"
201 ;;
202 user-prompts )
203 extract_user_prompts "${ session_file }"
204 ;;
205 tool-usage )
206 echo "=== Tool Usage: $( basename "${ session_file }" .jsonl) ==="
207 extract_tool_usage "${ session_file }"
208 echo ""
209 ;;
210 errors )
211 echo "=== Errors: $( basename "${ session_file }" .jsonl) ==="
212 extract_errors "${ session_file }"
213 echo ""
214 ;;
215 thinking )
216 echo "=== Thinking Blocks: $( basename "${ session_file }" .jsonl) ==="
217 extract_thinking "${ session_file }"
218 echo ""
219 ;;
220 text-responses )
221 extract_text_responses "${ session_file }"
222 ;;
223 statistics )
224 extract_statistics "${ session_file }"
225 ;;
226 all )
227 echo "========================================"
228 echo "Session: $( basename "${ session_file }" .jsonl)"
229 echo "========================================"
230 echo ""
231 extract_metadata "${ session_file }"
232 extract_statistics "${ session_file }"
233 echo "--- Tool Usage ---"
234 extract_tool_usage "${ session_file }"
235 echo ""
236 echo "--- Errors ---"
237 extract_errors "${ session_file }"
238 echo ""
239 ;;
240 *)
241 echo "Error: Unknown extraction type: ${ EXTRACT_TYPE }" >&2
242 echo "Valid types: metadata, user-prompts, tool-usage, errors, thinking, text-responses, statistics, all" >&2
243 exit 1
244 ;;
245 esac
246 done