genbox-agent 1.0.127 → 1.0.128
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/dist/configure-hooks.js +0 -0
- package/dist/hook.js +0 -0
- package/dist/readers/jsonl-watcher.d.ts +45 -0
- package/dist/readers/jsonl-watcher.d.ts.map +1 -0
- package/dist/readers/jsonl-watcher.js +288 -0
- package/dist/readers/jsonl-watcher.js.map +1 -0
- package/dist/readers/readers/claude-jsonl-reader.d.ts +156 -0
- package/dist/readers/readers/claude-jsonl-reader.js +556 -0
- package/dist/readers/readers/gemini-session-reader.d.ts +114 -0
- package/dist/readers/readers/gemini-session-reader.js +453 -0
- package/dist/readers/storage/repositories/messages.d.ts +156 -0
- package/dist/readers/storage/repositories/messages.js +276 -0
- package/dist/server/readers/claude-jsonl-reader.d.ts +156 -0
- package/dist/server/readers/claude-jsonl-reader.js +556 -0
- package/dist/server/readers/claude-session-reader.d.ts +117 -0
- package/dist/server/readers/claude-session-reader.js +414 -0
- package/dist/server/readers/gemini-session-reader.d.ts +114 -0
- package/dist/server/readers/gemini-session-reader.js +453 -0
- package/dist/server/readers/index.d.ts +8 -0
- package/dist/server/readers/index.js +24 -0
- package/dist/server/server/auth.d.ts +50 -0
- package/dist/server/server/auth.js +153 -0
- package/dist/server/server/index.d.ts +236 -0
- package/dist/server/server/index.js +1421 -0
- package/dist/server/server/port-finder.d.ts +44 -0
- package/dist/server/server/port-finder.js +266 -0
- package/dist/server/storage/index.d.ts +81 -0
- package/dist/server/storage/index.js +279 -0
- package/dist/server/storage/manager.d.ts +210 -0
- package/dist/server/storage/manager.js +988 -0
- package/dist/server/storage/repositories/events.d.ts +104 -0
- package/dist/server/storage/repositories/events.js +268 -0
- package/dist/server/storage/repositories/messages.d.ts +156 -0
- package/dist/server/storage/repositories/messages.js +276 -0
- package/dist/server/storage/repositories/sessions.d.ts +217 -0
- package/dist/server/storage/repositories/sessions.js +496 -0
- package/dist/server/storage/schema.d.ts +51 -0
- package/dist/server/storage/schema.js +332 -0
- package/dist/server/utils/prompt-detector.d.ts +27 -0
- package/dist/server/utils/prompt-detector.js +265 -0
- package/dist/server/utils/session-names.d.ts +18 -0
- package/dist/server/utils/session-names.js +41 -0
- package/dist/unified-daemon.js +0 -0
- package/dist/unified-hook.js +0 -0
- package/package.json +4 -4
package/dist/configure-hooks.js
CHANGED
|
File without changes
|
package/dist/hook.js
CHANGED
|
File without changes
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSONL File Watcher
|
|
3
|
+
*
|
|
4
|
+
* Watches Claude JSONL files for changes and incrementally syncs new messages
|
|
5
|
+
* to the local database. Provides instant message sync with zero polling overhead.
|
|
6
|
+
*/
|
|
7
|
+
import { StorageManager } from '../storage/manager';
|
|
8
|
+
export declare class JSONLWatcher {
|
|
9
|
+
private claudeProjectsDir;
|
|
10
|
+
private storageManager;
|
|
11
|
+
private watcher;
|
|
12
|
+
private fileStates;
|
|
13
|
+
private debounceTimers;
|
|
14
|
+
private broadcastCallback?;
|
|
15
|
+
constructor(claudeProjectsDir: string, storageManager: StorageManager);
|
|
16
|
+
/**
|
|
17
|
+
* Set callback for broadcasting events to connected clients
|
|
18
|
+
*/
|
|
19
|
+
setBroadcastCallback(callback: (event: any) => void): void;
|
|
20
|
+
/**
|
|
21
|
+
* Start watching JSONL files
|
|
22
|
+
*/
|
|
23
|
+
start(): void;
|
|
24
|
+
/**
|
|
25
|
+
* Stop watching files
|
|
26
|
+
*/
|
|
27
|
+
stop(): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Handle file change with debouncing
|
|
30
|
+
*/
|
|
31
|
+
private handleFileChange;
|
|
32
|
+
/**
|
|
33
|
+
* Incrementally sync new content from a JSONL file
|
|
34
|
+
*/
|
|
35
|
+
private syncFile;
|
|
36
|
+
/**
|
|
37
|
+
* Get watcher status
|
|
38
|
+
*/
|
|
39
|
+
getStatus(): {
|
|
40
|
+
running: boolean;
|
|
41
|
+
watchedFiles: number;
|
|
42
|
+
trackedFiles: number;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=jsonl-watcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonl-watcher.d.ts","sourceRoot":"","sources":["../../src/readers/jsonl-watcher.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAOpD,qBAAa,YAAY;IAOrB,OAAO,CAAC,iBAAiB;IACzB,OAAO,CAAC,cAAc;IAPxB,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,UAAU,CAAgC;IAClD,OAAO,CAAC,cAAc,CAAqC;IAC3D,OAAO,CAAC,iBAAiB,CAAC,CAAuB;gBAGvC,iBAAiB,EAAE,MAAM,EACzB,cAAc,EAAE,cAAc;IAGxC;;OAEG;IACH,oBAAoB,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI;IAI1D;;OAEG;IACH,KAAK,IAAI,IAAI;IA+Cb;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAqB3B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAgBxB;;OAEG;YACW,QAAQ;IAiJtB;;OAEG;IACH,SAAS,IAAI;QACX,OAAO,EAAE,OAAO,CAAC;QACjB,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;KACtB;CAOF"}
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* JSONL File Watcher
|
|
4
|
+
*
|
|
5
|
+
* Watches Claude JSONL files for changes and incrementally syncs new messages
|
|
6
|
+
* to the local database. Provides instant message sync with zero polling overhead.
|
|
7
|
+
*/
|
|
8
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(o, k2, desc);
|
|
15
|
+
}) : (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
o[k2] = m[k];
|
|
18
|
+
}));
|
|
19
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
20
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
21
|
+
}) : function(o, v) {
|
|
22
|
+
o["default"] = v;
|
|
23
|
+
});
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
41
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
42
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
43
|
+
};
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.JSONLWatcher = void 0;
|
|
46
|
+
const chokidar_1 = __importDefault(require("chokidar"));
|
|
47
|
+
const fs = __importStar(require("fs"));
|
|
48
|
+
const path = __importStar(require("path"));
|
|
49
|
+
class JSONLWatcher {
|
|
50
|
+
claudeProjectsDir;
|
|
51
|
+
storageManager;
|
|
52
|
+
watcher = null;
|
|
53
|
+
fileStates = new Map();
|
|
54
|
+
debounceTimers = new Map();
|
|
55
|
+
broadcastCallback;
|
|
56
|
+
constructor(claudeProjectsDir, storageManager) {
|
|
57
|
+
this.claudeProjectsDir = claudeProjectsDir;
|
|
58
|
+
this.storageManager = storageManager;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Set callback for broadcasting events to connected clients
|
|
62
|
+
*/
|
|
63
|
+
setBroadcastCallback(callback) {
|
|
64
|
+
this.broadcastCallback = callback;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Start watching JSONL files
|
|
68
|
+
*/
|
|
69
|
+
start() {
|
|
70
|
+
if (this.watcher) {
|
|
71
|
+
console.log('[JSONLWatcher] Already running');
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
// Check if directory exists
|
|
75
|
+
if (!fs.existsSync(this.claudeProjectsDir)) {
|
|
76
|
+
console.log(`[JSONLWatcher] Directory not found: ${this.claudeProjectsDir}`);
|
|
77
|
+
console.log('[JSONLWatcher] Will not start watcher (Claude Code not installed?)');
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const watchPattern = `${this.claudeProjectsDir}/**/*.jsonl`;
|
|
81
|
+
console.log(`[JSONLWatcher] Starting file watcher: ${watchPattern}`);
|
|
82
|
+
this.watcher = chokidar_1.default.watch(watchPattern, {
|
|
83
|
+
persistent: true,
|
|
84
|
+
ignoreInitial: true, // Don't trigger on existing files at startup
|
|
85
|
+
// IMPORTANT: Don't use awaitWriteFinish - Claude writes continuously during responses
|
|
86
|
+
// and we want real-time updates, not waiting for the file to stabilize
|
|
87
|
+
awaitWriteFinish: false,
|
|
88
|
+
// Performance options
|
|
89
|
+
usePolling: false, // Use native fs events (faster)
|
|
90
|
+
interval: 100,
|
|
91
|
+
binaryInterval: 300,
|
|
92
|
+
});
|
|
93
|
+
this.watcher.on('change', (filePath) => {
|
|
94
|
+
this.handleFileChange(filePath);
|
|
95
|
+
});
|
|
96
|
+
this.watcher.on('add', (filePath) => {
|
|
97
|
+
console.log(`[JSONLWatcher] New file detected: ${path.basename(filePath)}`);
|
|
98
|
+
this.handleFileChange(filePath);
|
|
99
|
+
});
|
|
100
|
+
this.watcher.on('error', (error) => {
|
|
101
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
102
|
+
console.error(`[JSONLWatcher] Error: ${message}`);
|
|
103
|
+
});
|
|
104
|
+
this.watcher.on('ready', () => {
|
|
105
|
+
console.log('[JSONLWatcher] Ready and watching for changes');
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Stop watching files
|
|
110
|
+
*/
|
|
111
|
+
async stop() {
|
|
112
|
+
if (!this.watcher)
|
|
113
|
+
return;
|
|
114
|
+
console.log('[JSONLWatcher] Stopping...');
|
|
115
|
+
// Clear all debounce timers
|
|
116
|
+
for (const timer of this.debounceTimers.values()) {
|
|
117
|
+
clearTimeout(timer);
|
|
118
|
+
}
|
|
119
|
+
this.debounceTimers.clear();
|
|
120
|
+
// Close watcher
|
|
121
|
+
await this.watcher.close();
|
|
122
|
+
this.watcher = null;
|
|
123
|
+
// Clear file states
|
|
124
|
+
this.fileStates.clear();
|
|
125
|
+
console.log('[JSONLWatcher] Stopped');
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Handle file change with debouncing
|
|
129
|
+
*/
|
|
130
|
+
handleFileChange(filePath) {
|
|
131
|
+
// Clear existing timer for this file
|
|
132
|
+
const existingTimer = this.debounceTimers.get(filePath);
|
|
133
|
+
if (existingTimer) {
|
|
134
|
+
clearTimeout(existingTimer);
|
|
135
|
+
}
|
|
136
|
+
// Set new timer - sync after 50ms of no changes (fast but batches rapid writes)
|
|
137
|
+
const timer = setTimeout(() => {
|
|
138
|
+
this.syncFile(filePath);
|
|
139
|
+
this.debounceTimers.delete(filePath);
|
|
140
|
+
}, 50);
|
|
141
|
+
this.debounceTimers.set(filePath, timer);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Incrementally sync new content from a JSONL file
|
|
145
|
+
*/
|
|
146
|
+
async syncFile(filePath) {
|
|
147
|
+
try {
|
|
148
|
+
// Get current file stats
|
|
149
|
+
const stats = fs.statSync(filePath);
|
|
150
|
+
const currentSize = stats.size;
|
|
151
|
+
// Get last known state
|
|
152
|
+
const fileState = this.fileStates.get(filePath) || {
|
|
153
|
+
lastPosition: 0,
|
|
154
|
+
lastSize: 0,
|
|
155
|
+
};
|
|
156
|
+
// Check if file was truncated (rare but possible)
|
|
157
|
+
if (currentSize < fileState.lastSize) {
|
|
158
|
+
console.warn(`[JSONLWatcher] File truncated: ${path.basename(filePath)} (${fileState.lastSize} → ${currentSize} bytes)`);
|
|
159
|
+
fileState.lastPosition = 0;
|
|
160
|
+
fileState.lastSize = 0;
|
|
161
|
+
}
|
|
162
|
+
// Calculate bytes to read
|
|
163
|
+
const bytesToRead = currentSize - fileState.lastPosition;
|
|
164
|
+
if (bytesToRead <= 0) {
|
|
165
|
+
// No new data
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
// Read only new bytes
|
|
169
|
+
const fd = fs.openSync(filePath, 'r');
|
|
170
|
+
const buffer = Buffer.alloc(bytesToRead);
|
|
171
|
+
fs.readSync(fd, buffer, 0, bytesToRead, fileState.lastPosition);
|
|
172
|
+
fs.closeSync(fd);
|
|
173
|
+
// Parse new lines
|
|
174
|
+
const newContent = buffer.toString('utf-8');
|
|
175
|
+
const newLines = newContent
|
|
176
|
+
.split('\n')
|
|
177
|
+
.filter(line => line.trim().length > 0);
|
|
178
|
+
if (newLines.length === 0) {
|
|
179
|
+
// Update position even if no complete lines
|
|
180
|
+
fileState.lastPosition = currentSize;
|
|
181
|
+
fileState.lastSize = currentSize;
|
|
182
|
+
this.fileStates.set(filePath, fileState);
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
// Parse JSONL entries
|
|
186
|
+
const newMessages = [];
|
|
187
|
+
for (const line of newLines) {
|
|
188
|
+
try {
|
|
189
|
+
const entry = JSON.parse(line);
|
|
190
|
+
newMessages.push(entry);
|
|
191
|
+
}
|
|
192
|
+
catch (error) {
|
|
193
|
+
console.error(`[JSONLWatcher] Failed to parse line: ${line.substring(0, 100)}...`);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
if (newMessages.length === 0) {
|
|
197
|
+
fileState.lastPosition = currentSize;
|
|
198
|
+
fileState.lastSize = currentSize;
|
|
199
|
+
this.fileStates.set(filePath, fileState);
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
// Extract Claude session ID from first message
|
|
203
|
+
const firstMessage = newMessages[0];
|
|
204
|
+
const sessionId = firstMessage.session_id || firstMessage.sessionId;
|
|
205
|
+
if (!sessionId) {
|
|
206
|
+
console.warn(`[JSONLWatcher] No session ID in messages from ${path.basename(filePath)}`);
|
|
207
|
+
fileState.lastPosition = currentSize;
|
|
208
|
+
fileState.lastSize = currentSize;
|
|
209
|
+
this.fileStates.set(filePath, fileState);
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
// Only process sessions that already exist in Genbox storage
|
|
213
|
+
// This prevents external Claude sessions from appearing in Genbox
|
|
214
|
+
const session = this.storageManager.sessions.getById(sessionId);
|
|
215
|
+
if (!session) {
|
|
216
|
+
// Session not created through Genbox - skip it
|
|
217
|
+
fileState.lastPosition = currentSize;
|
|
218
|
+
fileState.lastSize = currentSize;
|
|
219
|
+
this.fileStates.set(filePath, fileState);
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
// Store new messages - these are incremental new lines from the file
|
|
223
|
+
// Each entry from newMessages is a new line that wasn't read before
|
|
224
|
+
let messagesAdded = 0;
|
|
225
|
+
for (const msg of newMessages) {
|
|
226
|
+
// Only store user/assistant messages
|
|
227
|
+
if (msg.type === 'user' || msg.type === 'assistant') {
|
|
228
|
+
// Use message UUID from Claude if available, otherwise generate one
|
|
229
|
+
const messageId = msg.uuid || msg.id;
|
|
230
|
+
try {
|
|
231
|
+
this.storageManager.messages.create({
|
|
232
|
+
id: messageId, // Use Claude's message ID to avoid duplicates
|
|
233
|
+
sessionId,
|
|
234
|
+
role: msg.role || msg.type,
|
|
235
|
+
content: msg.message?.content || msg.content || [],
|
|
236
|
+
inputTokens: msg.message?.usage?.input_tokens || msg.input_tokens || 0,
|
|
237
|
+
outputTokens: msg.message?.usage?.output_tokens || msg.output_tokens || 0,
|
|
238
|
+
cacheReadTokens: msg.message?.usage?.cache_read_input_tokens || msg.cache_read_tokens || 0,
|
|
239
|
+
cacheWriteTokens: msg.message?.usage?.cache_creation_input_tokens || msg.cache_write_tokens || 0,
|
|
240
|
+
costCents: msg.costUSD ? Math.round(msg.costUSD * 100) : (msg.cost_cents || 0),
|
|
241
|
+
});
|
|
242
|
+
messagesAdded++;
|
|
243
|
+
}
|
|
244
|
+
catch (error) {
|
|
245
|
+
// Ignore duplicate messages (unique constraint on ID)
|
|
246
|
+
if (!String(error).includes('UNIQUE')) {
|
|
247
|
+
console.error(`[JSONLWatcher] Failed to store message: ${error}`);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
// Update file state
|
|
253
|
+
fileState.lastPosition = currentSize;
|
|
254
|
+
fileState.lastSize = currentSize;
|
|
255
|
+
this.fileStates.set(filePath, fileState);
|
|
256
|
+
if (messagesAdded > 0) {
|
|
257
|
+
console.log(`[JSONLWatcher] ✓ Synced ${messagesAdded} messages from ${path.basename(filePath)} (session: ${sessionId.substring(0, 8)}...)`);
|
|
258
|
+
// Broadcast update to connected clients
|
|
259
|
+
if (this.broadcastCallback) {
|
|
260
|
+
this.broadcastCallback({
|
|
261
|
+
type: 'message:received',
|
|
262
|
+
sessionId,
|
|
263
|
+
data: {
|
|
264
|
+
messageCount: newMessages.length,
|
|
265
|
+
messagesAdded,
|
|
266
|
+
source: 'file_watcher',
|
|
267
|
+
},
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
catch (error) {
|
|
273
|
+
console.error(`[JSONLWatcher] Error syncing ${path.basename(filePath)}: ${error.message}`);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Get watcher status
|
|
278
|
+
*/
|
|
279
|
+
getStatus() {
|
|
280
|
+
return {
|
|
281
|
+
running: this.watcher !== null,
|
|
282
|
+
watchedFiles: this.watcher ? Object.keys(this.watcher.getWatched()).length : 0,
|
|
283
|
+
trackedFiles: this.fileStates.size,
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
exports.JSONLWatcher = JSONLWatcher;
|
|
288
|
+
//# sourceMappingURL=jsonl-watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonl-watcher.js","sourceRoot":"","sources":["../../src/readers/jsonl-watcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude JSONL Session Reader
|
|
3
|
+
*
|
|
4
|
+
* Reads Claude Code session data directly from ~/.claude/projects/{project}/{session}.jsonl
|
|
5
|
+
* Parses JSONL entries and converts them to a unified message format.
|
|
6
|
+
*/
|
|
7
|
+
import { ContentBlock } from '../storage/repositories/messages';
|
|
8
|
+
export interface ClaudeJsonlEntry {
|
|
9
|
+
parentUuid?: string;
|
|
10
|
+
uuid: string;
|
|
11
|
+
type: 'user' | 'assistant' | 'system';
|
|
12
|
+
subtype?: string;
|
|
13
|
+
timestamp: string;
|
|
14
|
+
sessionId: string;
|
|
15
|
+
version?: string;
|
|
16
|
+
cwd?: string;
|
|
17
|
+
gitBranch?: string;
|
|
18
|
+
slug?: string;
|
|
19
|
+
isSidechain?: boolean;
|
|
20
|
+
userType?: string;
|
|
21
|
+
requestId?: string;
|
|
22
|
+
message?: {
|
|
23
|
+
role: 'user' | 'assistant';
|
|
24
|
+
model?: string;
|
|
25
|
+
id?: string;
|
|
26
|
+
type?: string;
|
|
27
|
+
content: string | Array<{
|
|
28
|
+
type: 'text' | 'tool_use' | 'tool_result' | 'image';
|
|
29
|
+
text?: string;
|
|
30
|
+
id?: string;
|
|
31
|
+
name?: string;
|
|
32
|
+
input?: Record<string, any>;
|
|
33
|
+
tool_use_id?: string;
|
|
34
|
+
content?: any;
|
|
35
|
+
is_error?: boolean;
|
|
36
|
+
}>;
|
|
37
|
+
stop_reason?: string | null;
|
|
38
|
+
usage?: {
|
|
39
|
+
input_tokens: number;
|
|
40
|
+
output_tokens: number;
|
|
41
|
+
cache_read_input_tokens?: number;
|
|
42
|
+
cache_creation_input_tokens?: number;
|
|
43
|
+
cache_creation?: {
|
|
44
|
+
ephemeral_5m_input_tokens?: number;
|
|
45
|
+
ephemeral_1h_input_tokens?: number;
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
toolUseResult?: Array<{
|
|
50
|
+
type: 'text' | 'image';
|
|
51
|
+
text?: string;
|
|
52
|
+
source?: any;
|
|
53
|
+
}>;
|
|
54
|
+
hookCount?: number;
|
|
55
|
+
hookInfos?: Array<{
|
|
56
|
+
command: string;
|
|
57
|
+
}>;
|
|
58
|
+
hookErrors?: string[];
|
|
59
|
+
level?: string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Unified message format for display
|
|
63
|
+
*/
|
|
64
|
+
export interface UnifiedMessage {
|
|
65
|
+
id: string;
|
|
66
|
+
sessionId: string;
|
|
67
|
+
role: 'user' | 'assistant' | 'system' | 'tool';
|
|
68
|
+
timestamp: number;
|
|
69
|
+
content: ContentBlock[];
|
|
70
|
+
model?: string;
|
|
71
|
+
inputTokens?: number;
|
|
72
|
+
outputTokens?: number;
|
|
73
|
+
cacheReadTokens?: number;
|
|
74
|
+
cacheWriteTokens?: number;
|
|
75
|
+
toolName?: string;
|
|
76
|
+
toolId?: string;
|
|
77
|
+
isToolResult?: boolean;
|
|
78
|
+
isError?: boolean;
|
|
79
|
+
preview?: string;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Session metadata from JSONL
|
|
83
|
+
*/
|
|
84
|
+
export interface ClaudeSessionMeta {
|
|
85
|
+
sessionId: string;
|
|
86
|
+
projectPath: string;
|
|
87
|
+
gitBranch?: string;
|
|
88
|
+
version?: string;
|
|
89
|
+
slug?: string;
|
|
90
|
+
messageCount: number;
|
|
91
|
+
lastTimestamp?: number;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Find Claude project folder for the current working directory
|
|
95
|
+
*/
|
|
96
|
+
export declare function findClaudeProjectFolder(cwd?: string): string | null;
|
|
97
|
+
/**
|
|
98
|
+
* Find the most recent session JSONL file across ALL project folders
|
|
99
|
+
* Useful for local/direct sessions where we don't know which project folder to use
|
|
100
|
+
*/
|
|
101
|
+
export declare function findLatestSessionFileGlobal(): string | null;
|
|
102
|
+
/**
|
|
103
|
+
* Find the Claude session file closest to a given timestamp
|
|
104
|
+
* Used to match dtach sessions to their corresponding Claude JSONL files
|
|
105
|
+
* @param targetTimestamp - Unix timestamp in milliseconds
|
|
106
|
+
* @param maxDeltaMs - Maximum time difference to consider a match (default 5 minutes)
|
|
107
|
+
*/
|
|
108
|
+
export declare function findSessionFileByTimestamp(targetTimestamp: number, maxDeltaMs?: number): string | null;
|
|
109
|
+
/**
|
|
110
|
+
* Find the Claude session file closest to a given timestamp within a specific project folder
|
|
111
|
+
* Used to match dtach sessions to their corresponding Claude JSONL files
|
|
112
|
+
* @param projectFolder - The Claude project folder path
|
|
113
|
+
* @param targetTimestamp - Unix timestamp in milliseconds
|
|
114
|
+
* @param maxDeltaMs - Maximum time difference to consider a match (default 5 minutes)
|
|
115
|
+
*/
|
|
116
|
+
export declare function findSessionFileByTimestampInProject(projectFolder: string, targetTimestamp: number, maxDeltaMs?: number): string | null;
|
|
117
|
+
/**
|
|
118
|
+
* Find the most recent session JSONL file in a project folder
|
|
119
|
+
*/
|
|
120
|
+
export declare function findLatestSessionFile(projectFolder: string): string | null;
|
|
121
|
+
/**
|
|
122
|
+
* Find session file by session ID (UUID)
|
|
123
|
+
*/
|
|
124
|
+
export declare function findSessionFile(projectFolder: string, sessionId: string): string | null;
|
|
125
|
+
/**
|
|
126
|
+
* Read and parse a Claude JSONL session file
|
|
127
|
+
* Returns messages in chronological order
|
|
128
|
+
*/
|
|
129
|
+
export declare function readClaudeSession(filePath: string, options?: {
|
|
130
|
+
limit?: number;
|
|
131
|
+
fromTimestamp?: number;
|
|
132
|
+
}): Promise<{
|
|
133
|
+
messages: UnifiedMessage[];
|
|
134
|
+
meta: ClaudeSessionMeta;
|
|
135
|
+
}>;
|
|
136
|
+
/**
|
|
137
|
+
* Read Claude session synchronously (for simpler use cases)
|
|
138
|
+
* Note: For large files, prefer the async version
|
|
139
|
+
*/
|
|
140
|
+
export declare function readClaudeSessionSync(filePath: string, limit?: number): UnifiedMessage[];
|
|
141
|
+
/**
|
|
142
|
+
* Watch a Claude session file for changes
|
|
143
|
+
* Calls callback with new messages when file is updated
|
|
144
|
+
*/
|
|
145
|
+
export declare function watchClaudeSession(filePath: string, callback: (messages: UnifiedMessage[]) => void, options?: {
|
|
146
|
+
pollInterval?: number;
|
|
147
|
+
}): () => void;
|
|
148
|
+
/**
|
|
149
|
+
* List all Claude sessions in a project folder
|
|
150
|
+
*/
|
|
151
|
+
export declare function listClaudeSessions(projectFolder: string): Array<{
|
|
152
|
+
sessionId: string;
|
|
153
|
+
filePath: string;
|
|
154
|
+
size: number;
|
|
155
|
+
lastModified: number;
|
|
156
|
+
}>;
|