@qiaolei81/copilot-session-viewer 0.1.9 → 0.2.1

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/.nycrc ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "all": true,
3
+ "include": [
4
+ "server.js",
5
+ "src/**/*.js",
6
+ "public/**/*.js"
7
+ ],
8
+ "exclude": [
9
+ "**/*.test.js",
10
+ "**/__tests__/**",
11
+ "**/node_modules/**",
12
+ "coverage/**",
13
+ ".nyc_output/**",
14
+ "test-results/**",
15
+ "scripts/**",
16
+ "**/*.spec.js"
17
+ ],
18
+ "reporter": [
19
+ "text",
20
+ "text-summary",
21
+ "html",
22
+ "lcov"
23
+ ],
24
+ "report-dir": "./coverage/combined",
25
+ "temp-dir": "./.nyc_output",
26
+ "cache": true,
27
+ "sourceMap": false,
28
+ "instrument": false
29
+ }
package/CHANGELOG.md CHANGED
@@ -5,6 +5,54 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.2.1] - 2026-02-25
9
+
10
+ ### Changed
11
+ - `.nyc_output/` and `coverage/` directories now properly ignored in `.gitignore`
12
+
13
+ ### Removed
14
+ - NYC coverage intermediate files (`.nyc_output/`, 1.6 MB) from repository
15
+ - Removed 28 coverage data files that should not be committed
16
+
17
+ ### Docs
18
+ - Translated `lib/parsers/README.md` from Chinese to English for international contributors
19
+
20
+ ## [0.2.0] - 2026-02-25
21
+
22
+ ### Added
23
+ - **Multi-Tool Support** - Full support for **Pi-Mono** sessions (now supports 3 tools: Copilot CLI, Claude Code, Pi-Mono)
24
+ - **Agent Review for All Tools** - AI-powered session analysis now works for all 3 supported tools
25
+ - **Pi-Mono Parser** - New `PiMonoSessionParser` with full strategy pattern implementation
26
+ - **Unified Event Format** - All 3 tools now use consistent event schema across backend and frontend
27
+ - **Backend-Generated Display Metadata** - Badge labels, source names, and display data generated in backend for consistency
28
+
29
+ ### Changed
30
+ - **Default Filter to Copilot** - Homepage now defaults to Copilot filter instead of "All" (matches user behavior)
31
+ - **Removed "All" Filter** - Simplified UI by removing the "All" filter option
32
+ - **Type Transformation Strategy** - Backend now transforms event types for unified schema (Pi-Mono `message` → `assistant.message`)
33
+ - **Tool Result Merging** - Pi-Mono tool results now properly merged into parent assistant messages
34
+ - **Badge Logic Moved to Backend** - Frontend no longer generates badge labels (single source of truth)
35
+
36
+ ### Fixed
37
+ - **Pi-Mono Agent Review Accuracy** - Fixed incorrect session data by explicitly specifying target file in prompt
38
+ - **Timeline Rendering for Old Copilot Sessions** - Old CLI format now properly expands to `assistant.message` events for timeline
39
+ - **Architecture Consistency** - Unified type transformation across all sources (no more "按了葫芦起了瓢")
40
+ - **CI Upload Directory Race Condition** - Tests now create directories defensively before file operations
41
+ - **Event Expansion Test Coverage** - Tests now verify `assistant.message` generation (frontend dependency)
42
+
43
+ ### Docs
44
+ - **README Multi-Tool Emphasis** - Updated subtitle and descriptions to highlight multi-tool support
45
+ - **lib/parsers Documentation** - Translated Chinese README to English for international contributors
46
+ - **Project Cleanup** - Removed backup files (`time-analyze-v2.ejs`, `*.bak`) and 30 failed E2E test screenshot directories
47
+
48
+ ### Performance
49
+ - **Agent Review Session Isolation** - Simplified from temporary directory approach to prompt-based file specification (6 lines vs 58 lines)
50
+
51
+ ### Architecture
52
+ - **Strategy Pattern Complete** - All 3 parsers follow unified `BaseSessionParser` interface
53
+ - **Backend Normalization** - `eventNormalizer.js` handles all format differences, frontend renders uniformly
54
+ - **No Frontend Source Checks** - Frontend doesn't check `source` field, only renders normalized data
55
+
8
56
  ## [0.1.7] - 2026-02-16
