@agllama/mcp 0.6.20 → 0.6.23

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.
Files changed (45) hide show
  1. package/dist/api-client.d.ts +22 -1
  2. package/dist/api-client.d.ts.map +1 -1
  3. package/dist/api-client.js +46 -0
  4. package/dist/api-client.js.map +1 -1
  5. package/dist/lib/__tests__/transcript-reader.test.d.ts +2 -0
  6. package/dist/lib/__tests__/transcript-reader.test.d.ts.map +1 -0
  7. package/dist/lib/__tests__/transcript-reader.test.js +279 -0
  8. package/dist/lib/__tests__/transcript-reader.test.js.map +1 -0
  9. package/dist/lib/session-registrar.d.ts +7 -0
  10. package/dist/lib/session-registrar.d.ts.map +1 -0
  11. package/dist/lib/session-registrar.js +86 -0
  12. package/dist/lib/session-registrar.js.map +1 -0
  13. package/dist/lib/transcript-reader.d.ts +29 -0
  14. package/dist/lib/transcript-reader.d.ts.map +1 -0
  15. package/dist/lib/transcript-reader.js +178 -0
  16. package/dist/lib/transcript-reader.js.map +1 -0
  17. package/dist/server.d.ts.map +1 -1
  18. package/dist/server.js +22 -3
  19. package/dist/server.js.map +1 -1
  20. package/dist/tools/__tests__/claudeSession.test.d.ts +2 -0
  21. package/dist/tools/__tests__/claudeSession.test.d.ts.map +1 -0
  22. package/dist/tools/__tests__/claudeSession.test.js +148 -0
  23. package/dist/tools/__tests__/claudeSession.test.js.map +1 -0
  24. package/dist/tools/__tests__/session.test.js +88 -1
  25. package/dist/tools/__tests__/session.test.js.map +1 -1
  26. package/dist/tools/claudeSession.d.ts +16 -0
  27. package/dist/tools/claudeSession.d.ts.map +1 -0
  28. package/dist/tools/claudeSession.js +63 -0
  29. package/dist/tools/claudeSession.js.map +1 -0
  30. package/dist/tools/comments.d.ts +2 -2
  31. package/dist/tools/index.d.ts +1 -0
  32. package/dist/tools/index.d.ts.map +1 -1
  33. package/dist/tools/index.js +1 -0
  34. package/dist/tools/index.js.map +1 -1
  35. package/dist/tools/plans.d.ts +4 -4
  36. package/dist/tools/prompts.d.ts +4 -4
  37. package/dist/tools/roadmap.d.ts +8 -8
  38. package/dist/tools/session.d.ts +3 -3
  39. package/dist/tools/session.d.ts.map +1 -1
  40. package/dist/tools/session.js +28 -1
  41. package/dist/tools/session.js.map +1 -1
  42. package/dist/tools/skills.d.ts +18 -18
  43. package/dist/types.d.ts +9 -0
  44. package/dist/types.d.ts.map +1 -1
  45. package/package.json +1 -1
