devday 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/README.md +58 -0
  2. package/bin/devday.js +2 -0
  3. package/dist/config.d.ts +14 -0
  4. package/dist/config.d.ts.map +1 -0
  5. package/dist/config.js +89 -0
  6. package/dist/config.js.map +1 -0
  7. package/dist/cost.d.ts +12 -0
  8. package/dist/cost.d.ts.map +1 -0
  9. package/dist/cost.js +47 -0
  10. package/dist/cost.js.map +1 -0
  11. package/dist/git.d.ts +6 -0
  12. package/dist/git.d.ts.map +1 -0
  13. package/dist/git.js +95 -0
  14. package/dist/git.js.map +1 -0
  15. package/dist/index.d.ts +2 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +231 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/merge.d.ts +6 -0
  20. package/dist/merge.d.ts.map +1 -0
  21. package/dist/merge.js +80 -0
  22. package/dist/merge.js.map +1 -0
  23. package/dist/parsers/claude-code.d.ts +18 -0
  24. package/dist/parsers/claude-code.d.ts.map +1 -0
  25. package/dist/parsers/claude-code.js +385 -0
  26. package/dist/parsers/claude-code.js.map +1 -0
  27. package/dist/parsers/cursor.d.ts +15 -0
  28. package/dist/parsers/cursor.d.ts.map +1 -0
  29. package/dist/parsers/cursor.js +302 -0
  30. package/dist/parsers/cursor.js.map +1 -0
  31. package/dist/parsers/opencode.d.ts +21 -0
  32. package/dist/parsers/opencode.d.ts.map +1 -0
  33. package/dist/parsers/opencode.js +301 -0
  34. package/dist/parsers/opencode.js.map +1 -0
  35. package/dist/render.d.ts +6 -0
  36. package/dist/render.d.ts.map +1 -0
  37. package/dist/render.js +161 -0
  38. package/dist/render.js.map +1 -0
  39. package/dist/summarize.d.ts +8 -0
  40. package/dist/summarize.d.ts.map +1 -0
  41. package/dist/summarize.js +157 -0
  42. package/dist/summarize.js.map +1 -0
  43. package/dist/types.d.ts +100 -0
  44. package/dist/types.d.ts.map +1 -0
  45. package/dist/types.js +23 -0
  46. package/dist/types.js.map +1 -0
  47. package/package.json +54 -0
