codesesh 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -6
- package/dist/{chunk-2UNXB2D3.js → chunk-EIIG7J6V.js} +705 -77
- package/dist/chunk-EIIG7J6V.js.map +1 -0
- package/dist/{dist-6EV6SS6N.js → dist-2YXXOCZJ.js} +18 -4
- package/dist/index.js +131 -20
- package/dist/index.js.map +1 -1
- package/dist/web/assets/index-DJuE5oTj.js +68 -0
- package/dist/web/assets/index-gSYgPU_H.css +2 -0
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/dist/chunk-2UNXB2D3.js.map +0 -1
- package/dist/web/assets/index-B4PtJ1VM.css +0 -2
- package/dist/web/assets/index-BzkyjHEA.js +0 -67
- /package/dist/{dist-6EV6SS6N.js.map → dist-2YXXOCZJ.js.map} +0 -0
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
basenameTitle,
|
|
5
5
|
clearCache,
|
|
6
6
|
createRegisteredAgents,
|
|
7
|
+
deleteBookmark,
|
|
7
8
|
filterSessions,
|
|
8
9
|
firstExisting,
|
|
9
10
|
getAgentByName,
|
|
@@ -11,9 +12,12 @@ import {
|
|
|
11
12
|
getCacheInfo,
|
|
12
13
|
getCursorDataPath,
|
|
13
14
|
getRegisteredAgents,
|
|
15
|
+
importBookmarks,
|
|
14
16
|
isSqliteAvailable,
|
|
17
|
+
listBookmarks,
|
|
15
18
|
loadCachedSessions,
|
|
16
19
|
normalizeTitleText,
|
|
20
|
+
openDb,
|
|
17
21
|
openDbReadOnly,
|
|
18
22
|
parseJsonlLines,
|
|
19
23
|
perf,
|
|
@@ -23,13 +27,17 @@ import {
|
|
|
23
27
|
resolveSessionTitle,
|
|
24
28
|
saveCachedSessions,
|
|
25
29
|
scanSessions,
|
|
26
|
-
scanSessionsAsync
|
|
27
|
-
|
|
30
|
+
scanSessionsAsync,
|
|
31
|
+
searchSessions,
|
|
32
|
+
syncSessionSearchIndex,
|
|
33
|
+
upsertBookmark
|
|
34
|
+
} from "./chunk-EIIG7J6V.js";
|
|
28
35
|
export {
|
|
29
36
|
BaseAgent,
|
|
30
37
|
basenameTitle,
|
|
31
38
|
clearCache,
|
|
32
39
|
createRegisteredAgents,
|
|
40
|
+
deleteBookmark,
|
|
33
41
|
filterSessions,
|
|
34
42
|
firstExisting,
|
|
35
43
|
getAgentByName,
|
|
@@ -37,9 +45,12 @@ export {
|
|
|
37
45
|
getCacheInfo,
|
|
38
46
|
getCursorDataPath,
|
|
39
47
|
getRegisteredAgents,
|
|
48
|
+
importBookmarks,
|
|
40
49
|
isSqliteAvailable,
|
|
50
|
+
listBookmarks,
|
|
41
51
|
loadCachedSessions,
|
|
42
52
|
normalizeTitleText,
|
|
53
|
+
openDb,
|
|
43
54
|
openDbReadOnly,
|
|
44
55
|
parseJsonlLines,
|
|
45
56
|
perf,
|
|
@@ -49,6 +60,9 @@ export {
|
|
|
49
60
|
resolveSessionTitle,
|
|
50
61
|
saveCachedSessions,
|
|
51
62
|
scanSessions,
|
|
52
|
-
scanSessionsAsync
|
|
63
|
+
scanSessionsAsync,
|
|
64
|
+
searchSessions,
|
|
65
|
+
syncSessionSearchIndex,
|
|
66
|
+
upsertBookmark
|
|
53
67
|
};
|
|
54
|
-
//# sourceMappingURL=dist-
|
|
68
|
+
//# sourceMappingURL=dist-2YXXOCZJ.js.map
|
package/dist/index.js
CHANGED
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
createRegisteredAgents,
|
|
4
|
+
deleteBookmark,
|
|
4
5
|
filterSessions,
|
|
5
6
|
getAgentInfoMap,
|
|
6
7
|
getCursorDataPath,
|
|
8
|
+
importBookmarks,
|
|
9
|
+
listBookmarks,
|
|
7
10
|
perf,
|
|
8
11
|
resolveProviderRoots,
|
|
9
12
|
saveCachedSessions,
|
|
10
|
-
scanSessions
|
|
11
|
-
|
|
13
|
+
scanSessions,
|
|
14
|
+
searchSessions,
|
|
15
|
+
syncSessionSearchIndex,
|
|
16
|
+
upsertBookmark
|
|
17
|
+
} from "./chunk-EIIG7J6V.js";
|
|
12
18
|
|
|
13
19
|
// src/index.ts
|
|
14
20
|
import { defineCommand, runMain } from "citty";
|
|
@@ -26,6 +32,29 @@ import { fileURLToPath } from "url";
|
|
|
26
32
|
import { Hono } from "hono";
|
|
27
33
|
|
|
28
34
|
// src/api/handlers.ts
|
|
35
|
+
function isRecord(value) {
|
|
36
|
+
return typeof value === "object" && value !== null;
|
|
37
|
+
}
|
|
38
|
+
function isSessionStats(value) {
|
|
39
|
+
if (!isRecord(value)) return false;
|
|
40
|
+
return typeof value.message_count === "number" && typeof value.total_input_tokens === "number" && typeof value.total_output_tokens === "number" && typeof value.total_cost === "number" && (value.total_tokens == null || typeof value.total_tokens === "number");
|
|
41
|
+
}
|
|
42
|
+
function parseBookmarkPayload(value) {
|
|
43
|
+
if (!isRecord(value)) return null;
|
|
44
|
+
if (typeof value.agentKey !== "string" || typeof value.sessionId !== "string" || typeof value.fullPath !== "string" || typeof value.title !== "string" || typeof value.directory !== "string" || typeof value.time_created !== "number" || value.time_updated != null && typeof value.time_updated !== "number" || !isSessionStats(value.stats)) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
agentKey: value.agentKey,
|
|
49
|
+
sessionId: value.sessionId,
|
|
50
|
+
fullPath: value.fullPath,
|
|
51
|
+
title: value.title,
|
|
52
|
+
directory: value.directory,
|
|
53
|
+
time_created: value.time_created,
|
|
54
|
+
time_updated: value.time_updated,
|
|
55
|
+
stats: value.stats
|
|
56
|
+
};
|
|
57
|
+
}
|
|
29
58
|
function getTotalTokens(stats) {
|
|
30
59
|
return stats.total_tokens ?? stats.total_input_tokens + stats.total_output_tokens;
|
|
31
60
|
}
|
|
@@ -38,12 +67,7 @@ function parseDateParam(value, fallback) {
|
|
|
38
67
|
return Number.isNaN(ts) ? fallback : ts;
|
|
39
68
|
}
|
|
40
69
|
function filterSessionsByWindow(sessions, from, to) {
|
|
41
|
-
|
|
42
|
-
return sessions.filter((s) => {
|
|
43
|
-
if (from != null && s.time_created < from) return false;
|
|
44
|
-
if (to != null && s.time_created > to) return false;
|
|
45
|
-
return true;
|
|
46
|
-
});
|
|
70
|
+
return filterSessionsByActivityWindow(sessions, from, to);
|
|
47
71
|
}
|
|
48
72
|
function filterSessionsByActivityWindow(sessions, from, to) {
|
|
49
73
|
if (from == null && to == null) return sessions;
|
|
@@ -91,17 +115,39 @@ function handleGetSessions(c, scanSource, defaults = {}) {
|
|
|
91
115
|
if (cwd) {
|
|
92
116
|
sessions = sessions.filter((s) => s.directory.toLowerCase().includes(cwd));
|
|
93
117
|
}
|
|
94
|
-
|
|
95
|
-
sessions = sessions.filter((s) => s.time_created >= from);
|
|
96
|
-
}
|
|
97
|
-
if (to != null) {
|
|
98
|
-
sessions = sessions.filter((s) => s.time_created <= to);
|
|
99
|
-
}
|
|
118
|
+
sessions = filterSessionsByActivityWindow(sessions, from, to);
|
|
100
119
|
if (q) {
|
|
101
120
|
sessions = sessions.filter((s) => s.title.toLowerCase().includes(q));
|
|
102
121
|
}
|
|
103
122
|
return c.json({ sessions });
|
|
104
123
|
}
|
|
124
|
+
function handleSearchSessions(c, scanSource, defaults = {}) {
|
|
125
|
+
const query = c.req.query("q")?.trim() ?? "";
|
|
126
|
+
if (!query) {
|
|
127
|
+
return c.json({ results: [] });
|
|
128
|
+
}
|
|
129
|
+
const scanResult = scanSource.getSnapshot();
|
|
130
|
+
const agent = c.req.query("agent");
|
|
131
|
+
const cwd = c.req.query("cwd");
|
|
132
|
+
const from = parseDateParam(c.req.query("from"), defaults.from);
|
|
133
|
+
const to = parseDateParam(c.req.query("to"), defaults.to);
|
|
134
|
+
for (const indexedAgent of scanResult.agents) {
|
|
135
|
+
const sessions = scanResult.byAgent[indexedAgent.name] ?? [];
|
|
136
|
+
syncSessionSearchIndex(
|
|
137
|
+
indexedAgent.name,
|
|
138
|
+
sessions,
|
|
139
|
+
(sessionId) => indexedAgent.getSessionData(sessionId)
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
const results = searchSessions(query, {
|
|
143
|
+
agent,
|
|
144
|
+
cwd,
|
|
145
|
+
from,
|
|
146
|
+
to,
|
|
147
|
+
limit: 50
|
|
148
|
+
});
|
|
149
|
+
return c.json({ results });
|
|
150
|
+
}
|
|
105
151
|
async function handleGetSessionData(c, scanSource) {
|
|
106
152
|
const scanResult = scanSource.getSnapshot();
|
|
107
153
|
const agentName = c.req.param("agent");
|
|
@@ -121,6 +167,36 @@ async function handleGetSessionData(c, scanSource) {
|
|
|
121
167
|
return c.json({ error: message }, 500);
|
|
122
168
|
}
|
|
123
169
|
}
|
|
170
|
+
function handleGetBookmarks(c) {
|
|
171
|
+
return c.json({ bookmarks: listBookmarks() });
|
|
172
|
+
}
|
|
173
|
+
async function handlePutBookmark(c) {
|
|
174
|
+
const payload = parseBookmarkPayload(await c.req.json().catch(() => null));
|
|
175
|
+
if (!payload) {
|
|
176
|
+
return c.json({ error: "Invalid bookmark payload" }, 400);
|
|
177
|
+
}
|
|
178
|
+
return c.json({ bookmark: upsertBookmark(payload) });
|
|
179
|
+
}
|
|
180
|
+
async function handleImportBookmarks(c) {
|
|
181
|
+
const payload = await c.req.json().catch(() => null);
|
|
182
|
+
if (!Array.isArray(payload)) {
|
|
183
|
+
return c.json({ error: "Invalid bookmark payload" }, 400);
|
|
184
|
+
}
|
|
185
|
+
const bookmarks = payload.map((entry) => parseBookmarkPayload(entry)).filter((entry) => entry !== null);
|
|
186
|
+
if (bookmarks.length !== payload.length) {
|
|
187
|
+
return c.json({ error: "Invalid bookmark payload" }, 400);
|
|
188
|
+
}
|
|
189
|
+
return c.json({ bookmarks: importBookmarks(bookmarks) });
|
|
190
|
+
}
|
|
191
|
+
function handleDeleteBookmark(c) {
|
|
192
|
+
const agentKey = c.req.param("agent");
|
|
193
|
+
const sessionId = c.req.param("id");
|
|
194
|
+
if (!agentKey || !sessionId) {
|
|
195
|
+
return c.json({ error: "Missing bookmark identifier" }, 400);
|
|
196
|
+
}
|
|
197
|
+
deleteBookmark(agentKey, sessionId);
|
|
198
|
+
return c.json({ ok: true });
|
|
199
|
+
}
|
|
124
200
|
function toLocalDateKey(ts) {
|
|
125
201
|
const d = new Date(ts);
|
|
126
202
|
const year = d.getFullYear();
|
|
@@ -203,12 +279,15 @@ function handleGetDashboard(c, scanSource, defaults = {}) {
|
|
|
203
279
|
};
|
|
204
280
|
}).filter((item) => item.sessions > 0).sort((a, b) => b.sessions - a.sessions);
|
|
205
281
|
const dailyMap = /* @__PURE__ */ new Map();
|
|
282
|
+
const dailyTokenMap = /* @__PURE__ */ new Map();
|
|
206
283
|
const bucketStart = startOfLocalDay(from);
|
|
207
284
|
for (let i = 0; i < days; i += 1) {
|
|
208
285
|
const ts = bucketStart + i * 864e5;
|
|
209
286
|
const key = toLocalDateKey(ts);
|
|
210
287
|
dailyMap.set(key, { date: key, sessions: 0, messages: 0 });
|
|
288
|
+
dailyTokenMap.set(key, { date: key, input: 0, output: 0, cache_read: 0, cache_create: 0 });
|
|
211
289
|
}
|
|
290
|
+
const modelAgg = /* @__PURE__ */ new Map();
|
|
212
291
|
for (const session of windowed) {
|
|
213
292
|
const key = toLocalDateKey(getSessionActivityTime(session));
|
|
214
293
|
const bucket = dailyMap.get(key);
|
|
@@ -216,8 +295,31 @@ function handleGetDashboard(c, scanSource, defaults = {}) {
|
|
|
216
295
|
bucket.sessions += 1;
|
|
217
296
|
bucket.messages += session.stats.message_count;
|
|
218
297
|
}
|
|
298
|
+
const tokenBucket = dailyTokenMap.get(key);
|
|
299
|
+
if (tokenBucket) {
|
|
300
|
+
const cacheRead = session.stats.total_cache_read_tokens ?? 0;
|
|
301
|
+
const cacheCreate = session.stats.total_cache_create_tokens ?? 0;
|
|
302
|
+
const pureInput = session.stats.total_input_tokens - cacheRead - cacheCreate;
|
|
303
|
+
tokenBucket.input += Math.max(0, pureInput);
|
|
304
|
+
tokenBucket.output += session.stats.total_output_tokens;
|
|
305
|
+
tokenBucket.cache_read += cacheRead;
|
|
306
|
+
tokenBucket.cache_create += cacheCreate;
|
|
307
|
+
}
|
|
308
|
+
if (session.model_usage) {
|
|
309
|
+
for (const [model, tokens] of Object.entries(session.model_usage)) {
|
|
310
|
+
const entry = modelAgg.get(model);
|
|
311
|
+
if (entry) {
|
|
312
|
+
entry.tokens += tokens;
|
|
313
|
+
entry.sessions += 1;
|
|
314
|
+
} else {
|
|
315
|
+
modelAgg.set(model, { tokens, sessions: 1 });
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
219
319
|
}
|
|
220
320
|
const dailyActivity = [...dailyMap.values()];
|
|
321
|
+
const dailyTokenActivity = [...dailyTokenMap.values()];
|
|
322
|
+
const modelDistribution = [...modelAgg.entries()].map(([model, { tokens, sessions: count }]) => ({ model, tokens, sessions: count })).sort((a, b) => b.tokens - a.tokens);
|
|
221
323
|
const recentSessions = [...windowed].sort((a, b) => getSessionActivityTime(b) - getSessionActivityTime(a)).slice(0, 10).map((session) => {
|
|
222
324
|
const agentKey = session.slug.split("/")[0] ?? "unknown";
|
|
223
325
|
return { ...session, agentName: agentKey };
|
|
@@ -232,6 +334,8 @@ function handleGetDashboard(c, scanSource, defaults = {}) {
|
|
|
232
334
|
},
|
|
233
335
|
perAgent,
|
|
234
336
|
dailyActivity,
|
|
337
|
+
dailyTokenActivity,
|
|
338
|
+
modelDistribution,
|
|
235
339
|
recentSessions,
|
|
236
340
|
window: { from, to, days }
|
|
237
341
|
};
|
|
@@ -288,8 +392,13 @@ function createApiRoutes(scanSource, store, options = {}) {
|
|
|
288
392
|
api.get("/config", (c) => handleGetConfig(c, listDefaults));
|
|
289
393
|
api.get("/agents", (c) => handleGetAgents(c, scanSource, listDefaults));
|
|
290
394
|
api.get("/sessions", (c) => handleGetSessions(c, scanSource, listDefaults));
|
|
395
|
+
api.get("/search", (c) => handleSearchSessions(c, scanSource, listDefaults));
|
|
291
396
|
api.get("/sessions/:agent/:id", (c) => handleGetSessionData(c, scanSource));
|
|
292
397
|
api.get("/dashboard", (c) => handleGetDashboard(c, scanSource, listDefaults));
|
|
398
|
+
api.get("/bookmarks", (c) => handleGetBookmarks(c));
|
|
399
|
+
api.put("/bookmarks", (c) => handlePutBookmark(c));
|
|
400
|
+
api.post("/bookmarks/import", (c) => handleImportBookmarks(c));
|
|
401
|
+
api.delete("/bookmarks/:agent/:id", (c) => handleDeleteBookmark(c));
|
|
293
402
|
if (store) {
|
|
294
403
|
api.get("/events", (c) => createSseResponse(store, c.req.raw.signal));
|
|
295
404
|
}
|
|
@@ -655,6 +764,7 @@ var LiveScanStore = class {
|
|
|
655
764
|
}
|
|
656
765
|
nextSessions = this.applyFilters(nextSessions);
|
|
657
766
|
saveCachedSessions(agentName, nextSessions, buildAgentCacheMeta(agent));
|
|
767
|
+
syncSessionSearchIndex(agentName, nextSessions, (sessionId) => agent.getSessionData(sessionId));
|
|
658
768
|
const event = buildUpdateEvent(agentName, previousSessions, nextSessions);
|
|
659
769
|
this.byAgent[agentName] = sortSessions(nextSessions);
|
|
660
770
|
this.rebuildSessions();
|
|
@@ -749,7 +859,7 @@ var main = defineCommand({
|
|
|
749
859
|
days: {
|
|
750
860
|
type: "string",
|
|
751
861
|
alias: "d",
|
|
752
|
-
description: "Only include sessions
|
|
862
|
+
description: "Only include sessions active in the last N days (0 = all time)",
|
|
753
863
|
default: "7"
|
|
754
864
|
},
|
|
755
865
|
cwd: {
|
|
@@ -758,11 +868,11 @@ var main = defineCommand({
|
|
|
758
868
|
},
|
|
759
869
|
from: {
|
|
760
870
|
type: "string",
|
|
761
|
-
description: "Sessions
|
|
871
|
+
description: "Sessions active after this date, YYYY-MM-DD (overrides --days)"
|
|
762
872
|
},
|
|
763
873
|
to: {
|
|
764
874
|
type: "string",
|
|
765
|
-
description: "Sessions
|
|
875
|
+
description: "Sessions active before this date (YYYY-MM-DD)"
|
|
766
876
|
},
|
|
767
877
|
session: {
|
|
768
878
|
type: "string",
|
|
@@ -807,7 +917,7 @@ var main = defineCommand({
|
|
|
807
917
|
perf.enable();
|
|
808
918
|
}
|
|
809
919
|
if (clearCache) {
|
|
810
|
-
const { clearCache: clear } = await import("./dist-
|
|
920
|
+
const { clearCache: clear } = await import("./dist-2YXXOCZJ.js");
|
|
811
921
|
clear();
|
|
812
922
|
console.log("Cache cleared.");
|
|
813
923
|
}
|
|
@@ -848,8 +958,9 @@ var main = defineCommand({
|
|
|
848
958
|
}
|
|
849
959
|
if (jsonOnly) {
|
|
850
960
|
const windowed = result.sessions.filter((s) => {
|
|
851
|
-
|
|
852
|
-
if (
|
|
961
|
+
const activity = s.time_updated ?? s.time_created;
|
|
962
|
+
if (listDefaultFrom != null && activity < listDefaultFrom) return false;
|
|
963
|
+
if (listDefaultTo != null && activity > listDefaultTo) return false;
|
|
853
964
|
return true;
|
|
854
965
|
});
|
|
855
966
|
const info = getAgentInfoMap(
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/server.ts","../src/api/routes.ts","../src/api/handlers.ts","../src/live-scan.ts","../src/output.ts","../src/version.ts"],"sourcesContent":["import { defineCommand, runMain } from \"citty\";\nimport { createServer, getServerStartupErrorMessage } from \"./server.js\";\nimport { LiveScanStore } from \"./live-scan.js\";\nimport { printScanResults } from \"./output.js\";\nimport { VERSION } from \"./version.js\";\nimport { createRegisteredAgents, getAgentInfoMap, type ScanOptions, perf } from \"@codesesh/core\";\n\nfunction parseDateToTimestamp(dateStr: string): number {\n const date = new Date(dateStr);\n if (Number.isNaN(date.getTime())) {\n throw new Error(`Invalid date: ${dateStr}`);\n }\n return date.getTime();\n}\n\nfunction parseSessionUri(uri: string): { agent: string; sessionId: string } | null {\n const match = uri.match(/^([a-z]+):\\/\\/(.+)$/i);\n if (!match) return null;\n return { agent: match[1]!, sessionId: match[2]! };\n}\n\nconst main = defineCommand({\n meta: {\n name: \"codesesh\",\n description: \"Discover, aggregate, and visualize AI coding agent sessions\",\n version: VERSION,\n },\n args: {\n port: {\n type: \"string\",\n alias: \"p\",\n description: \"HTTP server port\",\n default: \"4321\",\n },\n agent: {\n type: \"string\",\n alias: \"a\",\n description: \"Filter to specific agent(s), comma-separated\",\n },\n days: {\n type: \"string\",\n alias: \"d\",\n description: \"Only include sessions from the last N days (0 = all time)\",\n default: \"7\",\n },\n cwd: {\n type: \"string\",\n description: \"Filter to sessions from a specific project directory (use '.' for current dir)\",\n },\n from: {\n type: \"string\",\n description: \"Sessions created after this date, YYYY-MM-DD (overrides --days)\",\n },\n to: {\n type: \"string\",\n description: \"Sessions created before this date (YYYY-MM-DD)\",\n },\n session: {\n type: \"string\",\n alias: \"s\",\n description: \"Directly open a specific session (agent://session-id)\",\n },\n json: {\n type: \"boolean\",\n alias: \"j\",\n description: \"Output session index as JSON to stdout (no server)\",\n default: false,\n },\n noOpen: {\n type: \"boolean\",\n description: \"Don't auto-open browser\",\n default: false,\n },\n trace: {\n type: \"boolean\",\n description: \"Show performance trace logs\",\n default: false,\n },\n cache: {\n type: \"boolean\",\n description: \"Use cached scan results if available\",\n default: true,\n },\n \"clear-cache\": {\n type: \"boolean\",\n description: \"Clear scan cache before starting\",\n default: false,\n },\n },\n async run({ args }) {\n const port = parseInt(args.port as string, 10) || 4321;\n const noOpen = args.noOpen as boolean;\n const jsonOnly = args.json as boolean;\n const trace = args.trace as boolean;\n const useCache = args.cache as boolean;\n const clearCache = args[\"clear-cache\"] as boolean;\n\n if (trace) {\n perf.enable();\n }\n\n if (clearCache) {\n const { clearCache: clear } = await import(\"@codesesh/core\");\n clear();\n console.log(\"Cache cleared.\");\n }\n\n // Parse session URI if provided\n let targetSession: { agent: string; sessionId: string } | null = null;\n if (args.session) {\n targetSession = parseSessionUri(args.session as string);\n if (!targetSession) {\n console.error(`Invalid session format: ${args.session}. Expected: agent://session-id`);\n process.exit(1);\n }\n }\n\n // Resolve cwd filter: '.' => process.cwd()\n let cwdFilter = args.cwd as string | undefined;\n if (cwdFilter === \".\") {\n cwdFilter = process.cwd();\n }\n\n // Resolve app-level default window (shared across /api/agents, /sessions, /dashboard).\n // Priority: --from (absolute) over --days (relative).\n let listDefaultFrom: number | undefined;\n let listDefaultDays: number | undefined;\n if (args.from) {\n listDefaultFrom = parseDateToTimestamp(args.from as string);\n } else {\n const days = parseInt(args.days as string, 10);\n if (!Number.isNaN(days) && days > 0) {\n listDefaultFrom = Date.now() - days * 24 * 60 * 60 * 1000;\n listDefaultDays = days;\n }\n }\n const listDefaultTo = args.to ? parseDateToTimestamp(args.to as string) : undefined;\n\n // Build scan options (no time slicing — Dashboard needs full history)\n const scanOptions: ScanOptions = {\n agents: targetSession\n ? [targetSession.agent]\n : args.agent\n ? (args.agent as string).split(\",\").map((a) => a.trim())\n : undefined,\n cwd: cwdFilter,\n useCache: useCache,\n };\n\n const store = new LiveScanStore(!jsonOnly, scanOptions);\n await store.initialize();\n const result = store.getSnapshot();\n\n if (trace) {\n console.log(perf.getReport());\n }\n\n if (jsonOnly) {\n // Apply --days/--from/--to window to the JSON output so CLI semantics are preserved.\n const windowed = result.sessions.filter((s) => {\n if (listDefaultFrom != null && s.time_created < listDefaultFrom) return false;\n if (listDefaultTo != null && s.time_created > listDefaultTo) return false;\n return true;\n });\n const info = getAgentInfoMap(\n Object.fromEntries(Object.entries(result.byAgent).map(([k, v]) => [k, v.length])),\n );\n const output = {\n agents: info.map(({ name, displayName, count }) => ({\n name,\n displayName,\n count,\n available: count > 0,\n })),\n sessions: windowed,\n };\n console.log(JSON.stringify(output, null, 2));\n return;\n }\n\n // Print console output\n const agents = createRegisteredAgents();\n printScanResults(agents, result);\n\n // Start server\n let url: string;\n try {\n ({ url } = await createServer(port, store, {\n defaultSessionFrom: listDefaultFrom,\n defaultSessionTo: listDefaultTo,\n defaultSessionDays: listDefaultDays,\n }));\n } catch (error) {\n console.error(getServerStartupErrorMessage(error, port));\n process.exit(1);\n }\n\n console.log(` ${url}`);\n console.log(\"\");\n\n if (!noOpen) {\n const open = (await import(\"open\")).default;\n const targetUrl = targetSession\n ? `${url}/${targetSession.agent.toLowerCase()}/${targetSession.sessionId}`\n : url;\n await open(targetUrl);\n }\n },\n});\n\nif (process.argv.slice(2).includes(\"-v\")) {\n console.log(VERSION);\n process.exit(0);\n}\n\nrunMain(main);\n","import { Hono } from \"hono\";\nimport { serve } from \"@hono/node-server\";\nimport { serveStatic } from \"@hono/node-server/serve-static\";\nimport { logger } from \"hono/logger\";\nimport { existsSync } from \"node:fs\";\nimport type { Server } from \"node:http\";\nimport { resolve, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { ScanResultSource } from \"./api/handlers.js\";\nimport { createApiRoutes, type ApiRouteOptions } from \"./api/routes.js\";\nimport { LiveScanStore } from \"./live-scan.js\";\n\nexport interface CreateServerOptions {\n defaultSessionFrom?: number;\n defaultSessionTo?: number;\n defaultSessionDays?: number;\n}\n\nfunction findWebDistPath(): string | null {\n const __dirname = dirname(fileURLToPath(import.meta.url));\n\n // Priority 1: Packaged web dist (copied during build)\n const packagedPath = resolve(__dirname, \"web\");\n if (existsSync(packagedPath)) {\n return packagedPath;\n }\n\n // Priority 2: Development path (monorepo)\n const devPath = resolve(__dirname, \"../../../apps/web/dist\");\n if (existsSync(devPath)) {\n return devPath;\n }\n\n return null;\n}\n\nfunction waitForListening(server: Server): Promise<void> {\n return new Promise((resolve, reject) => {\n const handleListening = () => {\n server.off(\"error\", handleError);\n resolve();\n };\n const handleError = (error: Error) => {\n server.off(\"listening\", handleListening);\n reject(error);\n };\n\n server.once(\"listening\", handleListening);\n server.once(\"error\", handleError);\n });\n}\n\nexport function getServerStartupErrorMessage(error: unknown, port: number): string {\n if (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n error.code === \"EADDRINUSE\"\n ) {\n return `Port ${port} 已被占用,请关闭现有 CodeSesh 进程或改用 --port 指定其他端口。`;\n }\n\n return error instanceof Error ? error.message : `启动服务器失败: ${String(error)}`;\n}\n\nexport async function createServer(\n port: number,\n store: ScanResultSource & Partial<Pick<LiveScanStore, \"subscribe\" | \"shutdown\">>,\n options: CreateServerOptions = {},\n): Promise<{ url: string; shutdown: () => void }> {\n const app = new Hono();\n\n app.use(\"*\", logger());\n\n // API routes\n const routeOptions: ApiRouteOptions = {\n defaultSessionFrom: options.defaultSessionFrom,\n defaultSessionTo: options.defaultSessionTo,\n defaultSessionDays: options.defaultSessionDays,\n };\n app.route(\n \"/api\",\n createApiRoutes(\n store,\n \"subscribe\" in store ? (store as LiveScanStore) : undefined,\n routeOptions,\n ),\n );\n\n // Serve static files from web dist (if available)\n const webDistPath = findWebDistPath();\n\n if (webDistPath) {\n app.use(\"/*\", serveStatic({ root: webDistPath }));\n app.get(\"/*\", serveStatic({ root: webDistPath, path: \"index.html\" }));\n }\n\n const server = serve({ fetch: app.fetch, port });\n\n try {\n await waitForListening(server);\n } catch (error) {\n server.close();\n if (store.shutdown) {\n await store.shutdown();\n }\n throw new Error(getServerStartupErrorMessage(error, port));\n }\n\n const url = `http://localhost:${port}`;\n\n return {\n url,\n shutdown: () => {\n server.close();\n if (store.shutdown) {\n void store.shutdown();\n }\n },\n };\n}\n","import { Hono } from \"hono\";\nimport {\n handleGetAgents,\n handleGetConfig,\n handleGetDashboard,\n handleGetSessions,\n handleGetSessionData,\n type ScanResultSource,\n type SessionListDefaults,\n} from \"./handlers.js\";\nimport type { LiveScanStore } from \"../live-scan.js\";\n\nexport interface ApiRouteOptions {\n defaultSessionFrom?: number;\n defaultSessionTo?: number;\n defaultSessionDays?: number;\n}\n\nfunction createSseResponse(store: LiveScanStore, signal: AbortSignal): Response {\n const encoder = new TextEncoder();\n\n return new Response(\n new ReadableStream({\n start(controller) {\n const write = (event: string, data: unknown) => {\n controller.enqueue(encoder.encode(`event: ${event}\\n`));\n controller.enqueue(encoder.encode(`data: ${JSON.stringify(data)}\\n\\n`));\n };\n\n write(\"connected\", { timestamp: Date.now() });\n\n const unsubscribe = store.subscribe((event) => {\n write(event.type, event);\n });\n\n const heartbeat = setInterval(() => {\n controller.enqueue(encoder.encode(\": keepalive\\n\\n\"));\n }, 15000);\n\n const close = () => {\n clearInterval(heartbeat);\n unsubscribe();\n controller.close();\n };\n\n signal.addEventListener(\"abort\", close, { once: true });\n },\n cancel() {\n return;\n },\n }),\n {\n headers: {\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"Content-Type\": \"text/event-stream\",\n },\n },\n );\n}\n\nexport function createApiRoutes(\n scanSource: ScanResultSource,\n store?: LiveScanStore,\n options: ApiRouteOptions = {},\n): Hono {\n const api = new Hono();\n const listDefaults: SessionListDefaults = {\n from: options.defaultSessionFrom,\n to: options.defaultSessionTo,\n days: options.defaultSessionDays,\n };\n\n api.get(\"/config\", (c) => handleGetConfig(c, listDefaults));\n api.get(\"/agents\", (c) => handleGetAgents(c, scanSource, listDefaults));\n api.get(\"/sessions\", (c) => handleGetSessions(c, scanSource, listDefaults));\n api.get(\"/sessions/:agent/:id\", (c) => handleGetSessionData(c, scanSource));\n api.get(\"/dashboard\", (c) => handleGetDashboard(c, scanSource, listDefaults));\n if (store) {\n api.get(\"/events\", (c) => createSseResponse(store, c.req.raw.signal));\n }\n\n return api;\n}\n","import type { Context } from \"hono\";\nimport type { ScanResult, SessionData, SessionHead } from \"@codesesh/core\";\nimport { getAgentInfoMap } from \"@codesesh/core\";\n\nexport interface ScanResultSource {\n getSnapshot(): ScanResult;\n}\n\nexport interface SessionListDefaults {\n from?: number;\n to?: number;\n /** When --days was used, original value — kept for UI \"last N days\" label */\n days?: number;\n}\n\nfunction getTotalTokens(stats: SessionHead[\"stats\"]): number {\n return stats.total_tokens ?? stats.total_input_tokens + stats.total_output_tokens;\n}\n\nfunction getSessionActivityTime(session: SessionHead): number {\n return session.time_updated ?? session.time_created;\n}\n\nfunction parseDateParam(\n value: string | undefined,\n fallback: number | undefined,\n): number | undefined {\n if (value == null) return fallback;\n const ts = new Date(value).getTime();\n return Number.isNaN(ts) ? fallback : ts;\n}\n\nfunction filterSessionsByWindow(\n sessions: SessionHead[],\n from: number | undefined,\n to: number | undefined,\n): SessionHead[] {\n if (from == null && to == null) return sessions;\n return sessions.filter((s) => {\n if (from != null && s.time_created < from) return false;\n if (to != null && s.time_created > to) return false;\n return true;\n });\n}\n\nfunction filterSessionsByActivityWindow(\n sessions: SessionHead[],\n from: number | undefined,\n to: number | undefined,\n): SessionHead[] {\n if (from == null && to == null) return sessions;\n return sessions.filter((session) => {\n const activity = getSessionActivityTime(session);\n if (from != null && activity < from) return false;\n if (to != null && activity > to) return false;\n return true;\n });\n}\n\nexport function handleGetConfig(c: Context, defaults: SessionListDefaults) {\n return c.json({\n window: {\n from: defaults.from,\n to: defaults.to,\n days: defaults.days,\n },\n });\n}\n\nexport function handleGetAgents(\n c: Context,\n scanSource: ScanResultSource,\n defaults: SessionListDefaults = {},\n) {\n const scanResult = scanSource.getSnapshot();\n const { from, to } = defaults;\n const counts = Object.fromEntries(\n Object.entries(scanResult.byAgent).map(([agentName, sessions]) => [\n agentName,\n filterSessionsByWindow(sessions, from, to).length,\n ]),\n );\n const info = getAgentInfoMap(counts);\n return c.json(info);\n}\n\nexport function handleGetSessions(\n c: Context,\n scanSource: ScanResultSource,\n defaults: SessionListDefaults = {},\n) {\n const scanResult = scanSource.getSnapshot();\n const agent = c.req.query(\"agent\");\n const q = c.req.query(\"q\")?.toLowerCase();\n const cwd = c.req.query(\"cwd\")?.toLowerCase();\n const from = parseDateParam(c.req.query(\"from\"), defaults.from);\n const to = parseDateParam(c.req.query(\"to\"), defaults.to);\n\n let sessions: SessionHead[] = [];\n\n // If agent filter is specified, use byAgent directly\n if (agent && scanResult.byAgent[agent]) {\n sessions = [...scanResult.byAgent[agent]!];\n } else {\n sessions = [...scanResult.sessions];\n }\n\n if (cwd) {\n sessions = sessions.filter((s) => s.directory.toLowerCase().includes(cwd));\n }\n\n if (from != null) {\n sessions = sessions.filter((s) => s.time_created >= from);\n }\n\n if (to != null) {\n sessions = sessions.filter((s) => s.time_created <= to);\n }\n\n if (q) {\n sessions = sessions.filter((s) => s.title.toLowerCase().includes(q));\n }\n\n return c.json({ sessions });\n}\n\nexport async function handleGetSessionData(c: Context, scanSource: ScanResultSource) {\n const scanResult = scanSource.getSnapshot();\n const agentName = c.req.param(\"agent\");\n const sessionId = c.req.param(\"id\");\n\n if (!sessionId) {\n return c.json({ error: \"Missing session ID\" }, 400);\n }\n\n const agent = scanResult.agents.find((a) => a.name === agentName);\n\n if (!agent) {\n return c.json({ error: `Unknown agent: ${agentName}` }, 404);\n }\n\n try {\n const data: SessionData = agent.getSessionData(sessionId);\n return c.json(data);\n } catch (err) {\n const message = err instanceof Error ? err.message : \"Failed to load session\";\n return c.json({ error: message }, 500);\n }\n}\n\nexport interface DashboardAgentStat {\n name: string;\n displayName: string;\n icon: string;\n sessions: number;\n messages: number;\n tokens: number;\n}\n\nexport interface DashboardDailyBucket {\n /** Local YYYY-MM-DD */\n date: string;\n sessions: number;\n messages: number;\n}\n\nexport interface DashboardTotals {\n sessions: number;\n messages: number;\n tokens: number;\n cost: number;\n latestActivity?: number;\n}\n\nexport interface DashboardRecentSession extends SessionHead {\n agentName: string;\n}\n\nexport interface DashboardData {\n totals: DashboardTotals;\n perAgent: DashboardAgentStat[];\n dailyActivity: DashboardDailyBucket[];\n recentSessions: DashboardRecentSession[];\n /** Time window covered by dailyActivity (inclusive, ms) */\n window: { from: number; to: number; days: number };\n}\n\nfunction toLocalDateKey(ts: number): string {\n const d = new Date(ts);\n const year = d.getFullYear();\n const month = `${d.getMonth() + 1}`.padStart(2, \"0\");\n const day = `${d.getDate()}`.padStart(2, \"0\");\n return `${year}-${month}-${day}`;\n}\n\nfunction startOfLocalDay(ts: number): number {\n const d = new Date(ts);\n d.setHours(0, 0, 0, 0);\n return d.getTime();\n}\n\nfunction resolveDashboardWindow(\n defaults: SessionListDefaults,\n queryDays: string | undefined,\n queryFrom: string | undefined,\n queryTo: string | undefined,\n): { from: number; to: number; days: number } {\n const now = Date.now();\n const todayStart = startOfLocalDay(now);\n\n // Query \"to\" wins over defaults, then \"now\" end-of-today as fallback\n const toTs = parseDateParam(queryTo, defaults.to) ?? todayStart + 24 * 60 * 60 * 1000 - 1;\n\n // Resolve days (preferred): query, defaults.days, or derive from defaults.from\n const parsedDays = queryDays ? parseInt(queryDays, 10) : NaN;\n let days: number | undefined =\n Number.isFinite(parsedDays) && parsedDays > 0 ? parsedDays : defaults.days;\n\n const fromFromQuery = parseDateParam(queryFrom, undefined);\n let fromTs: number;\n if (fromFromQuery != null) {\n fromTs = startOfLocalDay(fromFromQuery);\n days ??= Math.max(1, Math.ceil((todayStart - fromTs) / 86400000) + 1);\n } else if (days && days > 0) {\n fromTs = todayStart - (days - 1) * 86400000;\n } else if (defaults.from != null) {\n fromTs = startOfLocalDay(defaults.from);\n days = Math.max(1, Math.ceil((todayStart - fromTs) / 86400000) + 1);\n } else {\n days = 30;\n fromTs = todayStart - (days - 1) * 86400000;\n }\n\n return { from: fromTs, to: toTs, days };\n}\n\nexport function handleGetDashboard(\n c: Context,\n scanSource: ScanResultSource,\n defaults: SessionListDefaults = {},\n) {\n const scanResult = scanSource.getSnapshot();\n const { from, to, days } = resolveDashboardWindow(\n defaults,\n c.req.query(\"days\"),\n c.req.query(\"from\"),\n c.req.query(\"to\"),\n );\n\n const windowed = filterSessionsByActivityWindow(scanResult.sessions, from, to);\n\n const agentInfo = getAgentInfoMap(\n Object.fromEntries(\n Object.entries(scanResult.byAgent).map(([name, sessions]) => [\n name,\n filterSessionsByActivityWindow(sessions, from, to).length,\n ]),\n ),\n );\n const agentInfoMap = new Map(agentInfo.map((a) => [a.name, a]));\n\n let totalMessages = 0;\n let totalTokens = 0;\n let totalCost = 0;\n let latestActivity = 0;\n for (const session of windowed) {\n totalMessages += session.stats.message_count;\n totalTokens += getTotalTokens(session.stats);\n totalCost += session.stats.total_cost ?? 0;\n const activity = getSessionActivityTime(session);\n if (activity > latestActivity) latestActivity = activity;\n }\n\n const perAgent: DashboardAgentStat[] = Object.entries(scanResult.byAgent)\n .map(([name, sessions]) => {\n const info = agentInfoMap.get(name);\n const agentWindowed = filterSessionsByActivityWindow(sessions, from, to);\n let messages = 0;\n let tokens = 0;\n for (const s of agentWindowed) {\n messages += s.stats.message_count;\n tokens += getTotalTokens(s.stats);\n }\n return {\n name,\n displayName: info?.displayName ?? name,\n icon: info?.icon ?? \"\",\n sessions: agentWindowed.length,\n messages,\n tokens,\n };\n })\n .filter((item) => item.sessions > 0)\n .sort((a, b) => b.sessions - a.sessions);\n\n // Daily activity buckets — one bucket per local day in [from, to]\n const dailyMap = new Map<string, DashboardDailyBucket>();\n const bucketStart = startOfLocalDay(from);\n for (let i = 0; i < days; i += 1) {\n const ts = bucketStart + i * 86400000;\n const key = toLocalDateKey(ts);\n dailyMap.set(key, { date: key, sessions: 0, messages: 0 });\n }\n\n for (const session of windowed) {\n const key = toLocalDateKey(getSessionActivityTime(session));\n const bucket = dailyMap.get(key);\n if (bucket) {\n bucket.sessions += 1;\n bucket.messages += session.stats.message_count;\n }\n }\n\n const dailyActivity = [...dailyMap.values()];\n\n const recentSessions: DashboardRecentSession[] = [...windowed]\n .sort((a, b) => getSessionActivityTime(b) - getSessionActivityTime(a))\n .slice(0, 10)\n .map((session) => {\n const agentKey = session.slug.split(\"/\")[0] ?? \"unknown\";\n return { ...session, agentName: agentKey };\n });\n\n const data: DashboardData = {\n totals: {\n sessions: windowed.length,\n messages: totalMessages,\n tokens: totalTokens,\n cost: totalCost,\n latestActivity: latestActivity || undefined,\n },\n perAgent,\n dailyActivity,\n recentSessions,\n window: { from, to, days },\n };\n\n return c.json(data);\n}\n","import { existsSync } from \"node:fs\";\nimport { dirname, isAbsolute, join } from \"node:path\";\nimport chokidar, { type FSWatcher } from \"chokidar\";\nimport {\n createRegisteredAgents,\n filterSessions,\n getCursorDataPath,\n resolveProviderRoots,\n scanSessions,\n saveCachedSessions,\n type BaseAgent,\n type ScanResult,\n type ScanOptions,\n type SessionCacheMeta,\n type SessionHead,\n} from \"@codesesh/core\";\n\nexport interface SessionsUpdatedEvent {\n type: \"sessions-updated\";\n changedAgents: string[];\n newSessions: number;\n updatedSessions: number;\n removedSessions: number;\n totalSessions: number;\n timestamp: number;\n}\n\ntype StoreListener = (event: SessionsUpdatedEvent) => void;\n\ninterface WatchTarget {\n path: string;\n depth?: number;\n}\n\nfunction sortSessions(sessions: SessionHead[]): SessionHead[] {\n return [...sessions].sort(\n (a, b) => (b.time_updated ?? b.time_created) - (a.time_updated ?? a.time_created),\n );\n}\n\nfunction sessionSignature(session: SessionHead): string {\n return JSON.stringify([\n session.title,\n session.directory,\n session.time_created,\n session.time_updated ?? session.time_created,\n session.stats.message_count,\n session.stats.total_input_tokens,\n session.stats.total_output_tokens,\n session.stats.total_cost,\n session.stats.total_tokens ?? 0,\n ]);\n}\n\nfunction buildAgentCacheMeta(agent: BaseAgent): Record<string, SessionCacheMeta> {\n const metaMap = agent.getSessionMetaMap?.();\n const meta: Record<string, SessionCacheMeta> = {};\n if (!metaMap) return meta;\n\n for (const [id, data] of metaMap.entries()) {\n meta[id] = { id, ...(data as Record<string, unknown>) } as SessionCacheMeta;\n }\n\n return meta;\n}\n\nfunction buildUpdateEvent(\n agentName: string,\n previousSessions: SessionHead[],\n nextSessions: SessionHead[],\n): SessionsUpdatedEvent | null {\n const previousMap = new Map(previousSessions.map((session) => [session.id, session]));\n const nextMap = new Map(nextSessions.map((session) => [session.id, session]));\n\n let newSessions = 0;\n let updatedSessions = 0;\n let removedSessions = 0;\n\n for (const [id, session] of nextMap.entries()) {\n const previous = previousMap.get(id);\n if (!previous) {\n newSessions += 1;\n continue;\n }\n if (sessionSignature(previous) !== sessionSignature(session)) {\n updatedSessions += 1;\n }\n }\n\n for (const id of previousMap.keys()) {\n if (!nextMap.has(id)) {\n removedSessions += 1;\n }\n }\n\n if (newSessions === 0 && updatedSessions === 0 && removedSessions === 0) {\n return null;\n }\n\n return {\n type: \"sessions-updated\",\n changedAgents: [agentName],\n newSessions,\n updatedSessions,\n removedSessions,\n totalSessions: nextSessions.length,\n timestamp: Date.now(),\n };\n}\n\nfunction closestWatchablePath(targetPath: string): string | null {\n if (!isAbsolute(targetPath) && !existsSync(targetPath)) {\n return null;\n }\n\n let current = targetPath;\n\n while (!existsSync(current)) {\n const parent = dirname(current);\n if (parent === current) {\n return null;\n }\n current = parent;\n }\n\n return current;\n}\n\nexport function resolveAgentWatchTargets(agentName: string): WatchTarget[] {\n const roots = resolveProviderRoots();\n const cursorDataPath = getCursorDataPath();\n\n switch (agentName) {\n case \"claudecode\":\n return [\n { path: join(roots.claudeRoot, \"projects\"), depth: 2 },\n { path: \"data/claudecode\", depth: 2 },\n ];\n case \"codex\":\n return [{ path: join(roots.codexRoot, \"sessions\"), depth: 4 }];\n case \"cursor\":\n return cursorDataPath\n ? [\n { path: join(cursorDataPath, \"globalStorage\", \"state.vscdb\") },\n { path: join(cursorDataPath, \"workspaceStorage\"), depth: 2 },\n ]\n : [];\n case \"kimi\":\n return [\n { path: join(roots.kimiRoot, \"sessions\"), depth: 2 },\n { path: \"data/kimi\", depth: 2 },\n ];\n case \"opencode\":\n return [\n { path: join(roots.opencodeRoot, \"opencode.db\") },\n { path: \"data/opencode/opencode.db\" },\n ];\n default:\n return [];\n }\n}\n\nexport class LiveScanStore {\n private agents: BaseAgent[] = [];\n private byAgent: Record<string, SessionHead[]> = {};\n private sessions: SessionHead[] = [];\n private listeners = new Set<StoreListener>();\n private refreshTimers = new Map<string, NodeJS.Timeout>();\n private refreshTimestamps = new Map<string, number>();\n private refreshInFlight = new Set<string>();\n private pendingRefreshes = new Set<string>();\n private watchers: FSWatcher[] = [];\n\n constructor(\n private readonly watchEnabled = true,\n private readonly scanOptions: ScanOptions = {},\n ) {}\n\n async initialize(): Promise<void> {\n const initialResult = await scanSessions({\n ...this.scanOptions,\n useCache: true,\n smartRefresh: false,\n });\n const knownAgents = createRegisteredAgents();\n const agentMap = new Map<string, BaseAgent>();\n const allowedAgents = this.getAllowedAgents();\n\n for (const agent of initialResult.agents) {\n agentMap.set(agent.name, agent);\n }\n for (const agent of knownAgents) {\n if (!agentMap.has(agent.name)) {\n agentMap.set(agent.name, agent);\n }\n }\n\n this.agents = [...agentMap.values()].filter((agent) => {\n if (!allowedAgents) {\n return true;\n }\n return allowedAgents.has(agent.name.toLowerCase());\n });\n\n for (const agent of this.agents) {\n this.byAgent[agent.name] = sortSessions(initialResult.byAgent[agent.name] ?? []);\n this.refreshTimestamps.set(agent.name, Date.now());\n }\n\n this.rebuildSessions();\n if (this.watchEnabled) {\n this.startWatching();\n }\n }\n\n getSnapshot(): ScanResult {\n return {\n sessions: this.sessions,\n byAgent: this.byAgent,\n agents: this.agents,\n };\n }\n\n subscribe(listener: StoreListener): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n async shutdown(): Promise<void> {\n for (const timer of this.refreshTimers.values()) {\n clearTimeout(timer);\n }\n this.refreshTimers.clear();\n\n await Promise.all(this.watchers.map((watcher) => watcher.close()));\n this.watchers = [];\n }\n\n private emit(event: SessionsUpdatedEvent): void {\n for (const listener of this.listeners) {\n listener(event);\n }\n }\n\n private rebuildSessions(): void {\n this.sessions = sortSessions(Object.values(this.byAgent).flat());\n }\n\n private getAllowedAgents(): Set<string> | null {\n if (!this.scanOptions.agents?.length) {\n return null;\n }\n return new Set(this.scanOptions.agents.map((agent) => agent.toLowerCase()));\n }\n\n private applyFilters(sessions: SessionHead[]): SessionHead[] {\n return filterSessions(sessions, this.scanOptions);\n }\n\n private startWatching(): void {\n for (const agent of this.agents) {\n const rawTargets = resolveAgentWatchTargets(agent.name);\n const watchTargets = rawTargets\n .map((target) => {\n const watchPath = closestWatchablePath(target.path);\n return watchPath ? { ...target, path: watchPath } : null;\n })\n .filter((target): target is WatchTarget => target !== null)\n .filter(\n (target, index, items) =>\n items.findIndex((item) => item.path === target.path && item.depth === target.depth) ===\n index,\n );\n\n if (watchTargets.length === 0) {\n continue;\n }\n\n const watcher = chokidar.watch(\n watchTargets.map((target) => target.path),\n {\n ignoreInitial: true,\n awaitWriteFinish: {\n stabilityThreshold: 250,\n pollInterval: 100,\n },\n depth: watchTargets.reduce(\n (maxDepth, target) => Math.max(maxDepth, target.depth ?? 0),\n 0,\n ),\n },\n );\n\n watcher.on(\"all\", () => {\n this.scheduleRefresh(agent.name);\n });\n watcher.on(\"error\", (error) => {\n console.error(`[${agent.name}] File watcher failed:`, error);\n });\n\n this.watchers.push(watcher);\n }\n }\n\n private scheduleRefresh(agentName: string, delayMs = 200): void {\n const existing = this.refreshTimers.get(agentName);\n if (existing) {\n clearTimeout(existing);\n }\n\n const timer = setTimeout(() => {\n this.refreshTimers.delete(agentName);\n void this.refreshAgent(agentName);\n }, delayMs);\n\n this.refreshTimers.set(agentName, timer);\n }\n\n private async refreshAgent(agentName: string): Promise<void> {\n if (this.refreshInFlight.has(agentName)) {\n this.pendingRefreshes.add(agentName);\n return;\n }\n\n this.refreshInFlight.add(agentName);\n\n try {\n await this.runRefresh(agentName);\n } finally {\n this.refreshInFlight.delete(agentName);\n\n if (this.pendingRefreshes.delete(agentName)) {\n this.scheduleRefresh(agentName, 100);\n }\n }\n }\n\n private async runRefresh(agentName: string): Promise<void> {\n const agent = this.agents.find((item) => item.name === agentName);\n if (!agent) {\n return;\n }\n\n const previousSessions = this.byAgent[agentName] ?? [];\n let nextSessions = previousSessions;\n\n if (!agent.isAvailable()) {\n nextSessions = [];\n this.refreshTimestamps.set(agentName, Date.now());\n } else if (previousSessions.length > 0 && agent.checkForChanges && agent.incrementalScan) {\n const checkResult = await Promise.resolve(\n agent.checkForChanges(this.refreshTimestamps.get(agentName) ?? 0, previousSessions),\n );\n\n this.refreshTimestamps.set(agentName, checkResult.timestamp);\n if (!checkResult.hasChanges) {\n return;\n }\n\n nextSessions = await Promise.resolve(\n agent.incrementalScan(previousSessions, checkResult.changedIds ?? []),\n );\n } else {\n nextSessions = await Promise.resolve(agent.scan());\n this.refreshTimestamps.set(agentName, Date.now());\n }\n\n nextSessions = this.applyFilters(nextSessions);\n saveCachedSessions(agentName, nextSessions, buildAgentCacheMeta(agent));\n\n const event = buildUpdateEvent(agentName, previousSessions, nextSessions);\n this.byAgent[agentName] = sortSessions(nextSessions);\n this.rebuildSessions();\n\n if (event) {\n event.totalSessions = this.sessions.length;\n this.emit(event);\n }\n }\n}\n","import { consola } from \"consola\";\nimport type { BaseAgent } from \"@codesesh/core\";\nimport type { ScanResult } from \"@codesesh/core\";\nimport { VERSION } from \"./version.js\";\n\nexport function printScanResults(agents: BaseAgent[], result: ScanResult): void {\n consola.log(\"\");\n consola.box({\n title: \"CodeSesh\",\n message: `v${VERSION} • ${result.sessions.length} sessions discovered`,\n style: {\n padding: 1,\n borderColor: \"cyan\",\n },\n });\n consola.log(\"\");\n\n const rows: string[] = [];\n let availableCount = 0;\n\n for (const agent of agents) {\n const sessions = result.byAgent[agent.name];\n const count = sessions?.length ?? 0;\n if (count > 0) {\n availableCount++;\n rows.push(` ${green(\"✔\")} ${pad(agent.displayName)} ${dim(`${count} sessions`)}`);\n } else {\n rows.push(` ${dim(\"✖\")} ${pad(agent.displayName)} ${dim(\"not found\")}`);\n }\n }\n\n consola.log(rows.join(\"\\n\"));\n consola.log(\"\");\n consola.info(`Active: ${availableCount}/${agents.length} agents`);\n consola.log(\"\");\n}\n\nfunction pad(text: string, length = 16): string {\n return text.padEnd(length);\n}\n\nfunction green(text: string): string {\n return `\\x1b[32m${text}\\x1b[0m`;\n}\n\nfunction dim(text: string): string {\n return `\\x1b[2m${text}\\x1b[0m`;\n}\n","import { readFileSync } from \"node:fs\";\nimport { resolve, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst pkg = JSON.parse(readFileSync(resolve(__dirname, \"../package.json\"), \"utf-8\"));\n\nexport const VERSION = pkg.version;\n"],"mappings":"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","names":["Hono","__dirname","resolve","Hono","existsSync","dirname","existsSync","dirname","resolve","dirname","fileURLToPath"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/server.ts","../src/api/routes.ts","../src/api/handlers.ts","../src/live-scan.ts","../src/output.ts","../src/version.ts"],"sourcesContent":["import { defineCommand, runMain } from \"citty\";\nimport { createServer, getServerStartupErrorMessage } from \"./server.js\";\nimport { LiveScanStore } from \"./live-scan.js\";\nimport { printScanResults } from \"./output.js\";\nimport { VERSION } from \"./version.js\";\nimport { createRegisteredAgents, getAgentInfoMap, type ScanOptions, perf } from \"@codesesh/core\";\n\nfunction parseDateToTimestamp(dateStr: string): number {\n const date = new Date(dateStr);\n if (Number.isNaN(date.getTime())) {\n throw new Error(`Invalid date: ${dateStr}`);\n }\n return date.getTime();\n}\n\nfunction parseSessionUri(uri: string): { agent: string; sessionId: string } | null {\n const match = uri.match(/^([a-z]+):\\/\\/(.+)$/i);\n if (!match) return null;\n return { agent: match[1]!, sessionId: match[2]! };\n}\n\nconst main = defineCommand({\n meta: {\n name: \"codesesh\",\n description: \"Discover, aggregate, and visualize AI coding agent sessions\",\n version: VERSION,\n },\n args: {\n port: {\n type: \"string\",\n alias: \"p\",\n description: \"HTTP server port\",\n default: \"4321\",\n },\n agent: {\n type: \"string\",\n alias: \"a\",\n description: \"Filter to specific agent(s), comma-separated\",\n },\n days: {\n type: \"string\",\n alias: \"d\",\n description: \"Only include sessions active in the last N days (0 = all time)\",\n default: \"7\",\n },\n cwd: {\n type: \"string\",\n description: \"Filter to sessions from a specific project directory (use '.' for current dir)\",\n },\n from: {\n type: \"string\",\n description: \"Sessions active after this date, YYYY-MM-DD (overrides --days)\",\n },\n to: {\n type: \"string\",\n description: \"Sessions active before this date (YYYY-MM-DD)\",\n },\n session: {\n type: \"string\",\n alias: \"s\",\n description: \"Directly open a specific session (agent://session-id)\",\n },\n json: {\n type: \"boolean\",\n alias: \"j\",\n description: \"Output session index as JSON to stdout (no server)\",\n default: false,\n },\n noOpen: {\n type: \"boolean\",\n description: \"Don't auto-open browser\",\n default: false,\n },\n trace: {\n type: \"boolean\",\n description: \"Show performance trace logs\",\n default: false,\n },\n cache: {\n type: \"boolean\",\n description: \"Use cached scan results if available\",\n default: true,\n },\n \"clear-cache\": {\n type: \"boolean\",\n description: \"Clear scan cache before starting\",\n default: false,\n },\n },\n async run({ args }) {\n const port = parseInt(args.port as string, 10) || 4321;\n const noOpen = args.noOpen as boolean;\n const jsonOnly = args.json as boolean;\n const trace = args.trace as boolean;\n const useCache = args.cache as boolean;\n const clearCache = args[\"clear-cache\"] as boolean;\n\n if (trace) {\n perf.enable();\n }\n\n if (clearCache) {\n const { clearCache: clear } = await import(\"@codesesh/core\");\n clear();\n console.log(\"Cache cleared.\");\n }\n\n // Parse session URI if provided\n let targetSession: { agent: string; sessionId: string } | null = null;\n if (args.session) {\n targetSession = parseSessionUri(args.session as string);\n if (!targetSession) {\n console.error(`Invalid session format: ${args.session}. Expected: agent://session-id`);\n process.exit(1);\n }\n }\n\n // Resolve cwd filter: '.' => process.cwd()\n let cwdFilter = args.cwd as string | undefined;\n if (cwdFilter === \".\") {\n cwdFilter = process.cwd();\n }\n\n // Resolve app-level default window (shared across /api/agents, /sessions, /dashboard).\n // Priority: --from (absolute) over --days (relative).\n let listDefaultFrom: number | undefined;\n let listDefaultDays: number | undefined;\n if (args.from) {\n listDefaultFrom = parseDateToTimestamp(args.from as string);\n } else {\n const days = parseInt(args.days as string, 10);\n if (!Number.isNaN(days) && days > 0) {\n listDefaultFrom = Date.now() - days * 24 * 60 * 60 * 1000;\n listDefaultDays = days;\n }\n }\n const listDefaultTo = args.to ? parseDateToTimestamp(args.to as string) : undefined;\n\n // Build scan options (no time slicing — Dashboard needs full history)\n const scanOptions: ScanOptions = {\n agents: targetSession\n ? [targetSession.agent]\n : args.agent\n ? (args.agent as string).split(\",\").map((a) => a.trim())\n : undefined,\n cwd: cwdFilter,\n useCache: useCache,\n };\n\n const store = new LiveScanStore(!jsonOnly, scanOptions);\n await store.initialize();\n const result = store.getSnapshot();\n\n if (trace) {\n console.log(perf.getReport());\n }\n\n if (jsonOnly) {\n // Apply --days/--from/--to window to the JSON output so CLI semantics are preserved.\n const windowed = result.sessions.filter((s) => {\n const activity = s.time_updated ?? s.time_created;\n if (listDefaultFrom != null && activity < listDefaultFrom) return false;\n if (listDefaultTo != null && activity > listDefaultTo) return false;\n return true;\n });\n const info = getAgentInfoMap(\n Object.fromEntries(Object.entries(result.byAgent).map(([k, v]) => [k, v.length])),\n );\n const output = {\n agents: info.map(({ name, displayName, count }) => ({\n name,\n displayName,\n count,\n available: count > 0,\n })),\n sessions: windowed,\n };\n console.log(JSON.stringify(output, null, 2));\n return;\n }\n\n // Print console output\n const agents = createRegisteredAgents();\n printScanResults(agents, result);\n\n // Start server\n let url: string;\n try {\n ({ url } = await createServer(port, store, {\n defaultSessionFrom: listDefaultFrom,\n defaultSessionTo: listDefaultTo,\n defaultSessionDays: listDefaultDays,\n }));\n } catch (error) {\n console.error(getServerStartupErrorMessage(error, port));\n process.exit(1);\n }\n\n console.log(` ${url}`);\n console.log(\"\");\n\n if (!noOpen) {\n const open = (await import(\"open\")).default;\n const targetUrl = targetSession\n ? `${url}/${targetSession.agent.toLowerCase()}/${targetSession.sessionId}`\n : url;\n await open(targetUrl);\n }\n },\n});\n\nif (process.argv.slice(2).includes(\"-v\")) {\n console.log(VERSION);\n process.exit(0);\n}\n\nrunMain(main);\n","import { Hono } from \"hono\";\nimport { serve } from \"@hono/node-server\";\nimport { serveStatic } from \"@hono/node-server/serve-static\";\nimport { logger } from \"hono/logger\";\nimport { existsSync } from \"node:fs\";\nimport type { Server } from \"node:http\";\nimport { resolve, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { ScanResultSource } from \"./api/handlers.js\";\nimport { createApiRoutes, type ApiRouteOptions } from \"./api/routes.js\";\nimport { LiveScanStore } from \"./live-scan.js\";\n\nexport interface CreateServerOptions {\n defaultSessionFrom?: number;\n defaultSessionTo?: number;\n defaultSessionDays?: number;\n}\n\nfunction findWebDistPath(): string | null {\n const __dirname = dirname(fileURLToPath(import.meta.url));\n\n // Priority 1: Packaged web dist (copied during build)\n const packagedPath = resolve(__dirname, \"web\");\n if (existsSync(packagedPath)) {\n return packagedPath;\n }\n\n // Priority 2: Development path (monorepo)\n const devPath = resolve(__dirname, \"../../../apps/web/dist\");\n if (existsSync(devPath)) {\n return devPath;\n }\n\n return null;\n}\n\nfunction waitForListening(server: Server): Promise<void> {\n return new Promise((resolve, reject) => {\n const handleListening = () => {\n server.off(\"error\", handleError);\n resolve();\n };\n const handleError = (error: Error) => {\n server.off(\"listening\", handleListening);\n reject(error);\n };\n\n server.once(\"listening\", handleListening);\n server.once(\"error\", handleError);\n });\n}\n\nexport function getServerStartupErrorMessage(error: unknown, port: number): string {\n if (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n error.code === \"EADDRINUSE\"\n ) {\n return `Port ${port} 已被占用,请关闭现有 CodeSesh 进程或改用 --port 指定其他端口。`;\n }\n\n return error instanceof Error ? error.message : `启动服务器失败: ${String(error)}`;\n}\n\nexport async function createServer(\n port: number,\n store: ScanResultSource & Partial<Pick<LiveScanStore, \"subscribe\" | \"shutdown\">>,\n options: CreateServerOptions = {},\n): Promise<{ url: string; shutdown: () => void }> {\n const app = new Hono();\n\n app.use(\"*\", logger());\n\n // API routes\n const routeOptions: ApiRouteOptions = {\n defaultSessionFrom: options.defaultSessionFrom,\n defaultSessionTo: options.defaultSessionTo,\n defaultSessionDays: options.defaultSessionDays,\n };\n app.route(\n \"/api\",\n createApiRoutes(\n store,\n \"subscribe\" in store ? (store as LiveScanStore) : undefined,\n routeOptions,\n ),\n );\n\n // Serve static files from web dist (if available)\n const webDistPath = findWebDistPath();\n\n if (webDistPath) {\n app.use(\"/*\", serveStatic({ root: webDistPath }));\n app.get(\"/*\", serveStatic({ root: webDistPath, path: \"index.html\" }));\n }\n\n const server = serve({ fetch: app.fetch, port });\n\n try {\n await waitForListening(server);\n } catch (error) {\n server.close();\n if (store.shutdown) {\n await store.shutdown();\n }\n throw new Error(getServerStartupErrorMessage(error, port));\n }\n\n const url = `http://localhost:${port}`;\n\n return {\n url,\n shutdown: () => {\n server.close();\n if (store.shutdown) {\n void store.shutdown();\n }\n },\n };\n}\n","import { Hono } from \"hono\";\nimport {\n handleGetAgents,\n handleGetBookmarks,\n handleGetConfig,\n handleGetDashboard,\n handleDeleteBookmark,\n handleImportBookmarks,\n handleSearchSessions,\n handleGetSessions,\n handleGetSessionData,\n handlePutBookmark,\n type ScanResultSource,\n type SessionListDefaults,\n} from \"./handlers.js\";\nimport type { LiveScanStore } from \"../live-scan.js\";\n\nexport interface ApiRouteOptions {\n defaultSessionFrom?: number;\n defaultSessionTo?: number;\n defaultSessionDays?: number;\n}\n\nfunction createSseResponse(store: LiveScanStore, signal: AbortSignal): Response {\n const encoder = new TextEncoder();\n\n return new Response(\n new ReadableStream({\n start(controller) {\n const write = (event: string, data: unknown) => {\n controller.enqueue(encoder.encode(`event: ${event}\\n`));\n controller.enqueue(encoder.encode(`data: ${JSON.stringify(data)}\\n\\n`));\n };\n\n write(\"connected\", { timestamp: Date.now() });\n\n const unsubscribe = store.subscribe((event) => {\n write(event.type, event);\n });\n\n const heartbeat = setInterval(() => {\n controller.enqueue(encoder.encode(\": keepalive\\n\\n\"));\n }, 15000);\n\n const close = () => {\n clearInterval(heartbeat);\n unsubscribe();\n controller.close();\n };\n\n signal.addEventListener(\"abort\", close, { once: true });\n },\n cancel() {\n return;\n },\n }),\n {\n headers: {\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"Content-Type\": \"text/event-stream\",\n },\n },\n );\n}\n\nexport function createApiRoutes(\n scanSource: ScanResultSource,\n store?: LiveScanStore,\n options: ApiRouteOptions = {},\n): Hono {\n const api = new Hono();\n const listDefaults: SessionListDefaults = {\n from: options.defaultSessionFrom,\n to: options.defaultSessionTo,\n days: options.defaultSessionDays,\n };\n\n api.get(\"/config\", (c) => handleGetConfig(c, listDefaults));\n api.get(\"/agents\", (c) => handleGetAgents(c, scanSource, listDefaults));\n api.get(\"/sessions\", (c) => handleGetSessions(c, scanSource, listDefaults));\n api.get(\"/search\", (c) => handleSearchSessions(c, scanSource, listDefaults));\n api.get(\"/sessions/:agent/:id\", (c) => handleGetSessionData(c, scanSource));\n api.get(\"/dashboard\", (c) => handleGetDashboard(c, scanSource, listDefaults));\n api.get(\"/bookmarks\", (c) => handleGetBookmarks(c));\n api.put(\"/bookmarks\", (c) => handlePutBookmark(c));\n api.post(\"/bookmarks/import\", (c) => handleImportBookmarks(c));\n api.delete(\"/bookmarks/:agent/:id\", (c) => handleDeleteBookmark(c));\n if (store) {\n api.get(\"/events\", (c) => createSseResponse(store, c.req.raw.signal));\n }\n\n return api;\n}\n","import type { Context } from \"hono\";\nimport type { BookmarkRecord, ScanResult, SessionData, SessionHead } from \"@codesesh/core\";\nimport {\n deleteBookmark,\n getAgentInfoMap,\n importBookmarks,\n listBookmarks,\n searchSessions,\n syncSessionSearchIndex,\n upsertBookmark,\n} from \"@codesesh/core\";\n\nexport interface ScanResultSource {\n getSnapshot(): ScanResult;\n}\n\nexport interface SessionListDefaults {\n from?: number;\n to?: number;\n /** When --days was used, original value — kept for UI \"last N days\" label */\n days?: number;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction isSessionStats(value: unknown): value is SessionHead[\"stats\"] {\n if (!isRecord(value)) return false;\n return (\n typeof value.message_count === \"number\" &&\n typeof value.total_input_tokens === \"number\" &&\n typeof value.total_output_tokens === \"number\" &&\n typeof value.total_cost === \"number\" &&\n (value.total_tokens == null || typeof value.total_tokens === \"number\")\n );\n}\n\nfunction parseBookmarkPayload(value: unknown): Omit<BookmarkRecord, \"bookmarked_at\"> | null {\n if (!isRecord(value)) return null;\n if (\n typeof value.agentKey !== \"string\" ||\n typeof value.sessionId !== \"string\" ||\n typeof value.fullPath !== \"string\" ||\n typeof value.title !== \"string\" ||\n typeof value.directory !== \"string\" ||\n typeof value.time_created !== \"number\" ||\n (value.time_updated != null && typeof value.time_updated !== \"number\") ||\n !isSessionStats(value.stats)\n ) {\n return null;\n }\n\n return {\n agentKey: value.agentKey,\n sessionId: value.sessionId,\n fullPath: value.fullPath,\n title: value.title,\n directory: value.directory,\n time_created: value.time_created,\n time_updated: value.time_updated,\n stats: value.stats,\n };\n}\n\nfunction getTotalTokens(stats: SessionHead[\"stats\"]): number {\n return stats.total_tokens ?? stats.total_input_tokens + stats.total_output_tokens;\n}\n\nfunction getSessionActivityTime(session: SessionHead): number {\n return session.time_updated ?? session.time_created;\n}\n\nfunction parseDateParam(\n value: string | undefined,\n fallback: number | undefined,\n): number | undefined {\n if (value == null) return fallback;\n const ts = new Date(value).getTime();\n return Number.isNaN(ts) ? fallback : ts;\n}\n\nfunction filterSessionsByWindow(\n sessions: SessionHead[],\n from: number | undefined,\n to: number | undefined,\n): SessionHead[] {\n return filterSessionsByActivityWindow(sessions, from, to);\n}\n\nfunction filterSessionsByActivityWindow(\n sessions: SessionHead[],\n from: number | undefined,\n to: number | undefined,\n): SessionHead[] {\n if (from == null && to == null) return sessions;\n return sessions.filter((session) => {\n const activity = getSessionActivityTime(session);\n if (from != null && activity < from) return false;\n if (to != null && activity > to) return false;\n return true;\n });\n}\n\nexport function handleGetConfig(c: Context, defaults: SessionListDefaults) {\n return c.json({\n window: {\n from: defaults.from,\n to: defaults.to,\n days: defaults.days,\n },\n });\n}\n\nexport function handleGetAgents(\n c: Context,\n scanSource: ScanResultSource,\n defaults: SessionListDefaults = {},\n) {\n const scanResult = scanSource.getSnapshot();\n const { from, to } = defaults;\n const counts = Object.fromEntries(\n Object.entries(scanResult.byAgent).map(([agentName, sessions]) => [\n agentName,\n filterSessionsByWindow(sessions, from, to).length,\n ]),\n );\n const info = getAgentInfoMap(counts);\n return c.json(info);\n}\n\nexport function handleGetSessions(\n c: Context,\n scanSource: ScanResultSource,\n defaults: SessionListDefaults = {},\n) {\n const scanResult = scanSource.getSnapshot();\n const agent = c.req.query(\"agent\");\n const q = c.req.query(\"q\")?.toLowerCase();\n const cwd = c.req.query(\"cwd\")?.toLowerCase();\n const from = parseDateParam(c.req.query(\"from\"), defaults.from);\n const to = parseDateParam(c.req.query(\"to\"), defaults.to);\n\n let sessions: SessionHead[] = [];\n\n // If agent filter is specified, use byAgent directly\n if (agent && scanResult.byAgent[agent]) {\n sessions = [...scanResult.byAgent[agent]!];\n } else {\n sessions = [...scanResult.sessions];\n }\n\n if (cwd) {\n sessions = sessions.filter((s) => s.directory.toLowerCase().includes(cwd));\n }\n sessions = filterSessionsByActivityWindow(sessions, from, to);\n\n if (q) {\n sessions = sessions.filter((s) => s.title.toLowerCase().includes(q));\n }\n\n return c.json({ sessions });\n}\n\nexport function handleSearchSessions(\n c: Context,\n scanSource: ScanResultSource,\n defaults: SessionListDefaults = {},\n) {\n const query = c.req.query(\"q\")?.trim() ?? \"\";\n if (!query) {\n return c.json({ results: [] });\n }\n\n const scanResult = scanSource.getSnapshot();\n const agent = c.req.query(\"agent\");\n const cwd = c.req.query(\"cwd\");\n const from = parseDateParam(c.req.query(\"from\"), defaults.from);\n const to = parseDateParam(c.req.query(\"to\"), defaults.to);\n\n for (const indexedAgent of scanResult.agents) {\n const sessions = scanResult.byAgent[indexedAgent.name] ?? [];\n syncSessionSearchIndex(indexedAgent.name, sessions, (sessionId) =>\n indexedAgent.getSessionData(sessionId),\n );\n }\n\n const results = searchSessions(query, {\n agent,\n cwd,\n from,\n to,\n limit: 50,\n });\n\n return c.json({ results });\n}\n\nexport async function handleGetSessionData(c: Context, scanSource: ScanResultSource) {\n const scanResult = scanSource.getSnapshot();\n const agentName = c.req.param(\"agent\");\n const sessionId = c.req.param(\"id\");\n\n if (!sessionId) {\n return c.json({ error: \"Missing session ID\" }, 400);\n }\n\n const agent = scanResult.agents.find((a) => a.name === agentName);\n\n if (!agent) {\n return c.json({ error: `Unknown agent: ${agentName}` }, 404);\n }\n\n try {\n const data: SessionData = agent.getSessionData(sessionId);\n return c.json(data);\n } catch (err) {\n const message = err instanceof Error ? err.message : \"Failed to load session\";\n return c.json({ error: message }, 500);\n }\n}\n\nexport function handleGetBookmarks(c: Context) {\n return c.json({ bookmarks: listBookmarks() });\n}\n\nexport async function handlePutBookmark(c: Context) {\n const payload = parseBookmarkPayload(await c.req.json().catch(() => null));\n if (!payload) {\n return c.json({ error: \"Invalid bookmark payload\" }, 400);\n }\n\n return c.json({ bookmark: upsertBookmark(payload) });\n}\n\nexport async function handleImportBookmarks(c: Context) {\n const payload = await c.req.json().catch(() => null);\n if (!Array.isArray(payload)) {\n return c.json({ error: \"Invalid bookmark payload\" }, 400);\n }\n\n const bookmarks = payload\n .map((entry) => parseBookmarkPayload(entry))\n .filter((entry): entry is NonNullable<typeof entry> => entry !== null);\n\n if (bookmarks.length !== payload.length) {\n return c.json({ error: \"Invalid bookmark payload\" }, 400);\n }\n\n return c.json({ bookmarks: importBookmarks(bookmarks) });\n}\n\nexport function handleDeleteBookmark(c: Context) {\n const agentKey = c.req.param(\"agent\");\n const sessionId = c.req.param(\"id\");\n if (!agentKey || !sessionId) {\n return c.json({ error: \"Missing bookmark identifier\" }, 400);\n }\n\n deleteBookmark(agentKey, sessionId);\n return c.json({ ok: true });\n}\n\nexport interface DashboardAgentStat {\n name: string;\n displayName: string;\n icon: string;\n sessions: number;\n messages: number;\n tokens: number;\n}\n\nexport interface DashboardDailyBucket {\n /** Local YYYY-MM-DD */\n date: string;\n sessions: number;\n messages: number;\n}\n\nexport interface DailyTokenBucket {\n date: string;\n input: number;\n output: number;\n cache_read: number;\n cache_create: number;\n}\n\nexport interface ModelDistributionEntry {\n model: string;\n tokens: number;\n sessions: number;\n}\n\nexport interface DashboardTotals {\n sessions: number;\n messages: number;\n tokens: number;\n cost: number;\n latestActivity?: number;\n}\n\nexport interface DashboardRecentSession extends SessionHead {\n agentName: string;\n}\n\nexport interface DashboardData {\n totals: DashboardTotals;\n perAgent: DashboardAgentStat[];\n dailyActivity: DashboardDailyBucket[];\n dailyTokenActivity: DailyTokenBucket[];\n modelDistribution: ModelDistributionEntry[];\n recentSessions: DashboardRecentSession[];\n /** Time window covered by dailyActivity (inclusive, ms) */\n window: { from: number; to: number; days: number };\n}\n\nfunction toLocalDateKey(ts: number): string {\n const d = new Date(ts);\n const year = d.getFullYear();\n const month = `${d.getMonth() + 1}`.padStart(2, \"0\");\n const day = `${d.getDate()}`.padStart(2, \"0\");\n return `${year}-${month}-${day}`;\n}\n\nfunction startOfLocalDay(ts: number): number {\n const d = new Date(ts);\n d.setHours(0, 0, 0, 0);\n return d.getTime();\n}\n\nfunction resolveDashboardWindow(\n defaults: SessionListDefaults,\n queryDays: string | undefined,\n queryFrom: string | undefined,\n queryTo: string | undefined,\n): { from: number; to: number; days: number } {\n const now = Date.now();\n const todayStart = startOfLocalDay(now);\n\n // Query \"to\" wins over defaults, then \"now\" end-of-today as fallback\n const toTs = parseDateParam(queryTo, defaults.to) ?? todayStart + 24 * 60 * 60 * 1000 - 1;\n\n // Resolve days (preferred): query, defaults.days, or derive from defaults.from\n const parsedDays = queryDays ? parseInt(queryDays, 10) : NaN;\n let days: number | undefined =\n Number.isFinite(parsedDays) && parsedDays > 0 ? parsedDays : defaults.days;\n\n const fromFromQuery = parseDateParam(queryFrom, undefined);\n let fromTs: number;\n if (fromFromQuery != null) {\n fromTs = startOfLocalDay(fromFromQuery);\n days ??= Math.max(1, Math.ceil((todayStart - fromTs) / 86400000) + 1);\n } else if (days && days > 0) {\n fromTs = todayStart - (days - 1) * 86400000;\n } else if (defaults.from != null) {\n fromTs = startOfLocalDay(defaults.from);\n days = Math.max(1, Math.ceil((todayStart - fromTs) / 86400000) + 1);\n } else {\n days = 30;\n fromTs = todayStart - (days - 1) * 86400000;\n }\n\n return { from: fromTs, to: toTs, days };\n}\n\nexport function handleGetDashboard(\n c: Context,\n scanSource: ScanResultSource,\n defaults: SessionListDefaults = {},\n) {\n const scanResult = scanSource.getSnapshot();\n const { from, to, days } = resolveDashboardWindow(\n defaults,\n c.req.query(\"days\"),\n c.req.query(\"from\"),\n c.req.query(\"to\"),\n );\n\n const windowed = filterSessionsByActivityWindow(scanResult.sessions, from, to);\n\n const agentInfo = getAgentInfoMap(\n Object.fromEntries(\n Object.entries(scanResult.byAgent).map(([name, sessions]) => [\n name,\n filterSessionsByActivityWindow(sessions, from, to).length,\n ]),\n ),\n );\n const agentInfoMap = new Map(agentInfo.map((a) => [a.name, a]));\n\n let totalMessages = 0;\n let totalTokens = 0;\n let totalCost = 0;\n let latestActivity = 0;\n for (const session of windowed) {\n totalMessages += session.stats.message_count;\n totalTokens += getTotalTokens(session.stats);\n totalCost += session.stats.total_cost ?? 0;\n const activity = getSessionActivityTime(session);\n if (activity > latestActivity) latestActivity = activity;\n }\n\n const perAgent: DashboardAgentStat[] = Object.entries(scanResult.byAgent)\n .map(([name, sessions]) => {\n const info = agentInfoMap.get(name);\n const agentWindowed = filterSessionsByActivityWindow(sessions, from, to);\n let messages = 0;\n let tokens = 0;\n for (const s of agentWindowed) {\n messages += s.stats.message_count;\n tokens += getTotalTokens(s.stats);\n }\n return {\n name,\n displayName: info?.displayName ?? name,\n icon: info?.icon ?? \"\",\n sessions: agentWindowed.length,\n messages,\n tokens,\n };\n })\n .filter((item) => item.sessions > 0)\n .sort((a, b) => b.sessions - a.sessions);\n\n // Daily activity buckets — one bucket per local day in [from, to]\n const dailyMap = new Map<string, DashboardDailyBucket>();\n const dailyTokenMap = new Map<string, DailyTokenBucket>();\n const bucketStart = startOfLocalDay(from);\n for (let i = 0; i < days; i += 1) {\n const ts = bucketStart + i * 86400000;\n const key = toLocalDateKey(ts);\n dailyMap.set(key, { date: key, sessions: 0, messages: 0 });\n dailyTokenMap.set(key, { date: key, input: 0, output: 0, cache_read: 0, cache_create: 0 });\n }\n\n const modelAgg = new Map<string, { tokens: number; sessions: number }>();\n\n for (const session of windowed) {\n const key = toLocalDateKey(getSessionActivityTime(session));\n const bucket = dailyMap.get(key);\n if (bucket) {\n bucket.sessions += 1;\n bucket.messages += session.stats.message_count;\n }\n\n const tokenBucket = dailyTokenMap.get(key);\n if (tokenBucket) {\n const cacheRead = session.stats.total_cache_read_tokens ?? 0;\n const cacheCreate = session.stats.total_cache_create_tokens ?? 0;\n const pureInput = session.stats.total_input_tokens - cacheRead - cacheCreate;\n tokenBucket.input += Math.max(0, pureInput);\n tokenBucket.output += session.stats.total_output_tokens;\n tokenBucket.cache_read += cacheRead;\n tokenBucket.cache_create += cacheCreate;\n }\n\n if (session.model_usage) {\n for (const [model, tokens] of Object.entries(session.model_usage)) {\n const entry = modelAgg.get(model);\n if (entry) {\n entry.tokens += tokens;\n entry.sessions += 1;\n } else {\n modelAgg.set(model, { tokens, sessions: 1 });\n }\n }\n }\n }\n\n const dailyActivity = [...dailyMap.values()];\n const dailyTokenActivity = [...dailyTokenMap.values()];\n\n const modelDistribution: ModelDistributionEntry[] = [...modelAgg.entries()]\n .map(([model, { tokens, sessions: count }]) => ({ model, tokens, sessions: count }))\n .sort((a, b) => b.tokens - a.tokens);\n\n const recentSessions: DashboardRecentSession[] = [...windowed]\n .sort((a, b) => getSessionActivityTime(b) - getSessionActivityTime(a))\n .slice(0, 10)\n .map((session) => {\n const agentKey = session.slug.split(\"/\")[0] ?? \"unknown\";\n return { ...session, agentName: agentKey };\n });\n\n const data: DashboardData = {\n totals: {\n sessions: windowed.length,\n messages: totalMessages,\n tokens: totalTokens,\n cost: totalCost,\n latestActivity: latestActivity || undefined,\n },\n perAgent,\n dailyActivity,\n dailyTokenActivity,\n modelDistribution,\n recentSessions,\n window: { from, to, days },\n };\n\n return c.json(data);\n}\n","import { existsSync } from \"node:fs\";\nimport { dirname, isAbsolute, join } from \"node:path\";\nimport chokidar, { type FSWatcher } from \"chokidar\";\nimport {\n createRegisteredAgents,\n filterSessions,\n getCursorDataPath,\n resolveProviderRoots,\n scanSessions,\n syncSessionSearchIndex,\n saveCachedSessions,\n type BaseAgent,\n type ScanResult,\n type ScanOptions,\n type SessionCacheMeta,\n type SessionHead,\n} from \"@codesesh/core\";\n\nexport interface SessionsUpdatedEvent {\n type: \"sessions-updated\";\n changedAgents: string[];\n newSessions: number;\n updatedSessions: number;\n removedSessions: number;\n totalSessions: number;\n timestamp: number;\n}\n\ntype StoreListener = (event: SessionsUpdatedEvent) => void;\n\ninterface WatchTarget {\n path: string;\n depth?: number;\n}\n\nfunction sortSessions(sessions: SessionHead[]): SessionHead[] {\n return [...sessions].sort(\n (a, b) => (b.time_updated ?? b.time_created) - (a.time_updated ?? a.time_created),\n );\n}\n\nfunction sessionSignature(session: SessionHead): string {\n return JSON.stringify([\n session.title,\n session.directory,\n session.time_created,\n session.time_updated ?? session.time_created,\n session.stats.message_count,\n session.stats.total_input_tokens,\n session.stats.total_output_tokens,\n session.stats.total_cost,\n session.stats.total_tokens ?? 0,\n ]);\n}\n\nfunction buildAgentCacheMeta(agent: BaseAgent): Record<string, SessionCacheMeta> {\n const metaMap = agent.getSessionMetaMap?.();\n const meta: Record<string, SessionCacheMeta> = {};\n if (!metaMap) return meta;\n\n for (const [id, data] of metaMap.entries()) {\n meta[id] = { id, ...(data as Record<string, unknown>) } as SessionCacheMeta;\n }\n\n return meta;\n}\n\nfunction buildUpdateEvent(\n agentName: string,\n previousSessions: SessionHead[],\n nextSessions: SessionHead[],\n): SessionsUpdatedEvent | null {\n const previousMap = new Map(previousSessions.map((session) => [session.id, session]));\n const nextMap = new Map(nextSessions.map((session) => [session.id, session]));\n\n let newSessions = 0;\n let updatedSessions = 0;\n let removedSessions = 0;\n\n for (const [id, session] of nextMap.entries()) {\n const previous = previousMap.get(id);\n if (!previous) {\n newSessions += 1;\n continue;\n }\n if (sessionSignature(previous) !== sessionSignature(session)) {\n updatedSessions += 1;\n }\n }\n\n for (const id of previousMap.keys()) {\n if (!nextMap.has(id)) {\n removedSessions += 1;\n }\n }\n\n if (newSessions === 0 && updatedSessions === 0 && removedSessions === 0) {\n return null;\n }\n\n return {\n type: \"sessions-updated\",\n changedAgents: [agentName],\n newSessions,\n updatedSessions,\n removedSessions,\n totalSessions: nextSessions.length,\n timestamp: Date.now(),\n };\n}\n\nfunction closestWatchablePath(targetPath: string): string | null {\n if (!isAbsolute(targetPath) && !existsSync(targetPath)) {\n return null;\n }\n\n let current = targetPath;\n\n while (!existsSync(current)) {\n const parent = dirname(current);\n if (parent === current) {\n return null;\n }\n current = parent;\n }\n\n return current;\n}\n\nexport function resolveAgentWatchTargets(agentName: string): WatchTarget[] {\n const roots = resolveProviderRoots();\n const cursorDataPath = getCursorDataPath();\n\n switch (agentName) {\n case \"claudecode\":\n return [\n { path: join(roots.claudeRoot, \"projects\"), depth: 2 },\n { path: \"data/claudecode\", depth: 2 },\n ];\n case \"codex\":\n return [{ path: join(roots.codexRoot, \"sessions\"), depth: 4 }];\n case \"cursor\":\n return cursorDataPath\n ? [\n { path: join(cursorDataPath, \"globalStorage\", \"state.vscdb\") },\n { path: join(cursorDataPath, \"workspaceStorage\"), depth: 2 },\n ]\n : [];\n case \"kimi\":\n return [\n { path: join(roots.kimiRoot, \"sessions\"), depth: 2 },\n { path: \"data/kimi\", depth: 2 },\n ];\n case \"opencode\":\n return [\n { path: join(roots.opencodeRoot, \"opencode.db\") },\n { path: \"data/opencode/opencode.db\" },\n ];\n default:\n return [];\n }\n}\n\nexport class LiveScanStore {\n private agents: BaseAgent[] = [];\n private byAgent: Record<string, SessionHead[]> = {};\n private sessions: SessionHead[] = [];\n private listeners = new Set<StoreListener>();\n private refreshTimers = new Map<string, NodeJS.Timeout>();\n private refreshTimestamps = new Map<string, number>();\n private refreshInFlight = new Set<string>();\n private pendingRefreshes = new Set<string>();\n private watchers: FSWatcher[] = [];\n\n constructor(\n private readonly watchEnabled = true,\n private readonly scanOptions: ScanOptions = {},\n ) {}\n\n async initialize(): Promise<void> {\n const initialResult = await scanSessions({\n ...this.scanOptions,\n useCache: true,\n smartRefresh: false,\n });\n const knownAgents = createRegisteredAgents();\n const agentMap = new Map<string, BaseAgent>();\n const allowedAgents = this.getAllowedAgents();\n\n for (const agent of initialResult.agents) {\n agentMap.set(agent.name, agent);\n }\n for (const agent of knownAgents) {\n if (!agentMap.has(agent.name)) {\n agentMap.set(agent.name, agent);\n }\n }\n\n this.agents = [...agentMap.values()].filter((agent) => {\n if (!allowedAgents) {\n return true;\n }\n return allowedAgents.has(agent.name.toLowerCase());\n });\n\n for (const agent of this.agents) {\n this.byAgent[agent.name] = sortSessions(initialResult.byAgent[agent.name] ?? []);\n this.refreshTimestamps.set(agent.name, Date.now());\n }\n\n this.rebuildSessions();\n if (this.watchEnabled) {\n this.startWatching();\n }\n }\n\n getSnapshot(): ScanResult {\n return {\n sessions: this.sessions,\n byAgent: this.byAgent,\n agents: this.agents,\n };\n }\n\n subscribe(listener: StoreListener): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n async shutdown(): Promise<void> {\n for (const timer of this.refreshTimers.values()) {\n clearTimeout(timer);\n }\n this.refreshTimers.clear();\n\n await Promise.all(this.watchers.map((watcher) => watcher.close()));\n this.watchers = [];\n }\n\n private emit(event: SessionsUpdatedEvent): void {\n for (const listener of this.listeners) {\n listener(event);\n }\n }\n\n private rebuildSessions(): void {\n this.sessions = sortSessions(Object.values(this.byAgent).flat());\n }\n\n private getAllowedAgents(): Set<string> | null {\n if (!this.scanOptions.agents?.length) {\n return null;\n }\n return new Set(this.scanOptions.agents.map((agent) => agent.toLowerCase()));\n }\n\n private applyFilters(sessions: SessionHead[]): SessionHead[] {\n return filterSessions(sessions, this.scanOptions);\n }\n\n private startWatching(): void {\n for (const agent of this.agents) {\n const rawTargets = resolveAgentWatchTargets(agent.name);\n const watchTargets = rawTargets\n .map((target) => {\n const watchPath = closestWatchablePath(target.path);\n return watchPath ? { ...target, path: watchPath } : null;\n })\n .filter((target): target is WatchTarget => target !== null)\n .filter(\n (target, index, items) =>\n items.findIndex((item) => item.path === target.path && item.depth === target.depth) ===\n index,\n );\n\n if (watchTargets.length === 0) {\n continue;\n }\n\n const watcher = chokidar.watch(\n watchTargets.map((target) => target.path),\n {\n ignoreInitial: true,\n awaitWriteFinish: {\n stabilityThreshold: 250,\n pollInterval: 100,\n },\n depth: watchTargets.reduce(\n (maxDepth, target) => Math.max(maxDepth, target.depth ?? 0),\n 0,\n ),\n },\n );\n\n watcher.on(\"all\", () => {\n this.scheduleRefresh(agent.name);\n });\n watcher.on(\"error\", (error) => {\n console.error(`[${agent.name}] File watcher failed:`, error);\n });\n\n this.watchers.push(watcher);\n }\n }\n\n private scheduleRefresh(agentName: string, delayMs = 200): void {\n const existing = this.refreshTimers.get(agentName);\n if (existing) {\n clearTimeout(existing);\n }\n\n const timer = setTimeout(() => {\n this.refreshTimers.delete(agentName);\n void this.refreshAgent(agentName);\n }, delayMs);\n\n this.refreshTimers.set(agentName, timer);\n }\n\n private async refreshAgent(agentName: string): Promise<void> {\n if (this.refreshInFlight.has(agentName)) {\n this.pendingRefreshes.add(agentName);\n return;\n }\n\n this.refreshInFlight.add(agentName);\n\n try {\n await this.runRefresh(agentName);\n } finally {\n this.refreshInFlight.delete(agentName);\n\n if (this.pendingRefreshes.delete(agentName)) {\n this.scheduleRefresh(agentName, 100);\n }\n }\n }\n\n private async runRefresh(agentName: string): Promise<void> {\n const agent = this.agents.find((item) => item.name === agentName);\n if (!agent) {\n return;\n }\n\n const previousSessions = this.byAgent[agentName] ?? [];\n let nextSessions = previousSessions;\n\n if (!agent.isAvailable()) {\n nextSessions = [];\n this.refreshTimestamps.set(agentName, Date.now());\n } else if (previousSessions.length > 0 && agent.checkForChanges && agent.incrementalScan) {\n const checkResult = await Promise.resolve(\n agent.checkForChanges(this.refreshTimestamps.get(agentName) ?? 0, previousSessions),\n );\n\n this.refreshTimestamps.set(agentName, checkResult.timestamp);\n if (!checkResult.hasChanges) {\n return;\n }\n\n nextSessions = await Promise.resolve(\n agent.incrementalScan(previousSessions, checkResult.changedIds ?? []),\n );\n } else {\n nextSessions = await Promise.resolve(agent.scan());\n this.refreshTimestamps.set(agentName, Date.now());\n }\n\n nextSessions = this.applyFilters(nextSessions);\n saveCachedSessions(agentName, nextSessions, buildAgentCacheMeta(agent));\n syncSessionSearchIndex(agentName, nextSessions, (sessionId) => agent.getSessionData(sessionId));\n\n const event = buildUpdateEvent(agentName, previousSessions, nextSessions);\n this.byAgent[agentName] = sortSessions(nextSessions);\n this.rebuildSessions();\n\n if (event) {\n event.totalSessions = this.sessions.length;\n this.emit(event);\n }\n }\n}\n","import { consola } from \"consola\";\nimport type { BaseAgent } from \"@codesesh/core\";\nimport type { ScanResult } from \"@codesesh/core\";\nimport { VERSION } from \"./version.js\";\n\nexport function printScanResults(agents: BaseAgent[], result: ScanResult): void {\n consola.log(\"\");\n consola.box({\n title: \"CodeSesh\",\n message: `v${VERSION} • ${result.sessions.length} sessions discovered`,\n style: {\n padding: 1,\n borderColor: \"cyan\",\n },\n });\n consola.log(\"\");\n\n const rows: string[] = [];\n let availableCount = 0;\n\n for (const agent of agents) {\n const sessions = result.byAgent[agent.name];\n const count = sessions?.length ?? 0;\n if (count > 0) {\n availableCount++;\n rows.push(` ${green(\"✔\")} ${pad(agent.displayName)} ${dim(`${count} sessions`)}`);\n } else {\n rows.push(` ${dim(\"✖\")} ${pad(agent.displayName)} ${dim(\"not found\")}`);\n }\n }\n\n consola.log(rows.join(\"\\n\"));\n consola.log(\"\");\n consola.info(`Active: ${availableCount}/${agents.length} agents`);\n consola.log(\"\");\n}\n\nfunction pad(text: string, length = 16): string {\n return text.padEnd(length);\n}\n\nfunction green(text: string): string {\n return `\\x1b[32m${text}\\x1b[0m`;\n}\n\nfunction dim(text: string): string {\n return `\\x1b[2m${text}\\x1b[0m`;\n}\n","import { readFileSync } from \"node:fs\";\nimport { resolve, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst pkg = JSON.parse(readFileSync(resolve(__dirname, \"../package.json\"), \"utf-8\"));\n\nexport const VERSION = pkg.version;\n"],"mappings":"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","names":["Hono","__dirname","resolve","Hono","existsSync","dirname","existsSync","dirname","resolve","dirname","fileURLToPath"]}
|