@@ -0,0 +1,279 @@
1
+ import { describe, it, expect, afterEach } from 'vitest';
2
+ import * as fs from 'node:fs';
3
+ import * as os from 'node:os';
4
+ import * as path from 'node:path';
5
+ import { parseTranscript, findActiveJsonl } from '../transcript-reader.js';
6
+ // ---------------------------------------------------------------------------
7
+ // Helpers
8
+ // ---------------------------------------------------------------------------
9
+ let tempFiles = [];
10
+ let tempDirs = [];
11
+ function writeTempFile(content, filename = 'test.jsonl') {
12
+ const filePath = path.join(os.tmpdir(), `transcript-reader-test-${Date.now()}-${Math.random().toString(36).slice(2)}-${filename}`);
13
+ fs.writeFileSync(filePath, content, 'utf-8');
14
+ tempFiles.push(filePath);
15
+ return filePath;
16
+ }
17
+ function makeTempDir() {
18
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'transcript-reader-test-'));
19
+ tempDirs.push(dir);
20
+ return dir;
21
+ }
22
+ afterEach(() => {
23
+ for (const f of tempFiles) {
24
+ try {
25
+ fs.unlinkSync(f);
26
+ }
27
+ catch { /* ignore */ }
28
+ }
29
+ tempFiles = [];
30
+ for (const d of tempDirs) {
31
+ try {
32
+ fs.rmSync(d, { recursive: true, force: true });
33
+ }
34
+ catch { /* ignore */ }
35
+ }
36
+ tempDirs = [];
37
+ // Restore CLAUDE_HOME after each test
38
+ delete process.env.CLAUDE_HOME;
39
+ });
40
+ // Build a JSONL line
41
+ function jsonlLine(record) {
42
+ return JSON.stringify(record);
43
+ }
44
+ // Build a minimal user record
45
+ function userLine(content) {
46
+ return jsonlLine({ type: 'user', message: { content } });
47
+ }
48
+ // Build a minimal assistant record
49
+ function assistantLine(opts) {
50
+ return jsonlLine({
51
+ type: 'assistant',
52
+ message: {
53
+ model: opts.model,
54
+ usage: {
55
+ input_tokens: opts.inputTokens ?? 0,
56
+ output_tokens: opts.outputTokens ?? 0,
57
+ cache_read_input_tokens: opts.cacheRead ?? 0,
58
+ cache_creation_input_tokens: opts.cacheCreation ?? 0,
59
+ },
60
+ content: opts.content ?? [],
61
+ },
62
+ });
63
+ }
64
+ // Build a tool_use block for a file-edit tool
65
+ function editBlock(toolName, filePath) {
66
+ return { type: 'tool_use', name: toolName, input: { file_path: filePath } };
67
+ }
68
+ // ---------------------------------------------------------------------------
69
+ // parseTranscript
70
+ // ---------------------------------------------------------------------------
71
+ describe('parseTranscript', () => {
72
+ it('returns null when file does not exist', () => {
73
+ const result = parseTranscript('/nonexistent/path/file.jsonl');
74
+ expect(result).toBeNull();
75
+ });
76
+ it('returns a zeroed-out result (not null) when file is empty — file exists but has no parseable records', () => {
77
+ const filePath = writeTempFile('');
78
+ const result = parseTranscript(filePath);
79
+ // parseTranscript only returns null for missing/unreadable files.
80
+ // An empty file is a valid (empty) transcript: all counts zero, no firstMessage/model.
81
+ expect(result).not.toBeNull();
82
+ expect(result.firstMessage).toBeNull();
83
+ expect(result.model).toBeNull();
84
+ expect(result.inputTokens).toBe(0);
85
+ expect(result.outputTokens).toBe(0);
86
+ expect(result.modifiedFiles).toEqual([]);
87
+ });
88
+ it('skips malformed lines without throwing and still parses valid lines', () => {
89
+ const content = [
90
+ 'NOT VALID JSON }{',
91
+ userLine('Hello from valid line'),
92
+ ].join('\n');
93
+ const filePath = writeTempFile(content);
94
+ const result = parseTranscript(filePath);
95
+ expect(result).not.toBeNull();
96
+ expect(result.firstMessage).toBe('Hello from valid line');
97
+ });
98
+ it('extracts firstMessage from string content', () => {
99
+ const content = userLine('Hello world');
100
+ const filePath = writeTempFile(content);
101
+ const result = parseTranscript(filePath);
102
+ expect(result).not.toBeNull();
103
+ expect(result.firstMessage).toBe('Hello world');
104
+ });
105
+ it('extracts firstMessage from array content (text block)', () => {
106
+ const content = userLine([
107
+ { type: 'text', text: 'Hello from array' },
108
+ ]);
109
+ const filePath = writeTempFile(content);
110
+ const result = parseTranscript(filePath);
111
+ expect(result).not.toBeNull();
112
+ expect(result.firstMessage).toBe('Hello from array');
113
+ });
114
+ it('extracts model from first assistant message', () => {
115
+ const content = [
116
+ userLine('Hi'),
117
+ assistantLine({ model: 'claude-opus-4-5' }),
118
+ assistantLine({ model: 'claude-should-be-ignored' }),
119
+ ].join('\n');
120
+ const filePath = writeTempFile(content);
121
+ const result = parseTranscript(filePath);
122
+ expect(result).not.toBeNull();
123
+ expect(result.model).toBe('claude-opus-4-5');
124
+ });
125
+ it('sums tokens across multiple assistant messages', () => {
126
+ const content = [
127
+ userLine('Hi'),
128
+ assistantLine({ inputTokens: 100, outputTokens: 50, cacheRead: 10, cacheCreation: 5 }),
129
+ assistantLine({ inputTokens: 200, outputTokens: 80, cacheRead: 20, cacheCreation: 15 }),
130
+ ].join('\n');
131
+ const filePath = writeTempFile(content);
132
+ const result = parseTranscript(filePath);
133
+ expect(result).not.toBeNull();
134
+ expect(result.inputTokens).toBe(300);
135
+ expect(result.outputTokens).toBe(130);
136
+ expect(result.cacheReadTokens).toBe(30);
137
+ expect(result.cacheCreationTokens).toBe(20);
138
+ });
139
+ it('extracts modifiedFiles from Edit, Write, NotebookEdit, MultiEdit tool_use blocks only', () => {
140
+ const content = [
141
+ userLine('Do stuff'),
142
+ assistantLine({
143
+ content: [
144
+ editBlock('Edit', '/src/foo.ts'),
145
+ editBlock('Write', '/src/bar.ts'),
146
+ editBlock('NotebookEdit', '/src/nb.ipynb'),
147
+ editBlock('MultiEdit', '/src/multi.ts'),
148
+ // These should be ignored
149
+ editBlock('Read', '/src/ignored-read.ts'),
150
+ editBlock('Bash', '/some/ignored-bash.sh'),
151
+ ],
152
+ }),
153
+ ].join('\n');
154
+ const filePath = writeTempFile(content);
155
+ const result = parseTranscript(filePath);
156
+ expect(result).not.toBeNull();
157
+ expect(result.modifiedFiles).toContain('/src/foo.ts');
158
+ expect(result.modifiedFiles).toContain('/src/bar.ts');
159
+ expect(result.modifiedFiles).toContain('/src/nb.ipynb');
160
+ expect(result.modifiedFiles).toContain('/src/multi.ts');
161
+ expect(result.modifiedFiles).not.toContain('/src/ignored-read.ts');
162
+ expect(result.modifiedFiles).not.toContain('/some/ignored-bash.sh');
163
+ });
164
+ it('dedupes and ranks modifiedFiles by edit count — file edited twice ranks before file edited once', () => {
165
+ const content = [
166
+ userLine('Do stuff'),
167
+ assistantLine({
168
+ content: [
169
+ editBlock('Edit', '/src/edited-twice.ts'),
170
+ editBlock('Edit', '/src/edited-once.ts'),
171
+ ],
172
+ }),
173
+ assistantLine({
174
+ content: [
175
+ editBlock('Write', '/src/edited-twice.ts'),
176
+ ],
177
+ }),
178
+ ].join('\n');
179
+ const filePath = writeTempFile(content);
180
+ const result = parseTranscript(filePath);
181
+ expect(result).not.toBeNull();
182
+ expect(result.modifiedFiles[0]).toBe('/src/edited-twice.ts');
183
+ expect(result.modifiedFiles[1]).toBe('/src/edited-once.ts');
184
+ });
185
+ it('caps modifiedFiles at 10', () => {
186
+ // Create 15 unique edited files
187
+ const editBlocks = Array.from({ length: 15 }, (_, i) => editBlock('Edit', `/src/file${i}.ts`));
188
+ const content = [
189
+ userLine('Do stuff'),
190
+ assistantLine({ content: editBlocks }),
191
+ ].join('\n');
192
+ const filePath = writeTempFile(content);
193
+ const result = parseTranscript(filePath);
194
+ expect(result).not.toBeNull();
195
+ expect(result.modifiedFiles.length).toBe(10);
196
+ });
197
+ });
198
+ // ---------------------------------------------------------------------------
199
+ // findActiveJsonl
200
+ // ---------------------------------------------------------------------------
201
+ describe('findActiveJsonl', () => {
202
+ it('returns null when project dir does not exist', () => {
203
+ const tmpDir = makeTempDir();
204
+ process.env.CLAUDE_HOME = tmpDir;
205
+ // No projects subdirectory created
206
+ const result = findActiveJsonl('/Users/foo/nonexistent-project');
207
+ expect(result).toBeNull();
208
+ });
209
+ it('returns null when project dir is empty', () => {
210
+ const tmpDir = makeTempDir();
211
+ process.env.CLAUDE_HOME = tmpDir;
212
+ const encoded = '-Users-foo-empty-project';
213
+ fs.mkdirSync(path.join(tmpDir, 'projects', encoded), { recursive: true });
214
+ const result = findActiveJsonl('/Users/foo/empty-project');
215
+ expect(result).toBeNull();
216
+ });
217
+ it('returns most-recently-modified .jsonl when multiple exist', () => {
218
+ const tmpDir = makeTempDir();
219
+ process.env.CLAUDE_HOME = tmpDir;
220
+ const cwd = '/Users/foo/myproject';
221
+ const encoded = '-Users-foo-myproject';
222
+ const projectDir = path.join(tmpDir, 'projects', encoded);
223
+ fs.mkdirSync(projectDir, { recursive: true });
224
+ const older = path.join(projectDir, 'older-session.jsonl');
225
+ const newer = path.join(projectDir, 'newer-session.jsonl');
226
+ fs.writeFileSync(older, userLine('first'), 'utf-8');
227
+ fs.writeFileSync(newer, userLine('second'), 'utf-8');
228
+ // Set mtimes: older = 1000s ago, newer = 500s ago
229
+ const now = Date.now() / 1000;
230
+ fs.utimesSync(older, now - 1000, now - 1000);
231
+ fs.utimesSync(newer, now - 500, now - 500);
232
+ const result = findActiveJsonl(cwd);
233
+ expect(result).not.toBeNull();
234
+ expect(result.transcriptPath).toBe(newer);
235
+ expect(result.claudeSessionId).toBe('newer-session');
236
+ expect(result.cwd).toBe(cwd);
237
+ });
238
+ it('honors CLAUDE_HOME env var', () => {
239
+ const customHome = makeTempDir();
240
+ process.env.CLAUDE_HOME = customHome;
241
+ const cwd = '/Users/foo/testproject';
242
+ const encoded = '-Users-foo-testproject';
243
+ const projectDir = path.join(customHome, 'projects', encoded);
244
+ fs.mkdirSync(projectDir, { recursive: true });
245
+ fs.writeFileSync(path.join(projectDir, 'abc123.jsonl'), userLine('hello'), 'utf-8');
246
+ const result = findActiveJsonl(cwd);
247
+ expect(result).not.toBeNull();
248
+ expect(result.claudeSessionId).toBe('abc123');
249
+ expect(result.transcriptPath).toContain(customHome);
250
+ });
251
+ it('encodes cwd correctly — forward slashes become hyphens', () => {
252
+ const tmpDir = makeTempDir();
253
+ process.env.CLAUDE_HOME = tmpDir;
254
+ const cwd = '/Users/willis/JiraKiller';
255
+ // Correct encoding: leading slash also becomes hyphen
256
+ const encoded = '-Users-willis-JiraKiller';
257
+ const projectDir = path.join(tmpDir, 'projects', encoded);
258
+ fs.mkdirSync(projectDir, { recursive: true });
259
+ fs.writeFileSync(path.join(projectDir, 'session-xyz.jsonl'), userLine('yo'), 'utf-8');
260
+ const result = findActiveJsonl(cwd);
261
+ expect(result).not.toBeNull();
262
+ expect(result.claudeSessionId).toBe('session-xyz');
263
+ });
264
+ it('encodes Windows-style cwd correctly — backslashes and drive colon become hyphens', () => {
265
+ const tmpDir = makeTempDir();
266
+ process.env.CLAUDE_HOME = tmpDir;
267
+ // Claude Code on Windows encodes both `:` and `\` as `-`.
268
+ // C:\Users\Keith\Repos\App → C--Users-Keith-Repos-App
269
+ const cwd = 'C:\\Users\\Keith\\Repos\\App';
270
+ const encoded = 'C--Users-Keith-Repos-App';
271
+ const projectDir = path.join(tmpDir, 'projects', encoded);
272
+ fs.mkdirSync(projectDir, { recursive: true });
273
+ fs.writeFileSync(path.join(projectDir, 'win-session-1.jsonl'), userLine('hi'), 'utf-8');
274
+ const result = findActiveJsonl(cwd);
275
+ expect(result).not.toBeNull();
276
+ expect(result.claudeSessionId).toBe('win-session-1');
277
+ });
278
+ });
279
+ //# sourceMappingURL=transcript-reader.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript-reader.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/transcript-reader.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Called transparently from server.ts dispatch on every Llama MCP tool call.
3
+ * Discovers the active Claude session, fetches user prefs, and POSTs to the API.
4
+ * Always fire-and-forget — never throws, never blocks the calling tool.
5
+ */
6
+ export declare function registerActiveSession(): void;
7
+ //# sourceMappingURL=session-registrar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-registrar.d.ts","sourceRoot":"","sources":["../../src/lib/session-registrar.ts"],"names":[],"mappings":"AASA;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CA6E5C"}
@@ -0,0 +1,86 @@
1
+ import { getApiClient } from '../api-client.js';
2
+ import { findActiveJsonl, parseTranscript } from './transcript-reader.js';
3
+ let prefsCache = null;
4
+ const PREFS_TTL_MS = 10_000; // 10 seconds — tight enough that toggle changes feel instant
5
+ /** Dedupe: skip POST when (claudeSessionId, mtime) unchanged and allowTranscriptReading was false */
6
+ let lastRegistered = null;
7
+ /**
8
+ * Called transparently from server.ts dispatch on every Llama MCP tool call.
9
+ * Discovers the active Claude session, fetches user prefs, and POSTs to the API.
10
+ * Always fire-and-forget — never throws, never blocks the calling tool.
11
+ */
12
+ export function registerActiveSession() {
13
+ Promise.resolve().then(async () => {
14
+ try {
15
+ const cwd = process.cwd();
16
+ const minimal = findActiveJsonl(cwd);
17
+ if (!minimal)
18
+ return;
19
+ const { claudeSessionId, transcriptPath, mtime } = minimal;
20
+ // Fetch user preferences (cached for PREFS_TTL_MS)
21
+ let allowTranscriptReading = false;
22
+ try {
23
+ const now = Date.now();
24
+ if (!prefsCache || now - prefsCache.fetchedAt > PREFS_TTL_MS) {
25
+ const prefs = await getApiClient().getUserPreferences();
26
+ prefsCache = { allowTranscriptReading: prefs.allowTranscriptReading, fetchedAt: now };
27
+ }
28
+ allowTranscriptReading = prefsCache.allowTranscriptReading;
29
+ }
30
+ catch {
31
+ // Default to minimal (no transcript reading) if prefs unreachable.
32
+ allowTranscriptReading = false;
33
+ }
34
+ // Dedupe: skip if nothing changed and transcript reading is off.
35
+ // When allowTranscriptReading is true, re-POST whenever mtime changes.
36
+ if (lastRegistered &&
37
+ lastRegistered.claudeSessionId === claudeSessionId &&
38
+ lastRegistered.mtime === mtime &&
39
+ !allowTranscriptReading) {
40
+ return;
41
+ }
42
+ const lastActiveAt = new Date().toISOString();
43
+ if (allowTranscriptReading) {
44
+ const parsed = parseTranscript(transcriptPath);
45
+ if (!parsed) {
46
+ await getApiClient().upsertClaudeSession({
47
+ claudeSessionId,
48
+ cwd,
49
+ transcriptPath,
50
+ lastActiveAt,
51
+ });
52
+ }
53
+ else {
54
+ await getApiClient().upsertClaudeSession({
55
+ claudeSessionId,
56
+ cwd,
57
+ transcriptPath,
58
+ firstMessage: parsed.firstMessage,
59
+ model: parsed.model,
60
+ lastActiveAt,
61
+ inputTokens: parsed.inputTokens,
62
+ outputTokens: parsed.outputTokens,
63
+ cacheReadTokens: parsed.cacheReadTokens,
64
+ cacheCreationTokens: parsed.cacheCreationTokens,
65
+ modifiedFiles: parsed.modifiedFiles,
66
+ });
67
+ }
68
+ }
69
+ else {
70
+ await getApiClient().upsertClaudeSession({
71
+ claudeSessionId,
72
+ cwd,
73
+ transcriptPath,
74
+ lastActiveAt,
75
+ });
76
+ }
77
+ lastRegistered = { claudeSessionId, mtime };
78
+ }
79
+ catch (err) {
80
+ console.error('[session-registrar] error:', err instanceof Error ? err.message : String(err));
81
+ }
82
+ }).catch((err) => {
83
+ console.error('[session-registrar] unhandled:', err instanceof Error ? err.message : String(err));
84
+ });
85
+ }
86
+ //# sourceMappingURL=session-registrar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-registrar.js","sourceRoot":"","sources":["../../src/lib/session-registrar.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ export interface TranscriptData {
2
+ transcriptPath: string;
3
+ firstMessage: string | null;
4
+ model: string | null;
5
+ inputTokens: number;
6
+ outputTokens: number;
7
+ cacheReadTokens: number;
8
+ cacheCreationTokens: number;
9
+ modifiedFiles: string[];
10
+ mtime: number;
11
+ }
12
+ export interface MinimalSessionData {
13
+ claudeSessionId: string;
14
+ cwd: string;
15
+ transcriptPath: string;
16
+ mtime: number;
17
+ }
18
+ /**
19
+ * Find the active JSONL transcript for the current Claude Code session.
20
+ * Returns minimal session data (filename = claudeSessionId, cwd, path) without parsing content.
21
+ */
22
+ export declare function findActiveJsonl(cwd: string): MinimalSessionData | null;
23
+ /**
24
+ * Parse the JSONL transcript file and return full TranscriptData.
25
+ * Returns null on error (missing file, malformed JSON, etc.) — never throws.
26
+ * Results are cached by (path, mtime).
27
+ */
28
+ export declare function parseTranscript(jsonlPath: string): TranscriptData | null;
29
+ //# sourceMappingURL=transcript-reader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript-reader.d.ts","sourceRoot":"","sources":["../../src/lib/transcript-reader.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,cAAc;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,eAAe,EAAE,MAAM,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;CACf;AAwBD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI,CAiDtE;AA8BD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAkHxE"}
@@ -0,0 +1,178 @@
1
+ import * as fs from 'fs';
2
+ import * as os from 'os';
3
+ import * as path from 'path';
4
+ const parseCache = new Map();
5
+ function getClaudeHome() {
6
+ if (process.env.CLAUDE_HOME) {
7
+ return process.env.CLAUDE_HOME;
8
+ }
9
+ return path.join(os.homedir(), '.claude');
10
+ }
11
+ // Match Claude Code's project-directory naming: replace path separators and the
12
+ // Windows drive colon with hyphens. POSIX uses /, Windows uses \ and a leading
13
+ // drive letter like "C:".
14
+ // /Users/willis/JiraKiller → -Users-willis-JiraKiller
15
+ // C:\Users\Keith\Repos\App → C--Users-Keith-Repos-App
16
+ function encodeCwd(cwd) {
17
+ return cwd.replace(/[/\\:]/g, '-');
18
+ }
19
+ /**
20
+ * Find the active JSONL transcript for the current Claude Code session.
21
+ * Returns minimal session data (filename = claudeSessionId, cwd, path) without parsing content.
22
+ */
23
+ export function findActiveJsonl(cwd) {
24
+ try {
25
+ const claudeHome = getClaudeHome();
26
+ const encoded = encodeCwd(cwd);
27
+ const dir = path.join(claudeHome, 'projects', encoded);
28
+ if (!fs.existsSync(dir)) {
29
+ return null;
30
+ }
31
+ const entries = fs.readdirSync(dir);
32
+ const jsonlFiles = entries.filter((f) => f.endsWith('.jsonl'));
33
+ if (jsonlFiles.length === 0) {
34
+ return null;
35
+ }
36
+ // Sort by mtime descending, pick most recent
37
+ const withStats = jsonlFiles
38
+ .map((f) => {
39
+ const fullPath = path.join(dir, f);
40
+ try {
41
+ const stat = fs.statSync(fullPath);
42
+ return { file: f, fullPath, mtime: stat.mtimeMs };
43
+ }
44
+ catch {
45
+ return null;
46
+ }
47
+ })
48
+ .filter((x) => x !== null);
49
+ if (withStats.length === 0) {
50
+ return null;
51
+ }
52
+ withStats.sort((a, b) => b.mtime - a.mtime);
53
+ const best = withStats[0];
54
+ // claudeSessionId = filename without .jsonl extension
55
+ const claudeSessionId = best.file.replace(/\.jsonl$/, '');
56
+ return {
57
+ claudeSessionId,
58
+ cwd,
59
+ transcriptPath: best.fullPath,
60
+ mtime: best.mtime,
61
+ };
62
+ }
63
+ catch {
64
+ return null;
65
+ }
66
+ }
67
+ /**
68
+ * Parse the JSONL transcript file and return full TranscriptData.
69
+ * Returns null on error (missing file, malformed JSON, etc.) — never throws.
70
+ * Results are cached by (path, mtime).
71
+ */
72
+ export function parseTranscript(jsonlPath) {
73
+ try {
74
+ // Check mtime for cache invalidation
75
+ let mtime;
76
+ try {
77
+ const stat = fs.statSync(jsonlPath);
78
+ mtime = stat.mtimeMs;
79
+ }
80
+ catch {
81
+ return null;
82
+ }
83
+ const cached = parseCache.get(jsonlPath);
84
+ if (cached && cached.mtime === mtime) {
85
+ return cached.data;
86
+ }
87
+ const raw = fs.readFileSync(jsonlPath, 'utf-8');
88
+ const lines = raw.split('\n');
89
+ let firstMessage = null;
90
+ let model = null;
91
+ let inputTokens = 0;
92
+ let outputTokens = 0;
93
+ let cacheReadTokens = 0;
94
+ let cacheCreationTokens = 0;
95
+ const fileCounts = new Map();
96
+ for (const line of lines) {
97
+ const trimmed = line.trim();
98
+ if (!trimmed)
99
+ continue;
100
+ let record;
101
+ try {
102
+ record = JSON.parse(trimmed);
103
+ }
104
+ catch {
105
+ // Skip malformed lines
106
+ continue;
107
+ }
108
+ if (record.type === 'user' && firstMessage === null) {
109
+ const content = record.message?.content;
110
+ if (content != null) {
111
+ if (typeof content === 'string') {
112
+ firstMessage = content;
113
+ }
114
+ else if (Array.isArray(content)) {
115
+ const textBlock = content.find((b) => b.type === 'text');
116
+ if (textBlock?.text) {
117
+ firstMessage = textBlock.text;
118
+ }
119
+ }
120
+ }
121
+ }
122
+ if (record.type === 'assistant') {
123
+ const msg = record.message;
124
+ if (!msg)
125
+ continue;
126
+ // First assistant model wins
127
+ if (model === null && msg.model) {
128
+ model = msg.model;
129
+ }
130
+ // Accumulate token usage
131
+ const usage = msg.usage;
132
+ if (usage) {
133
+ inputTokens += usage.input_tokens ?? 0;
134
+ outputTokens += usage.output_tokens ?? 0;
135
+ cacheReadTokens += usage.cache_read_input_tokens ?? 0;
136
+ cacheCreationTokens += usage.cache_creation_input_tokens ?? 0;
137
+ }
138
+ // Scan content for file-editing tool calls
139
+ const content = msg.content;
140
+ if (Array.isArray(content)) {
141
+ for (const block of content) {
142
+ if (block.type === 'tool_use' &&
143
+ block.name != null &&
144
+ ['Edit', 'Write', 'NotebookEdit', 'MultiEdit'].includes(block.name)) {
145
+ const filePath = block.input?.file_path;
146
+ if (filePath) {
147
+ fileCounts.set(filePath, (fileCounts.get(filePath) ?? 0) + 1);
148
+ }
149
+ }
150
+ }
151
+ }
152
+ }
153
+ }
154
+ // Top 10 modified files by edit count
155
+ const modifiedFiles = Array.from(fileCounts.entries())
156
+ .sort((a, b) => b[1] - a[1])
157
+ .slice(0, 10)
158
+ .map(([fp]) => fp);
159
+ const data = {
160
+ transcriptPath: jsonlPath,
161
+ // Truncate to 200 chars: API's Zod validator rejects (not truncates) longer values.
162
+ firstMessage: firstMessage !== null ? firstMessage.slice(0, 200) : null,
163
+ model,
164
+ inputTokens,
165
+ outputTokens,
166
+ cacheReadTokens,
167
+ cacheCreationTokens,
168
+ modifiedFiles,
169
+ mtime,
170
+ };
171
+ parseCache.set(jsonlPath, { mtime, data });
172
+ return data;
173
+ }
174
+ catch {
175
+ return null;
176
+ }
177
+ }
178
+ //# sourceMappingURL=transcript-reader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript-reader.js","sourceRoot":"","sources":["../../src/lib/transcript-reader.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAq5CnE,wBAAsB,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CAuGpD;AAED,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAQ/C"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAq6CnE,wBAAsB,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CA4GpD;AAED,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAQ/C"}