dev-sessions 0.1.0

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.
@@ -0,0 +1,36 @@
1
+ import { ClaudeTmuxBackend } from './backends/claude-tmux';
2
+ import { CodexAppServerBackend } from './backends/codex-appserver';
3
+ import { GatewaySessionManager } from './gateway/client';
4
+ import { SessionStore } from './session-store';
5
+ import { AgentTurnStatus, SessionCli, SessionMode, StoredSession, WaitResult } from './types';
6
+ export interface CreateSessionOptions {
7
+ path?: string;
8
+ description?: string;
9
+ cli?: SessionCli;
10
+ mode?: SessionMode;
11
+ model?: string;
12
+ }
13
+ export interface WaitOptions {
14
+ timeoutSeconds?: number;
15
+ intervalSeconds?: number;
16
+ }
17
+ export declare class SessionManager {
18
+ private readonly store;
19
+ private readonly claudeBackend;
20
+ private readonly codexBackend;
21
+ constructor(store: SessionStore, claudeBackend: ClaudeTmuxBackend, codexBackend?: CodexAppServerBackend);
22
+ createSession(options: CreateSessionOptions): Promise<StoredSession>;
23
+ sendMessage(championId: string, message: string): Promise<void>;
24
+ killSession(championId: string): Promise<void>;
25
+ listSessions(): Promise<StoredSession[]>;
26
+ getLastAssistantTextBlocks(championId: string, count: number): Promise<string[]>;
27
+ getSessionStatus(championId: string): Promise<AgentTurnStatus>;
28
+ waitForSession(championId: string, options?: WaitOptions): Promise<WaitResult>;
29
+ private requireSession;
30
+ private findAvailableChampionId;
31
+ private sleep;
32
+ private hasActiveCodexSessions;
33
+ private hasAssistantResponseAtOrAfter;
34
+ }
35
+ export declare function shouldUseGatewaySessionManager(env?: NodeJS.ProcessEnv): boolean;
36
+ export declare function createDefaultSessionManager(env?: NodeJS.ProcessEnv): SessionManager | GatewaySessionManager;
@@ -0,0 +1,407 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SessionManager = void 0;
7
+ exports.shouldUseGatewaySessionManager = shouldUseGatewaySessionManager;
8
+ exports.createDefaultSessionManager = createDefaultSessionManager;
9
+ const node_crypto_1 = require("node:crypto");
10
+ const promises_1 = require("node:fs/promises");
11
+ const node_path_1 = __importDefault(require("node:path"));
12
+ const champion_ids_1 = require("./champion-ids");
13
+ const claude_tmux_1 = require("./backends/claude-tmux");
14
+ const codex_appserver_1 = require("./backends/codex-appserver");
15
+ const client_1 = require("./gateway/client");
16
+ const session_store_1 = require("./session-store");
17
+ const claude_parser_1 = require("./transcript/claude-parser");
18
+ class SessionManager {
19
+ store;
20
+ claudeBackend;
21
+ codexBackend;
22
+ constructor(store, claudeBackend, codexBackend = new codex_appserver_1.CodexAppServerBackend()) {
23
+ this.store = store;
24
+ this.claudeBackend = claudeBackend;
25
+ this.codexBackend = codexBackend;
26
+ }
27
+ async createSession(options) {
28
+ const workspacePath = node_path_1.default.resolve(options.path ?? process.cwd());
29
+ const cli = options.cli ?? 'claude';
30
+ const championId = await this.findAvailableChampionId();
31
+ const timestamp = new Date().toISOString();
32
+ let session;
33
+ if (cli === 'codex') {
34
+ const model = options.model ?? 'gpt-5.3-codex';
35
+ const codexSession = await this.codexBackend.createSession(championId, workspacePath, model);
36
+ session = {
37
+ championId,
38
+ internalId: codexSession.threadId,
39
+ cli: 'codex',
40
+ mode: 'native',
41
+ path: workspacePath,
42
+ description: options.description,
43
+ status: 'active',
44
+ appServerPid: codexSession.appServerPid,
45
+ appServerPort: codexSession.appServerPort,
46
+ model: codexSession.model,
47
+ codexTurnInProgress: false,
48
+ lastAssistantMessages: [],
49
+ createdAt: timestamp,
50
+ lastUsed: timestamp
51
+ };
52
+ }
53
+ else {
54
+ const mode = options.mode ?? 'yolo';
55
+ const tmuxSessionName = (0, champion_ids_1.toTmuxSessionName)(championId);
56
+ const internalId = (0, node_crypto_1.randomUUID)();
57
+ await this.claudeBackend.createSession(tmuxSessionName, workspacePath, mode, internalId);
58
+ session = {
59
+ championId,
60
+ internalId,
61
+ cli: 'claude',
62
+ mode,
63
+ path: workspacePath,
64
+ description: options.description,
65
+ status: 'active',
66
+ createdAt: timestamp,
67
+ lastUsed: timestamp
68
+ };
69
+ }
70
+ await this.store.upsertSession(session);
71
+ return session;
72
+ }
73
+ async sendMessage(championId, message) {
74
+ const session = await this.requireSession(championId);
75
+ if (session.cli === 'codex') {
76
+ const turnStartTime = new Date().toISOString();
77
+ await this.store.updateSession(championId, {
78
+ lastUsed: turnStartTime,
79
+ status: 'active',
80
+ codexTurnInProgress: true,
81
+ lastTurnStatus: undefined,
82
+ lastTurnError: undefined
83
+ });
84
+ let sendResult;
85
+ try {
86
+ sendResult = await this.codexBackend.sendMessage(session.championId, session.internalId, message, {
87
+ workspacePath: session.path,
88
+ model: session.model
89
+ });
90
+ }
91
+ catch (error) {
92
+ if (error instanceof Error) {
93
+ const latestSession = await this.store.getSession(championId);
94
+ if (latestSession?.cli === 'codex' && latestSession.codexTurnInProgress === true) {
95
+ await this.store.updateSession(championId, {
96
+ codexTurnInProgress: false,
97
+ lastTurnStatus: 'failed',
98
+ lastTurnError: error.message,
99
+ lastUsed: new Date().toISOString()
100
+ });
101
+ }
102
+ }
103
+ throw error;
104
+ }
105
+ const nextAssistantMessages = sendResult.assistantMessage.length > 0
106
+ ? [...(session.lastAssistantMessages ?? []), sendResult.assistantMessage]
107
+ : [...(session.lastAssistantMessages ?? [])];
108
+ const completionTime = new Date().toISOString();
109
+ const turnStillInProgress = sendResult.timedOut;
110
+ await this.store.updateSession(championId, {
111
+ internalId: sendResult.threadId,
112
+ appServerPid: sendResult.appServerPid,
113
+ appServerPort: sendResult.appServerPort,
114
+ lastUsed: completionTime,
115
+ status: 'active',
116
+ codexTurnInProgress: turnStillInProgress,
117
+ codexLastCompletedAt: turnStillInProgress ? session.codexLastCompletedAt : completionTime,
118
+ lastTurnStatus: sendResult.status,
119
+ lastTurnError: sendResult.errorMessage,
120
+ lastAssistantMessages: nextAssistantMessages
121
+ });
122
+ if (sendResult.timedOut || sendResult.status === 'interrupted') {
123
+ throw new Error(sendResult.errorMessage ?? `Codex turn timed out for ${championId}`);
124
+ }
125
+ if (sendResult.status === 'failed') {
126
+ const messageText = sendResult.errorMessage
127
+ ? `Codex turn failed: ${sendResult.errorMessage}`
128
+ : 'Codex turn failed';
129
+ throw new Error(messageText);
130
+ }
131
+ return;
132
+ }
133
+ const tmuxSessionName = (0, champion_ids_1.toTmuxSessionName)(session.championId);
134
+ const sendTime = new Date().toISOString();
135
+ await this.claudeBackend.sendMessage(tmuxSessionName, message);
136
+ await this.store.updateSession(championId, {
137
+ lastUsed: sendTime,
138
+ status: 'active',
139
+ lastTurnStatus: undefined,
140
+ lastTurnError: undefined
141
+ });
142
+ }
143
+ async killSession(championId) {
144
+ const session = await this.requireSession(championId);
145
+ if (session.cli === 'codex') {
146
+ await this.codexBackend.killSession(session.championId, session.appServerPid, session.internalId, session.appServerPort);
147
+ }
148
+ else {
149
+ const tmuxSessionName = (0, champion_ids_1.toTmuxSessionName)(session.championId);
150
+ try {
151
+ await this.claudeBackend.killSession(tmuxSessionName);
152
+ }
153
+ catch (error) {
154
+ if (!(error instanceof Error) ||
155
+ !/failed to connect server|no server running|can't find session/i.test(error.message)) {
156
+ throw error;
157
+ }
158
+ }
159
+ }
160
+ await this.store.deleteSession(championId);
161
+ if (session.cli === 'codex' && !(await this.hasActiveCodexSessions())) {
162
+ await this.codexBackend.stopAppServer();
163
+ }
164
+ }
165
+ async listSessions() {
166
+ const sessions = (await this.store.listSessions()).filter((session) => session.status === 'active');
167
+ const livenessChecks = await Promise.all(sessions.map(async (session) => ({
168
+ championId: session.championId,
169
+ exists: session.cli === 'codex'
170
+ ? await this.codexBackend.sessionExists(session.championId, session.appServerPid, session.appServerPort)
171
+ : await this.claudeBackend.sessionExists((0, champion_ids_1.toTmuxSessionName)(session.championId))
172
+ })));
173
+ const deadSessions = sessions.filter((session) => livenessChecks.some((check) => check.championId === session.championId && !check.exists));
174
+ const deadCodexSessionIds = deadSessions
175
+ .filter((session) => session.cli === 'codex')
176
+ .map((session) => session.championId);
177
+ const deadNonCodexSessionIds = deadSessions
178
+ .filter((session) => session.cli !== 'codex')
179
+ .map((session) => session.championId);
180
+ if (deadCodexSessionIds.length > 0) {
181
+ await Promise.all(deadCodexSessionIds.map(async (deadSessionId) => {
182
+ await this.store.updateSession(deadSessionId, {
183
+ status: 'inactive',
184
+ codexTurnInProgress: false
185
+ });
186
+ }));
187
+ }
188
+ if (deadNonCodexSessionIds.length > 0) {
189
+ await this.store.pruneSessions(deadNonCodexSessionIds);
190
+ }
191
+ return (await this.store.listSessions()).filter((session) => session.status === 'active');
192
+ }
193
+ async getLastAssistantTextBlocks(championId, count) {
194
+ const session = await this.requireSession(championId);
195
+ if (session.cli === 'codex') {
196
+ const safeCount = Math.max(1, count);
197
+ const sessionMessages = session.lastAssistantMessages ?? [];
198
+ if (sessionMessages.length > 0) {
199
+ return sessionMessages.slice(-safeCount);
200
+ }
201
+ return this.codexBackend.getLastAssistantMessages(championId, safeCount);
202
+ }
203
+ const transcriptPath = (0, claude_parser_1.getClaudeTranscriptPath)(session.path, session.internalId);
204
+ const transcriptEntries = await (0, claude_parser_1.readClaudeTranscript)(transcriptPath);
205
+ const blocks = (0, claude_parser_1.getAssistantTextBlocks)(transcriptEntries);
206
+ return blocks.slice(-Math.max(1, count));
207
+ }
208
+ async getSessionStatus(championId) {
209
+ const session = await this.requireSession(championId);
210
+ if (session.cli === 'codex') {
211
+ if (session.codexTurnInProgress) {
212
+ return 'working';
213
+ }
214
+ if (session.lastTurnStatus === 'failed') {
215
+ const suffix = session.lastTurnError ? `: ${session.lastTurnError}` : '';
216
+ throw new Error(`Codex turn failed${suffix}`);
217
+ }
218
+ return 'idle';
219
+ }
220
+ const transcriptPath = (0, claude_parser_1.getClaudeTranscriptPath)(session.path, session.internalId);
221
+ const transcriptEntries = await (0, claude_parser_1.readClaudeTranscript)(transcriptPath);
222
+ return (0, claude_parser_1.inferTranscriptStatus)(transcriptEntries);
223
+ }
224
+ async waitForSession(championId, options = {}) {
225
+ const session = await this.requireSession(championId);
226
+ if (session.cli === 'codex') {
227
+ const timeoutMs = Math.max(1, options.timeoutSeconds ?? 300) * 1000;
228
+ const intervalMs = Math.max(1, options.intervalSeconds ?? 2) * 1000;
229
+ const startTime = Date.now();
230
+ if (!session.codexTurnInProgress && session.lastTurnStatus === 'failed') {
231
+ const message = session.lastTurnError
232
+ ? `Codex turn failed: ${session.lastTurnError}`
233
+ : 'Codex turn failed';
234
+ throw new Error(message);
235
+ }
236
+ await this.store.updateSession(championId, {
237
+ lastUsed: new Date().toISOString()
238
+ });
239
+ if (!session.codexTurnInProgress) {
240
+ if (session.lastTurnStatus === 'interrupted') {
241
+ return {
242
+ completed: false,
243
+ timedOut: true,
244
+ elapsedMs: timeoutMs
245
+ };
246
+ }
247
+ return {
248
+ completed: true,
249
+ timedOut: false,
250
+ elapsedMs: 0
251
+ };
252
+ }
253
+ const deadline = startTime + timeoutMs;
254
+ while (Date.now() <= deadline) {
255
+ const latestSession = await this.requireSession(championId);
256
+ if (latestSession.cli !== 'codex') {
257
+ throw new Error(`Session ${championId} is no longer a Codex session`);
258
+ }
259
+ if (!latestSession.codexTurnInProgress) {
260
+ if (latestSession.lastTurnStatus === 'failed') {
261
+ const message = latestSession.lastTurnError
262
+ ? `Codex turn failed: ${latestSession.lastTurnError}`
263
+ : 'Codex turn failed';
264
+ throw new Error(message);
265
+ }
266
+ return {
267
+ completed: latestSession.lastTurnStatus !== 'interrupted',
268
+ timedOut: latestSession.lastTurnStatus === 'interrupted',
269
+ elapsedMs: Date.now() - startTime
270
+ };
271
+ }
272
+ await this.sleep(intervalMs);
273
+ }
274
+ return {
275
+ completed: false,
276
+ timedOut: true,
277
+ elapsedMs: Date.now() - startTime
278
+ };
279
+ }
280
+ const transcriptPath = (0, claude_parser_1.getClaudeTranscriptPath)(session.path, session.internalId);
281
+ const timeoutMs = Math.max(1, options.timeoutSeconds ?? 300) * 1000;
282
+ const intervalMs = Math.max(1, options.intervalSeconds ?? 2) * 1000;
283
+ const startTime = Date.now();
284
+ const deadline = startTime + timeoutMs;
285
+ const latestSendMs = Date.parse(session.lastUsed);
286
+ const initialEntries = await (0, claude_parser_1.readClaudeTranscript)(transcriptPath);
287
+ const baselineAssistantCount = (0, claude_parser_1.countAssistantMessages)(initialEntries);
288
+ const baselineSystemCount = (0, claude_parser_1.countSystemEntries)(initialEntries);
289
+ let lastMtimeMs = -1;
290
+ let shouldReadTranscript = false;
291
+ let cachedEntries = initialEntries;
292
+ while (Date.now() <= deadline) {
293
+ try {
294
+ const fileStat = await (0, promises_1.stat)(transcriptPath);
295
+ if (fileStat.mtimeMs !== lastMtimeMs) {
296
+ lastMtimeMs = fileStat.mtimeMs;
297
+ shouldReadTranscript = true;
298
+ }
299
+ }
300
+ catch (error) {
301
+ if (error.code !== 'ENOENT') {
302
+ throw error;
303
+ }
304
+ shouldReadTranscript = true;
305
+ cachedEntries = [];
306
+ }
307
+ if (shouldReadTranscript) {
308
+ cachedEntries = await (0, claude_parser_1.readClaudeTranscript)(transcriptPath);
309
+ shouldReadTranscript = false;
310
+ }
311
+ const status = (0, claude_parser_1.inferTranscriptStatus)(cachedEntries);
312
+ const hasNewSystemEntry = (0, claude_parser_1.countSystemEntries)(cachedEntries) > baselineSystemCount;
313
+ const hasNewAssistant = (0, claude_parser_1.countAssistantMessages)(cachedEntries) > baselineAssistantCount;
314
+ const hasRecentAssistant = this.hasAssistantResponseAtOrAfter(cachedEntries, latestSendMs);
315
+ // Primary signal: a new 'system' entry marks the definitive end of a Claude Code turn.
316
+ // This avoids false positives from intermediate tool_use assistant entries.
317
+ if (hasNewSystemEntry && (hasNewAssistant || hasRecentAssistant)) {
318
+ await this.store.updateSession(championId, {
319
+ lastUsed: new Date().toISOString()
320
+ });
321
+ return {
322
+ completed: true,
323
+ timedOut: false,
324
+ elapsedMs: Date.now() - startTime
325
+ };
326
+ }
327
+ // Fallback: if inferTranscriptStatus reports idle/waiting and we have new assistant
328
+ // entries, the turn is complete. This handles transcripts that may not have system entries.
329
+ if ((status === 'idle' || status === 'waiting_for_input') &&
330
+ (0, claude_parser_1.hasAssistantResponseAfterLatestUser)(cachedEntries) &&
331
+ (hasNewAssistant || hasRecentAssistant)) {
332
+ await this.store.updateSession(championId, {
333
+ lastUsed: new Date().toISOString()
334
+ });
335
+ return {
336
+ completed: true,
337
+ timedOut: false,
338
+ elapsedMs: Date.now() - startTime
339
+ };
340
+ }
341
+ await this.sleep(intervalMs);
342
+ }
343
+ return {
344
+ completed: false,
345
+ timedOut: true,
346
+ elapsedMs: Date.now() - startTime
347
+ };
348
+ }
349
+ async requireSession(championId) {
350
+ const session = await this.store.getSession(championId);
351
+ if (!session) {
352
+ throw new Error(`Session not found: ${championId}`);
353
+ }
354
+ return session;
355
+ }
356
+ async findAvailableChampionId(maxAttempts = 250) {
357
+ for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
358
+ const candidate = (0, champion_ids_1.generateChampionId)();
359
+ if (await this.store.getSession(candidate)) {
360
+ continue;
361
+ }
362
+ if (await this.claudeBackend.sessionExists((0, champion_ids_1.toTmuxSessionName)(candidate))) {
363
+ continue;
364
+ }
365
+ return candidate;
366
+ }
367
+ throw new Error('Unable to allocate a unique champion ID');
368
+ }
369
+ async sleep(ms) {
370
+ await new Promise((resolve) => {
371
+ setTimeout(resolve, ms);
372
+ });
373
+ }
374
+ async hasActiveCodexSessions() {
375
+ const sessions = await this.store.listSessions();
376
+ return sessions.some((session) => session.status === 'active' && session.cli === 'codex');
377
+ }
378
+ hasAssistantResponseAtOrAfter(entries, thresholdMs) {
379
+ if (!Number.isFinite(thresholdMs)) {
380
+ return false;
381
+ }
382
+ return entries.some((entry) => {
383
+ if (entry.type?.toLowerCase() !== 'assistant') {
384
+ return false;
385
+ }
386
+ const timestamp = entry.timestamp;
387
+ if (typeof timestamp !== 'string') {
388
+ return false;
389
+ }
390
+ const parsed = Date.parse(timestamp);
391
+ return !Number.isNaN(parsed) && parsed >= thresholdMs;
392
+ });
393
+ }
394
+ }
395
+ exports.SessionManager = SessionManager;
396
+ function shouldUseGatewaySessionManager(env = process.env) {
397
+ return env.IS_SANDBOX === '1';
398
+ }
399
+ function createDefaultSessionManager(env = process.env) {
400
+ if (shouldUseGatewaySessionManager(env)) {
401
+ return new client_1.GatewaySessionManager({
402
+ baseUrl: (0, client_1.resolveGatewayBaseUrl)(env)
403
+ });
404
+ }
405
+ return new SessionManager((0, session_store_1.createDefaultSessionStore)(), new claude_tmux_1.ClaudeTmuxBackend(), new codex_appserver_1.CodexAppServerBackend());
406
+ }
407
+ //# sourceMappingURL=session-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-manager.js","sourceRoot":"","sources":["../src/session-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { StoredSession } from './types';
2
+ export declare class SessionStore {
3
+ private readonly storePath;
4
+ constructor(storePath?: string);
5
+ get filePath(): string;
6
+ listSessions(): Promise<StoredSession[]>;
7
+ getSession(championId: string): Promise<StoredSession | undefined>;
8
+ upsertSession(session: StoredSession): Promise<void>;
9
+ updateSession(championId: string, partial: Partial<Omit<StoredSession, 'championId'>>): Promise<StoredSession | undefined>;
10
+ deleteSession(championId: string): Promise<boolean>;
11
+ pruneSessions(championIds: string[]): Promise<number>;
12
+ private readStore;
13
+ private writeStore;
14
+ }
15
+ export declare function createDefaultSessionStore(): SessionStore;
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SessionStore = void 0;
7
+ exports.createDefaultSessionStore = createDefaultSessionStore;
8
+ const promises_1 = require("node:fs/promises");
9
+ const node_os_1 = __importDefault(require("node:os"));
10
+ const node_path_1 = __importDefault(require("node:path"));
11
+ const CURRENT_VERSION = 1;
12
+ function getDefaultStorePath() {
13
+ return node_path_1.default.join(node_os_1.default.homedir(), '.dev-sessions', 'sessions.json');
14
+ }
15
+ function isStoredSession(value) {
16
+ if (!value || typeof value !== 'object') {
17
+ return false;
18
+ }
19
+ const candidate = value;
20
+ return (typeof candidate.championId === 'string' &&
21
+ typeof candidate.internalId === 'string' &&
22
+ (candidate.cli === 'claude' || candidate.cli === 'codex') &&
23
+ (candidate.mode === 'yolo' || candidate.mode === 'native' || candidate.mode === 'docker') &&
24
+ typeof candidate.path === 'string' &&
25
+ (candidate.description === undefined || typeof candidate.description === 'string') &&
26
+ (candidate.status === 'active' || candidate.status === 'inactive') &&
27
+ (candidate.appServerPid === undefined || Number.isInteger(candidate.appServerPid)) &&
28
+ (candidate.appServerPort === undefined || Number.isInteger(candidate.appServerPort)) &&
29
+ (candidate.model === undefined || typeof candidate.model === 'string') &&
30
+ (candidate.codexTurnInProgress === undefined || typeof candidate.codexTurnInProgress === 'boolean') &&
31
+ (candidate.codexLastCompletedAt === undefined || typeof candidate.codexLastCompletedAt === 'string') &&
32
+ (candidate.lastTurnStatus === undefined ||
33
+ candidate.lastTurnStatus === 'completed' ||
34
+ candidate.lastTurnStatus === 'failed' ||
35
+ candidate.lastTurnStatus === 'interrupted') &&
36
+ (candidate.lastTurnError === undefined || typeof candidate.lastTurnError === 'string') &&
37
+ (candidate.lastAssistantMessages === undefined ||
38
+ (Array.isArray(candidate.lastAssistantMessages) &&
39
+ candidate.lastAssistantMessages.every((message) => typeof message === 'string'))) &&
40
+ typeof candidate.createdAt === 'string' &&
41
+ typeof candidate.lastUsed === 'string');
42
+ }
43
+ class SessionStore {
44
+ storePath;
45
+ constructor(storePath = getDefaultStorePath()) {
46
+ this.storePath = storePath;
47
+ }
48
+ get filePath() {
49
+ return this.storePath;
50
+ }
51
+ async listSessions() {
52
+ const store = await this.readStore();
53
+ return [...store.sessions].sort((a, b) => a.createdAt.localeCompare(b.createdAt));
54
+ }
55
+ async getSession(championId) {
56
+ const store = await this.readStore();
57
+ return store.sessions.find((session) => session.championId === championId);
58
+ }
59
+ async upsertSession(session) {
60
+ const store = await this.readStore();
61
+ const index = store.sessions.findIndex((candidate) => candidate.championId === session.championId);
62
+ if (index >= 0) {
63
+ store.sessions[index] = session;
64
+ }
65
+ else {
66
+ store.sessions.push(session);
67
+ }
68
+ await this.writeStore(store);
69
+ }
70
+ async updateSession(championId, partial) {
71
+ const store = await this.readStore();
72
+ const index = store.sessions.findIndex((candidate) => candidate.championId === championId);
73
+ if (index < 0) {
74
+ return undefined;
75
+ }
76
+ const updatedSession = {
77
+ ...store.sessions[index],
78
+ ...partial,
79
+ championId: store.sessions[index].championId
80
+ };
81
+ store.sessions[index] = updatedSession;
82
+ await this.writeStore(store);
83
+ return updatedSession;
84
+ }
85
+ async deleteSession(championId) {
86
+ const store = await this.readStore();
87
+ const initialLength = store.sessions.length;
88
+ store.sessions = store.sessions.filter((candidate) => candidate.championId !== championId);
89
+ if (store.sessions.length === initialLength) {
90
+ return false;
91
+ }
92
+ await this.writeStore(store);
93
+ return true;
94
+ }
95
+ async pruneSessions(championIds) {
96
+ if (championIds.length === 0) {
97
+ return 0;
98
+ }
99
+ const ids = new Set(championIds);
100
+ const store = await this.readStore();
101
+ const initialLength = store.sessions.length;
102
+ store.sessions = store.sessions.filter((candidate) => !ids.has(candidate.championId));
103
+ const removed = initialLength - store.sessions.length;
104
+ if (removed > 0) {
105
+ await this.writeStore(store);
106
+ }
107
+ return removed;
108
+ }
109
+ async readStore() {
110
+ try {
111
+ const raw = await (0, promises_1.readFile)(this.storePath, 'utf8');
112
+ const parsed = JSON.parse(raw);
113
+ const sessions = Array.isArray(parsed.sessions)
114
+ ? parsed.sessions.filter(isStoredSession)
115
+ : [];
116
+ return {
117
+ version: typeof parsed.version === 'number' ? parsed.version : CURRENT_VERSION,
118
+ sessions
119
+ };
120
+ }
121
+ catch (error) {
122
+ if (error.code === 'ENOENT') {
123
+ return {
124
+ version: CURRENT_VERSION,
125
+ sessions: []
126
+ };
127
+ }
128
+ throw error;
129
+ }
130
+ }
131
+ async writeStore(store) {
132
+ await (0, promises_1.mkdir)(node_path_1.default.dirname(this.storePath), { recursive: true });
133
+ const tmpPath = `${this.storePath}.tmp`;
134
+ const payload = JSON.stringify(store, null, 2);
135
+ await (0, promises_1.writeFile)(tmpPath, payload, 'utf8');
136
+ await (0, promises_1.rename)(tmpPath, this.storePath);
137
+ }
138
+ }
139
+ exports.SessionStore = SessionStore;
140
+ function createDefaultSessionStore() {
141
+ return new SessionStore();
142
+ }
143
+ //# sourceMappingURL=session-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-store.js","sourceRoot":"","sources":["../src/session-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import { AgentTurnStatus } from '../types';
2
+ export interface ClaudeTranscriptEntry {
3
+ type?: string;
4
+ message?: {
5
+ content?: unknown;
6
+ };
7
+ [key: string]: unknown;
8
+ }
9
+ export declare function sanitizeWorkspacePath(workspacePath: string): string;
10
+ export declare function getClaudeTranscriptPath(workspacePath: string, internalId: string, homeDir?: string): string;
11
+ export declare function readClaudeTranscript(filePath: string): Promise<ClaudeTranscriptEntry[]>;
12
+ export declare function extractTextBlocks(content: unknown): string[];
13
+ export declare function getAssistantTextBlocks(entries: ClaudeTranscriptEntry[]): string[];
14
+ export declare function countAssistantMessages(entries: ClaudeTranscriptEntry[]): number;
15
+ export declare function countSystemEntries(entries: ClaudeTranscriptEntry[]): number;
16
+ export declare function inferTranscriptStatus(entries: ClaudeTranscriptEntry[]): AgentTurnStatus;
17
+ export declare function hasAssistantResponseAfterLatestUser(entries: ClaudeTranscriptEntry[]): boolean;