@lim324/my-claude-code-viewer 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +80 -0
- package/bin/my-claude-code-viewer +3 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +47 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/cost-calculator.d.ts +25 -0
- package/dist/lib/cost-calculator.d.ts.map +1 -0
- package/dist/lib/cost-calculator.js +75 -0
- package/dist/lib/cost-calculator.js.map +1 -0
- package/dist/lib/jsonl-parser.d.ts +47 -0
- package/dist/lib/jsonl-parser.d.ts.map +1 -0
- package/dist/lib/jsonl-parser.js +68 -0
- package/dist/lib/jsonl-parser.js.map +1 -0
- package/dist/lib/pricing.d.ts +47 -0
- package/dist/lib/pricing.d.ts.map +1 -0
- package/dist/lib/pricing.js +119 -0
- package/dist/lib/pricing.js.map +1 -0
- package/dist/routes/api.d.ts +4 -0
- package/dist/routes/api.d.ts.map +1 -0
- package/dist/routes/api.js +103 -0
- package/dist/routes/api.js.map +1 -0
- package/dist/routes/views.d.ts +4 -0
- package/dist/routes/views.d.ts.map +1 -0
- package/dist/routes/views.js +737 -0
- package/dist/routes/views.js.map +1 -0
- package/dist/server/project-scanner.d.ts +63 -0
- package/dist/server/project-scanner.d.ts.map +1 -0
- package/dist/server/project-scanner.js +220 -0
- package/dist/server/project-scanner.js.map +1 -0
- package/dist/server/session-analyzer.d.ts +42 -0
- package/dist/server/session-analyzer.d.ts.map +1 -0
- package/dist/server/session-analyzer.js +185 -0
- package/dist/server/session-analyzer.js.map +1 -0
- package/package.json +47 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"views.js","sourceRoot":"","sources":["../../src/routes/views.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { Session } from "./session-analyzer";
|
|
2
|
+
export declare const CLAUDE_PROJECTS_PATH: string;
|
|
3
|
+
export interface Project {
|
|
4
|
+
id: string;
|
|
5
|
+
name: string;
|
|
6
|
+
path: string;
|
|
7
|
+
lastModifiedAt: Date;
|
|
8
|
+
sessionCount: number;
|
|
9
|
+
totalMessageCount: number;
|
|
10
|
+
totalCost: number;
|
|
11
|
+
}
|
|
12
|
+
export interface ProjectDetail extends Project {
|
|
13
|
+
sessions: Session[];
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Validate and sanitize project ID to prevent path traversal
|
|
17
|
+
*/
|
|
18
|
+
export declare function sanitizeProjectId(id: string): string | null;
|
|
19
|
+
/**
|
|
20
|
+
* Validate and sanitize session ID to prevent path traversal
|
|
21
|
+
*/
|
|
22
|
+
export declare function sanitizeSessionId(id: string): string | null;
|
|
23
|
+
/**
|
|
24
|
+
* Validate that a resolved path is within the allowed directory
|
|
25
|
+
*/
|
|
26
|
+
export declare function isPathSafe(resolvedPath: string, basePath: string): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Get the safe project path, returning null if invalid
|
|
29
|
+
*/
|
|
30
|
+
export declare function getSafeProjectPath(projectId: string): string | null;
|
|
31
|
+
/**
|
|
32
|
+
* Get the safe session file path, returning null if invalid
|
|
33
|
+
*/
|
|
34
|
+
export declare function getSafeSessionPath(projectPath: string, sessionId: string): string | null;
|
|
35
|
+
/**
|
|
36
|
+
* Encode project name to a URL-safe ID (now just returns the sanitized name)
|
|
37
|
+
* Note: We now use the directory name directly as the ID for better security
|
|
38
|
+
*/
|
|
39
|
+
export declare function encodeProjectId(projectName: string): string;
|
|
40
|
+
/**
|
|
41
|
+
* Decode project ID to get the original path
|
|
42
|
+
* @deprecated Use getSafeProjectPath instead
|
|
43
|
+
*/
|
|
44
|
+
export declare function decodeProjectId(id: string): string;
|
|
45
|
+
/**
|
|
46
|
+
* Scan all projects in the Claude projects directory
|
|
47
|
+
*/
|
|
48
|
+
export declare function scanProjects(): Project[];
|
|
49
|
+
/**
|
|
50
|
+
* Get detailed project information with sessions
|
|
51
|
+
*/
|
|
52
|
+
export declare function getProjectDetail(projectId: string): ProjectDetail | null;
|
|
53
|
+
/**
|
|
54
|
+
* Get global statistics
|
|
55
|
+
*/
|
|
56
|
+
export declare function getGlobalStats(): {
|
|
57
|
+
totalProjects: number;
|
|
58
|
+
totalSessions: number;
|
|
59
|
+
totalMessages: number;
|
|
60
|
+
totalCost: number;
|
|
61
|
+
projectsPath: string;
|
|
62
|
+
};
|
|
63
|
+
//# sourceMappingURL=project-scanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-scanner.d.ts","sourceRoot":"","sources":["../../src/server/project-scanner.ts"],"names":[],"mappings":"AAGA,OAAO,EAAsB,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAEjE,eAAO,MAAM,oBAAoB,QAAiD,CAAC;AAQnF,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,IAAI,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAc,SAAQ,OAAO;IAC5C,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAU3D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAU3D;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAI1E;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAUnE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAaxF;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAGlD;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,OAAO,EAAE,CAgFxC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CA6CxE;AAED;;GAEG;AACH,wBAAgB,cAAc;;;;;;EAe7B"}
|
|
@@ -0,0 +1,220 @@
|
|
|
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.CLAUDE_PROJECTS_PATH = void 0;
|
|
7
|
+
exports.sanitizeProjectId = sanitizeProjectId;
|
|
8
|
+
exports.sanitizeSessionId = sanitizeSessionId;
|
|
9
|
+
exports.isPathSafe = isPathSafe;
|
|
10
|
+
exports.getSafeProjectPath = getSafeProjectPath;
|
|
11
|
+
exports.getSafeSessionPath = getSafeSessionPath;
|
|
12
|
+
exports.encodeProjectId = encodeProjectId;
|
|
13
|
+
exports.decodeProjectId = decodeProjectId;
|
|
14
|
+
exports.scanProjects = scanProjects;
|
|
15
|
+
exports.getProjectDetail = getProjectDetail;
|
|
16
|
+
exports.getGlobalStats = getGlobalStats;
|
|
17
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
18
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
19
|
+
const node_os_1 = __importDefault(require("node:os"));
|
|
20
|
+
const session_analyzer_1 = require("./session-analyzer");
|
|
21
|
+
exports.CLAUDE_PROJECTS_PATH = node_path_1.default.join(node_os_1.default.homedir(), ".claude", "projects");
|
|
22
|
+
// Valid project ID pattern: only alphanumeric, hyphen, underscore
|
|
23
|
+
const VALID_PROJECT_ID_PATTERN = /^[a-zA-Z0-9_-]+$/;
|
|
24
|
+
// Valid session ID pattern: UUID format or alphanumeric with hyphens
|
|
25
|
+
const VALID_SESSION_ID_PATTERN = /^[a-zA-Z0-9-_.]+$/;
|
|
26
|
+
/**
|
|
27
|
+
* Validate and sanitize project ID to prevent path traversal
|
|
28
|
+
*/
|
|
29
|
+
function sanitizeProjectId(id) {
|
|
30
|
+
if (!id || typeof id !== "string")
|
|
31
|
+
return null;
|
|
32
|
+
// Remove any path separators and parent directory references
|
|
33
|
+
const sanitized = id.replace(/[\\\/]/g, "").replace(/\.{2,}/g, "");
|
|
34
|
+
// Validate against allowed pattern
|
|
35
|
+
if (!VALID_PROJECT_ID_PATTERN.test(sanitized))
|
|
36
|
+
return null;
|
|
37
|
+
return sanitized;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Validate and sanitize session ID to prevent path traversal
|
|
41
|
+
*/
|
|
42
|
+
function sanitizeSessionId(id) {
|
|
43
|
+
if (!id || typeof id !== "string")
|
|
44
|
+
return null;
|
|
45
|
+
// Remove any path separators and parent directory references
|
|
46
|
+
const sanitized = id.replace(/[\\\/]/g, "").replace(/\.{2,}/g, "");
|
|
47
|
+
// Validate against allowed pattern
|
|
48
|
+
if (!VALID_SESSION_ID_PATTERN.test(sanitized))
|
|
49
|
+
return null;
|
|
50
|
+
return sanitized;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Validate that a resolved path is within the allowed directory
|
|
54
|
+
*/
|
|
55
|
+
function isPathSafe(resolvedPath, basePath) {
|
|
56
|
+
const resolved = node_path_1.default.resolve(resolvedPath);
|
|
57
|
+
const base = node_path_1.default.resolve(basePath);
|
|
58
|
+
return resolved.startsWith(base + node_path_1.default.sep) || resolved === base;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Get the safe project path, returning null if invalid
|
|
62
|
+
*/
|
|
63
|
+
function getSafeProjectPath(projectId) {
|
|
64
|
+
const sanitizedId = sanitizeProjectId(projectId);
|
|
65
|
+
if (!sanitizedId)
|
|
66
|
+
return null;
|
|
67
|
+
const projectPath = node_path_1.default.join(exports.CLAUDE_PROJECTS_PATH, sanitizedId);
|
|
68
|
+
// Verify the path is within the allowed directory
|
|
69
|
+
if (!isPathSafe(projectPath, exports.CLAUDE_PROJECTS_PATH))
|
|
70
|
+
return null;
|
|
71
|
+
return projectPath;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Get the safe session file path, returning null if invalid
|
|
75
|
+
*/
|
|
76
|
+
function getSafeSessionPath(projectPath, sessionId) {
|
|
77
|
+
const sanitizedSessionId = sanitizeSessionId(sessionId);
|
|
78
|
+
if (!sanitizedSessionId)
|
|
79
|
+
return null;
|
|
80
|
+
// Ensure projectPath itself is safe
|
|
81
|
+
if (!isPathSafe(projectPath, exports.CLAUDE_PROJECTS_PATH))
|
|
82
|
+
return null;
|
|
83
|
+
const sessionPath = node_path_1.default.join(projectPath, `${sanitizedSessionId}.jsonl`);
|
|
84
|
+
// Double-check the final path is still safe
|
|
85
|
+
if (!isPathSafe(sessionPath, exports.CLAUDE_PROJECTS_PATH))
|
|
86
|
+
return null;
|
|
87
|
+
return sessionPath;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Encode project name to a URL-safe ID (now just returns the sanitized name)
|
|
91
|
+
* Note: We now use the directory name directly as the ID for better security
|
|
92
|
+
*/
|
|
93
|
+
function encodeProjectId(projectName) {
|
|
94
|
+
return sanitizeProjectId(projectName) || "";
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Decode project ID to get the original path
|
|
98
|
+
* @deprecated Use getSafeProjectPath instead
|
|
99
|
+
*/
|
|
100
|
+
function decodeProjectId(id) {
|
|
101
|
+
const safePath = getSafeProjectPath(id);
|
|
102
|
+
return safePath || "";
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Scan all projects in the Claude projects directory
|
|
106
|
+
*/
|
|
107
|
+
function scanProjects() {
|
|
108
|
+
try {
|
|
109
|
+
if (!node_fs_1.default.existsSync(exports.CLAUDE_PROJECTS_PATH)) {
|
|
110
|
+
console.warn(`Claude projects directory not found at ${exports.CLAUDE_PROJECTS_PATH}`);
|
|
111
|
+
return [];
|
|
112
|
+
}
|
|
113
|
+
const entries = node_fs_1.default.readdirSync(exports.CLAUDE_PROJECTS_PATH, { withFileTypes: true });
|
|
114
|
+
const projects = [];
|
|
115
|
+
for (const entry of entries) {
|
|
116
|
+
if (!entry.isDirectory())
|
|
117
|
+
continue;
|
|
118
|
+
// Validate directory name
|
|
119
|
+
const sanitizedName = sanitizeProjectId(entry.name);
|
|
120
|
+
if (!sanitizedName) {
|
|
121
|
+
console.warn(`Skipping project with invalid name: ${entry.name}`);
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
const projectPath = node_path_1.default.join(exports.CLAUDE_PROJECTS_PATH, entry.name);
|
|
125
|
+
const projectId = sanitizedName;
|
|
126
|
+
// Get sessions to calculate stats
|
|
127
|
+
const sessions = (0, session_analyzer_1.getProjectSessions)(projectId, projectPath);
|
|
128
|
+
if (sessions.length === 0) {
|
|
129
|
+
// Still include the project even if no sessions
|
|
130
|
+
try {
|
|
131
|
+
const stat = node_fs_1.default.statSync(projectPath);
|
|
132
|
+
projects.push({
|
|
133
|
+
id: projectId,
|
|
134
|
+
name: entry.name,
|
|
135
|
+
path: entry.name, // Return relative path only
|
|
136
|
+
lastModifiedAt: stat.mtime,
|
|
137
|
+
sessionCount: 0,
|
|
138
|
+
totalMessageCount: 0,
|
|
139
|
+
totalCost: 0,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
// Skip if can't stat
|
|
144
|
+
}
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
const totalMessageCount = sessions.reduce((sum, s) => sum + s.meta.messageCount, 0);
|
|
148
|
+
const totalCost = sessions.reduce((sum, s) => sum + s.meta.cost.totalUsd, 0);
|
|
149
|
+
// Get the latest modified date from sessions
|
|
150
|
+
const lastModifiedAt = sessions.reduce((latest, s) => s.lastModifiedAt > latest ? s.lastModifiedAt : latest, sessions[0]?.lastModifiedAt || new Date());
|
|
151
|
+
projects.push({
|
|
152
|
+
id: projectId,
|
|
153
|
+
name: entry.name,
|
|
154
|
+
path: entry.name, // Return relative path only
|
|
155
|
+
lastModifiedAt,
|
|
156
|
+
sessionCount: sessions.length,
|
|
157
|
+
totalMessageCount,
|
|
158
|
+
totalCost,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
// Sort by last modified date
|
|
162
|
+
return projects.sort((a, b) => b.lastModifiedAt.getTime() - a.lastModifiedAt.getTime());
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
console.error("Error scanning projects:", error);
|
|
166
|
+
return [];
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Get detailed project information with sessions
|
|
171
|
+
*/
|
|
172
|
+
function getProjectDetail(projectId) {
|
|
173
|
+
try {
|
|
174
|
+
const projectPath = getSafeProjectPath(projectId);
|
|
175
|
+
if (!projectPath) {
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
if (!node_fs_1.default.existsSync(projectPath)) {
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
const name = node_path_1.default.basename(projectPath);
|
|
182
|
+
const sessions = (0, session_analyzer_1.getProjectSessions)(projectId, projectPath);
|
|
183
|
+
const totalMessageCount = sessions.reduce((sum, s) => sum + s.meta.messageCount, 0);
|
|
184
|
+
const totalCost = sessions.reduce((sum, s) => sum + s.meta.cost.totalUsd, 0);
|
|
185
|
+
const lastModifiedAt = sessions.reduce((latest, s) => s.lastModifiedAt > latest ? s.lastModifiedAt : latest, new Date(0));
|
|
186
|
+
const stat = node_fs_1.default.statSync(projectPath);
|
|
187
|
+
return {
|
|
188
|
+
id: projectId,
|
|
189
|
+
name,
|
|
190
|
+
path: name, // Return relative path only
|
|
191
|
+
lastModifiedAt: sessions.length > 0 ? lastModifiedAt : stat.mtime,
|
|
192
|
+
sessionCount: sessions.length,
|
|
193
|
+
totalMessageCount,
|
|
194
|
+
totalCost,
|
|
195
|
+
sessions,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
catch (error) {
|
|
199
|
+
console.error(`Error getting project ${projectId}:`, error);
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Get global statistics
|
|
205
|
+
*/
|
|
206
|
+
function getGlobalStats() {
|
|
207
|
+
const projects = scanProjects();
|
|
208
|
+
const totalProjects = projects.length;
|
|
209
|
+
const totalSessions = projects.reduce((sum, p) => sum + p.sessionCount, 0);
|
|
210
|
+
const totalMessages = projects.reduce((sum, p) => sum + p.totalMessageCount, 0);
|
|
211
|
+
const totalCost = projects.reduce((sum, p) => sum + p.totalCost, 0);
|
|
212
|
+
return {
|
|
213
|
+
totalProjects,
|
|
214
|
+
totalSessions,
|
|
215
|
+
totalMessages,
|
|
216
|
+
totalCost,
|
|
217
|
+
projectsPath: "~/.claude/projects", // Return masked path
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
//# sourceMappingURL=project-scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-scanner.js","sourceRoot":"","sources":["../../src/server/project-scanner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { parseJsonl } from "../lib/jsonl-parser";
|
|
2
|
+
import { AggregatedCost } from "../lib/cost-calculator";
|
|
3
|
+
export interface SessionMeta {
|
|
4
|
+
messageCount: number;
|
|
5
|
+
firstUserMessage: string | null;
|
|
6
|
+
cost: AggregatedCost;
|
|
7
|
+
modelName: string;
|
|
8
|
+
}
|
|
9
|
+
export interface Session {
|
|
10
|
+
id: string;
|
|
11
|
+
projectId: string;
|
|
12
|
+
jsonlFilePath: string;
|
|
13
|
+
lastModifiedAt: Date;
|
|
14
|
+
meta: SessionMeta;
|
|
15
|
+
}
|
|
16
|
+
export interface SessionDetail extends Session {
|
|
17
|
+
conversations: ReturnType<typeof parseJsonl>;
|
|
18
|
+
userMessageCount: number;
|
|
19
|
+
assistantMessageCount: number;
|
|
20
|
+
systemMessageCount: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Check if a file is a regular session file (not agent file)
|
|
24
|
+
*/
|
|
25
|
+
export declare function isRegularSessionFile(filename: string): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Get agent session files for a given session
|
|
28
|
+
*/
|
|
29
|
+
export declare function getAgentSessionFiles(projectPath: string, sessionId: string): string[];
|
|
30
|
+
/**
|
|
31
|
+
* Analyze a session file and return session metadata
|
|
32
|
+
*/
|
|
33
|
+
export declare function analyzeSession(projectId: string, sessionId: string, projectPath: string): Session | null;
|
|
34
|
+
/**
|
|
35
|
+
* Get detailed session information including conversations
|
|
36
|
+
*/
|
|
37
|
+
export declare function getSessionDetail(projectId: string, sessionId: string, projectPath: string): SessionDetail | null;
|
|
38
|
+
/**
|
|
39
|
+
* Get all sessions for a project
|
|
40
|
+
*/
|
|
41
|
+
export declare function getProjectSessions(projectId: string, projectPath: string): Session[];
|
|
42
|
+
//# sourceMappingURL=session-analyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-analyzer.d.ts","sourceRoot":"","sources":["../../src/server/session-analyzer.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAA0C,MAAM,qBAAqB,CAAC;AACzF,OAAO,EAAqB,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAG3E,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,IAAI,CAAC;IACrB,IAAI,EAAE,WAAW,CAAC;CACnB;AAED,MAAM,WAAW,aAAc,SAAQ,OAAO;IAC5C,aAAa,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;IAC7C,gBAAgB,EAAE,MAAM,CAAC;IACzB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,MAAM,EAAE,CAgBV;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAClB,OAAO,GAAG,IAAI,CAqFhB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAClB,aAAa,GAAG,IAAI,CA+BtB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAClB,OAAO,EAAE,CA4BX"}
|
|
@@ -0,0 +1,185 @@
|
|
|
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.isRegularSessionFile = isRegularSessionFile;
|
|
7
|
+
exports.getAgentSessionFiles = getAgentSessionFiles;
|
|
8
|
+
exports.analyzeSession = analyzeSession;
|
|
9
|
+
exports.getSessionDetail = getSessionDetail;
|
|
10
|
+
exports.getProjectSessions = getProjectSessions;
|
|
11
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
12
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
13
|
+
const jsonl_parser_1 = require("../lib/jsonl-parser");
|
|
14
|
+
const cost_calculator_1 = require("../lib/cost-calculator");
|
|
15
|
+
const project_scanner_1 = require("./project-scanner");
|
|
16
|
+
/**
|
|
17
|
+
* Check if a file is a regular session file (not agent file)
|
|
18
|
+
*/
|
|
19
|
+
function isRegularSessionFile(filename) {
|
|
20
|
+
return filename.endsWith(".jsonl") && !filename.startsWith("agent-");
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Get agent session files for a given session
|
|
24
|
+
*/
|
|
25
|
+
function getAgentSessionFiles(projectPath, sessionId) {
|
|
26
|
+
try {
|
|
27
|
+
// Validate sessionId
|
|
28
|
+
const sanitizedSessionId = (0, project_scanner_1.sanitizeSessionId)(sessionId);
|
|
29
|
+
if (!sanitizedSessionId)
|
|
30
|
+
return [];
|
|
31
|
+
// Validate projectPath is safe
|
|
32
|
+
if (!(0, project_scanner_1.isPathSafe)(projectPath, project_scanner_1.CLAUDE_PROJECTS_PATH))
|
|
33
|
+
return [];
|
|
34
|
+
const files = node_fs_1.default.readdirSync(projectPath);
|
|
35
|
+
return files
|
|
36
|
+
.filter((f) => f.startsWith(`agent-${sanitizedSessionId}`) && f.endsWith(".jsonl"))
|
|
37
|
+
.map((f) => node_path_1.default.join(projectPath, f));
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Analyze a session file and return session metadata
|
|
45
|
+
*/
|
|
46
|
+
function analyzeSession(projectId, sessionId, projectPath) {
|
|
47
|
+
// Validate inputs
|
|
48
|
+
const sanitizedSessionId = (0, project_scanner_1.sanitizeSessionId)(sessionId);
|
|
49
|
+
if (!sanitizedSessionId) {
|
|
50
|
+
console.error(`Invalid session ID: ${sessionId}`);
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
// Validate projectPath is within allowed directory
|
|
54
|
+
if (!(0, project_scanner_1.isPathSafe)(projectPath, project_scanner_1.CLAUDE_PROJECTS_PATH)) {
|
|
55
|
+
console.error(`Invalid project path: ${projectPath}`);
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
const sessionFilePath = node_path_1.default.join(projectPath, `${sanitizedSessionId}.jsonl`);
|
|
59
|
+
// Double-check the constructed path is still safe
|
|
60
|
+
if (!(0, project_scanner_1.isPathSafe)(sessionFilePath, project_scanner_1.CLAUDE_PROJECTS_PATH)) {
|
|
61
|
+
console.error(`Path traversal attempt detected: ${sessionFilePath}`);
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
if (!node_fs_1.default.existsSync(sessionFilePath)) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
const stat = node_fs_1.default.statSync(sessionFilePath);
|
|
69
|
+
const content = node_fs_1.default.readFileSync(sessionFilePath, "utf-8");
|
|
70
|
+
const lines = content.split("\n").filter((line) => line.trim());
|
|
71
|
+
// Parse first line to extract actual sessionId
|
|
72
|
+
let actualSessionId;
|
|
73
|
+
if (lines[0]) {
|
|
74
|
+
try {
|
|
75
|
+
const firstLineData = JSON.parse(lines[0]);
|
|
76
|
+
if (firstLineData.sessionId) {
|
|
77
|
+
actualSessionId = firstLineData.sessionId;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
// Invalid JSON, skip
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// Get agent session files
|
|
85
|
+
const agentFiles = actualSessionId
|
|
86
|
+
? getAgentSessionFiles(projectPath, actualSessionId)
|
|
87
|
+
: [];
|
|
88
|
+
// Read agent file contents
|
|
89
|
+
const agentContents = agentFiles
|
|
90
|
+
.map((f) => {
|
|
91
|
+
try {
|
|
92
|
+
// Validate each agent file path before reading
|
|
93
|
+
if (!(0, project_scanner_1.isPathSafe)(f, project_scanner_1.CLAUDE_PROJECTS_PATH))
|
|
94
|
+
return "";
|
|
95
|
+
return node_fs_1.default.readFileSync(f, "utf-8");
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return "";
|
|
99
|
+
}
|
|
100
|
+
})
|
|
101
|
+
.filter((c) => c.length > 0);
|
|
102
|
+
// Calculate costs including agent files
|
|
103
|
+
const allContents = [content, ...agentContents];
|
|
104
|
+
const costInfo = (0, cost_calculator_1.calculateFileCost)(allContents.join("\n"));
|
|
105
|
+
const conversations = (0, jsonl_parser_1.parseJsonl)(content);
|
|
106
|
+
const firstUserMessage = (0, jsonl_parser_1.extractFirstUserMessage)(conversations);
|
|
107
|
+
return {
|
|
108
|
+
id: sanitizedSessionId,
|
|
109
|
+
projectId,
|
|
110
|
+
jsonlFilePath: `${sanitizedSessionId}.jsonl`, // Return relative path only
|
|
111
|
+
lastModifiedAt: stat.mtime,
|
|
112
|
+
meta: {
|
|
113
|
+
messageCount: lines.length,
|
|
114
|
+
firstUserMessage,
|
|
115
|
+
cost: costInfo,
|
|
116
|
+
modelName: costInfo.modelName,
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
console.error(`Error analyzing session ${sessionId}:`, error);
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Get detailed session information including conversations
|
|
127
|
+
*/
|
|
128
|
+
function getSessionDetail(projectId, sessionId, projectPath) {
|
|
129
|
+
const session = analyzeSession(projectId, sessionId, projectPath);
|
|
130
|
+
if (!session)
|
|
131
|
+
return null;
|
|
132
|
+
// Validate projectPath again
|
|
133
|
+
if (!(0, project_scanner_1.isPathSafe)(projectPath, project_scanner_1.CLAUDE_PROJECTS_PATH)) {
|
|
134
|
+
console.error(`Invalid project path in getSessionDetail: ${projectPath}`);
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
const sanitizedSessionId = (0, project_scanner_1.sanitizeSessionId)(sessionId);
|
|
138
|
+
if (!sanitizedSessionId)
|
|
139
|
+
return null;
|
|
140
|
+
const sessionFilePath = node_path_1.default.join(projectPath, `${sanitizedSessionId}.jsonl`);
|
|
141
|
+
// Validate final path
|
|
142
|
+
if (!(0, project_scanner_1.isPathSafe)(sessionFilePath, project_scanner_1.CLAUDE_PROJECTS_PATH)) {
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
const content = node_fs_1.default.readFileSync(sessionFilePath, "utf-8");
|
|
146
|
+
const conversations = (0, jsonl_parser_1.parseJsonl)(content);
|
|
147
|
+
const messageCounts = (0, jsonl_parser_1.countMessages)(conversations);
|
|
148
|
+
return {
|
|
149
|
+
...session,
|
|
150
|
+
conversations,
|
|
151
|
+
userMessageCount: messageCounts.user,
|
|
152
|
+
assistantMessageCount: messageCounts.assistant,
|
|
153
|
+
systemMessageCount: messageCounts.system,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Get all sessions for a project
|
|
158
|
+
*/
|
|
159
|
+
function getProjectSessions(projectId, projectPath) {
|
|
160
|
+
try {
|
|
161
|
+
// Validate projectPath is safe
|
|
162
|
+
if (!(0, project_scanner_1.isPathSafe)(projectPath, project_scanner_1.CLAUDE_PROJECTS_PATH)) {
|
|
163
|
+
console.error(`Invalid project path in getProjectSessions: ${projectPath}`);
|
|
164
|
+
return [];
|
|
165
|
+
}
|
|
166
|
+
if (!node_fs_1.default.existsSync(projectPath)) {
|
|
167
|
+
return [];
|
|
168
|
+
}
|
|
169
|
+
const files = node_fs_1.default.readdirSync(projectPath);
|
|
170
|
+
const sessionFiles = files.filter(isRegularSessionFile);
|
|
171
|
+
const sessions = sessionFiles
|
|
172
|
+
.map((file) => {
|
|
173
|
+
const sessionId = file.replace(".jsonl", "");
|
|
174
|
+
return analyzeSession(projectId, sessionId, projectPath);
|
|
175
|
+
})
|
|
176
|
+
.filter((s) => s !== null)
|
|
177
|
+
.sort((a, b) => b.lastModifiedAt.getTime() - a.lastModifiedAt.getTime());
|
|
178
|
+
return sessions;
|
|
179
|
+
}
|
|
180
|
+
catch (error) {
|
|
181
|
+
console.error(`Error getting sessions for ${projectId}:`, error);
|
|
182
|
+
return [];
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=session-analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-analyzer.js","sourceRoot":"","sources":["../../src/server/session-analyzer.ts"],"names":[],"mappings":";;;;;AA+BA,oDAEC;AAKD,oDAmBC;AAKD,wCAyFC;AAKD,4CAmCC;AAKD,gDA+BC;AAnOD,sDAAyB;AACzB,0DAA6B;AAC7B,sDAAyF;AACzF,4DAA2E;AAC3E,uDAAwF;AAwBxF;;GAEG;AACH,SAAgB,oBAAoB,CAAC,QAAgB;IACnD,OAAO,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;AACvE,CAAC;AAED;;GAEG;AACH,SAAgB,oBAAoB,CAClC,WAAmB,EACnB,SAAiB;IAEjB,IAAI,CAAC;QACH,qBAAqB;QACrB,MAAM,kBAAkB,GAAG,IAAA,mCAAiB,EAAC,SAAS,CAAC,CAAC;QACxD,IAAI,CAAC,kBAAkB;YAAE,OAAO,EAAE,CAAC;QAEnC,+BAA+B;QAC/B,IAAI,CAAC,IAAA,4BAAU,EAAC,WAAW,EAAE,sCAAoB,CAAC;YAAE,OAAO,EAAE,CAAC;QAE9D,MAAM,KAAK,GAAG,iBAAE,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;QAC1C,OAAO,KAAK;aACT,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,kBAAkB,EAAE,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;aAClF,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,mBAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAgB,cAAc,CAC5B,SAAiB,EACjB,SAAiB,EACjB,WAAmB;IAEnB,kBAAkB;IAClB,MAAM,kBAAkB,GAAG,IAAA,mCAAiB,EAAC,SAAS,CAAC,CAAC;IACxD,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACxB,OAAO,CAAC,KAAK,CAAC,uBAAuB,SAAS,EAAE,CAAC,CAAC;QAClD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,mDAAmD;IACnD,IAAI,CAAC,IAAA,4BAAU,EAAC,WAAW,EAAE,sCAAoB,CAAC,EAAE,CAAC;QACnD,OAAO,CAAC,KAAK,CAAC,yBAAyB,WAAW,EAAE,CAAC,CAAC;QACtD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,eAAe,GAAG,mBAAI,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,kBAAkB,QAAQ,CAAC,CAAC;IAE9E,kDAAkD;IAClD,IAAI,CAAC,IAAA,4BAAU,EAAC,eAAe,EAAE,sCAAoB,CAAC,EAAE,CAAC;QACvD,OAAO,CAAC,KAAK,CAAC,oCAAoC,eAAe,EAAE,CAAC,CAAC;QACrE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,IAAI,CAAC,iBAAE,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;YACpC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,IAAI,GAAG,iBAAE,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;QAC1C,MAAM,OAAO,GAAG,iBAAE,CAAC,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;QAC1D,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAEhE,+CAA+C;QAC/C,IAAI,eAAmC,CAAC;QACxC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YACb,IAAI,CAAC;gBACH,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC3C,IAAI,aAAa,CAAC,SAAS,EAAE,CAAC;oBAC5B,eAAe,GAAG,aAAa,CAAC,SAAS,CAAC;gBAC5C,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,qBAAqB;YACvB,CAAC;QACH,CAAC;QAED,0BAA0B;QAC1B,MAAM,UAAU,GAAG,eAAe;YAChC,CAAC,CAAC,oBAAoB,CAAC,WAAW,EAAE,eAAe,CAAC;YACpD,CAAC,CAAC,EAAE,CAAC;QAEP,2BAA2B;QAC3B,MAAM,aAAa,GAAG,UAAU;aAC7B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YACT,IAAI,CAAC;gBACH,+CAA+C;gBAC/C,IAAI,CAAC,IAAA,4BAAU,EAAC,CAAC,EAAE,sCAAoB,CAAC;oBAAE,OAAO,EAAE,CAAC;gBACpD,OAAO,iBAAE,CAAC,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YACrC,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC,CAAC;aACD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAE/B,wCAAwC;QACxC,MAAM,WAAW,GAAG,CAAC,OAAO,EAAE,GAAG,aAAa,CAAC,CAAC;QAChD,MAAM,QAAQ,GAAG,IAAA,mCAAiB,EAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAE3D,MAAM,aAAa,GAAG,IAAA,yBAAU,EAAC,OAAO,CAAC,CAAC;QAC1C,MAAM,gBAAgB,GAAG,IAAA,sCAAuB,EAAC,aAAa,CAAC,CAAC;QAEhE,OAAO;YACL,EAAE,EAAE,kBAAkB;YACtB,SAAS;YACT,aAAa,EAAE,GAAG,kBAAkB,QAAQ,EAAE,4BAA4B;YAC1E,cAAc,EAAE,IAAI,CAAC,KAAK;YAC1B,IAAI,EAAE;gBACJ,YAAY,EAAE,KAAK,CAAC,MAAM;gBAC1B,gBAAgB;gBAChB,IAAI,EAAE,QAAQ;gBACd,SAAS,EAAE,QAAQ,CAAC,SAAS;aAC9B;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,2BAA2B,SAAS,GAAG,EAAE,KAAK,CAAC,CAAC;QAC9D,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAgB,gBAAgB,CAC9B,SAAiB,EACjB,SAAiB,EACjB,WAAmB;IAEnB,MAAM,OAAO,GAAG,cAAc,CAAC,SAAS,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;IAClE,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAE1B,6BAA6B;IAC7B,IAAI,CAAC,IAAA,4BAAU,EAAC,WAAW,EAAE,sCAAoB,CAAC,EAAE,CAAC;QACnD,OAAO,CAAC,KAAK,CAAC,6CAA6C,WAAW,EAAE,CAAC,CAAC;QAC1E,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,kBAAkB,GAAG,IAAA,mCAAiB,EAAC,SAAS,CAAC,CAAC;IACxD,IAAI,CAAC,kBAAkB;QAAE,OAAO,IAAI,CAAC;IAErC,MAAM,eAAe,GAAG,mBAAI,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,kBAAkB,QAAQ,CAAC,CAAC;IAE9E,sBAAsB;IACtB,IAAI,CAAC,IAAA,4BAAU,EAAC,eAAe,EAAE,sCAAoB,CAAC,EAAE,CAAC;QACvD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,OAAO,GAAG,iBAAE,CAAC,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;IAC1D,MAAM,aAAa,GAAG,IAAA,yBAAU,EAAC,OAAO,CAAC,CAAC;IAC1C,MAAM,aAAa,GAAG,IAAA,4BAAa,EAAC,aAAa,CAAC,CAAC;IAEnD,OAAO;QACL,GAAG,OAAO;QACV,aAAa;QACb,gBAAgB,EAAE,aAAa,CAAC,IAAI;QACpC,qBAAqB,EAAE,aAAa,CAAC,SAAS;QAC9C,kBAAkB,EAAE,aAAa,CAAC,MAAM;KACzC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAgB,kBAAkB,CAChC,SAAiB,EACjB,WAAmB;IAEnB,IAAI,CAAC;QACH,+BAA+B;QAC/B,IAAI,CAAC,IAAA,4BAAU,EAAC,WAAW,EAAE,sCAAoB,CAAC,EAAE,CAAC;YACnD,OAAO,CAAC,KAAK,CAAC,+CAA+C,WAAW,EAAE,CAAC,CAAC;YAC5E,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,IAAI,CAAC,iBAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAChC,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,KAAK,GAAG,iBAAE,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;QAC1C,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;QAExD,MAAM,QAAQ,GAAG,YAAY;aAC1B,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YACZ,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YAC7C,OAAO,cAAc,CAAC,SAAS,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;QAC3D,CAAC,CAAC;aACD,MAAM,CAAC,CAAC,CAAC,EAAgB,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC;aACvC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC;QAE3E,OAAO,QAAQ,CAAC;IAClB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,8BAA8B,SAAS,GAAG,EAAE,KAAK,CAAC,CAAC;QACjE,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lim324/my-claude-code-viewer",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "CLI tool to view Claude Code statistics",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"my-claude-code-viewer": "bin/my-claude-code-viewer"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"start": "node dist/index.js",
|
|
13
|
+
"dev": "nodemon --exec ts-node src/index.ts",
|
|
14
|
+
"prepublishOnly": "pnpm build"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"claude",
|
|
18
|
+
"claude-code",
|
|
19
|
+
"viewer",
|
|
20
|
+
"stats",
|
|
21
|
+
"cli"
|
|
22
|
+
],
|
|
23
|
+
"author": "",
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"packageManager": "pnpm@10.30.3",
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"commander": "^14.0.3",
|
|
28
|
+
"escape-html": "^1.0.3",
|
|
29
|
+
"express": "^5.2.1",
|
|
30
|
+
"fuse.js": "^7.1.0"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/escape-html": "^1.0.4",
|
|
34
|
+
"@types/express": "^5.0.6",
|
|
35
|
+
"@types/node": "^25.3.3",
|
|
36
|
+
"nodemon": "^3.1.14",
|
|
37
|
+
"ts-node": "^10.9.2",
|
|
38
|
+
"typescript": "^5.9.3"
|
|
39
|
+
},
|
|
40
|
+
"files": [
|
|
41
|
+
"dist",
|
|
42
|
+
"bin"
|
|
43
|
+
],
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=18.0.0"
|
|
46
|
+
}
|
|
47
|
+
}
|