9
57
 
10
58
  ### Changed
package/README.md CHANGED
@@ -1,12 +1,14 @@
1
1
  # 🤖 Copilot Session Viewer
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/@qiaolei81/copilot-session-viewer.svg)](https://www.npmjs.com/package/@qiaolei81/copilot-session-viewer)
4
+ [![CI](https://github.com/qiaolei81/copilot-session-viewer/actions/workflows/ci.yml/badge.svg)](https://github.com/qiaolei81/copilot-session-viewer/actions/workflows/ci.yml)
4
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
6
  [![Node.js Version](https://img.shields.io/badge/node-%3E%3D18.0.0-brightgreen)](https://nodejs.org/)
6
7
 
7
- **AI-Powered Session Log Analysis Tool for GitHub Copilot CLI**
8
+ **Multi-Tool Session Log Viewer & Analyzer**
9
+ View and analyze AI coding assistant sessions from **GitHub Copilot CLI**, **Claude Code CLI**, and **Pi-Mono** with time analysis, virtual scrolling, and AI-powered insights.
8
10
 
9
- A modern web-based viewer for analyzing GitHub Copilot CLI session logs with virtual scrolling, infinite loading, time analysis, and AI-powered insights.
11
+ A modern web-based viewer for analyzing AI coding assistant session logs with virtual scrolling, infinite loading, time analysis, and AI-powered insights. Supports **GitHub Copilot CLI**, **Claude Code CLI**, and **Pi-Mono** sessions.
10
12
 
11
13
  ### Session List
12
14
  ![Session List](https://raw.githubusercontent.com/qiaolei81/copilot-session-viewer/main/docs/images/homepage.png)
@@ -39,7 +41,10 @@ copilot-session-viewer
39
41
  ### Requirements
40
42
 
41
43
  - Node.js ≥ 18.0.0
42
- - GitHub Copilot CLI (for generating session data)
44
+ - At least one AI coding assistant (optional for generating sessions):
45
+ - [GitHub Copilot CLI](https://github.com/cli/cli) (recommended)
46
+ - [Claude Code CLI](https://github.com/anthropics/claude-code)
47
+ - [Pi-Mono](https://github.com/badlogic/pi-mono)
43
48
 
44
49
  ---
45
50
 
@@ -52,37 +57,53 @@ copilot-session-viewer
52
57
  - **🚀 Virtual Scrolling** - Handle 1000+ events smoothly
53
58
  - **♾️ Infinite Scroll** - Progressive session loading for better performance
54
59
  - **🤖 AI Insights** - LLM-powered session analysis
60
+ - **🎭 Multi-Format Support** - Copilot, Claude Code, and Pi-Mono sessions
55
61
 
56
62
  ### 🎨 **User Experience**
57
63
  - **🌙 Dark Theme** - GitHub-inspired interface
58
64
  - **📱 Responsive** - Works on desktop, tablet, and mobile
59
65
  - **⚡ Fast** - Optimized virtual rendering and lazy loading
60
- - **🔐 Secure** - Local-first with no data sharing
66
+ - **🔐 Secure** - Local-first with no data sharing, XSS protection, ZIP bomb defense
61
67
 
62
68
  ### 🛠️ **Technical Features**
63
69
  - **Vue 3** - Reactive virtual scrolling
64
70
  - **Express.js** - Robust backend API
65
- - **ZIP Import/Export** - Session sharing capabilities
66
- - **Multi-format Support** - Directory and JSONL sessions
71
+ - **ZIP Import/Export** - Session sharing capabilities with security validation
72
+ - **Multi-Source Support** - Copilot (`~/.copilot/session-state/`), Claude (`~/.claude/projects/`), Pi-Mono (`~/.pi/agent/sessions/`)
73
+ - **Unified Event Format** - Consistent schema across all sources
74
+ - **Memory Pagination** - Efficient handling of large sessions
75
+ - **XSS Protection** - DOMPurify-based HTML sanitization
76
+ - **ZIP Bomb Defense** - 4-layer protection (compressed size, uncompressed size, file count, depth)
67
77
 
68
78
  ---
69
79
 
70
80
  ## 🚀 How It Works
71
81
 
72
- 1. **Generate Sessions** - Use GitHub Copilot CLI to create session logs
73
- 2. **Auto-Discovery** - Sessions are automatically detected in `~/.copilot/session-state/`
82
+ 1. **Generate Sessions** - Use GitHub Copilot CLI, Claude Code CLI, or Pi-Mono to create session logs
83
+ 2. **Auto-Discovery** - Sessions are automatically detected from:
84
+ - Copilot: `~/.copilot/session-state/`
85
+ - Claude: `~/.claude/projects/`
86
+ - Pi-Mono: `~/.pi/agent/sessions/`
74
87
  3. **Browse & Analyze** - View sessions with infinite scroll and detailed event streams
75
88
  4. **Time Analysis** - Analyze turn durations, tool usage, and sub-agent performance
76
89
  5. **AI Insights** - Generate comprehensive session analysis with Copilot
77
90
 
78
91
  ```bash
79
- # Example: Generate a session with Copilot CLI
92
+ # Example: Generate sessions with different tools
93
+
94
+ # GitHub Copilot CLI
80
95
  copilot --model claude-sonnet-4.5 -p "Help me refactor this code"
81
96
 
97
+ # Claude Code CLI
98
+ claude -p "Implement user authentication"
99
+
100
+ # Pi-Mono CLI
101
+ pi -p "Create a REST API endpoint"
102
+
82
103
  # Start the viewer
83
104
  npx @qiaolei81/copilot-session-viewer
84
105
 
85
- # Browse sessions at http://localhost:3838
106
+ # Browse all sessions at http://localhost:3838
86
107
  ```
87
108
 
88
109
  ---
@@ -97,6 +118,53 @@ npx @qiaolei81/copilot-session-viewer
97
118
 
98
119
  ---
99
120
 
121
+ ## 🧪 Testing & Quality
122
+
123
+ This project includes comprehensive unit and E2E test coverage with CI/CD integration.
124
+
125
+ ### Test Coverage
126
+
127
+ - **470+ Tests** (411 unit + 59 E2E)
128
+ - **Unified Format Tests** - Mock data validation for all sources (Copilot, Claude, Pi-Mono)
129
+ - **Security Tests** - XSS prevention, ZIP bomb defense
130
+ - **Integration Tests** - Session import/export, file operations
131
+ - **CI-Friendly** - Mock data generation for reproducible tests
132
+
133
+ ### Running Tests
134
+
135
+ ```bash
136
+ # Unit tests only
137
+ npm test
138
+
139
+ # Unit tests with coverage
140
+ npm run test:coverage
141
+
142
+ # E2E tests only
143
+ npm run test:e2e
144
+
145
+ # Lint check
146
+ npm run lint:check
147
+
148
+ # Run all tests (unit + E2E)
149
+ npm run test:all
150
+ ```
151
+
152
+ ### CI/CD Pipeline
153
+
154
+ GitHub Actions workflow includes:
155
+ 1. **Linting** - ESLint code quality checks
156
+ 2. **Unit Tests** - 411 Jest tests with coverage
157
+ 3. **Mock Data Generation** - Reproducible test session fixtures
158
+ 4. **E2E Tests** - 59 Playwright tests with Chromium
159
+ 5. **Artifact Upload** - Test results on failure
160
+
161
+ **Test Data Strategy:**
162
+ - ✅ CI uses generated mock data (fast, reliable, no external dependencies)
163
+ - ✅ Local development can use real sessions for integration testing
164
+ - ✅ Fixtures cover all event formats (Copilot, Claude, Pi-Mono)
165
+
166
+ ---
167
+
100
168
  ## 🏗️ Architecture
101
169
 
102
170
  ```
@@ -105,23 +173,84 @@ npx @qiaolei81/copilot-session-viewer
105
173
  │ • Virtual Scroller (vue-virtual-scroller) │
106
174
  │ • Infinite Scroll (JavaScript) │
107
175
  │ • GitHub-inspired Dark Theme │
176
+ │ • XSS Protection (DOMPurify) │
108
177
  └─────────────────────────────────────────────────┘
109
178
  ↕ HTTP/API
110
179
  ┌─────────────────────────────────────────────────┐
111
180
  │ Backend (Node.js + Express) │
112
- │ • Session Repository & File Watcher
181
+ │ • Multi-Source Session Repository
182
+ │ • Unified Event Format Normalizer │
113
183
  │ • JSONL Streaming Parser │
114
184
  │ • Paginated API Endpoints │
185
+ │ • ZIP Import/Export with Security Validation │
115
186
  └─────────────────────────────────────────────────┘
116
187
  ↕ File System
117
188
  ┌─────────────────────────────────────────────────┐
118
- │ Data Layer (~/.copilot/session-state/)
119
- │ • events.jsonl (event streams)
120
- │ • workspace.yaml (metadata)
121
- │ • copilot-insight.md (AI analysis)
189
+ │ Data Layer (Multi-Source)
190
+ │ • Copilot: ~/.copilot/session-state/
191
+ │ • Claude: ~/.claude/projects/
192
+ │ • Pi-Mono: ~/.pi/agent/sessions/
122
193
  └─────────────────────────────────────────────────┘
123
194
  ```
124
195
 
196
+ ### Unified Event Format
197
+
198
+ All session sources are normalized to a consistent schema:
199
+
200
+ ```javascript
201
+ {
202
+ type: 'assistant.message',
203
+ timestamp: '2026-02-23T00:00:00.000Z',
204
+ data: {
205
+ message: 'Response text',
206
+ tools: [
207
+ {
208
+ id: 'tool-001',
209
+ name: 'read',
210
+ startTime: '2026-02-23T00:00:01.000Z',
211
+ endTime: '2026-02-23T00:00:02.000Z',
212
+ status: 'completed',
213
+ input: { path: 'file.js' },
214
+ result: { content: '...' },
215
+ error: null,
216
+ metadata: {
217
+ source: 'copilot', // or 'claude', 'pi-mono'
218
+ duration: 1000
219
+ }
220
+ }
221
+ ]
222
+ }
223
+ }
224
+ ```
225
+
226
+ **Benefits:**
227
+ - ✅ Consistent UI rendering across all sources
228
+ - ✅ Simplified frontend logic
229
+ - ✅ Easy to add new sources
230
+
231
+ ---
232
+
233
+ ## 🔒 Security
234
+
235
+ ### XSS Protection
236
+ - **DOMPurify Sanitization** - All user-generated content is sanitized before rendering
237
+ - **Whitelist-based** - Only safe HTML tags and attributes are allowed
238
+ - **JavaScript URL Protection** - Blocks `javascript:`, `data:`, and `onclick` handlers
239
+ - **Tested** - Comprehensive E2E tests for XSS attack vectors
240
+
241
+ ### ZIP Bomb Defense
242
+ 4-layer protection against malicious archives:
243
+ 1. **Compressed Size Limit** - 50 MB max upload
244
+ 2. **Uncompressed Size Limit** - 200 MB max expansion
245
+ 3. **File Count Limit** - 1000 files max
246
+ 4. **Directory Depth Limit** - 5 levels max
247
+
248
+ ### Local-First Design
249
+ - No external API calls for session data
250
+ - All processing happens locally
251
+ - Optional AI insights require user action
252
+ - No telemetry or tracking
253
+
125
254
  ---
126
255
 
127
256
  ## 🎯 Use Cases
@@ -172,6 +301,16 @@ MIT License - see [LICENSE](LICENSE) file for details
172
301
  - [vue-virtual-scroller](https://github.com/Akryum/vue-virtual-scroller) - High-performance virtual scrolling
173
302
  - [Express.js](https://expressjs.com/) - Web application framework
174
303
  - [EJS](https://ejs.co/) - Templating engine
304
+ - [DOMPurify](https://github.com/cure53/DOMPurify) - XSS protection
305
+ - [Playwright](https://playwright.dev/) - E2E testing
306
+
307
+ **Recent Updates (v0.1.9+):**
308
+ - ✨ Multi-source support (Copilot, Claude, Pi-Mono)
309
+ - 🔒 XSS protection with DOMPurify
310
+ - 🛡️ ZIP bomb defense (4-layer validation)
311
+ - 📄 Memory pagination API
312
+ - 🧪 470+ tests with CI/CD integration
313
+ - 📚 Comprehensive documentation
175
314
 
176
315
  ---
177
316
 
@@ -0,0 +1,114 @@
1
+ const { ParserFactory } = require('../lib/parsers');
2
+
3
+ // Example: Parse Copilot CLI session
4
+ function parseCopilotSession() {
5
+ const copilotEvents = [
6
+ {
7
+ type: 'session.start',
8
+ data: {
9
+ sessionId: '12345',
10
+ startTime: '2026-02-20T00:00:00Z',
11
+ selectedModel: 'claude-sonnet-4.5',
12
+ copilotVersion: '0.0.411',
13
+ context: {
14
+ cwd: '/path/to/project',
15
+ branch: 'main'
16
+ }
17
+ },
18
+ id: 'evt-1',
19
+ timestamp: '2026-02-20T00:00:00Z'
20
+ },
21
+ {
22
+ type: 'user.message',
23
+ data: {
24
+ content: 'Hello',
25
+ transformedContent: 'Hello'
26
+ },
27
+ id: 'evt-2',
28
+ timestamp: '2026-02-20T00:00:01Z',
29
+ parentId: 'evt-1'
30
+ },
31
+ {
32
+ type: 'assistant.message',
33
+ data: {
34
+ messageId: 'msg-1',
35
+ content: 'Hi there!',
36
+ toolRequests: []
37
+ },
38
+ id: 'evt-3',
39
+ timestamp: '2026-02-20T00:00:02Z',
40
+ parentId: 'evt-2'
41
+ }
42
+ ];
43
+
44
+ const factory = new ParserFactory();
45
+ const result = factory.parse(copilotEvents);
46
+
47
+ console.log('=== Copilot Session ===');
48
+ console.log('Parser type:', factory.getParserType(copilotEvents));
49
+ console.log('Metadata:', JSON.stringify(result.metadata, null, 2));
50
+ console.log('Turns:', result.turns.length);
51
+ console.log('First turn:', JSON.stringify(result.turns[0], null, 2));
52
+ }
53
+
54
+ // Example: Parse Claude Code session
55
+ function parseClaudeSession() {
56
+ const claudeEvents = [
57
+ {
58
+ type: 'user',
59
+ uuid: 'uuid-1',
60
+ parentUuid: null,
61
+ sessionId: 'session-123',
62
+ timestamp: '2026-02-20T00:00:00Z',
63
+ cwd: '/path/to/project',
64
+ gitBranch: 'main',
65
+ version: '2.1.42',
66
+ message: {
67
+ role: 'user',
68
+ content: 'Analyze this code'
69
+ }
70
+ },
71
+ {
72
+ type: 'assistant',
73
+ uuid: 'uuid-2',
74
+ parentUuid: 'uuid-1',
75
+ sessionId: 'session-123',
76
+ timestamp: '2026-02-20T00:00:01Z',
77
+ message: {
78
+ id: 'msg-1',
79
+ role: 'assistant',
80
+ model: 'claude-opus-4.6',
81
+ content: [
82
+ { type: 'text', text: "I'll analyze the code." },
83
+ {
84
+ type: 'tool_use',
85
+ id: 'tool-1',
86
+ name: 'read_file',
87
+ input: { path: 'src/main.js' }
88
+ }
89
+ ]
90
+ }
91
+ }
92
+ ];
93
+
94
+ const factory = new ParserFactory();
95
+ const result = factory.parse(claudeEvents);
96
+
97
+ console.log('\n=== Claude Code Session ===');
98
+ console.log('Parser type:', factory.getParserType(claudeEvents));
99
+ console.log('Metadata:', JSON.stringify(result.metadata, null, 2));
100
+ console.log('Turns:', result.turns.length);
101
+ console.log('First turn:', JSON.stringify(result.turns[0], null, 2));
102
+ console.log('Tool calls:', result.toolCalls.length);
103
+ }
104
+
105
+ // Run examples
106
+ if (require.main === module) {
107
+ parseCopilotSession();
108
+ parseClaudeSession();
109
+ }
110
+
111
+ module.exports = {
112
+ parseCopilotSession,
113
+ parseClaudeSession
114
+ };
@@ -0,0 +1,239 @@
1
+ # Session Event Parsers
2
+
3
+ Strategy pattern implementation for parsing session events from multiple formats.
4
+
5
+ ## Architecture
6
+
7
+ ```
8
+ lib/parsers/
9
+ ├── base-parser.js # Base parser interface
10
+ ├── copilot-parser.js # Copilot CLI format parser
11
+ ├── claude-parser.js # Claude Code format parser
12
+ ├── pi-mono-parser.js # Pi-Mono format parser
13
+ ├── parser-factory.js # Parser factory (auto-detection)
14
+ └── index.js # Export all parsers
15
+ ```
16
+
17
+ ## Design Pattern
18
+
19
+ ### Strategy Pattern
20
+
21
+ - **Strategy Interface**: `BaseSessionParser` defines methods all parsers must implement
22
+ - **Concrete Strategies**: `CopilotSessionParser`, `ClaudeSessionParser`, `PiMonoSessionParser` implement specific parsing logic
23
+ - **Context**: `ParserFactory` automatically selects the appropriate strategy
24
+
25
+ ### Benefits
26
+
27
+ 1. **Extensible**: Add new formats by simply implementing `BaseSessionParser`
28
+ 2. **Decoupled**: Parsing logic is separated from consumers
29
+ 3. **Auto-detection**: `ParserFactory` automatically identifies formats
30
+ 4. **Unified Interface**: Different formats output the same data structure
31
+
32
+ ## Usage
33
+
34
+ ### Auto-detect Format
35
+
36
+ ```javascript
37
+ const { ParserFactory } = require('./lib/parsers');
38
+
39
+ const events = [...]; // Events read from jsonl
40
+ const factory = new ParserFactory();
41
+
42
+ // Auto-detect and parse
43
+ const result = factory.parse(events);
44
+
45
+ // Get parser type
46
+ const parserType = factory.getParserType(events); // 'copilot', 'claude', or 'pi-mono'
47
+ ```
48
+
49
+ ### Use Specific Parser Directly
50
+
51
+ ```javascript
52
+ const { CopilotSessionParser, ClaudeSessionParser, PiMonoSessionParser } = require('./lib/parsers');
53
+
54
+ // Copilot CLI
55
+ const copilotParser = new CopilotSessionParser();
56
+ if (copilotParser.canParse(events)) {
57
+ const result = copilotParser.parse(events);
58
+ }
59
+
60
+ // Claude Code
61
+ const claudeParser = new ClaudeSessionParser();
62
+ if (claudeParser.canParse(events)) {
63
+ const result = claudeParser.parse(events);
64
+ }
65
+
66
+ // Pi-Mono
67
+ const piMonoParser = new PiMonoSessionParser();
68
+ if (piMonoParser.canParse(events)) {
69
+ const result = piMonoParser.parse(events);
70
+ }
71
+ ```
72
+
73
+ ## Unified Output Format
74
+
75
+ All parsers output the same data structure:
76
+
77
+ ```javascript
78
+ {
79
+ metadata: {
80
+ sessionId: "...",
81
+ startTime: "...",
82
+ model: "...",
83
+ version: "...",
84
+ cwd: "...",
85
+ branch: "...",
86
+ // ...
87
+ },
88
+ turns: [
89
+ {
90
+ turnId: "...",
91
+ userMessage: {
92
+ id: "...",
93
+ content: "...",
94
+ timestamp: "..."
95
+ },
96
+ assistantMessages: [
97
+ {
98
+ id: "...",
99
+ content: "...",
100
+ toolRequests: [...],
101
+ timestamp: "..."
102
+ }
103
+ ],
104
+ toolCalls: [...]
105
+ }
106
+ ],
107
+ toolCalls: [...],
108
+ allEvents: [...] // Raw events
109
+ }
110
+ ```
111
+
112
+ ## Supported Formats
113
+
114
+ ### 1. Copilot CLI Format
115
+
116
+ **Characteristics:**
117
+ - Event types: `session.start`, `user.message`, `assistant.message`, `tool.execution_start`
118
+ - Structure: `{type, data: {...}, id, parentId}`
119
+ - Tree relationship: Connected via `parentId`
120
+
121
+ **Example:**
122
+ ```json
123
+ {
124
+ "type": "session.start",
125
+ "data": {
126
+ "sessionId": "...",
127
+ "selectedModel": "claude-sonnet-4.5"
128
+ },
129
+ "id": "...",
130
+ "timestamp": "..."
131
+ }
132
+ ```
133
+
134
+ ### 2. Claude Code Format
135
+
136
+ **Characteristics:**
137
+ - Event types: `user`, `assistant`, `file-history-snapshot`, `queue-operation`
138
+ - Structure: `{type, uuid, parentUuid, message: {...}}`
139
+ - Tree relationship: Connected via `parentUuid`
140
+
141
+ **Example:**
142
+ ```json
143
+ {
144
+ "type": "user",
145
+ "uuid": "...",
146
+ "parentUuid": null,
147
+ "sessionId": "...",
148
+ "message": {
149
+ "role": "user",
150
+ "content": "..."
151
+ }
152
+ }
153
+ ```
154
+
155
+ ### 3. Pi-Mono Format
156
+
157
+ **Characteristics:**
158
+ - Event types: `message` (with role), `model_change`, `thinking_change`
159
+ - Structure: `{type, role, message, toolResult, timestamp}`
160
+ - Flat structure with parentId linkage for tool results
161
+
162
+ **Example:**
163
+ ```json
164
+ {
165
+ "type": "message",
166
+ "role": "user",
167
+ "message": "...",
168
+ "timestamp": "...",
169
+ "id": "..."
170
+ }
171
+ ```
172
+
173
+ ## Adding New Formats
174
+
175
+ 1. Extend `BaseSessionParser`
176
+ 2. Implement all required methods
177
+ 3. Register in `ParserFactory`
178
+
179
+ ```javascript
180
+ const BaseSessionParser = require('./base-parser');
181
+
182
+ class MyCustomParser extends BaseSessionParser {
183
+ canParse(events) {
184
+ // Detection logic
185
+ return events.some(e => e.customField);
186
+ }
187
+
188
+ parse(events) {
189
+ return {
190
+ metadata: this.getMetadata(events),
191
+ turns: this.extractTurns(events),
192
+ toolCalls: this.extractToolCalls(events),
193
+ allEvents: events
194
+ };
195
+ }
196
+
197
+ getMetadata(events) { /* ... */ }
198
+ extractTurns(events) { /* ... */ }
199
+ extractToolCalls(events) { /* ... */ }
200
+ }
201
+
202
+ // Add to parser-factory.js
203
+ this.parsers.push(new MyCustomParser());
204
+ ```
205
+
206
+ ## Testing
207
+
208
+ Run example:
209
+ ```bash
210
+ node examples/parser-usage.js
211
+ ```
212
+
213
+ ## API Documentation
214
+
215
+ ### BaseSessionParser
216
+
217
+ Base class for all parsers.
218
+
219
+ #### Methods
220
+
221
+ - `canParse(events)` - Check if this format can be parsed
222
+ - `parse(events)` - Parse events and return unified format
223
+ - `getMetadata(events)` - Extract session metadata
224
+ - `extractTurns(events)` - Extract conversation turns
225
+ - `extractToolCalls(events)` - Extract tool calls
226
+
227
+ ### ParserFactory
228
+
229
+ Parser factory for automatic format detection.
230
+
231
+ #### Methods
232
+
233
+ - `getParser(events)` - Return appropriate parser instance
234
+ - `parse(events)` - Auto-detect and parse
235
+ - `getParserType(events)` - Return parser type name
236
+
237
+ ## License
238
+
239
+ MIT