@maxanatsko/llm-cli-bridge 3.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.
- package/LICENSE +26 -0
- package/README.md +203 -0
- package/dist/backends/codex.d.ts +37 -0
- package/dist/backends/codex.d.ts.map +1 -0
- package/dist/backends/codex.js +438 -0
- package/dist/backends/codex.js.map +1 -0
- package/dist/backends/gemini.d.ts +17 -0
- package/dist/backends/gemini.d.ts.map +1 -0
- package/dist/backends/gemini.js +174 -0
- package/dist/backends/gemini.js.map +1 -0
- package/dist/backends/index.d.ts +8 -0
- package/dist/backends/index.d.ts.map +1 -0
- package/dist/backends/index.js +9 -0
- package/dist/backends/index.js.map +1 -0
- package/dist/backends/registry.d.ts +33 -0
- package/dist/backends/registry.d.ts.map +1 -0
- package/dist/backends/registry.js +80 -0
- package/dist/backends/registry.js.map +1 -0
- package/dist/backends/types.d.ts +61 -0
- package/dist/backends/types.d.ts.map +1 -0
- package/dist/backends/types.js +5 -0
- package/dist/backends/types.js.map +1 -0
- package/dist/constants.d.ts +223 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +228 -0
- package/dist/constants.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +192 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/ask.tool.d.ts +4 -0
- package/dist/tools/ask.tool.d.ts.map +1 -0
- package/dist/tools/ask.tool.js +113 -0
- package/dist/tools/ask.tool.js.map +1 -0
- package/dist/tools/brainstorm.tool.d.ts +3 -0
- package/dist/tools/brainstorm.tool.d.ts.map +1 -0
- package/dist/tools/brainstorm.tool.js +250 -0
- package/dist/tools/brainstorm.tool.js.map +1 -0
- package/dist/tools/index.d.ts +5 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +13 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/registry.d.ts +42 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +85 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/review-code.tool.d.ts +3 -0
- package/dist/tools/review-code.tool.d.ts.map +1 -0
- package/dist/tools/review-code.tool.js +279 -0
- package/dist/tools/review-code.tool.js.map +1 -0
- package/dist/tools/test-tool.example.d.ts +13 -0
- package/dist/tools/test-tool.example.d.ts.map +1 -0
- package/dist/tools/test-tool.example.js +32 -0
- package/dist/tools/test-tool.example.js.map +1 -0
- package/dist/tools/timeout-test.tool.d.ts +3 -0
- package/dist/tools/timeout-test.tool.d.ts.map +1 -0
- package/dist/tools/timeout-test.tool.js +38 -0
- package/dist/tools/timeout-test.tool.js.map +1 -0
- package/dist/utils/askSessionManager.d.ts +59 -0
- package/dist/utils/askSessionManager.d.ts.map +1 -0
- package/dist/utils/askSessionManager.js +123 -0
- package/dist/utils/askSessionManager.js.map +1 -0
- package/dist/utils/brainstormSessionManager.d.ts +67 -0
- package/dist/utils/brainstormSessionManager.d.ts.map +1 -0
- package/dist/utils/brainstormSessionManager.js +174 -0
- package/dist/utils/brainstormSessionManager.js.map +1 -0
- package/dist/utils/changeModeInstructions.d.ts +17 -0
- package/dist/utils/changeModeInstructions.d.ts.map +1 -0
- package/dist/utils/changeModeInstructions.js +100 -0
- package/dist/utils/changeModeInstructions.js.map +1 -0
- package/dist/utils/changeModeParser.d.ts +15 -0
- package/dist/utils/changeModeParser.d.ts.map +1 -0
- package/dist/utils/changeModeParser.js +81 -0
- package/dist/utils/changeModeParser.js.map +1 -0
- package/dist/utils/changeModeTranslator.d.ts +4 -0
- package/dist/utils/changeModeTranslator.d.ts.map +1 -0
- package/dist/utils/changeModeTranslator.js +42 -0
- package/dist/utils/changeModeTranslator.js.map +1 -0
- package/dist/utils/commandExecutor.d.ts +2 -0
- package/dist/utils/commandExecutor.d.ts.map +1 -0
- package/dist/utils/commandExecutor.js +76 -0
- package/dist/utils/commandExecutor.js.map +1 -0
- package/dist/utils/envAllowlist.d.ts +17 -0
- package/dist/utils/envAllowlist.d.ts.map +1 -0
- package/dist/utils/envAllowlist.js +54 -0
- package/dist/utils/envAllowlist.js.map +1 -0
- package/dist/utils/geminiExecutor.d.ts +3 -0
- package/dist/utils/geminiExecutor.d.ts.map +1 -0
- package/dist/utils/geminiExecutor.js +94 -0
- package/dist/utils/geminiExecutor.js.map +1 -0
- package/dist/utils/gitStateDetector.d.ts +32 -0
- package/dist/utils/gitStateDetector.d.ts.map +1 -0
- package/dist/utils/gitStateDetector.js +68 -0
- package/dist/utils/gitStateDetector.js.map +1 -0
- package/dist/utils/logger.d.ts +13 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +42 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/reviewFormatter.d.ts +35 -0
- package/dist/utils/reviewFormatter.d.ts.map +1 -0
- package/dist/utils/reviewFormatter.js +201 -0
- package/dist/utils/reviewFormatter.js.map +1 -0
- package/dist/utils/reviewPromptBuilder.d.ts +43 -0
- package/dist/utils/reviewPromptBuilder.d.ts.map +1 -0
- package/dist/utils/reviewPromptBuilder.js +170 -0
- package/dist/utils/reviewPromptBuilder.js.map +1 -0
- package/dist/utils/reviewResponseParser.d.ts +20 -0
- package/dist/utils/reviewResponseParser.d.ts.map +1 -0
- package/dist/utils/reviewResponseParser.js +149 -0
- package/dist/utils/reviewResponseParser.js.map +1 -0
- package/dist/utils/reviewSessionCache.d.ts +81 -0
- package/dist/utils/reviewSessionCache.d.ts.map +1 -0
- package/dist/utils/reviewSessionCache.js +220 -0
- package/dist/utils/reviewSessionCache.js.map +1 -0
- package/dist/utils/reviewSessionManager.d.ts +52 -0
- package/dist/utils/reviewSessionManager.d.ts.map +1 -0
- package/dist/utils/reviewSessionManager.js +65 -0
- package/dist/utils/reviewSessionManager.js.map +1 -0
- package/dist/utils/sessionManager.d.ts +95 -0
- package/dist/utils/sessionManager.d.ts.map +1 -0
- package/dist/utils/sessionManager.js +382 -0
- package/dist/utils/sessionManager.js.map +1 -0
- package/dist/utils/sessionSchemas.d.ts +140 -0
- package/dist/utils/sessionSchemas.d.ts.map +1 -0
- package/dist/utils/sessionSchemas.js +2 -0
- package/dist/utils/sessionSchemas.js.map +1 -0
- package/dist/utils/timeoutManager.d.ts +2 -0
- package/dist/utils/timeoutManager.d.ts.map +1 -0
- package/dist/utils/timeoutManager.js +2 -0
- package/dist/utils/timeoutManager.js.map +1 -0
- package/package.json +72 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reviewSessionCache.js","sourceRoot":"","sources":["../../src/utils/reviewSessionCache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { ReviewCodeSessionData } from './sessionSchemas.js';
|
|
2
|
+
import { GitState } from './gitStateDetector.js';
|
|
3
|
+
/**
|
|
4
|
+
* Specialized session manager for review-code tool
|
|
5
|
+
* Wraps generic SessionManager with review-specific helpers
|
|
6
|
+
* Maintains backward compatibility with reviewSessionCache.ts
|
|
7
|
+
*/
|
|
8
|
+
export declare class ReviewSessionManager {
|
|
9
|
+
private sessionManager;
|
|
10
|
+
constructor();
|
|
11
|
+
/**
|
|
12
|
+
* Saves a review session (maintains existing interface)
|
|
13
|
+
*/
|
|
14
|
+
saveReviewSession(session: ReviewCodeSessionData): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Loads a review session (maintains existing interface)
|
|
17
|
+
*/
|
|
18
|
+
loadReviewSession(sessionId: string): Promise<ReviewCodeSessionData | null>;
|
|
19
|
+
/**
|
|
20
|
+
* Lists active review sessions
|
|
21
|
+
*/
|
|
22
|
+
listActiveSessions(): Promise<ReviewCodeSessionData[]>;
|
|
23
|
+
/**
|
|
24
|
+
* Creates a new review session
|
|
25
|
+
*/
|
|
26
|
+
createNewSession(sessionId: string, gitState: GitState, focusFiles?: string[]): ReviewCodeSessionData;
|
|
27
|
+
/**
|
|
28
|
+
* Gets cache statistics
|
|
29
|
+
*/
|
|
30
|
+
getReviewCacheStats(): Promise<{
|
|
31
|
+
toolName: string;
|
|
32
|
+
sessionCount: number;
|
|
33
|
+
ttl: number;
|
|
34
|
+
maxSessions: number;
|
|
35
|
+
evictionPolicy: string;
|
|
36
|
+
cacheDir: string;
|
|
37
|
+
}>;
|
|
38
|
+
}
|
|
39
|
+
export declare const reviewSessionManager: ReviewSessionManager;
|
|
40
|
+
export declare const saveReviewSession: (session: ReviewCodeSessionData) => Promise<void>;
|
|
41
|
+
export declare const loadReviewSession: (sessionId: string) => Promise<ReviewCodeSessionData | null>;
|
|
42
|
+
export declare const listActiveSessions: () => Promise<ReviewCodeSessionData[]>;
|
|
43
|
+
export declare const createNewSession: (sessionId: string, gitState: GitState, focusFiles?: string[]) => ReviewCodeSessionData;
|
|
44
|
+
export declare const getReviewCacheStats: () => Promise<{
|
|
45
|
+
toolName: string;
|
|
46
|
+
sessionCount: number;
|
|
47
|
+
ttl: number;
|
|
48
|
+
maxSessions: number;
|
|
49
|
+
evictionPolicy: string;
|
|
50
|
+
cacheDir: string;
|
|
51
|
+
}>;
|
|
52
|
+
//# sourceMappingURL=reviewSessionManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reviewSessionManager.d.ts","sourceRoot":"","sources":["../../src/utils/reviewSessionManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEjD;;;;GAIG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,cAAc,CAAwC;;IAM9D;;OAEG;IACG,iBAAiB,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IAItE;;OAEG;IACG,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC;IAIjF;;OAEG;IACG,kBAAkB,IAAI,OAAO,CAAC,qBAAqB,EAAE,CAAC;IAI5D;;OAEG;IACH,gBAAgB,CACd,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,QAAQ,EAClB,UAAU,CAAC,EAAE,MAAM,EAAE,GACpB,qBAAqB;IAkBxB;;OAEG;IACG,mBAAmB;;;;;;;;CAG1B;AAGD,eAAO,MAAM,oBAAoB,sBAA6B,CAAC;AAG/D,eAAO,MAAM,iBAAiB,GAAU,SAAS,qBAAqB,kBACf,CAAC;AAExD,eAAO,MAAM,iBAAiB,GAAU,WAAW,MAAM,0CACA,CAAC;AAE1D,eAAO,MAAM,kBAAkB,wCACkB,CAAC;AAElD,eAAO,MAAM,gBAAgB,GAC3B,WAAW,MAAM,EACjB,UAAU,QAAQ,EAClB,aAAa,MAAM,EAAE,0BACoD,CAAC;AAE5E,eAAO,MAAM,mBAAmB;;;;;;;EACkB,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { SessionManager } from './sessionManager.js';
|
|
2
|
+
/**
|
|
3
|
+
* Specialized session manager for review-code tool
|
|
4
|
+
* Wraps generic SessionManager with review-specific helpers
|
|
5
|
+
* Maintains backward compatibility with reviewSessionCache.ts
|
|
6
|
+
*/
|
|
7
|
+
export class ReviewSessionManager {
|
|
8
|
+
sessionManager;
|
|
9
|
+
constructor() {
|
|
10
|
+
this.sessionManager = new SessionManager('review-code');
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Saves a review session (maintains existing interface)
|
|
14
|
+
*/
|
|
15
|
+
async saveReviewSession(session) {
|
|
16
|
+
await this.sessionManager.save(session.sessionId, session);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Loads a review session (maintains existing interface)
|
|
20
|
+
*/
|
|
21
|
+
async loadReviewSession(sessionId) {
|
|
22
|
+
return await this.sessionManager.load(sessionId);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Lists active review sessions
|
|
26
|
+
*/
|
|
27
|
+
async listActiveSessions() {
|
|
28
|
+
return await this.sessionManager.list();
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Creates a new review session
|
|
32
|
+
*/
|
|
33
|
+
createNewSession(sessionId, gitState, focusFiles) {
|
|
34
|
+
const now = Date.now();
|
|
35
|
+
return {
|
|
36
|
+
sessionId,
|
|
37
|
+
createdAt: now,
|
|
38
|
+
lastAccessedAt: now,
|
|
39
|
+
gitState,
|
|
40
|
+
currentGitState: gitState,
|
|
41
|
+
rounds: [],
|
|
42
|
+
allComments: [],
|
|
43
|
+
filesTracked: [],
|
|
44
|
+
focusFiles,
|
|
45
|
+
reviewScope: focusFiles ? 'focused' : 'full',
|
|
46
|
+
totalRounds: 0,
|
|
47
|
+
sessionState: 'active'
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Gets cache statistics
|
|
52
|
+
*/
|
|
53
|
+
async getReviewCacheStats() {
|
|
54
|
+
return await this.sessionManager.getStats();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// Export singleton instance for backward compatibility
|
|
58
|
+
export const reviewSessionManager = new ReviewSessionManager();
|
|
59
|
+
// Export existing function signatures for drop-in replacement
|
|
60
|
+
export const saveReviewSession = async (session) => await reviewSessionManager.saveReviewSession(session);
|
|
61
|
+
export const loadReviewSession = async (sessionId) => await reviewSessionManager.loadReviewSession(sessionId);
|
|
62
|
+
export const listActiveSessions = async () => await reviewSessionManager.listActiveSessions();
|
|
63
|
+
export const createNewSession = (sessionId, gitState, focusFiles) => reviewSessionManager.createNewSession(sessionId, gitState, focusFiles);
|
|
64
|
+
export const getReviewCacheStats = async () => await reviewSessionManager.getReviewCacheStats();
|
|
65
|
+
//# sourceMappingURL=reviewSessionManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reviewSessionManager.js","sourceRoot":"","sources":["../../src/utils/reviewSessionManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAIrD;;;;GAIG;AACH,MAAM,OAAO,oBAAoB;IACvB,cAAc,CAAwC;IAE9D;QACE,IAAI,CAAC,cAAc,GAAG,IAAI,cAAc,CAAwB,aAAa,CAAC,CAAC;IACjF,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,iBAAiB,CAAC,OAA8B;QACpD,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAC7D,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,iBAAiB,CAAC,SAAiB;QACvC,OAAO,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACnD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,kBAAkB;QACtB,OAAO,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;IAC1C,CAAC;IAED;;OAEG;IACH,gBAAgB,CACd,SAAiB,EACjB,QAAkB,EAClB,UAAqB;QAErB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,OAAO;YACL,SAAS;YACT,SAAS,EAAE,GAAG;YACd,cAAc,EAAE,GAAG;YACnB,QAAQ;YACR,eAAe,EAAE,QAAQ;YACzB,MAAM,EAAE,EAAE;YACV,WAAW,EAAE,EAAE;YACf,YAAY,EAAE,EAAE;YAChB,UAAU;YACV,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM;YAC5C,WAAW,EAAE,CAAC;YACd,YAAY,EAAE,QAAQ;SACvB,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,mBAAmB;QACvB,OAAO,MAAM,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,CAAC;IAC9C,CAAC;CACF;AAED,uDAAuD;AACvD,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,oBAAoB,EAAE,CAAC;AAE/D,8DAA8D;AAC9D,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,EAAE,OAA8B,EAAE,EAAE,CACxE,MAAM,oBAAoB,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;AAExD,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,EAAE,SAAiB,EAAE,EAAE,CAC3D,MAAM,oBAAoB,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;AAE1D,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,IAAI,EAAE,CAC3C,MAAM,oBAAoB,CAAC,kBAAkB,EAAE,CAAC;AAElD,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,SAAiB,EACjB,QAAkB,EAClB,UAAqB,EACrB,EAAE,CAAC,oBAAoB,CAAC,gBAAgB,CAAC,SAAS,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;AAE5E,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,IAAI,EAAE,CAC5C,MAAM,oBAAoB,CAAC,mBAAmB,EAAE,CAAC"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base interface that all tool-specific session data must extend
|
|
3
|
+
* Ensures every session has core metadata fields
|
|
4
|
+
*/
|
|
5
|
+
export interface SessionData {
|
|
6
|
+
sessionId: string;
|
|
7
|
+
createdAt: number;
|
|
8
|
+
lastAccessedAt: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Configuration for a tool's session management
|
|
12
|
+
*/
|
|
13
|
+
export interface SessionConfig {
|
|
14
|
+
toolName: string;
|
|
15
|
+
ttl: number;
|
|
16
|
+
maxSessions: number;
|
|
17
|
+
evictionPolicy: 'fifo' | 'lru';
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Generic session manager for all MCP tools
|
|
21
|
+
* Type parameter T ensures type safety for tool-specific session data
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* const manager = new SessionManager<MySessionData>('my-tool');
|
|
26
|
+
* manager.save('session-1', { sessionId: 'session-1', ... });
|
|
27
|
+
* const session = manager.load('session-1');
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export declare class SessionManager<T extends SessionData> {
|
|
31
|
+
private config;
|
|
32
|
+
private cacheDir;
|
|
33
|
+
private initPromise;
|
|
34
|
+
constructor(toolName: string, customConfig?: Partial<SessionConfig>);
|
|
35
|
+
/**
|
|
36
|
+
* Ensures the tool's session directory exists (lazy initialization)
|
|
37
|
+
*/
|
|
38
|
+
private ensureCacheDirAsync;
|
|
39
|
+
/**
|
|
40
|
+
* Helper method to quickly get session count without parsing files
|
|
41
|
+
*/
|
|
42
|
+
private getSessionCountFast;
|
|
43
|
+
/**
|
|
44
|
+
* Helper method to read and parse a session file
|
|
45
|
+
*/
|
|
46
|
+
private readSessionFile;
|
|
47
|
+
/**
|
|
48
|
+
* Saves a session to persistent storage
|
|
49
|
+
* @param sessionId User-provided or generated session ID
|
|
50
|
+
* @param data Tool-specific session data
|
|
51
|
+
*/
|
|
52
|
+
save(sessionId: string, data: T): Promise<void>;
|
|
53
|
+
/**
|
|
54
|
+
* Loads a session from storage
|
|
55
|
+
* @param sessionId The session ID to load
|
|
56
|
+
* @returns Session data or null if not found/expired
|
|
57
|
+
*/
|
|
58
|
+
load(sessionId: string): Promise<T | null>;
|
|
59
|
+
/**
|
|
60
|
+
* Lists all active sessions for this tool
|
|
61
|
+
* @returns Array of session data
|
|
62
|
+
*/
|
|
63
|
+
list(): Promise<T[]>;
|
|
64
|
+
/**
|
|
65
|
+
* Deletes a specific session
|
|
66
|
+
* @param sessionId The session ID to delete
|
|
67
|
+
* @returns true if deleted, false if not found
|
|
68
|
+
*/
|
|
69
|
+
delete(sessionId: string): Promise<boolean>;
|
|
70
|
+
/**
|
|
71
|
+
* Cleans up expired sessions
|
|
72
|
+
*/
|
|
73
|
+
private cleanExpiredSessions;
|
|
74
|
+
/**
|
|
75
|
+
* Enforces maximum session limits using configured eviction policy
|
|
76
|
+
*/
|
|
77
|
+
private enforceSessionLimits;
|
|
78
|
+
/**
|
|
79
|
+
* Gets the file path for a session
|
|
80
|
+
*/
|
|
81
|
+
private getSessionFilePath;
|
|
82
|
+
private getSafeSessionId;
|
|
83
|
+
/**
|
|
84
|
+
* Gets statistics about the session cache
|
|
85
|
+
*/
|
|
86
|
+
getStats(): Promise<{
|
|
87
|
+
toolName: string;
|
|
88
|
+
sessionCount: number;
|
|
89
|
+
ttl: number;
|
|
90
|
+
maxSessions: number;
|
|
91
|
+
evictionPolicy: string;
|
|
92
|
+
cacheDir: string;
|
|
93
|
+
}>;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=sessionManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessionManager.d.ts","sourceRoot":"","sources":["../../src/utils/sessionManager.ts"],"names":[],"mappings":"AAOA;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;CACxB;AAWD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,GAAG,KAAK,CAAC;CAChC;AAeD;;;;;;;;;;GAUG;AACH,qBAAa,cAAc,CAAC,CAAC,SAAS,WAAW;IAC/C,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,WAAW,CAA8B;gBAErC,QAAQ,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC;IAenE;;OAEG;YACW,mBAAmB;IAkBjC;;OAEG;YACW,mBAAmB;IASjC;;OAEG;YACW,eAAe;IAS7B;;;;OAIG;IACG,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAsCrD;;;;OAIG;IACG,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IA2EhD;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,CAAC,EAAE,CAAC;IA8B1B;;;;OAIG;IACG,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAiBjD;;OAEG;YACW,oBAAoB;IAwClC;;OAEG;YACW,oBAAoB;IAiDlC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAK1B,OAAO,CAAC,gBAAgB;IAgBxB;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC;QACxB,QAAQ,EAAE,MAAM,CAAC;QACjB,YAAY,EAAE,MAAM,CAAC;QACrB,GAAG,EAAE,MAAM,CAAC;QACZ,WAAW,EAAE,MAAM,CAAC;QACpB,cAAc,EAAE,MAAM,CAAC;QACvB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CAqBH"}
|
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
import * as fs from 'fs/promises';
|
|
2
|
+
import { existsSync, constants as fsConstants } from 'fs';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import * as os from 'os';
|
|
5
|
+
import { Logger } from './logger.js';
|
|
6
|
+
import { SESSION } from '../constants.js';
|
|
7
|
+
/**
|
|
8
|
+
* Default session configuration for all tools
|
|
9
|
+
*/
|
|
10
|
+
const DEFAULT_SESSION_CONFIG = {
|
|
11
|
+
ttl: SESSION.DEFAULT_TTL,
|
|
12
|
+
maxSessions: SESSION.DEFAULT_MAX_SESSIONS,
|
|
13
|
+
evictionPolicy: SESSION.DEFAULT_EVICTION_POLICY
|
|
14
|
+
};
|
|
15
|
+
// Base session storage directory (primary + legacy for backwards compatibility)
|
|
16
|
+
const PRIMARY_BASE_SESSIONS_DIR = path.join(os.homedir(), SESSION.BASE_DIR);
|
|
17
|
+
const LEGACY_BASE_SESSIONS_DIR = path.join(os.homedir(), '.gemini-mcp', 'sessions');
|
|
18
|
+
/**
|
|
19
|
+
* Generic session manager for all MCP tools
|
|
20
|
+
* Type parameter T ensures type safety for tool-specific session data
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* const manager = new SessionManager<MySessionData>('my-tool');
|
|
25
|
+
* manager.save('session-1', { sessionId: 'session-1', ... });
|
|
26
|
+
* const session = manager.load('session-1');
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export class SessionManager {
|
|
30
|
+
config;
|
|
31
|
+
cacheDir;
|
|
32
|
+
initPromise = null;
|
|
33
|
+
constructor(toolName, customConfig) {
|
|
34
|
+
const toolConfig = SESSION.TOOL_CONFIGS[toolName];
|
|
35
|
+
this.config = {
|
|
36
|
+
toolName,
|
|
37
|
+
ttl: customConfig?.ttl ?? toolConfig?.TTL ?? DEFAULT_SESSION_CONFIG.ttl,
|
|
38
|
+
maxSessions: customConfig?.maxSessions ?? toolConfig?.MAX_SESSIONS ?? DEFAULT_SESSION_CONFIG.maxSessions,
|
|
39
|
+
evictionPolicy: customConfig?.evictionPolicy ?? toolConfig?.EVICTION_POLICY ?? DEFAULT_SESSION_CONFIG.evictionPolicy
|
|
40
|
+
};
|
|
41
|
+
this.cacheDir = path.join(PRIMARY_BASE_SESSIONS_DIR, toolName);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Ensures the tool's session directory exists (lazy initialization)
|
|
45
|
+
*/
|
|
46
|
+
async ensureCacheDirAsync() {
|
|
47
|
+
if (this.initPromise)
|
|
48
|
+
return this.initPromise;
|
|
49
|
+
this.initPromise = (async () => {
|
|
50
|
+
try {
|
|
51
|
+
if (!existsSync(this.cacheDir)) {
|
|
52
|
+
await fs.mkdir(this.cacheDir, { recursive: true });
|
|
53
|
+
Logger.debug(`[${this.config.toolName}] Created session directory: ${this.cacheDir}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
Logger.error(`[${this.config.toolName}] Failed to create session directory ${this.cacheDir}: ${error}`);
|
|
58
|
+
throw new Error(`Session directory initialization failed: ${error}`);
|
|
59
|
+
}
|
|
60
|
+
})();
|
|
61
|
+
return this.initPromise;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Helper method to quickly get session count without parsing files
|
|
65
|
+
*/
|
|
66
|
+
async getSessionCountFast() {
|
|
67
|
+
try {
|
|
68
|
+
const files = await fs.readdir(this.cacheDir);
|
|
69
|
+
return files.filter(f => f.endsWith('.json')).length;
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return 0;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Helper method to read and parse a session file
|
|
77
|
+
*/
|
|
78
|
+
async readSessionFile(filePath) {
|
|
79
|
+
try {
|
|
80
|
+
const fileContent = await fs.readFile(filePath, 'utf-8');
|
|
81
|
+
return JSON.parse(fileContent);
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
throw new Error(`Failed to read session file: ${error}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Saves a session to persistent storage
|
|
89
|
+
* @param sessionId User-provided or generated session ID
|
|
90
|
+
* @param data Tool-specific session data
|
|
91
|
+
*/
|
|
92
|
+
async save(sessionId, data) {
|
|
93
|
+
await this.ensureCacheDirAsync();
|
|
94
|
+
// Moderate cleanup: only at 80% threshold
|
|
95
|
+
const sessionCount = await this.getSessionCountFast();
|
|
96
|
+
if (sessionCount >= this.config.maxSessions * 0.8) {
|
|
97
|
+
await this.cleanExpiredSessions();
|
|
98
|
+
}
|
|
99
|
+
const filePath = this.getSessionFilePath(sessionId);
|
|
100
|
+
// Ensure createdAt is always set (Issue #4)
|
|
101
|
+
const now = Date.now();
|
|
102
|
+
const cacheEntry = {
|
|
103
|
+
data: {
|
|
104
|
+
...data,
|
|
105
|
+
sessionId,
|
|
106
|
+
createdAt: data.createdAt || now, // Fallback if not set
|
|
107
|
+
lastAccessedAt: now
|
|
108
|
+
},
|
|
109
|
+
timestamp: now,
|
|
110
|
+
expiryTime: now + this.config.ttl
|
|
111
|
+
};
|
|
112
|
+
try {
|
|
113
|
+
await fs.writeFile(filePath, JSON.stringify(cacheEntry, null, 2), 'utf-8');
|
|
114
|
+
Logger.debug(`[${this.config.toolName}] Saved session: ${sessionId}`);
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
Logger.error(`[${this.config.toolName}] Failed to save session ${sessionId}: ${error}`);
|
|
118
|
+
throw new Error(`Failed to save session ${sessionId}: ${error}`);
|
|
119
|
+
}
|
|
120
|
+
// Only enforce limits if over max
|
|
121
|
+
if (sessionCount >= this.config.maxSessions) {
|
|
122
|
+
await this.enforceSessionLimits();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Loads a session from storage
|
|
127
|
+
* @param sessionId The session ID to load
|
|
128
|
+
* @returns Session data or null if not found/expired
|
|
129
|
+
*/
|
|
130
|
+
async load(sessionId) {
|
|
131
|
+
await this.ensureCacheDirAsync();
|
|
132
|
+
const safeSessionId = this.getSafeSessionId(sessionId);
|
|
133
|
+
const filePath = path.join(this.cacheDir, `${safeSessionId}.json`);
|
|
134
|
+
const legacyFilePath = path.join(LEGACY_BASE_SESSIONS_DIR, this.config.toolName, `${safeSessionId}.json`);
|
|
135
|
+
try {
|
|
136
|
+
// Check if file exists asynchronously (primary first, then legacy)
|
|
137
|
+
let activeFilePath = filePath;
|
|
138
|
+
try {
|
|
139
|
+
await fs.access(activeFilePath, fsConstants.F_OK);
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
try {
|
|
143
|
+
await fs.access(legacyFilePath, fsConstants.F_OK);
|
|
144
|
+
activeFilePath = legacyFilePath;
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
Logger.debug(`[${this.config.toolName}] Session not found: ${sessionId}`);
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
const cacheEntry = await this.readSessionFile(activeFilePath);
|
|
152
|
+
// Check expiry
|
|
153
|
+
if (Date.now() > cacheEntry.expiryTime) {
|
|
154
|
+
await fs.unlink(activeFilePath);
|
|
155
|
+
Logger.debug(`[${this.config.toolName}] Session expired and deleted: ${sessionId}`);
|
|
156
|
+
// Moderate optimization: run cleanup when we find expired sessions
|
|
157
|
+
await this.cleanExpiredSessions();
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
// Update last accessed time for LRU
|
|
161
|
+
if (this.config.evictionPolicy === 'lru') {
|
|
162
|
+
cacheEntry.data.lastAccessedAt = Date.now();
|
|
163
|
+
cacheEntry.timestamp = Date.now();
|
|
164
|
+
await fs.writeFile(activeFilePath, JSON.stringify(cacheEntry, null, 2), 'utf-8');
|
|
165
|
+
}
|
|
166
|
+
// Migrate legacy sessions to the primary cache dir on successful load
|
|
167
|
+
if (activeFilePath === legacyFilePath) {
|
|
168
|
+
try {
|
|
169
|
+
const primaryPath = path.join(this.cacheDir, `${safeSessionId}.json`);
|
|
170
|
+
await fs.writeFile(primaryPath, JSON.stringify(cacheEntry, null, 2), 'utf-8');
|
|
171
|
+
await fs.unlink(legacyFilePath).catch(() => undefined);
|
|
172
|
+
Logger.debug(`[${this.config.toolName}] Migrated legacy session: ${sessionId}`);
|
|
173
|
+
}
|
|
174
|
+
catch (migrationError) {
|
|
175
|
+
Logger.debug(`[${this.config.toolName}] Failed to migrate legacy session ${sessionId}: ${migrationError}`);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
Logger.debug(`[${this.config.toolName}] Loaded session: ${sessionId}`);
|
|
179
|
+
return cacheEntry.data;
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
Logger.warn(`[${this.config.toolName}] Failed to load session ${sessionId}: ${error}`);
|
|
183
|
+
// Issue #13: Only delete if file exists and is corrupt (not transient errors)
|
|
184
|
+
try {
|
|
185
|
+
await fs.access(filePath, fsConstants.F_OK);
|
|
186
|
+
// File exists, try to delete it
|
|
187
|
+
try {
|
|
188
|
+
await fs.unlink(filePath);
|
|
189
|
+
Logger.debug(`[${this.config.toolName}] Removed corrupt session file: ${sessionId}`);
|
|
190
|
+
}
|
|
191
|
+
catch (unlinkError) {
|
|
192
|
+
Logger.debug(`[${this.config.toolName}] Could not remove corrupt file ${sessionId}: ${unlinkError}`);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
// File doesn't exist, nothing to clean up
|
|
197
|
+
}
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Lists all active sessions for this tool
|
|
203
|
+
* @returns Array of session data
|
|
204
|
+
*/
|
|
205
|
+
async list() {
|
|
206
|
+
await this.ensureCacheDirAsync();
|
|
207
|
+
const sessions = [];
|
|
208
|
+
const now = Date.now();
|
|
209
|
+
try {
|
|
210
|
+
const files = await fs.readdir(this.cacheDir);
|
|
211
|
+
for (const file of files) {
|
|
212
|
+
if (!file.endsWith('.json'))
|
|
213
|
+
continue;
|
|
214
|
+
const filePath = path.join(this.cacheDir, file);
|
|
215
|
+
try {
|
|
216
|
+
const cacheEntry = await this.readSessionFile(filePath);
|
|
217
|
+
// Skip expired sessions
|
|
218
|
+
if (now <= cacheEntry.expiryTime) {
|
|
219
|
+
sessions.push(cacheEntry.data);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
catch (error) {
|
|
223
|
+
Logger.debug(`[${this.config.toolName}] Error reading session file ${file}: ${error}`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
catch (error) {
|
|
228
|
+
Logger.error(`[${this.config.toolName}] Failed to list sessions: ${error}`);
|
|
229
|
+
}
|
|
230
|
+
return sessions;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Deletes a specific session
|
|
234
|
+
* @param sessionId The session ID to delete
|
|
235
|
+
* @returns true if deleted, false if not found
|
|
236
|
+
*/
|
|
237
|
+
async delete(sessionId) {
|
|
238
|
+
const filePath = this.getSessionFilePath(sessionId);
|
|
239
|
+
try {
|
|
240
|
+
await fs.unlink(filePath);
|
|
241
|
+
Logger.debug(`[${this.config.toolName}] Deleted session: ${sessionId}`);
|
|
242
|
+
return true;
|
|
243
|
+
}
|
|
244
|
+
catch (error) {
|
|
245
|
+
if (error.code === 'ENOENT') {
|
|
246
|
+
Logger.debug(`[${this.config.toolName}] Session not found for deletion: ${sessionId}`);
|
|
247
|
+
return false; // File doesn't exist, effectively "deleted"
|
|
248
|
+
}
|
|
249
|
+
Logger.error(`[${this.config.toolName}] Failed to delete session ${sessionId}: ${error}`);
|
|
250
|
+
return false;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Cleans up expired sessions
|
|
255
|
+
*/
|
|
256
|
+
async cleanExpiredSessions() {
|
|
257
|
+
try {
|
|
258
|
+
await this.ensureCacheDirAsync();
|
|
259
|
+
const files = await fs.readdir(this.cacheDir);
|
|
260
|
+
const now = Date.now();
|
|
261
|
+
let cleaned = 0;
|
|
262
|
+
for (const file of files) {
|
|
263
|
+
if (!file.endsWith('.json'))
|
|
264
|
+
continue;
|
|
265
|
+
const filePath = path.join(this.cacheDir, file);
|
|
266
|
+
try {
|
|
267
|
+
const cacheEntry = await this.readSessionFile(filePath);
|
|
268
|
+
if (now > cacheEntry.expiryTime) {
|
|
269
|
+
await fs.unlink(filePath);
|
|
270
|
+
cleaned++;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
catch (error) {
|
|
274
|
+
// Issue #3: Log errors instead of empty catch
|
|
275
|
+
Logger.debug(`[${this.config.toolName}] Error checking session file ${file}: ${error}`);
|
|
276
|
+
// Try to remove corrupt file
|
|
277
|
+
try {
|
|
278
|
+
await fs.unlink(filePath);
|
|
279
|
+
cleaned++;
|
|
280
|
+
}
|
|
281
|
+
catch (unlinkError) {
|
|
282
|
+
Logger.debug(`[${this.config.toolName}] Could not remove corrupt file ${file}: ${unlinkError}`);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
if (cleaned > 0) {
|
|
287
|
+
Logger.debug(`[${this.config.toolName}] Cleaned ${cleaned} expired sessions`);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
catch (error) {
|
|
291
|
+
Logger.debug(`[${this.config.toolName}] Session cleanup error: ${error}`);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Enforces maximum session limits using configured eviction policy
|
|
296
|
+
*/
|
|
297
|
+
async enforceSessionLimits() {
|
|
298
|
+
try {
|
|
299
|
+
const files = await fs.readdir(this.cacheDir);
|
|
300
|
+
const jsonFiles = files.filter(f => f.endsWith('.json'));
|
|
301
|
+
if (jsonFiles.length <= this.config.maxSessions) {
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
// Get file stats for sorting
|
|
305
|
+
const fileStats = await Promise.all(jsonFiles.map(async (name) => {
|
|
306
|
+
const filePath = path.join(this.cacheDir, name);
|
|
307
|
+
const stat = await fs.stat(filePath);
|
|
308
|
+
return { name, path: filePath, stat };
|
|
309
|
+
}));
|
|
310
|
+
// Sort based on eviction policy
|
|
311
|
+
if (this.config.evictionPolicy === 'fifo') {
|
|
312
|
+
// Sort by creation time (oldest first)
|
|
313
|
+
fileStats.sort((a, b) => a.stat.birthtimeMs - b.stat.birthtimeMs);
|
|
314
|
+
}
|
|
315
|
+
else {
|
|
316
|
+
// LRU: Sort by modification time (least recently accessed first)
|
|
317
|
+
fileStats.sort((a, b) => a.stat.mtimeMs - b.stat.mtimeMs);
|
|
318
|
+
}
|
|
319
|
+
// Remove oldest files
|
|
320
|
+
const toRemove = fileStats.slice(0, fileStats.length - this.config.maxSessions);
|
|
321
|
+
let removed = 0;
|
|
322
|
+
for (const file of toRemove) {
|
|
323
|
+
try {
|
|
324
|
+
await fs.unlink(file.path);
|
|
325
|
+
removed++;
|
|
326
|
+
}
|
|
327
|
+
catch (error) {
|
|
328
|
+
// Issue #3: Log instead of empty catch
|
|
329
|
+
Logger.debug(`[${this.config.toolName}] Failed to remove session file ${file.name}: ${error}`);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
Logger.debug(`[${this.config.toolName}] Removed ${removed}/${toRemove.length} sessions (${this.config.evictionPolicy} policy)`);
|
|
333
|
+
}
|
|
334
|
+
catch (error) {
|
|
335
|
+
Logger.debug(`[${this.config.toolName}] Error enforcing session limits: ${error}`);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Gets the file path for a session
|
|
340
|
+
*/
|
|
341
|
+
getSessionFilePath(sessionId) {
|
|
342
|
+
const safeSessionId = this.getSafeSessionId(sessionId);
|
|
343
|
+
return path.join(this.cacheDir, `${safeSessionId}.json`);
|
|
344
|
+
}
|
|
345
|
+
getSafeSessionId(sessionId) {
|
|
346
|
+
// Issue #12: More robust sanitization
|
|
347
|
+
// Replace invalid characters, then clean up consecutive/leading/trailing hyphens
|
|
348
|
+
let safeSessionId = sessionId
|
|
349
|
+
.replace(/[^a-zA-Z0-9-_]/g, '-') // Replace invalid chars
|
|
350
|
+
.replace(/-+/g, '-') // Collapse consecutive hyphens
|
|
351
|
+
.replace(/^-+|-+$/g, ''); // Remove leading/trailing hyphens
|
|
352
|
+
// Ensure we have a valid ID after sanitization
|
|
353
|
+
if (!safeSessionId) {
|
|
354
|
+
safeSessionId = 'session';
|
|
355
|
+
}
|
|
356
|
+
return safeSessionId;
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Gets statistics about the session cache
|
|
360
|
+
*/
|
|
361
|
+
async getStats() {
|
|
362
|
+
await this.ensureCacheDirAsync();
|
|
363
|
+
let sessionCount = 0;
|
|
364
|
+
try {
|
|
365
|
+
const files = await fs.readdir(this.cacheDir);
|
|
366
|
+
sessionCount = files.filter(f => f.endsWith('.json')).length;
|
|
367
|
+
}
|
|
368
|
+
catch (error) {
|
|
369
|
+
// Issue #9/#14: Log error instead of empty catch
|
|
370
|
+
Logger.debug(`[${this.config.toolName}] Error reading session directory for stats: ${error}`);
|
|
371
|
+
}
|
|
372
|
+
return {
|
|
373
|
+
toolName: this.config.toolName,
|
|
374
|
+
sessionCount,
|
|
375
|
+
ttl: this.config.ttl,
|
|
376
|
+
maxSessions: this.config.maxSessions,
|
|
377
|
+
evictionPolicy: this.config.evictionPolicy,
|
|
378
|
+
cacheDir: this.cacheDir
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
//# sourceMappingURL=sessionManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessionManager.js","sourceRoot":"","sources":["../../src/utils/sessionManager.ts"],"names":[],"mappings":"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"}
|