medicine-wheel-session-reader 0.1.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/README.md +147 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/sessions.d.ts +28 -0
- package/dist/sessions.d.ts.map +1 -0
- package/dist/sessions.js +265 -0
- package/dist/sessions.js.map +1 -0
- package/dist/types.d.ts +67 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +21 -0
- package/dist/types.js.map +1 -0
- package/package.json +48 -0
package/README.md
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# medicine-wheel-session-reader
|
|
2
|
+
|
|
3
|
+
Session event reader for the Medicine Wheel Developer Suite — JSONL parsing, session summaries, analytics extraction, and search across agent session data.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This package reads agent session event data from `_sessiondata/` JSONL files. Zero external dependencies — only uses Node.js built-ins.
|
|
8
|
+
|
|
9
|
+
### What it provides
|
|
10
|
+
|
|
11
|
+
| Module | Description |
|
|
12
|
+
|--------|-------------|
|
|
13
|
+
| `sessions` | Session listing, detail retrieval, search, and utility functions |
|
|
14
|
+
| `types` | TypeScript type definitions and constants for session events |
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install medicine-wheel-session-reader
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Or link locally:
|
|
23
|
+
```bash
|
|
24
|
+
npm link ../medicine-wheel/src/session-reader
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
import {
|
|
31
|
+
// Session operations
|
|
32
|
+
listSessions,
|
|
33
|
+
getSessionDetail,
|
|
34
|
+
getSessionSummary,
|
|
35
|
+
getSessionEvents,
|
|
36
|
+
searchSessions,
|
|
37
|
+
readSessionFile,
|
|
38
|
+
getLatestEvents,
|
|
39
|
+
getDistinctModels,
|
|
40
|
+
|
|
41
|
+
// Types
|
|
42
|
+
type SessionEvent,
|
|
43
|
+
type SessionAnalytics,
|
|
44
|
+
type SessionSummary,
|
|
45
|
+
type SessionFilters,
|
|
46
|
+
|
|
47
|
+
// Constants
|
|
48
|
+
EVENT_ICONS,
|
|
49
|
+
} from 'medicine-wheel-session-reader';
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Sub-path exports
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
import type { SessionEvent, SessionFilters } from 'medicine-wheel-session-reader/types';
|
|
56
|
+
import { listSessions, searchSessions } from 'medicine-wheel-session-reader/sessions';
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## API Reference
|
|
60
|
+
|
|
61
|
+
### Session listing
|
|
62
|
+
|
|
63
|
+
**`listSessions(filters?)`** — List sessions from `_sessiondata/` directories with optional filters.
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
const sessions = await listSessions({ model: 'claude-sonnet-4-20250514' });
|
|
67
|
+
const recent = await listSessions({ since: '2025-01-01', minEvents: 5 });
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Session detail
|
|
71
|
+
|
|
72
|
+
**`getSessionDetail(sessionId)`** — Full session detail including events and analytics.
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
const detail = await getSessionDetail(sessions[0].id);
|
|
76
|
+
console.log(detail.analytics.toolUsage);
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**`getSessionSummary(sessionId)`** — Summary metadata for a single session.
|
|
80
|
+
|
|
81
|
+
**`getSessionEvents(sessionId)`** — Raw event array for a session.
|
|
82
|
+
|
|
83
|
+
### Search
|
|
84
|
+
|
|
85
|
+
**`searchSessions(query)`** — Full-text search across session data.
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
const results = await searchSessions('authentication');
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Utilities
|
|
92
|
+
|
|
93
|
+
**`readSessionFile(filePath)`** — Parse a single JSONL session file into events.
|
|
94
|
+
|
|
95
|
+
**`getLatestEvents(count?)`** — Retrieve the most recent events across all sessions.
|
|
96
|
+
|
|
97
|
+
**`getDistinctModels()`** — List all unique model identifiers found in session data.
|
|
98
|
+
|
|
99
|
+
### Types
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
interface SessionEvent {
|
|
103
|
+
session_id?: string;
|
|
104
|
+
hook_event_name?: string;
|
|
105
|
+
timestamp?: string;
|
|
106
|
+
model?: string;
|
|
107
|
+
tool_name?: string;
|
|
108
|
+
prompt?: string;
|
|
109
|
+
// ... extensible with [key: string]: unknown
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
interface SessionAnalytics {
|
|
113
|
+
toolUsage: Record<string, number>;
|
|
114
|
+
filesEdited: string[];
|
|
115
|
+
promptCount: number;
|
|
116
|
+
toolCallCount: number;
|
|
117
|
+
errorCount: number;
|
|
118
|
+
// ...
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
interface SessionSummary {
|
|
122
|
+
id: string;
|
|
123
|
+
model?: string;
|
|
124
|
+
startedAt?: string;
|
|
125
|
+
endedAt?: string;
|
|
126
|
+
eventCount: number;
|
|
127
|
+
analytics?: SessionAnalytics;
|
|
128
|
+
// ...
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
interface SessionFilters {
|
|
132
|
+
model?: string;
|
|
133
|
+
hasTranscript?: boolean;
|
|
134
|
+
minEvents?: number;
|
|
135
|
+
maxEvents?: number;
|
|
136
|
+
since?: string;
|
|
137
|
+
until?: string;
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Constants
|
|
142
|
+
|
|
143
|
+
**`EVENT_ICONS`** — Emoji map for session event types (e.g., `SessionStart` → 🚀, `PreToolUse` → 🔧, `SessionEnd` → 🏁).
|
|
144
|
+
|
|
145
|
+
## License
|
|
146
|
+
|
|
147
|
+
MIT — IAIP Collaborative, Shawinigan, QC
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Medicine Wheel Session Reader
|
|
3
|
+
*
|
|
4
|
+
* Reads agent session event data from _sessiondata/ JSONL files.
|
|
5
|
+
* Zero external dependencies — only uses Node.js built-ins.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { listSessions, getSessionDetail, searchSessions } from 'medicine-wheel-session-reader';
|
|
10
|
+
*
|
|
11
|
+
* const sessions = await listSessions({ model: 'claude-sonnet-4-20250514' });
|
|
12
|
+
* const detail = await getSessionDetail(sessions[0].id);
|
|
13
|
+
* console.log(detail.analytics.toolUsage);
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export type { SessionEvent, SessionAnalytics, SessionSummary, SessionFilters, } from './types.js';
|
|
17
|
+
export { EVENT_ICONS } from './types.js';
|
|
18
|
+
export { listSessions, getDistinctModels, getSessionSummary, getSessionEvents, getSessionDetail, searchSessions, readSessionFile, getLatestEvents, } from './sessions.js';
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,YAAY,EACV,YAAY,EACZ,gBAAgB,EAChB,cAAc,EACd,cAAc,GACf,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAGzC,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,eAAe,GAChB,MAAM,eAAe,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Medicine Wheel Session Reader
|
|
3
|
+
*
|
|
4
|
+
* Reads agent session event data from _sessiondata/ JSONL files.
|
|
5
|
+
* Zero external dependencies — only uses Node.js built-ins.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { listSessions, getSessionDetail, searchSessions } from 'medicine-wheel-session-reader';
|
|
10
|
+
*
|
|
11
|
+
* const sessions = await listSessions({ model: 'claude-sonnet-4-20250514' });
|
|
12
|
+
* const detail = await getSessionDetail(sessions[0].id);
|
|
13
|
+
* console.log(detail.analytics.toolUsage);
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export { EVENT_ICONS } from './types.js';
|
|
17
|
+
// Session operations
|
|
18
|
+
export { listSessions, getDistinctModels, getSessionSummary, getSessionEvents, getSessionDetail, searchSessions, readSessionFile, getLatestEvents, } from './sessions.js';
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAUH,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,qBAAqB;AACrB,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,eAAe,GAChB,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Medicine Wheel Session Reader — Session File Operations
|
|
3
|
+
*
|
|
4
|
+
* Reads agent session event data from _sessiondata/ JSONL files.
|
|
5
|
+
* Zero external dependencies — only uses node:fs and node:path.
|
|
6
|
+
*/
|
|
7
|
+
import type { SessionSummary, SessionEvent, SessionAnalytics, SessionFilters } from './types.js';
|
|
8
|
+
export declare function listSessions(filters?: SessionFilters): Promise<SessionSummary[]>;
|
|
9
|
+
export declare function getDistinctModels(): Promise<string[]>;
|
|
10
|
+
export declare function getSessionSummary(sessionId: string): Promise<SessionSummary | null>;
|
|
11
|
+
export declare function getSessionEvents(sessionId: string): Promise<SessionEvent[]>;
|
|
12
|
+
export declare function getSessionDetail(sessionId: string): Promise<{
|
|
13
|
+
analytics: SessionAnalytics;
|
|
14
|
+
id: string;
|
|
15
|
+
model?: string;
|
|
16
|
+
cwd?: string;
|
|
17
|
+
startedAt?: string;
|
|
18
|
+
endedAt?: string;
|
|
19
|
+
eventCount: number;
|
|
20
|
+
hasTranscript: boolean;
|
|
21
|
+
isActive: boolean;
|
|
22
|
+
files: string[];
|
|
23
|
+
firstPrompt?: string;
|
|
24
|
+
} | null>;
|
|
25
|
+
export declare function searchSessions(query: string, limit?: number): Promise<SessionSummary[]>;
|
|
26
|
+
export declare function readSessionFile(sessionId: string, fileName: string): Promise<unknown[]>;
|
|
27
|
+
export declare function getLatestEvents(sessionId: string, sinceLineCount?: number): Promise<SessionEvent[]>;
|
|
28
|
+
//# sourceMappingURL=sessions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../src/sessions.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAgFjG,wBAAsB,YAAY,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAkCtF;AAED,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAe3D;AAED,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CA4DzF;AAED,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAyBjF;AAED,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,MAAM;;;;;;;;;;;;UAMvD;AAED,wBAAsB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAiBzF;AAED,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAK7F;AAED,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,cAAc,SAAI,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAGpG"}
|
package/dist/sessions.js
ADDED
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Medicine Wheel Session Reader — Session File Operations
|
|
3
|
+
*
|
|
4
|
+
* Reads agent session event data from _sessiondata/ JSONL files.
|
|
5
|
+
* Zero external dependencies — only uses node:fs and node:path.
|
|
6
|
+
*/
|
|
7
|
+
import { promises as fs } from 'node:fs';
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
const DEFAULT_SESSION_DATA_DIR = '/a/src/_sessiondata';
|
|
10
|
+
function getSessionDir() {
|
|
11
|
+
return process.env.SESSION_DATA_DIR || DEFAULT_SESSION_DATA_DIR;
|
|
12
|
+
}
|
|
13
|
+
function parseJsonlLines(content) {
|
|
14
|
+
return content
|
|
15
|
+
.trim()
|
|
16
|
+
.split('\n')
|
|
17
|
+
.filter(Boolean)
|
|
18
|
+
.map((line) => {
|
|
19
|
+
try {
|
|
20
|
+
return JSON.parse(line);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
})
|
|
26
|
+
.filter(Boolean);
|
|
27
|
+
}
|
|
28
|
+
async function safeRead(filePath) {
|
|
29
|
+
try {
|
|
30
|
+
return await fs.readFile(filePath, 'utf-8');
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return '';
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function extractAnalytics(events) {
|
|
37
|
+
const toolUsage = {};
|
|
38
|
+
const filesEdited = new Set();
|
|
39
|
+
const eventsByType = {};
|
|
40
|
+
let promptCount = 0;
|
|
41
|
+
let toolCallCount = 0;
|
|
42
|
+
let errorCount = 0;
|
|
43
|
+
let subagentCount = 0;
|
|
44
|
+
let feedbackCount = 0;
|
|
45
|
+
let firstPrompt;
|
|
46
|
+
for (const e of events) {
|
|
47
|
+
const type = String(e.hook_event_name || 'unknown');
|
|
48
|
+
eventsByType[type] = (eventsByType[type] || 0) + 1;
|
|
49
|
+
switch (type) {
|
|
50
|
+
case 'UserPromptSubmit':
|
|
51
|
+
promptCount++;
|
|
52
|
+
if (!firstPrompt && e.prompt)
|
|
53
|
+
firstPrompt = String(e.prompt);
|
|
54
|
+
break;
|
|
55
|
+
case 'PreToolUse':
|
|
56
|
+
case 'PostToolUse':
|
|
57
|
+
toolCallCount++;
|
|
58
|
+
if (e.tool_name) {
|
|
59
|
+
const name = String(e.tool_name);
|
|
60
|
+
toolUsage[name] = (toolUsage[name] || 0) + 1;
|
|
61
|
+
}
|
|
62
|
+
if (e.file_path)
|
|
63
|
+
filesEdited.add(String(e.file_path));
|
|
64
|
+
break;
|
|
65
|
+
case 'PostToolUseFailure':
|
|
66
|
+
errorCount++;
|
|
67
|
+
break;
|
|
68
|
+
case 'SubagentStart':
|
|
69
|
+
subagentCount++;
|
|
70
|
+
break;
|
|
71
|
+
case 'CorrectiveFeedback':
|
|
72
|
+
case 'AcceptedRedirection':
|
|
73
|
+
feedbackCount++;
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
toolUsage,
|
|
79
|
+
filesEdited: [...filesEdited],
|
|
80
|
+
promptCount,
|
|
81
|
+
toolCallCount,
|
|
82
|
+
errorCount,
|
|
83
|
+
subagentCount,
|
|
84
|
+
feedbackCount,
|
|
85
|
+
eventsByType,
|
|
86
|
+
firstPrompt,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
export async function listSessions(filters) {
|
|
90
|
+
const sessionDataDir = getSessionDir();
|
|
91
|
+
const entries = await fs.readdir(sessionDataDir, { withFileTypes: true });
|
|
92
|
+
const sessions = [];
|
|
93
|
+
for (const entry of entries) {
|
|
94
|
+
if (!entry.isDirectory())
|
|
95
|
+
continue;
|
|
96
|
+
if (entry.name === 'data' || entry.name === '_' || entry.name.startsWith('.'))
|
|
97
|
+
continue;
|
|
98
|
+
try {
|
|
99
|
+
const summary = await getSessionSummary(entry.name);
|
|
100
|
+
if (!summary)
|
|
101
|
+
continue;
|
|
102
|
+
if (filters) {
|
|
103
|
+
if (filters.model && summary.model !== filters.model)
|
|
104
|
+
continue;
|
|
105
|
+
if (filters.hasTranscript !== undefined && summary.hasTranscript !== filters.hasTranscript)
|
|
106
|
+
continue;
|
|
107
|
+
if (filters.minEvents && summary.eventCount < filters.minEvents)
|
|
108
|
+
continue;
|
|
109
|
+
if (filters.maxEvents && summary.eventCount > filters.maxEvents)
|
|
110
|
+
continue;
|
|
111
|
+
if (filters.since && summary.startedAt && new Date(summary.startedAt) < new Date(filters.since))
|
|
112
|
+
continue;
|
|
113
|
+
if (filters.until && summary.startedAt && new Date(summary.startedAt) > new Date(filters.until))
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
sessions.push(summary);
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
// Skip unreadable sessions
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
sessions.sort((a, b) => {
|
|
123
|
+
if (!a.startedAt || !b.startedAt)
|
|
124
|
+
return 0;
|
|
125
|
+
return new Date(b.startedAt).getTime() - new Date(a.startedAt).getTime();
|
|
126
|
+
});
|
|
127
|
+
return sessions;
|
|
128
|
+
}
|
|
129
|
+
export async function getDistinctModels() {
|
|
130
|
+
const sessionDataDir = getSessionDir();
|
|
131
|
+
const entries = await fs.readdir(sessionDataDir, { withFileTypes: true });
|
|
132
|
+
const models = new Set();
|
|
133
|
+
for (const entry of entries) {
|
|
134
|
+
if (!entry.isDirectory() || entry.name === 'data' || entry.name === '_')
|
|
135
|
+
continue;
|
|
136
|
+
const startFile = path.join(sessionDataDir, entry.name, '_claude_session_starts.jsonl');
|
|
137
|
+
const content = await safeRead(startFile);
|
|
138
|
+
if (!content)
|
|
139
|
+
continue;
|
|
140
|
+
const lines = parseJsonlLines(content);
|
|
141
|
+
if (lines[0]?.model)
|
|
142
|
+
models.add(String(lines[0].model));
|
|
143
|
+
}
|
|
144
|
+
return [...models].sort();
|
|
145
|
+
}
|
|
146
|
+
export async function getSessionSummary(sessionId) {
|
|
147
|
+
const sessionDir = path.join(getSessionDir(), sessionId);
|
|
148
|
+
try {
|
|
149
|
+
await fs.access(sessionDir);
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
const files = await fs.readdir(sessionDir);
|
|
155
|
+
const jsonlFiles = files.filter((f) => f.endsWith('.jsonl'));
|
|
156
|
+
let model;
|
|
157
|
+
let cwd;
|
|
158
|
+
let startedAt;
|
|
159
|
+
let endedAt;
|
|
160
|
+
let eventCount = 0;
|
|
161
|
+
let firstPrompt;
|
|
162
|
+
const startContent = await safeRead(path.join(sessionDir, '_claude_session_starts.jsonl'));
|
|
163
|
+
if (startContent) {
|
|
164
|
+
const lines = parseJsonlLines(startContent);
|
|
165
|
+
if (lines[0]) {
|
|
166
|
+
model = lines[0].model;
|
|
167
|
+
cwd = lines[0].cwd;
|
|
168
|
+
startedAt = (lines[0].timestamp || lines[0].created_at);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
const inputContent = await safeRead(path.join(sessionDir, '_claude_user_inputs.jsonl'));
|
|
172
|
+
if (inputContent) {
|
|
173
|
+
const lines = parseJsonlLines(inputContent);
|
|
174
|
+
if (lines[0]?.prompt)
|
|
175
|
+
firstPrompt = String(lines[0].prompt).slice(0, 200);
|
|
176
|
+
}
|
|
177
|
+
const endContent = await safeRead(path.join(sessionDir, '_claude_SessionEnd.jsonl'));
|
|
178
|
+
const hasEnd = endContent.trim().length > 0;
|
|
179
|
+
if (hasEnd) {
|
|
180
|
+
const lines = parseJsonlLines(endContent);
|
|
181
|
+
const last = lines[lines.length - 1];
|
|
182
|
+
if (last)
|
|
183
|
+
endedAt = (last.timestamp || last.created_at);
|
|
184
|
+
}
|
|
185
|
+
for (const f of jsonlFiles) {
|
|
186
|
+
const content = await safeRead(path.join(sessionDir, f));
|
|
187
|
+
if (content)
|
|
188
|
+
eventCount += content.trim().split('\n').filter(Boolean).length;
|
|
189
|
+
}
|
|
190
|
+
const hasTranscript = files.includes('_transcript_final.jsonl');
|
|
191
|
+
const isActive = !hasEnd && startContent.trim().length > 0;
|
|
192
|
+
return {
|
|
193
|
+
id: sessionId,
|
|
194
|
+
model,
|
|
195
|
+
cwd,
|
|
196
|
+
startedAt,
|
|
197
|
+
endedAt,
|
|
198
|
+
eventCount,
|
|
199
|
+
hasTranscript,
|
|
200
|
+
isActive,
|
|
201
|
+
files: jsonlFiles,
|
|
202
|
+
firstPrompt,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
export async function getSessionEvents(sessionId) {
|
|
206
|
+
const sessionDir = path.join(getSessionDir(), sessionId);
|
|
207
|
+
const files = await fs.readdir(sessionDir);
|
|
208
|
+
const events = [];
|
|
209
|
+
const eventFiles = files.filter((f) => f.startsWith('_claude_') && f.endsWith('.jsonl'));
|
|
210
|
+
for (const file of eventFiles) {
|
|
211
|
+
const content = await safeRead(path.join(sessionDir, file));
|
|
212
|
+
if (!content)
|
|
213
|
+
continue;
|
|
214
|
+
const lines = content.trim().split('\n').filter(Boolean);
|
|
215
|
+
for (let i = 0; i < lines.length; i++) {
|
|
216
|
+
try {
|
|
217
|
+
const parsed = JSON.parse(lines[i]);
|
|
218
|
+
events.push({ ...parsed, line_number: i + 1, _source_file: file });
|
|
219
|
+
}
|
|
220
|
+
catch { /* skip malformed lines */ }
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
events.sort((a, b) => {
|
|
224
|
+
if (a.timestamp && b.timestamp)
|
|
225
|
+
return new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime();
|
|
226
|
+
return 0;
|
|
227
|
+
});
|
|
228
|
+
return events;
|
|
229
|
+
}
|
|
230
|
+
export async function getSessionDetail(sessionId) {
|
|
231
|
+
const summary = await getSessionSummary(sessionId);
|
|
232
|
+
if (!summary)
|
|
233
|
+
return null;
|
|
234
|
+
const events = await getSessionEvents(sessionId);
|
|
235
|
+
const analytics = extractAnalytics(events);
|
|
236
|
+
return { ...summary, analytics };
|
|
237
|
+
}
|
|
238
|
+
export async function searchSessions(query, limit = 50) {
|
|
239
|
+
const all = await listSessions();
|
|
240
|
+
const results = [];
|
|
241
|
+
const lowerQuery = query.toLowerCase();
|
|
242
|
+
for (const session of all) {
|
|
243
|
+
if (results.length >= limit)
|
|
244
|
+
break;
|
|
245
|
+
if (session.id.includes(lowerQuery) ||
|
|
246
|
+
session.model?.toLowerCase().includes(lowerQuery) ||
|
|
247
|
+
session.cwd?.toLowerCase().includes(lowerQuery) ||
|
|
248
|
+
session.firstPrompt?.toLowerCase().includes(lowerQuery)) {
|
|
249
|
+
results.push(session);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return results;
|
|
253
|
+
}
|
|
254
|
+
export async function readSessionFile(sessionId, fileName) {
|
|
255
|
+
const filePath = path.join(getSessionDir(), sessionId, fileName);
|
|
256
|
+
const content = await safeRead(filePath);
|
|
257
|
+
if (!content)
|
|
258
|
+
return [];
|
|
259
|
+
return parseJsonlLines(content);
|
|
260
|
+
}
|
|
261
|
+
export async function getLatestEvents(sessionId, sinceLineCount = 0) {
|
|
262
|
+
const events = await getSessionEvents(sessionId);
|
|
263
|
+
return events.slice(sinceLineCount);
|
|
264
|
+
}
|
|
265
|
+
//# sourceMappingURL=sessions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.js","sourceRoot":"","sources":["../src/sessions.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Medicine Wheel Session Reader — Types
|
|
3
|
+
*
|
|
4
|
+
* Shared types for agent session event data from _sessiondata/ JSONL files.
|
|
5
|
+
*/
|
|
6
|
+
export interface SessionEvent {
|
|
7
|
+
session_id?: string;
|
|
8
|
+
hook_event_name?: string;
|
|
9
|
+
timestamp?: string;
|
|
10
|
+
line_number: number;
|
|
11
|
+
_source_file?: string;
|
|
12
|
+
cwd?: string;
|
|
13
|
+
model?: string;
|
|
14
|
+
source?: string;
|
|
15
|
+
transcript_path?: string;
|
|
16
|
+
permission_mode?: string;
|
|
17
|
+
prompt?: string;
|
|
18
|
+
tool_name?: string;
|
|
19
|
+
tool_input?: Record<string, unknown>;
|
|
20
|
+
tool_response?: string;
|
|
21
|
+
file_path?: string;
|
|
22
|
+
old_string?: string;
|
|
23
|
+
new_string?: string;
|
|
24
|
+
reason?: string;
|
|
25
|
+
agent_id?: string;
|
|
26
|
+
agent_transcript_path?: string;
|
|
27
|
+
stop_hook_active?: boolean;
|
|
28
|
+
is_error?: boolean;
|
|
29
|
+
feedback?: string;
|
|
30
|
+
tool_use_id?: string;
|
|
31
|
+
permission_suggestions?: unknown[];
|
|
32
|
+
[key: string]: unknown;
|
|
33
|
+
}
|
|
34
|
+
export interface SessionAnalytics {
|
|
35
|
+
toolUsage: Record<string, number>;
|
|
36
|
+
filesEdited: string[];
|
|
37
|
+
promptCount: number;
|
|
38
|
+
toolCallCount: number;
|
|
39
|
+
errorCount: number;
|
|
40
|
+
subagentCount: number;
|
|
41
|
+
feedbackCount: number;
|
|
42
|
+
eventsByType: Record<string, number>;
|
|
43
|
+
firstPrompt?: string;
|
|
44
|
+
}
|
|
45
|
+
export interface SessionSummary {
|
|
46
|
+
id: string;
|
|
47
|
+
model?: string;
|
|
48
|
+
cwd?: string;
|
|
49
|
+
startedAt?: string;
|
|
50
|
+
endedAt?: string;
|
|
51
|
+
eventCount: number;
|
|
52
|
+
hasTranscript: boolean;
|
|
53
|
+
isActive: boolean;
|
|
54
|
+
files: string[];
|
|
55
|
+
analytics?: SessionAnalytics;
|
|
56
|
+
firstPrompt?: string;
|
|
57
|
+
}
|
|
58
|
+
export interface SessionFilters {
|
|
59
|
+
model?: string;
|
|
60
|
+
hasTranscript?: boolean;
|
|
61
|
+
minEvents?: number;
|
|
62
|
+
maxEvents?: number;
|
|
63
|
+
since?: string;
|
|
64
|
+
until?: string;
|
|
65
|
+
}
|
|
66
|
+
export declare const EVENT_ICONS: Record<string, string>;
|
|
67
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,YAAY;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAE/B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,sBAAsB,CAAC,EAAE,OAAO,EAAE,CAAC;IAEnC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,OAAO,CAAC;IACvB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAc9C,CAAC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Medicine Wheel Session Reader — Types
|
|
3
|
+
*
|
|
4
|
+
* Shared types for agent session event data from _sessiondata/ JSONL files.
|
|
5
|
+
*/
|
|
6
|
+
export const EVENT_ICONS = {
|
|
7
|
+
SessionStart: '🚀',
|
|
8
|
+
UserPromptSubmit: '💬',
|
|
9
|
+
PreToolUse: '🔧',
|
|
10
|
+
PostToolUse: '✅',
|
|
11
|
+
PostToolUseFailure: '❌',
|
|
12
|
+
SessionEnd: '🏁',
|
|
13
|
+
Notification: '🔔',
|
|
14
|
+
SubagentStart: '🤖',
|
|
15
|
+
SubagentStop: '⏹️',
|
|
16
|
+
Stop: '🛑',
|
|
17
|
+
CorrectiveFeedback: '📝',
|
|
18
|
+
AcceptedRedirection: '↩️',
|
|
19
|
+
PermissionRequest: '🔐',
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA2EH,MAAM,CAAC,MAAM,WAAW,GAA2B;IACjD,YAAY,EAAE,IAAI;IAClB,gBAAgB,EAAE,IAAI;IACtB,UAAU,EAAE,IAAI;IAChB,WAAW,EAAE,GAAG;IAChB,kBAAkB,EAAE,GAAG;IACvB,UAAU,EAAE,IAAI;IAChB,YAAY,EAAE,IAAI;IAClB,aAAa,EAAE,IAAI;IACnB,YAAY,EAAE,IAAI;IAClB,IAAI,EAAE,IAAI;IACV,kBAAkB,EAAE,IAAI;IACxB,mBAAmB,EAAE,IAAI;IACzB,iBAAiB,EAAE,IAAI;CACxB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "medicine-wheel-session-reader",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Session event reader for the Medicine Wheel Developer Suite — JSONL parsing, session summaries, analytics extraction, and search across agent session data",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
},
|
|
13
|
+
"./types": {
|
|
14
|
+
"import": "./dist/types.js",
|
|
15
|
+
"types": "./dist/types.d.ts"
|
|
16
|
+
},
|
|
17
|
+
"./sessions": {
|
|
18
|
+
"import": "./dist/sessions.js",
|
|
19
|
+
"types": "./dist/sessions.d.ts"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"sideEffects": false,
|
|
23
|
+
"files": [
|
|
24
|
+
"dist",
|
|
25
|
+
"README.md"
|
|
26
|
+
],
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "tsc",
|
|
29
|
+
"dev": "tsc --watch",
|
|
30
|
+
"lint": "tsc --noEmit",
|
|
31
|
+
"clean": "rm -rf dist",
|
|
32
|
+
"prepublishOnly": "npm run clean && npm run build"
|
|
33
|
+
},
|
|
34
|
+
"keywords": [
|
|
35
|
+
"medicine-wheel",
|
|
36
|
+
"session-reader",
|
|
37
|
+
"jsonl",
|
|
38
|
+
"agent-sessions",
|
|
39
|
+
"analytics",
|
|
40
|
+
"claude-hooks"
|
|
41
|
+
],
|
|
42
|
+
"author": "IAIP Collaborative - Shawinigan, QC",
|
|
43
|
+
"license": "MIT",
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@types/node": "^20.10.0",
|
|
46
|
+
"typescript": "^5.3.0"
|
|
47
|
+
}
|
|
48
|
+
}
|