package/dist/merge.js ADDED
@@ -0,0 +1,80 @@
1
+ import { basename } from 'node:path';
2
+ import { sumTokens } from './cost.js';
3
+ /**
4
+ * Merge sessions and git activity into a DayRecap.
5
+ */
6
+ export function buildDayRecap(date, sessions, gitActivities) {
7
+ // Group sessions by project path
8
+ const sessionsByProject = new Map();
9
+ for (const session of sessions) {
10
+ const key = session.projectPath ?? '__unknown__';
11
+ if (!sessionsByProject.has(key)) {
12
+ sessionsByProject.set(key, []);
13
+ }
14
+ sessionsByProject.get(key).push(session);
15
+ }
16
+ // Build a map of git activities by project path
17
+ const gitByProject = new Map();
18
+ for (const git of gitActivities) {
19
+ gitByProject.set(git.projectPath, git);
20
+ }
21
+ // Collect all unique project paths (from sessions and git)
22
+ const allProjectPaths = new Set([
23
+ ...sessionsByProject.keys(),
24
+ ...gitByProject.keys(),
25
+ ]);
26
+ const projects = [];
27
+ for (const projectPath of allProjectPaths) {
28
+ const projectSessions = sessionsByProject.get(projectPath) ?? [];
29
+ const git = gitByProject.get(projectPath) ?? null;
30
+ if (projectSessions.length === 0 && (!git || git.commits.length === 0)) {
31
+ continue;
32
+ }
33
+ const totalTokens = sumTokens(...projectSessions.map((s) => s.tokens));
34
+ const totalCostUsd = projectSessions.reduce((sum, s) => sum + s.costUsd, 0);
35
+ const totalDurationMs = projectSessions.reduce((sum, s) => sum + s.durationMs, 0);
36
+ const totalMessages = projectSessions.reduce((sum, s) => sum + s.messageCount, 0);
37
+ const toolsUsed = [...new Set(projectSessions.map((s) => s.tool))];
38
+ const modelsUsed = [...new Set(projectSessions.flatMap((s) => s.models))];
39
+ const filesTouched = [...new Set(projectSessions.flatMap((s) => s.filesTouched))];
40
+ const projectName = projectSessions[0]?.projectName ??
41
+ git?.projectName ??
42
+ basename(projectPath);
43
+ projects.push({
44
+ projectPath,
45
+ projectName,
46
+ sessions: projectSessions,
47
+ git,
48
+ totalSessions: projectSessions.length,
49
+ totalMessages,
50
+ totalTokens: totalTokens.total,
51
+ totalCostUsd,
52
+ totalDurationMs,
53
+ toolsUsed,
54
+ modelsUsed,
55
+ filesTouched,
56
+ aiSummary: null, // filled by summarizer
57
+ });
58
+ }
59
+ // Sort projects by total cost (most expensive first)
60
+ projects.sort((a, b) => b.totalCostUsd - a.totalCostUsd);
61
+ // Global aggregates
62
+ const totalSessions = projects.reduce((sum, p) => sum + p.totalSessions, 0);
63
+ const totalMessages = projects.reduce((sum, p) => sum + p.totalMessages, 0);
64
+ const globalTokens = sumTokens(...sessions.map((s) => s.tokens));
65
+ const totalCostUsd = projects.reduce((sum, p) => sum + p.totalCostUsd, 0);
66
+ const totalDurationMs = projects.reduce((sum, p) => sum + p.totalDurationMs, 0);
67
+ const toolsUsed = [...new Set(projects.flatMap((p) => p.toolsUsed))];
68
+ return {
69
+ date,
70
+ projects,
71
+ totalSessions,
72
+ totalMessages,
73
+ totalTokens: globalTokens.total,
74
+ totalCostUsd,
75
+ totalDurationMs,
76
+ toolsUsed,
77
+ standupMessage: null, // filled by summarizer
78
+ };
79
+ }
80
+ //# sourceMappingURL=merge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge.js","sourceRoot":"","sources":["../src/merge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { Parser, Session } from '../types.js';
2
+ export declare class ClaudeCodeParser implements Parser {
3
+ readonly name: "claude-code";
4
+ private claudeHome;
5
+ constructor(claudeHome: string);
6
+ isAvailable(): Promise<boolean>;
7
+ getSessions(date: string): Promise<Session[]>;
8
+ private buildSession;
9
+ private buildSessionFromDb;
10
+ private buildSessionFromJsonl;
11
+ private parseJsonlFile;
12
+ /** Deduplicate assistant messages: streaming chunks share the same message.id */
13
+ private deduplicateAssistant;
14
+ private extractContentFromJsonl;
15
+ private extractContentFromMessages;
16
+ private truncatePrompt;
17
+ }
18
+ //# sourceMappingURL=claude-code.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../../src/parsers/claude-code.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAc,MAAM,aAAa,CAAC;AAuF/D,qBAAa,gBAAiB,YAAW,MAAM;IAC7C,QAAQ,CAAC,IAAI,EAAG,aAAa,CAAU;IACvC,OAAO,CAAC,UAAU,CAAS;gBAEf,UAAU,EAAE,MAAM;IAIxB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAO/B,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAgFnD,OAAO,CAAC,YAAY;IAoBpB,OAAO,CAAC,kBAAkB;IAyG1B,OAAO,CAAC,qBAAqB;IA+E7B,OAAO,CAAC,cAAc;IA0CtB,iFAAiF;IACjF,OAAO,CAAC,oBAAoB;IAY5B,OAAO,CAAC,uBAAuB;IAa/B,OAAO,CAAC,0BAA0B;IA4FlC,OAAO,CAAC,cAAc;CAMvB"}
@@ -0,0 +1,385 @@
1
+ import { existsSync, readdirSync, readFileSync } from 'node:fs';
2
+ import { join, basename } from 'node:path';
3
+ import { homedir } from 'node:os';
4
+ import Database from 'better-sqlite3';
5
+ import { estimateCost, emptyTokenUsage } from '../cost.js';
6
+ // ── Parser ───────────────────────────────────────────────────────
7
+ export class ClaudeCodeParser {
8
+ name = 'claude-code';
9
+ claudeHome;
10
+ constructor(claudeHome) {
11
+ this.claudeHome = claudeHome;
12
+ }
13
+ async isAvailable() {
14
+ return (existsSync(this.claudeHome) &&
15
+ existsSync(join(this.claudeHome, 'projects')));
16
+ }
17
+ async getSessions(date) {
18
+ // Build day boundaries in local time
19
+ const [year, month, day] = date.split('-').map(Number);
20
+ const dayStart = new Date(year, month - 1, day, 0, 0, 0, 0);
21
+ const dayEnd = new Date(year, month - 1, day, 23, 59, 59, 999);
22
+ const dayStartMs = dayStart.getTime();
23
+ const dayEndMs = dayEnd.getTime();
24
+ const projectsDir = join(this.claudeHome, 'projects');
25
+ if (!existsSync(projectsDir))
26
+ return [];
27
+ // Open SQLite for cost/duration data (optional — parser works without it)
28
+ const dbPath = join(this.claudeHome, '__store.db');
29
+ let db = null;
30
+ if (existsSync(dbPath)) {
31
+ try {
32
+ db = new Database(dbPath, { readonly: true });
33
+ }
34
+ catch {
35
+ // Can't open DB — continue without it
36
+ }
37
+ }
38
+ const sessions = [];
39
+ try {
40
+ const projectDirs = readdirSync(projectsDir, { withFileTypes: true })
41
+ .filter((d) => d.isDirectory());
42
+ for (const projDir of projectDirs) {
43
+ const projPath = join(projectsDir, projDir.name);
44
+ const indexPath = join(projPath, 'sessions-index.json');
45
+ if (!existsSync(indexPath))
46
+ continue;
47
+ let index;
48
+ try {
49
+ index = JSON.parse(readFileSync(indexPath, 'utf-8'));
50
+ }
51
+ catch {
52
+ continue;
53
+ }
54
+ // Get the real project path from the first session entry
55
+ // (directory name encoding is lossy — dashes in dir names become ambiguous)
56
+ const projectPath = index.entries[0]?.projectPath ?? projDir.name.replace(/^-/, '/').replace(/-/g, '/');
57
+ const projectName = basename(projectPath);
58
+ for (const entry of index.entries) {
59
+ if (entry.isSidechain)
60
+ continue;
61
+ // Filter by date: session must overlap with the target day
62
+ const createdMs = new Date(entry.created).getTime();
63
+ const modifiedMs = new Date(entry.modified).getTime();
64
+ const overlapsDay = (createdMs >= dayStartMs && createdMs <= dayEndMs) ||
65
+ (modifiedMs >= dayStartMs && modifiedMs <= dayEndMs) ||
66
+ (createdMs <= dayStartMs && modifiedMs >= dayEndMs);
67
+ if (!overlapsDay)
68
+ continue;
69
+ // Build session from JSONL + optional DB data
70
+ const session = this.buildSession(entry, projectPath, projectName, dayStartMs, dayEndMs, db);
71
+ if (session)
72
+ sessions.push(session);
73
+ }
74
+ }
75
+ }
76
+ finally {
77
+ db?.close();
78
+ }
79
+ return sessions;
80
+ }
81
+ // ── Build a single session ──────────────────────────────────────
82
+ buildSession(entry, projectPath, projectName, dayStartMs, dayEndMs, db) {
83
+ // Try DB-based approach first (more structured)
84
+ if (db) {
85
+ const dbSession = this.buildSessionFromDb(entry, projectPath, projectName, dayStartMs, dayEndMs, db);
86
+ if (dbSession)
87
+ return dbSession;
88
+ }
89
+ // Fall back to JSONL parsing
90
+ return this.buildSessionFromJsonl(entry, projectPath, projectName, dayStartMs, dayEndMs);
91
+ }
92
+ // ── DB-based session building ───────────────────────────────────
93
+ buildSessionFromDb(entry, projectPath, projectName, dayStartMs, dayEndMs, db) {
94
+ try {
95
+ // Get assistant messages for this session within the target day
96
+ const assistantRows = db.prepare(`
97
+ SELECT b.uuid, b.session_id, b.timestamp, a.cost_usd, a.duration_ms, a.model, a.message
98
+ FROM base_messages b
99
+ JOIN assistant_messages a ON a.uuid = b.uuid
100
+ WHERE b.session_id = ? AND b.timestamp >= ? AND b.timestamp <= ?
101
+ ORDER BY b.timestamp
102
+ `).all(entry.sessionId, dayStartMs, dayEndMs);
103
+ const userRows = db.prepare(`
104
+ SELECT b.uuid, b.session_id, b.timestamp, u.message
105
+ FROM base_messages b
106
+ JOIN user_messages u ON u.uuid = b.uuid
107
+ WHERE b.session_id = ? AND b.timestamp >= ? AND b.timestamp <= ?
108
+ ORDER BY b.timestamp
109
+ `).all(entry.sessionId, dayStartMs, dayEndMs);
110
+ const totalMessages = assistantRows.length + userRows.length;
111
+ if (totalMessages === 0)
112
+ return null;
113
+ // Aggregate cost and duration
114
+ let totalCost = 0;
115
+ let totalDurationMs = 0;
116
+ const MAX_MSG_DURATION_MS = 5 * 60 * 1000;
117
+ const models = new Set();
118
+ const totalTokens = emptyTokenUsage();
119
+ for (const row of assistantRows) {
120
+ if (row.cost_usd)
121
+ totalCost += row.cost_usd;
122
+ if (row.duration_ms) {
123
+ totalDurationMs += Math.min(row.duration_ms, MAX_MSG_DURATION_MS);
124
+ }
125
+ if (row.model)
126
+ models.add(row.model);
127
+ // Parse usage from the full message JSON
128
+ try {
129
+ const msg = JSON.parse(row.message);
130
+ if (msg.usage) {
131
+ const u = msg.usage;
132
+ totalTokens.input += u.input_tokens ?? 0;
133
+ totalTokens.output += u.output_tokens ?? 0;
134
+ totalTokens.cacheRead += u.cache_read_input_tokens ?? 0;
135
+ totalTokens.cacheWrite += u.cache_creation_input_tokens ?? 0;
136
+ }
137
+ }
138
+ catch {
139
+ // skip
140
+ }
141
+ }
142
+ totalTokens.total = totalTokens.input + totalTokens.output + totalTokens.cacheRead + totalTokens.cacheWrite;
143
+ // If no cost from DB, estimate from tokens
144
+ if (totalCost === 0 && totalTokens.total > 0 && models.size > 0) {
145
+ const model = [...models][0];
146
+ totalCost = estimateCost(model, totalTokens);
147
+ }
148
+ // Extract content from JSONL for conversation digest
149
+ const contentExtraction = this.extractContentFromJsonl(entry.fullPath, dayStartMs, dayEndMs);
150
+ // Timestamps
151
+ const allTimestamps = [
152
+ ...assistantRows.map((r) => r.timestamp),
153
+ ...userRows.map((r) => r.timestamp),
154
+ ];
155
+ const earliest = Math.max(dayStartMs, Math.min(...allTimestamps));
156
+ const latest = Math.min(dayEndMs, Math.max(...allTimestamps));
157
+ return {
158
+ id: entry.sessionId,
159
+ tool: 'claude-code',
160
+ projectPath,
161
+ projectName,
162
+ title: entry.summary ?? this.truncatePrompt(entry.firstPrompt) ?? null,
163
+ startedAt: new Date(earliest),
164
+ endedAt: new Date(latest),
165
+ durationMs: totalDurationMs,
166
+ messageCount: totalMessages,
167
+ userMessageCount: userRows.length,
168
+ assistantMessageCount: assistantRows.length,
169
+ summary: entry.summary ?? null,
170
+ topics: entry.summary ? [entry.summary] : [],
171
+ tokens: totalTokens,
172
+ costUsd: totalCost,
173
+ models: [...models],
174
+ filesTouched: contentExtraction.filesTouched,
175
+ conversationDigest: contentExtraction.conversationDigest,
176
+ toolCallSummaries: contentExtraction.toolCallSummaries,
177
+ };
178
+ }
179
+ catch {
180
+ return null;
181
+ }
182
+ }
183
+ // ── JSONL-based session building (fallback) ─────────────────────
184
+ buildSessionFromJsonl(entry, projectPath, projectName, dayStartMs, dayEndMs) {
185
+ if (!existsSync(entry.fullPath))
186
+ return null;
187
+ const messages = this.parseJsonlFile(entry.fullPath, dayStartMs, dayEndMs);
188
+ if (messages.user.length === 0 && messages.assistant.length === 0)
189
+ return null;
190
+ const MAX_MSG_DURATION_MS = 5 * 60 * 1000;
191
+ const models = new Set();
192
+ const totalTokens = emptyTokenUsage();
193
+ let totalCost = 0;
194
+ let totalDurationMs = 0;
195
+ // Deduplicate assistant messages by message.id (streaming chunks)
196
+ const dedupedAssistant = this.deduplicateAssistant(messages.assistant);
197
+ for (const msg of dedupedAssistant) {
198
+ if (msg.message.model)
199
+ models.add(msg.message.model);
200
+ if (msg.message.usage) {
201
+ const u = msg.message.usage;
202
+ totalTokens.input += u.input_tokens ?? 0;
203
+ totalTokens.output += u.output_tokens ?? 0;
204
+ totalTokens.cacheRead += u.cache_read_input_tokens ?? 0;
205
+ totalTokens.cacheWrite += u.cache_creation_input_tokens ?? 0;
206
+ }
207
+ }
208
+ totalTokens.total = totalTokens.input + totalTokens.output + totalTokens.cacheRead + totalTokens.cacheWrite;
209
+ if (totalTokens.total > 0 && models.size > 0) {
210
+ totalCost = estimateCost([...models][0], totalTokens);
211
+ }
212
+ // Estimate duration from timestamp gaps between consecutive messages
213
+ const allTimestamps = [
214
+ ...messages.user.map((m) => new Date(m.timestamp).getTime()),
215
+ ...messages.assistant.map((m) => new Date(m.timestamp).getTime()),
216
+ ].sort((a, b) => a - b);
217
+ for (let i = 1; i < allTimestamps.length; i++) {
218
+ const gap = allTimestamps[i] - allTimestamps[i - 1];
219
+ totalDurationMs += Math.min(gap, MAX_MSG_DURATION_MS);
220
+ }
221
+ const contentExtraction = this.extractContentFromMessages(messages, dayStartMs, dayEndMs);
222
+ const earliest = Math.max(dayStartMs, allTimestamps[0] ?? dayStartMs);
223
+ const latest = Math.min(dayEndMs, allTimestamps[allTimestamps.length - 1] ?? dayEndMs);
224
+ return {
225
+ id: entry.sessionId,
226
+ tool: 'claude-code',
227
+ projectPath,
228
+ projectName,
229
+ title: entry.summary ?? this.truncatePrompt(entry.firstPrompt) ?? null,
230
+ startedAt: new Date(earliest),
231
+ endedAt: new Date(latest),
232
+ durationMs: totalDurationMs,
233
+ messageCount: messages.user.length + dedupedAssistant.length,
234
+ userMessageCount: messages.user.length,
235
+ assistantMessageCount: dedupedAssistant.length,
236
+ summary: entry.summary ?? null,
237
+ topics: entry.summary ? [entry.summary] : [],
238
+ tokens: totalTokens,
239
+ costUsd: totalCost,
240
+ models: [...models],
241
+ filesTouched: contentExtraction.filesTouched,
242
+ conversationDigest: contentExtraction.conversationDigest,
243
+ toolCallSummaries: contentExtraction.toolCallSummaries,
244
+ };
245
+ }
246
+ // ── JSONL parsing ───────────────────────────────────────────────
247
+ parseJsonlFile(filePath, dayStartMs, dayEndMs) {
248
+ const user = [];
249
+ const assistant = [];
250
+ let content;
251
+ try {
252
+ content = readFileSync(filePath, 'utf-8');
253
+ }
254
+ catch {
255
+ return { user, assistant };
256
+ }
257
+ for (const line of content.split('\n')) {
258
+ if (!line.trim())
259
+ continue;
260
+ try {
261
+ const obj = JSON.parse(line);
262
+ if (obj.type === 'user') {
263
+ const msg = obj;
264
+ const ts = new Date(msg.timestamp).getTime();
265
+ if (ts >= dayStartMs && ts <= dayEndMs) {
266
+ user.push(msg);
267
+ }
268
+ }
269
+ else if (obj.type === 'assistant') {
270
+ const msg = obj;
271
+ const ts = new Date(msg.timestamp).getTime();
272
+ if (ts >= dayStartMs && ts <= dayEndMs) {
273
+ assistant.push(msg);
274
+ }
275
+ }
276
+ // Skip file-history-snapshot, progress, system types
277
+ }
278
+ catch {
279
+ // skip malformed lines
280
+ }
281
+ }
282
+ return { user, assistant };
283
+ }
284
+ /** Deduplicate assistant messages: streaming chunks share the same message.id */
285
+ deduplicateAssistant(msgs) {
286
+ const byMsgId = new Map();
287
+ for (const msg of msgs) {
288
+ const key = msg.message.id;
289
+ // Keep the last chunk (most complete content)
290
+ byMsgId.set(key, msg);
291
+ }
292
+ return [...byMsgId.values()];
293
+ }
294
+ // ── Content extraction from JSONL ───────────────────────────────
295
+ extractContentFromJsonl(filePath, dayStartMs, dayEndMs) {
296
+ if (!existsSync(filePath)) {
297
+ return { conversationDigest: '', toolCallSummaries: [], filesTouched: [] };
298
+ }
299
+ const messages = this.parseJsonlFile(filePath, dayStartMs, dayEndMs);
300
+ return this.extractContentFromMessages(messages, dayStartMs, dayEndMs);
301
+ }
302
+ extractContentFromMessages(messages, _dayStartMs, _dayEndMs) {
303
+ const digestParts = [];
304
+ const toolSummaries = [];
305
+ const files = new Set();
306
+ const home = homedir();
307
+ const all = [
308
+ ...messages.user.map((m) => ({ ts: new Date(m.timestamp).getTime(), role: 'user', msg: m })),
309
+ ...messages.assistant.map((m) => ({ ts: new Date(m.timestamp).getTime(), role: 'assistant', msg: m })),
310
+ ].sort((a, b) => a.ts - b.ts);
311
+ // Deduplicate assistant messages
312
+ const seenMsgIds = new Set();
313
+ for (const { role, msg } of all) {
314
+ if (role === 'user') {
315
+ const userMsg = msg;
316
+ const content = userMsg.message.content;
317
+ // Only include human text, not tool results
318
+ if (typeof content === 'string') {
319
+ const truncated = content.length > 500 ? content.slice(0, 500) + '...' : content;
320
+ digestParts.push(`[User]: ${truncated}`);
321
+ }
322
+ // Array content with tool_result entries → skip for digest
323
+ }
324
+ else {
325
+ const assistantMsg = msg;
326
+ const msgId = assistantMsg.message.id;
327
+ // Skip duplicate streaming chunks
328
+ if (seenMsgIds.has(msgId))
329
+ continue;
330
+ seenMsgIds.add(msgId);
331
+ const contentBlocks = assistantMsg.message.content ?? [];
332
+ const textParts = [];
333
+ for (const block of contentBlocks) {
334
+ if (block.type === 'text' && block.text) {
335
+ textParts.push(block.text);
336
+ }
337
+ if (block.type === 'tool_use' && block.name) {
338
+ const input = block.input ?? {};
339
+ let summary = block.name;
340
+ const filePath = (input.filePath ?? input.path ?? input.file);
341
+ const command = input.command;
342
+ const pattern = input.pattern;
343
+ if (filePath) {
344
+ const short = filePath.startsWith(home) ? '~' + filePath.slice(home.length) : filePath;
345
+ summary = `${block.name} ${short}`;
346
+ files.add(filePath);
347
+ }
348
+ else if (command) {
349
+ summary = `bash: ${String(command).slice(0, 80)}`;
350
+ }
351
+ else if (pattern) {
352
+ summary = `${block.name}: ${pattern}`;
353
+ }
354
+ toolSummaries.push(summary);
355
+ }
356
+ }
357
+ if (textParts.length > 0) {
358
+ const text = textParts.join('\n');
359
+ const truncated = text.length > 500 ? text.slice(0, 500) + '...' : text;
360
+ digestParts.push(`[Assistant]: ${truncated}`);
361
+ }
362
+ }
363
+ }
364
+ // Cap total digest
365
+ let conversationDigest = digestParts.join('\n\n');
366
+ if (conversationDigest.length > 4000) {
367
+ conversationDigest = conversationDigest.slice(0, 4000) + '\n\n[...truncated]';
368
+ }
369
+ return {
370
+ conversationDigest,
371
+ toolCallSummaries: toolSummaries,
372
+ filesTouched: [...files],
373
+ };
374
+ }
375
+ // ── Helpers ─────────────────────────────────────────────────────
376
+ truncatePrompt(prompt) {
377
+ if (!prompt)
378
+ return null;
379
+ const clean = prompt.replace(/\n/g, ' ').trim();
380
+ if (clean.length <= 60)
381
+ return clean;
382
+ return clean.slice(0, 57) + '...';
383
+ }
384
+ }
385
+ //# sourceMappingURL=claude-code.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../src/parsers/claude-code.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { Parser, Session } from '../types.js';
2
+ export declare class CursorParser implements Parser {
3
+ readonly name: "cursor";
4
+ private dbPath;
5
+ constructor(dbPath: string);
6
+ isAvailable(): Promise<boolean>;
7
+ getSessions(date: string): Promise<Session[]>;
8
+ private loadBubbles;
9
+ /** Check if a bubble's timestamp falls within the target day */
10
+ private bubbleInDay;
11
+ /** Extract the best available timestamp from a bubble (ms epoch) */
12
+ private getBubbleTimestamp;
13
+ private buildSession;
14
+ }
15
+ //# sourceMappingURL=cursor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../../src/parsers/cursor.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAc,MAAM,aAAa,CAAC;AAsE/D,qBAAa,YAAa,YAAW,MAAM;IACzC,QAAQ,CAAC,IAAI,EAAG,QAAQ,CAAU;IAClC,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,MAAM;IAIpB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAI/B,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IA8DnD,OAAO,CAAC,WAAW;IAkEnB,gEAAgE;IAChE,OAAO,CAAC,WAAW;IAWnB,oEAAoE;IACpE,OAAO,CAAC,kBAAkB;IAgB1B,OAAO,CAAC,YAAY;CAiKrB"}