@medicine-wheel/session-reader 0.2.2
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 +148 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -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 +278 -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 +24 -0
- package/dist/types.js.map +1 -0
- package/package.json +53 -0
package/README.md
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
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
|
|
148
|
+
|
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,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Medicine Wheel Session Reader
|
|
4
|
+
*
|
|
5
|
+
* Reads agent session event data from _sessiondata/ JSONL files.
|
|
6
|
+
* Zero external dependencies — only uses Node.js built-ins.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { listSessions, getSessionDetail, searchSessions } from '@medicine-wheel/session-reader';
|
|
11
|
+
*
|
|
12
|
+
* const sessions = await listSessions({ model: 'claude-sonnet-4-20250514' });
|
|
13
|
+
* const detail = await getSessionDetail(sessions[0].id);
|
|
14
|
+
* console.log(detail.analytics.toolUsage);
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.getLatestEvents = exports.readSessionFile = exports.searchSessions = exports.getSessionDetail = exports.getSessionEvents = exports.getSessionSummary = exports.getDistinctModels = exports.listSessions = exports.EVENT_ICONS = void 0;
|
|
19
|
+
var types_js_1 = require("./types.js");
|
|
20
|
+
Object.defineProperty(exports, "EVENT_ICONS", { enumerable: true, get: function () { return types_js_1.EVENT_ICONS; } });
|
|
21
|
+
// Session operations
|
|
22
|
+
var sessions_js_1 = require("./sessions.js");
|
|
23
|
+
Object.defineProperty(exports, "listSessions", { enumerable: true, get: function () { return sessions_js_1.listSessions; } });
|
|
24
|
+
Object.defineProperty(exports, "getDistinctModels", { enumerable: true, get: function () { return sessions_js_1.getDistinctModels; } });
|
|
25
|
+
Object.defineProperty(exports, "getSessionSummary", { enumerable: true, get: function () { return sessions_js_1.getSessionSummary; } });
|
|
26
|
+
Object.defineProperty(exports, "getSessionEvents", { enumerable: true, get: function () { return sessions_js_1.getSessionEvents; } });
|
|
27
|
+
Object.defineProperty(exports, "getSessionDetail", { enumerable: true, get: function () { return sessions_js_1.getSessionDetail; } });
|
|
28
|
+
Object.defineProperty(exports, "searchSessions", { enumerable: true, get: function () { return sessions_js_1.searchSessions; } });
|
|
29
|
+
Object.defineProperty(exports, "readSessionFile", { enumerable: true, get: function () { return sessions_js_1.readSessionFile; } });
|
|
30
|
+
Object.defineProperty(exports, "getLatestEvents", { enumerable: true, get: function () { return sessions_js_1.getLatestEvents; } });
|
|
31
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;AAUH,uCAAyC;AAAhC,uGAAA,WAAW,OAAA;AAEpB,qBAAqB;AACrB,6CASuB;AARrB,2GAAA,YAAY,OAAA;AACZ,gHAAA,iBAAiB,OAAA;AACjB,gHAAA,iBAAiB,OAAA;AACjB,+GAAA,gBAAgB,OAAA;AAChB,+GAAA,gBAAgB,OAAA;AAChB,6GAAA,cAAc,OAAA;AACd,8GAAA,eAAe,OAAA;AACf,8GAAA,eAAe,OAAA"}
|
|
@@ -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,278 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Medicine Wheel Session Reader — Session File Operations
|
|
4
|
+
*
|
|
5
|
+
* Reads agent session event data from _sessiondata/ JSONL files.
|
|
6
|
+
* Zero external dependencies — only uses node:fs and node:path.
|
|
7
|
+
*/
|
|
8
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
9
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.listSessions = listSessions;
|
|
13
|
+
exports.getDistinctModels = getDistinctModels;
|
|
14
|
+
exports.getSessionSummary = getSessionSummary;
|
|
15
|
+
exports.getSessionEvents = getSessionEvents;
|
|
16
|
+
exports.getSessionDetail = getSessionDetail;
|
|
17
|
+
exports.searchSessions = searchSessions;
|
|
18
|
+
exports.readSessionFile = readSessionFile;
|
|
19
|
+
exports.getLatestEvents = getLatestEvents;
|
|
20
|
+
const node_fs_1 = require("node:fs");
|
|
21
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
22
|
+
const DEFAULT_SESSION_DATA_DIR = '/a/src/_sessiondata';
|
|
23
|
+
function getSessionDir() {
|
|
24
|
+
return process.env.SESSION_DATA_DIR || DEFAULT_SESSION_DATA_DIR;
|
|
25
|
+
}
|
|
26
|
+
function parseJsonlLines(content) {
|
|
27
|
+
return content
|
|
28
|
+
.trim()
|
|
29
|
+
.split('\n')
|
|
30
|
+
.filter(Boolean)
|
|
31
|
+
.map((line) => {
|
|
32
|
+
try {
|
|
33
|
+
return JSON.parse(line);
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
.filter(Boolean);
|
|
40
|
+
}
|
|
41
|
+
async function safeRead(filePath) {
|
|
42
|
+
try {
|
|
43
|
+
return await node_fs_1.promises.readFile(filePath, 'utf-8');
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return '';
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function extractAnalytics(events) {
|
|
50
|
+
const toolUsage = {};
|
|
51
|
+
const filesEdited = new Set();
|
|
52
|
+
const eventsByType = {};
|
|
53
|
+
let promptCount = 0;
|
|
54
|
+
let toolCallCount = 0;
|
|
55
|
+
let errorCount = 0;
|
|
56
|
+
let subagentCount = 0;
|
|
57
|
+
let feedbackCount = 0;
|
|
58
|
+
let firstPrompt;
|
|
59
|
+
for (const e of events) {
|
|
60
|
+
const type = String(e.hook_event_name || 'unknown');
|
|
61
|
+
eventsByType[type] = (eventsByType[type] || 0) + 1;
|
|
62
|
+
switch (type) {
|
|
63
|
+
case 'UserPromptSubmit':
|
|
64
|
+
promptCount++;
|
|
65
|
+
if (!firstPrompt && e.prompt)
|
|
66
|
+
firstPrompt = String(e.prompt);
|
|
67
|
+
break;
|
|
68
|
+
case 'PreToolUse':
|
|
69
|
+
case 'PostToolUse':
|
|
70
|
+
toolCallCount++;
|
|
71
|
+
if (e.tool_name) {
|
|
72
|
+
const name = String(e.tool_name);
|
|
73
|
+
toolUsage[name] = (toolUsage[name] || 0) + 1;
|
|
74
|
+
}
|
|
75
|
+
if (e.file_path)
|
|
76
|
+
filesEdited.add(String(e.file_path));
|
|
77
|
+
break;
|
|
78
|
+
case 'PostToolUseFailure':
|
|
79
|
+
errorCount++;
|
|
80
|
+
break;
|
|
81
|
+
case 'SubagentStart':
|
|
82
|
+
subagentCount++;
|
|
83
|
+
break;
|
|
84
|
+
case 'CorrectiveFeedback':
|
|
85
|
+
case 'AcceptedRedirection':
|
|
86
|
+
feedbackCount++;
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
toolUsage,
|
|
92
|
+
filesEdited: [...filesEdited],
|
|
93
|
+
promptCount,
|
|
94
|
+
toolCallCount,
|
|
95
|
+
errorCount,
|
|
96
|
+
subagentCount,
|
|
97
|
+
feedbackCount,
|
|
98
|
+
eventsByType,
|
|
99
|
+
firstPrompt,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
async function listSessions(filters) {
|
|
103
|
+
const sessionDataDir = getSessionDir();
|
|
104
|
+
const entries = await node_fs_1.promises.readdir(sessionDataDir, { withFileTypes: true });
|
|
105
|
+
const sessions = [];
|
|
106
|
+
for (const entry of entries) {
|
|
107
|
+
if (!entry.isDirectory())
|
|
108
|
+
continue;
|
|
109
|
+
if (entry.name === 'data' || entry.name === '_' || entry.name.startsWith('.'))
|
|
110
|
+
continue;
|
|
111
|
+
try {
|
|
112
|
+
const summary = await getSessionSummary(entry.name);
|
|
113
|
+
if (!summary)
|
|
114
|
+
continue;
|
|
115
|
+
if (filters) {
|
|
116
|
+
if (filters.model && summary.model !== filters.model)
|
|
117
|
+
continue;
|
|
118
|
+
if (filters.hasTranscript !== undefined && summary.hasTranscript !== filters.hasTranscript)
|
|
119
|
+
continue;
|
|
120
|
+
if (filters.minEvents && summary.eventCount < filters.minEvents)
|
|
121
|
+
continue;
|
|
122
|
+
if (filters.maxEvents && summary.eventCount > filters.maxEvents)
|
|
123
|
+
continue;
|
|
124
|
+
if (filters.since && summary.startedAt && new Date(summary.startedAt) < new Date(filters.since))
|
|
125
|
+
continue;
|
|
126
|
+
if (filters.until && summary.startedAt && new Date(summary.startedAt) > new Date(filters.until))
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
sessions.push(summary);
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
// Skip unreadable sessions
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
sessions.sort((a, b) => {
|
|
136
|
+
if (!a.startedAt || !b.startedAt)
|
|
137
|
+
return 0;
|
|
138
|
+
return new Date(b.startedAt).getTime() - new Date(a.startedAt).getTime();
|
|
139
|
+
});
|
|
140
|
+
return sessions;
|
|
141
|
+
}
|
|
142
|
+
async function getDistinctModels() {
|
|
143
|
+
const sessionDataDir = getSessionDir();
|
|
144
|
+
const entries = await node_fs_1.promises.readdir(sessionDataDir, { withFileTypes: true });
|
|
145
|
+
const models = new Set();
|
|
146
|
+
for (const entry of entries) {
|
|
147
|
+
if (!entry.isDirectory() || entry.name === 'data' || entry.name === '_')
|
|
148
|
+
continue;
|
|
149
|
+
const startFile = node_path_1.default.join(sessionDataDir, entry.name, '_claude_session_starts.jsonl');
|
|
150
|
+
const content = await safeRead(startFile);
|
|
151
|
+
if (!content)
|
|
152
|
+
continue;
|
|
153
|
+
const lines = parseJsonlLines(content);
|
|
154
|
+
if (lines[0]?.model)
|
|
155
|
+
models.add(String(lines[0].model));
|
|
156
|
+
}
|
|
157
|
+
return [...models].sort();
|
|
158
|
+
}
|
|
159
|
+
async function getSessionSummary(sessionId) {
|
|
160
|
+
const sessionDir = node_path_1.default.join(getSessionDir(), sessionId);
|
|
161
|
+
try {
|
|
162
|
+
await node_fs_1.promises.access(sessionDir);
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
const files = await node_fs_1.promises.readdir(sessionDir);
|
|
168
|
+
const jsonlFiles = files.filter((f) => f.endsWith('.jsonl'));
|
|
169
|
+
let model;
|
|
170
|
+
let cwd;
|
|
171
|
+
let startedAt;
|
|
172
|
+
let endedAt;
|
|
173
|
+
let eventCount = 0;
|
|
174
|
+
let firstPrompt;
|
|
175
|
+
const startContent = await safeRead(node_path_1.default.join(sessionDir, '_claude_session_starts.jsonl'));
|
|
176
|
+
if (startContent) {
|
|
177
|
+
const lines = parseJsonlLines(startContent);
|
|
178
|
+
if (lines[0]) {
|
|
179
|
+
model = lines[0].model;
|
|
180
|
+
cwd = lines[0].cwd;
|
|
181
|
+
startedAt = (lines[0].timestamp || lines[0].created_at);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
const inputContent = await safeRead(node_path_1.default.join(sessionDir, '_claude_user_inputs.jsonl'));
|
|
185
|
+
if (inputContent) {
|
|
186
|
+
const lines = parseJsonlLines(inputContent);
|
|
187
|
+
if (lines[0]?.prompt)
|
|
188
|
+
firstPrompt = String(lines[0].prompt).slice(0, 200);
|
|
189
|
+
}
|
|
190
|
+
const endContent = await safeRead(node_path_1.default.join(sessionDir, '_claude_SessionEnd.jsonl'));
|
|
191
|
+
const hasEnd = endContent.trim().length > 0;
|
|
192
|
+
if (hasEnd) {
|
|
193
|
+
const lines = parseJsonlLines(endContent);
|
|
194
|
+
const last = lines[lines.length - 1];
|
|
195
|
+
if (last)
|
|
196
|
+
endedAt = (last.timestamp || last.created_at);
|
|
197
|
+
}
|
|
198
|
+
for (const f of jsonlFiles) {
|
|
199
|
+
const content = await safeRead(node_path_1.default.join(sessionDir, f));
|
|
200
|
+
if (content)
|
|
201
|
+
eventCount += content.trim().split('\n').filter(Boolean).length;
|
|
202
|
+
}
|
|
203
|
+
const hasTranscript = files.includes('_transcript_final.jsonl');
|
|
204
|
+
const isActive = !hasEnd && startContent.trim().length > 0;
|
|
205
|
+
return {
|
|
206
|
+
id: sessionId,
|
|
207
|
+
model,
|
|
208
|
+
cwd,
|
|
209
|
+
startedAt,
|
|
210
|
+
endedAt,
|
|
211
|
+
eventCount,
|
|
212
|
+
hasTranscript,
|
|
213
|
+
isActive,
|
|
214
|
+
files: jsonlFiles,
|
|
215
|
+
firstPrompt,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
async function getSessionEvents(sessionId) {
|
|
219
|
+
const sessionDir = node_path_1.default.join(getSessionDir(), sessionId);
|
|
220
|
+
const files = await node_fs_1.promises.readdir(sessionDir);
|
|
221
|
+
const events = [];
|
|
222
|
+
const eventFiles = files.filter((f) => f.startsWith('_claude_') && f.endsWith('.jsonl'));
|
|
223
|
+
for (const file of eventFiles) {
|
|
224
|
+
const content = await safeRead(node_path_1.default.join(sessionDir, file));
|
|
225
|
+
if (!content)
|
|
226
|
+
continue;
|
|
227
|
+
const lines = content.trim().split('\n').filter(Boolean);
|
|
228
|
+
for (let i = 0; i < lines.length; i++) {
|
|
229
|
+
try {
|
|
230
|
+
const parsed = JSON.parse(lines[i]);
|
|
231
|
+
events.push({ ...parsed, line_number: i + 1, _source_file: file });
|
|
232
|
+
}
|
|
233
|
+
catch { /* skip malformed lines */ }
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
events.sort((a, b) => {
|
|
237
|
+
if (a.timestamp && b.timestamp)
|
|
238
|
+
return new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime();
|
|
239
|
+
return 0;
|
|
240
|
+
});
|
|
241
|
+
return events;
|
|
242
|
+
}
|
|
243
|
+
async function getSessionDetail(sessionId) {
|
|
244
|
+
const summary = await getSessionSummary(sessionId);
|
|
245
|
+
if (!summary)
|
|
246
|
+
return null;
|
|
247
|
+
const events = await getSessionEvents(sessionId);
|
|
248
|
+
const analytics = extractAnalytics(events);
|
|
249
|
+
return { ...summary, analytics };
|
|
250
|
+
}
|
|
251
|
+
async function searchSessions(query, limit = 50) {
|
|
252
|
+
const all = await listSessions();
|
|
253
|
+
const results = [];
|
|
254
|
+
const lowerQuery = query.toLowerCase();
|
|
255
|
+
for (const session of all) {
|
|
256
|
+
if (results.length >= limit)
|
|
257
|
+
break;
|
|
258
|
+
if (session.id.includes(lowerQuery) ||
|
|
259
|
+
session.model?.toLowerCase().includes(lowerQuery) ||
|
|
260
|
+
session.cwd?.toLowerCase().includes(lowerQuery) ||
|
|
261
|
+
session.firstPrompt?.toLowerCase().includes(lowerQuery)) {
|
|
262
|
+
results.push(session);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
return results;
|
|
266
|
+
}
|
|
267
|
+
async function readSessionFile(sessionId, fileName) {
|
|
268
|
+
const filePath = node_path_1.default.join(getSessionDir(), sessionId, fileName);
|
|
269
|
+
const content = await safeRead(filePath);
|
|
270
|
+
if (!content)
|
|
271
|
+
return [];
|
|
272
|
+
return parseJsonlLines(content);
|
|
273
|
+
}
|
|
274
|
+
async function getLatestEvents(sessionId, sinceLineCount = 0) {
|
|
275
|
+
const events = await getSessionEvents(sessionId);
|
|
276
|
+
return events.slice(sinceLineCount);
|
|
277
|
+
}
|
|
278
|
+
//# sourceMappingURL=sessions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.js","sourceRoot":"","sources":["../src/sessions.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;AAoFH,oCAkCC;AAED,8CAeC;AAED,8CA4DC;AAED,4CAyBC;AAED,4CAMC;AAED,wCAiBC;AAED,0CAKC;AAED,0CAGC;AArQD,qCAAyC;AACzC,0DAA6B;AAG7B,MAAM,wBAAwB,GAAG,qBAAqB,CAAC;AAEvD,SAAS,aAAa;IACpB,OAAO,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,wBAAwB,CAAC;AAClE,CAAC;AAED,SAAS,eAAe,CAAC,OAAe;IACtC,OAAO,OAAO;SACX,IAAI,EAAE;SACN,KAAK,CAAC,IAAI,CAAC;SACX,MAAM,CAAC,OAAO,CAAC;SACf,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACZ,IAAI,CAAC;YAAC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAAC,CAAC;QAChC,MAAM,CAAC;YAAC,OAAO,IAAI,CAAC;QAAC,CAAC;IACxB,CAAC,CAAC;SACD,MAAM,CAAC,OAAO,CAA8B,CAAC;AAClD,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,QAAgB;IACtC,IAAI,CAAC;QAAC,OAAO,MAAM,kBAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAAC,CAAC;IACpD,MAAM,CAAC;QAAC,OAAO,EAAE,CAAC;IAAC,CAAC;AACtB,CAAC;AAED,SAAS,gBAAgB,CAAC,MAAsB;IAC9C,MAAM,SAAS,GAA2B,EAAE,CAAC;IAC7C,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;IACtC,MAAM,YAAY,GAA2B,EAAE,CAAC;IAChD,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,IAAI,WAA+B,CAAC;IAEpC,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,eAAe,IAAI,SAAS,CAAC,CAAC;QACpD,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAEnD,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,kBAAkB;gBACrB,WAAW,EAAE,CAAC;gBACd,IAAI,CAAC,WAAW,IAAI,CAAC,CAAC,MAAM;oBAAE,WAAW,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;gBAC7D,MAAM;YACR,KAAK,YAAY,CAAC;YAClB,KAAK,aAAa;gBAChB,aAAa,EAAE,CAAC;gBAChB,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC;oBAChB,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;oBACjC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;gBAC/C,CAAC;gBACD,IAAI,CAAC,CAAC,SAAS;oBAAE,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;gBACtD,MAAM;YACR,KAAK,oBAAoB;gBACvB,UAAU,EAAE,CAAC;gBACb,MAAM;YACR,KAAK,eAAe;gBAClB,aAAa,EAAE,CAAC;gBAChB,MAAM;YACR,KAAK,oBAAoB,CAAC;YAC1B,KAAK,qBAAqB;gBACxB,aAAa,EAAE,CAAC;gBAChB,MAAM;QACV,CAAC;IACH,CAAC;IAED,OAAO;QACL,SAAS;QACT,WAAW,EAAE,CAAC,GAAG,WAAW,CAAC;QAC7B,WAAW;QACX,aAAa;QACb,UAAU;QACV,aAAa;QACb,aAAa;QACb,YAAY;QACZ,WAAW;KACZ,CAAC;AACJ,CAAC;AAEM,KAAK,UAAU,YAAY,CAAC,OAAwB;IACzD,MAAM,cAAc,GAAG,aAAa,EAAE,CAAC;IACvC,MAAM,OAAO,GAAG,MAAM,kBAAE,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1E,MAAM,QAAQ,GAAqB,EAAE,CAAC;IAEtC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;YAAE,SAAS;QACnC,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,IAAI,KAAK,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAExF,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACpD,IAAI,CAAC,OAAO;gBAAE,SAAS;YAEvB,IAAI,OAAO,EAAE,CAAC;gBACZ,IAAI,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,KAAK,OAAO,CAAC,KAAK;oBAAE,SAAS;gBAC/D,IAAI,OAAO,CAAC,aAAa,KAAK,SAAS,IAAI,OAAO,CAAC,aAAa,KAAK,OAAO,CAAC,aAAa;oBAAE,SAAS;gBACrG,IAAI,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,UAAU,GAAG,OAAO,CAAC,SAAS;oBAAE,SAAS;gBAC1E,IAAI,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,UAAU,GAAG,OAAO,CAAC,SAAS;oBAAE,SAAS;gBAC1E,IAAI,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,SAAS,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;oBAAE,SAAS;gBAC1G,IAAI,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,SAAS,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;oBAAE,SAAS;YAC5G,CAAC;YAED,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzB,CAAC;QAAC,MAAM,CAAC;YACP,2BAA2B;QAC7B,CAAC;IACH,CAAC;IAED,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACrB,IAAI,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,SAAS;YAAE,OAAO,CAAC,CAAC;QAC3C,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;IAC3E,CAAC,CAAC,CAAC;IAEH,OAAO,QAAQ,CAAC;AAClB,CAAC;AAEM,KAAK,UAAU,iBAAiB;IACrC,MAAM,cAAc,GAAG,aAAa,EAAE,CAAC;IACvC,MAAM,OAAO,GAAG,MAAM,kBAAE,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1E,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;IAEjC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,IAAI,KAAK,GAAG;YAAE,SAAS;QAClF,MAAM,SAAS,GAAG,mBAAI,CAAC,IAAI,CAAC,cAAc,EAAE,KAAK,CAAC,IAAI,EAAE,8BAA8B,CAAC,CAAC;QACxF,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,SAAS,CAAC,CAAC;QAC1C,IAAI,CAAC,OAAO;YAAE,SAAS;QACvB,MAAM,KAAK,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;QACvC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK;YAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;AAC5B,CAAC;AAEM,KAAK,UAAU,iBAAiB,CAAC,SAAiB;IACvD,MAAM,UAAU,GAAG,mBAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,SAAS,CAAC,CAAC;IAEzD,IAAI,CAAC;QAAC,MAAM,kBAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAAC,CAAC;IACpC,MAAM,CAAC;QAAC,OAAO,IAAI,CAAC;IAAC,CAAC;IAEtB,MAAM,KAAK,GAAG,MAAM,kBAAE,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC3C,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;IAE7D,IAAI,KAAyB,CAAC;IAC9B,IAAI,GAAuB,CAAC;IAC5B,IAAI,SAA6B,CAAC;IAClC,IAAI,OAA2B,CAAC;IAChC,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,WAA+B,CAAC;IAEpC,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,mBAAI,CAAC,IAAI,CAAC,UAAU,EAAE,8BAA8B,CAAC,CAAC,CAAC;IAC3F,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,KAAK,GAAG,eAAe,CAAC,YAAY,CAAC,CAAC;QAC5C,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YACb,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,KAAe,CAAC;YACjC,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,GAAa,CAAC;YAC7B,SAAS,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAW,CAAC;QACpE,CAAC;IACH,CAAC;IAED,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,mBAAI,CAAC,IAAI,CAAC,UAAU,EAAE,2BAA2B,CAAC,CAAC,CAAC;IACxF,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,KAAK,GAAG,eAAe,CAAC,YAAY,CAAC,CAAC;QAC5C,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM;YAAE,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC5E,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,mBAAI,CAAC,IAAI,CAAC,UAAU,EAAE,0BAA0B,CAAC,CAAC,CAAC;IACrF,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;IAC5C,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,KAAK,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;QAC1C,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACrC,IAAI,IAAI;YAAE,OAAO,GAAG,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,UAAU,CAAW,CAAC;IACpE,CAAC;IAED,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,mBAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;QACzD,IAAI,OAAO;YAAE,UAAU,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;IAC/E,CAAC;IAED,MAAM,aAAa,GAAG,KAAK,CAAC,QAAQ,CAAC,yBAAyB,CAAC,CAAC;IAChE,MAAM,QAAQ,GAAG,CAAC,MAAM,IAAI,YAAY,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;IAE3D,OAAO;QACL,EAAE,EAAE,SAAS;QACb,KAAK;QACL,GAAG;QACH,SAAS;QACT,OAAO;QACP,UAAU;QACV,aAAa;QACb,QAAQ;QACR,KAAK,EAAE,UAAU;QACjB,WAAW;KACZ,CAAC;AACJ,CAAC;AAEM,KAAK,UAAU,gBAAgB,CAAC,SAAiB;IACtD,MAAM,UAAU,GAAG,mBAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,SAAS,CAAC,CAAC;IACzD,MAAM,KAAK,GAAG,MAAM,kBAAE,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAmB,EAAE,CAAC;IAElC,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEzF,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,mBAAI,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC;QAC5D,IAAI,CAAC,OAAO;YAAE,SAAS;QACvB,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACzD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBACpC,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,MAAM,EAAE,WAAW,EAAE,CAAC,GAAG,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;YACrE,CAAC;YAAC,MAAM,CAAC,CAAC,0BAA0B,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACnB,IAAI,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,SAAS;YAAE,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;QACzG,OAAO,CAAC,CAAC;IACX,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC;AAEM,KAAK,UAAU,gBAAgB,CAAC,SAAiB;IACtD,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,SAAS,CAAC,CAAC;IACnD,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,SAAS,CAAC,CAAC;IACjD,MAAM,SAAS,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAC3C,OAAO,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,CAAC;AACnC,CAAC;AAEM,KAAK,UAAU,cAAc,CAAC,KAAa,EAAE,KAAK,GAAG,EAAE;IAC5D,MAAM,GAAG,GAAG,MAAM,YAAY,EAAE,CAAC;IACjC,MAAM,OAAO,GAAqB,EAAE,CAAC;IACrC,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IAEvC,KAAK,MAAM,OAAO,IAAI,GAAG,EAAE,CAAC;QAC1B,IAAI,OAAO,CAAC,MAAM,IAAI,KAAK;YAAE,MAAM;QAEnC,IAAI,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;YAC/B,OAAO,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;YACjD,OAAO,CAAC,GAAG,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;YAC/C,OAAO,CAAC,WAAW,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YAC5D,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAEM,KAAK,UAAU,eAAe,CAAC,SAAiB,EAAE,QAAgB;IACvE,MAAM,QAAQ,GAAG,mBAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;IACjE,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACzC,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,CAAC;IACxB,OAAO,eAAe,CAAC,OAAO,CAAC,CAAC;AAClC,CAAC;AAEM,KAAK,UAAU,eAAe,CAAC,SAAiB,EAAE,cAAc,GAAG,CAAC;IACzE,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,SAAS,CAAC,CAAC;IACjD,OAAO,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;AACtC,CAAC"}
|
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,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Medicine Wheel Session Reader — Types
|
|
4
|
+
*
|
|
5
|
+
* Shared types for agent session event data from _sessiondata/ JSONL files.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.EVENT_ICONS = void 0;
|
|
9
|
+
exports.EVENT_ICONS = {
|
|
10
|
+
SessionStart: '🚀',
|
|
11
|
+
UserPromptSubmit: '💬',
|
|
12
|
+
PreToolUse: '🔧',
|
|
13
|
+
PostToolUse: '✅',
|
|
14
|
+
PostToolUseFailure: '❌',
|
|
15
|
+
SessionEnd: '🏁',
|
|
16
|
+
Notification: '🔔',
|
|
17
|
+
SubagentStart: '🤖',
|
|
18
|
+
SubagentStop: '⏹️',
|
|
19
|
+
Stop: '🛑',
|
|
20
|
+
CorrectiveFeedback: '📝',
|
|
21
|
+
AcceptedRedirection: '↩️',
|
|
22
|
+
PermissionRequest: '🔐',
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AA2EU,QAAA,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,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@medicine-wheel/session-reader",
|
|
3
|
+
"version": "0.2.2",
|
|
4
|
+
"description": "Session event reader for the Medicine Wheel Developer Suite — JSONL parsing, session summaries, analytics extraction, and search across agent session data",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"require": "./dist/index.js",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./types": {
|
|
15
|
+
"import": "./dist/types.js",
|
|
16
|
+
"types": "./dist/types.d.ts",
|
|
17
|
+
"require": "./dist/types.js",
|
|
18
|
+
"default": "./dist/types.js"
|
|
19
|
+
},
|
|
20
|
+
"./sessions": {
|
|
21
|
+
"import": "./dist/sessions.js",
|
|
22
|
+
"types": "./dist/sessions.d.ts",
|
|
23
|
+
"require": "./dist/sessions.js",
|
|
24
|
+
"default": "./dist/sessions.js"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"sideEffects": false,
|
|
28
|
+
"files": [
|
|
29
|
+
"dist",
|
|
30
|
+
"README.md"
|
|
31
|
+
],
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "tsc",
|
|
34
|
+
"dev": "tsc --watch",
|
|
35
|
+
"lint": "tsc --noEmit",
|
|
36
|
+
"clean": "rm -rf dist",
|
|
37
|
+
"prepublishOnly": "npm run clean && npm run build"
|
|
38
|
+
},
|
|
39
|
+
"keywords": [
|
|
40
|
+
"medicine-wheel",
|
|
41
|
+
"session-reader",
|
|
42
|
+
"jsonl",
|
|
43
|
+
"agent-sessions",
|
|
44
|
+
"analytics",
|
|
45
|
+
"claude-hooks"
|
|
46
|
+
],
|
|
47
|
+
"author": "IAIP Collaborative - Shawinigan, QC",
|
|
48
|
+
"license": "MIT",
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@types/node": "^20.10.0",
|
|
51
|
+
"typescript": "^5.3.0"
|
|
52
|
+
}
|
|
53
|
+
}
|