@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.
@@ -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":"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"}
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
+ }