codesesh 0.15.0 → 0.16.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 +1 -0
- package/dist/chunk-EWC6IODK.js +166 -0
- package/dist/chunk-EWC6IODK.js.map +1 -0
- package/dist/{chunk-NBCLV4CX.js → chunk-MWSJTNOW.js} +682 -356
- package/dist/chunk-MWSJTNOW.js.map +1 -0
- package/dist/{dist-5356XOFP.js → dist-AIDCOQZO.js} +20 -2
- package/dist/index.js +131 -239
- package/dist/index.js.map +1 -1
- package/dist/scan-refresh-worker.js +2 -1
- package/dist/scan-refresh-worker.js.map +1 -1
- package/dist/search-index-worker.js +11 -2
- package/dist/search-index-worker.js.map +1 -1
- package/dist/smart-tag-worker.js +2 -1
- package/dist/smart-tag-worker.js.map +1 -1
- package/dist/web/assets/index-BpmbwB2_.js +113 -0
- package/dist/web/assets/index-Bxe686Vr.css +2 -0
- package/dist/web/assets/{syntax-C_RLNYQn.js → syntax-mZXQuVcd.js} +1 -1
- package/dist/web/assets/vendor-BVE7Fps8.js +41 -0
- package/dist/web/icon/agent/cursor.svg +1 -12
- package/dist/web/icon/agent/pi.svg +2 -2
- package/dist/web/index.html +55 -4
- package/package.json +1 -1
- package/dist/chunk-NBCLV4CX.js.map +0 -1
- package/dist/web/assets/index-B6p64k_Q.js +0 -113
- package/dist/web/assets/index-DiFr4_5-.css +0 -2
- package/dist/web/assets/vendor-CShgXaOi.js +0 -40
- /package/dist/{dist-5356XOFP.js.map → dist-AIDCOQZO.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
appLogger,
|
|
4
|
+
logSearchIndexSync
|
|
5
|
+
} from "./chunk-EWC6IODK.js";
|
|
2
6
|
import {
|
|
3
7
|
FileSystemSessionSource,
|
|
4
8
|
StateStorageUnavailableError,
|
|
@@ -29,11 +33,12 @@ import {
|
|
|
29
33
|
listFileActivity,
|
|
30
34
|
listSessionAliases,
|
|
31
35
|
listSessionFileActivity,
|
|
32
|
-
|
|
36
|
+
loadCachedSessionDataEntry,
|
|
33
37
|
loadCachedSessions,
|
|
34
38
|
markAgentFullSyncCompleted,
|
|
35
39
|
matchesProjectIdentity,
|
|
36
40
|
matchesProjectScope,
|
|
41
|
+
matchesSessionSearchFilters,
|
|
37
42
|
mergeSearchQueryOptions,
|
|
38
43
|
perf,
|
|
39
44
|
realFs,
|
|
@@ -45,7 +50,7 @@ import {
|
|
|
45
50
|
startOfLocalDay,
|
|
46
51
|
upsertBookmark,
|
|
47
52
|
upsertSessionAlias
|
|
48
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-MWSJTNOW.js";
|
|
49
54
|
|
|
50
55
|
// src/index.ts
|
|
51
56
|
import { defineCommand, runMain } from "citty";
|
|
@@ -53,164 +58,16 @@ import { defineCommand, runMain } from "citty";
|
|
|
53
58
|
// src/server.ts
|
|
54
59
|
import { Hono as Hono2 } from "hono";
|
|
55
60
|
import { bodyLimit } from "hono/body-limit";
|
|
61
|
+
import { compress } from "hono/compress";
|
|
56
62
|
import { serve } from "@hono/node-server";
|
|
57
63
|
import { serveStatic } from "@hono/node-server/serve-static";
|
|
58
|
-
import { existsSync
|
|
64
|
+
import { existsSync } from "fs";
|
|
59
65
|
import { resolve, dirname } from "path";
|
|
60
66
|
import { fileURLToPath } from "url";
|
|
61
67
|
|
|
62
68
|
// src/api/routes.ts
|
|
63
69
|
import { Hono } from "hono";
|
|
64
70
|
|
|
65
|
-
// src/logging.ts
|
|
66
|
-
import {
|
|
67
|
-
appendFileSync,
|
|
68
|
-
existsSync,
|
|
69
|
-
mkdirSync,
|
|
70
|
-
readdirSync,
|
|
71
|
-
renameSync,
|
|
72
|
-
statSync,
|
|
73
|
-
unlinkSync
|
|
74
|
-
} from "fs";
|
|
75
|
-
import { homedir } from "os";
|
|
76
|
-
import { join } from "path";
|
|
77
|
-
var LEVEL_WEIGHT = {
|
|
78
|
-
debug: 10,
|
|
79
|
-
info: 20,
|
|
80
|
-
warn: 30,
|
|
81
|
-
error: 40
|
|
82
|
-
};
|
|
83
|
-
function parseLevel(value) {
|
|
84
|
-
if (value === "debug" || value === "info" || value === "warn" || value === "error") {
|
|
85
|
-
return value;
|
|
86
|
-
}
|
|
87
|
-
return "info";
|
|
88
|
-
}
|
|
89
|
-
function parsePositiveInt(value, fallback) {
|
|
90
|
-
const parsed = Number(value);
|
|
91
|
-
return Number.isFinite(parsed) && parsed > 0 ? Math.floor(parsed) : fallback;
|
|
92
|
-
}
|
|
93
|
-
function getDefaultLogDir() {
|
|
94
|
-
const base = process.env.XDG_CACHE_HOME ?? join(homedir(), ".cache");
|
|
95
|
-
return join(base, "codesesh", "logs");
|
|
96
|
-
}
|
|
97
|
-
function toLogValue(value, depth = 0) {
|
|
98
|
-
if (value == null || typeof value === "string" || typeof value === "number") return value;
|
|
99
|
-
if (typeof value === "boolean") return value;
|
|
100
|
-
if (typeof value === "bigint") return value.toString();
|
|
101
|
-
if (value instanceof Error) {
|
|
102
|
-
return {
|
|
103
|
-
name: value.name,
|
|
104
|
-
message: value.message,
|
|
105
|
-
stack: value.stack
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
if (depth >= 4) return "[truncated]";
|
|
109
|
-
if (Array.isArray(value)) return value.slice(0, 50).map((item) => toLogValue(item, depth + 1));
|
|
110
|
-
if (typeof value === "object") {
|
|
111
|
-
return Object.fromEntries(
|
|
112
|
-
Object.entries(value).map(([key, item]) => [
|
|
113
|
-
key,
|
|
114
|
-
toLogValue(item, depth + 1)
|
|
115
|
-
])
|
|
116
|
-
);
|
|
117
|
-
}
|
|
118
|
-
return String(value);
|
|
119
|
-
}
|
|
120
|
-
function timestampForFile(date = /* @__PURE__ */ new Date()) {
|
|
121
|
-
return date.toISOString().replace(/[:.]/g, "-");
|
|
122
|
-
}
|
|
123
|
-
var AppLogger = class {
|
|
124
|
-
logDir;
|
|
125
|
-
level;
|
|
126
|
-
maxBytes;
|
|
127
|
-
maxFiles;
|
|
128
|
-
currentPath;
|
|
129
|
-
rotationIndex = 0;
|
|
130
|
-
constructor(options = {}) {
|
|
131
|
-
this.logDir = options.logDir ?? process.env.CODESESH_LOG_DIR ?? getDefaultLogDir();
|
|
132
|
-
this.level = options.level ?? parseLevel(process.env.CODESESH_LOG_LEVEL);
|
|
133
|
-
this.maxBytes = options.maxBytes ?? parsePositiveInt(process.env.CODESESH_LOG_MAX_BYTES, 5e6);
|
|
134
|
-
this.maxFiles = options.maxFiles ?? parsePositiveInt(process.env.CODESESH_LOG_MAX_FILES, 5);
|
|
135
|
-
this.currentPath = join(this.logDir, "codesesh.log");
|
|
136
|
-
}
|
|
137
|
-
getLogPath() {
|
|
138
|
-
return this.currentPath;
|
|
139
|
-
}
|
|
140
|
-
debug(event, data = {}) {
|
|
141
|
-
this.write("debug", event, data);
|
|
142
|
-
}
|
|
143
|
-
info(event, data = {}) {
|
|
144
|
-
this.write("info", event, data);
|
|
145
|
-
}
|
|
146
|
-
warn(event, data = {}) {
|
|
147
|
-
this.write("warn", event, data);
|
|
148
|
-
}
|
|
149
|
-
error(event, data = {}) {
|
|
150
|
-
this.write("error", event, data);
|
|
151
|
-
}
|
|
152
|
-
write(level, event, data) {
|
|
153
|
-
if (LEVEL_WEIGHT[level] < LEVEL_WEIGHT[this.level]) return;
|
|
154
|
-
try {
|
|
155
|
-
mkdirSync(this.logDir, { recursive: true });
|
|
156
|
-
const line = `${JSON.stringify({
|
|
157
|
-
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
158
|
-
level,
|
|
159
|
-
event,
|
|
160
|
-
pid: process.pid,
|
|
161
|
-
...toLogValue(data)
|
|
162
|
-
})}
|
|
163
|
-
`;
|
|
164
|
-
this.rotateIfNeeded(Buffer.byteLength(line));
|
|
165
|
-
appendFileSync(this.currentPath, line, "utf8");
|
|
166
|
-
} catch {
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
rotateIfNeeded(nextBytes) {
|
|
170
|
-
if (!existsSync(this.currentPath)) {
|
|
171
|
-
this.removeExpiredLogs();
|
|
172
|
-
return;
|
|
173
|
-
}
|
|
174
|
-
const currentSize = statSync(this.currentPath).size;
|
|
175
|
-
if (currentSize + nextBytes <= this.maxBytes) return;
|
|
176
|
-
this.rotationIndex += 1;
|
|
177
|
-
const rotatedPath = join(
|
|
178
|
-
this.logDir,
|
|
179
|
-
`codesesh-${timestampForFile()}-${process.pid}-${this.rotationIndex}.log`
|
|
180
|
-
);
|
|
181
|
-
renameSync(this.currentPath, rotatedPath);
|
|
182
|
-
this.removeExpiredLogs();
|
|
183
|
-
}
|
|
184
|
-
removeExpiredLogs() {
|
|
185
|
-
const rotated = readdirSync(this.logDir).filter((name) => /^codesesh-.+\.log$/.test(name)).map((name) => {
|
|
186
|
-
const path = join(this.logDir, name);
|
|
187
|
-
return { path, mtimeMs: statSync(path).mtimeMs };
|
|
188
|
-
}).toSorted((a, b) => b.mtimeMs - a.mtimeMs);
|
|
189
|
-
for (const item of rotated.slice(Math.max(0, this.maxFiles - 1))) {
|
|
190
|
-
unlinkSync(item.path);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
};
|
|
194
|
-
var appLogger = new AppLogger();
|
|
195
|
-
function logSearchIndexSync(context, result, data = {}) {
|
|
196
|
-
if (!result || result.mode !== "bulk" || result.rebuildDurationMs == null) {
|
|
197
|
-
return;
|
|
198
|
-
}
|
|
199
|
-
appLogger.info("search_index.sync", {
|
|
200
|
-
context,
|
|
201
|
-
agent: result.agentName,
|
|
202
|
-
mode: result.mode,
|
|
203
|
-
sessions: result.sessions,
|
|
204
|
-
changed: result.changed,
|
|
205
|
-
deleted: result.deleted,
|
|
206
|
-
indexed: result.indexed,
|
|
207
|
-
skipped: result.skipped,
|
|
208
|
-
duration_ms: Math.round(result.durationMs),
|
|
209
|
-
rebuild_duration_ms: Math.round(result.rebuildDurationMs),
|
|
210
|
-
...data
|
|
211
|
-
});
|
|
212
|
-
}
|
|
213
|
-
|
|
214
71
|
// src/time-window-resolution.ts
|
|
215
72
|
var DAY_MS = 24 * 60 * 60 * 1e3;
|
|
216
73
|
var DEFAULT_DASHBOARD_DAYS = 30;
|
|
@@ -275,6 +132,11 @@ function elapsedDays(from, to) {
|
|
|
275
132
|
}
|
|
276
133
|
|
|
277
134
|
// src/api/handlers.ts
|
|
135
|
+
function cacheMatchesCurrentSource(cachedMeta, currentMeta) {
|
|
136
|
+
const currentFingerprint = currentMeta?.sourceFingerprint;
|
|
137
|
+
if (typeof currentFingerprint !== "string") return true;
|
|
138
|
+
return cachedMeta?.sourceFingerprint === currentFingerprint;
|
|
139
|
+
}
|
|
278
140
|
function getSessionAliasKey(agentKey, sessionId) {
|
|
279
141
|
return `${agentKey.toLowerCase()}\0${sessionId}`;
|
|
280
142
|
}
|
|
@@ -315,26 +177,34 @@ function withFileActivityDisplayTitle(activity, aliases) {
|
|
|
315
177
|
session: withDisplayTitle(activity.session, activity.agent_name, aliases)
|
|
316
178
|
};
|
|
317
179
|
}
|
|
180
|
+
function findSessionByAliasKey(scanResult, aliasKey) {
|
|
181
|
+
const separatorIndex = aliasKey.indexOf("\0");
|
|
182
|
+
const agentName = aliasKey.slice(0, separatorIndex);
|
|
183
|
+
const sessionId = aliasKey.slice(separatorIndex + 1);
|
|
184
|
+
return scanResult.byAgent[agentName]?.find((session) => session.id === sessionId);
|
|
185
|
+
}
|
|
318
186
|
function findAliasSearchResults(query, options, scanResult, aliases) {
|
|
319
187
|
const search = mergeSearchQueryOptions(query, options);
|
|
320
188
|
const needle = search.text.trim().toLowerCase();
|
|
321
189
|
if (!needle || aliases.size === 0) return [];
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
190
|
+
const projectScope = search.options.cwd ? createProjectScopeMatcher(search.options.cwd) : null;
|
|
191
|
+
const results = [];
|
|
192
|
+
for (const [aliasKey, alias] of aliases) {
|
|
193
|
+
if (!alias.toLowerCase().includes(needle)) continue;
|
|
194
|
+
const session = findSessionByAliasKey(scanResult, aliasKey);
|
|
195
|
+
if (!session) continue;
|
|
196
|
+
const agentName = aliasKey.slice(0, aliasKey.indexOf("\0"));
|
|
197
|
+
if (!matchesSessionSearchFilters(agentName, session, search.options, projectScope)) continue;
|
|
198
|
+
results.push({
|
|
199
|
+
agentName,
|
|
200
|
+
session: withDisplayTitle(session, agentName, aliases),
|
|
201
|
+
snippet: `Alias \xB7 ${session.directory}`,
|
|
202
|
+
matchType: "title"
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
return results.sort(
|
|
206
|
+
(a, b) => getSessionActivityTime(b.session) - getSessionActivityTime(a.session)
|
|
207
|
+
);
|
|
338
208
|
}
|
|
339
209
|
function isRecord(value) {
|
|
340
210
|
return typeof value === "object" && value !== null;
|
|
@@ -656,9 +526,11 @@ async function handleGetSessionData(c, scanSource) {
|
|
|
656
526
|
try {
|
|
657
527
|
const head = scanResult.byAgent[agentName]?.find((item) => item.id === sessionId);
|
|
658
528
|
const loadStartedAt = performance.now();
|
|
659
|
-
const
|
|
529
|
+
const cachedEntry = loadCachedSessionDataEntry(agentName, sessionId);
|
|
530
|
+
const cachedData = cachedEntry?.data ?? null;
|
|
660
531
|
const cachedMessageCount = cachedData?.stats.message_count ?? 0;
|
|
661
|
-
const
|
|
532
|
+
const currentMeta = head ? agent.getSessionMetaMap().get(sessionId) : void 0;
|
|
533
|
+
const cacheHasExpectedMessages = cachedData !== null && cacheMatchesCurrentSource(cachedEntry?.meta ?? null, currentMeta) && (cachedData.messages.length > 0 || cachedMessageCount === 0);
|
|
662
534
|
const data = cacheHasExpectedMessages ? cachedData : head ? agent.getSessionData(sessionId) : null;
|
|
663
535
|
const loadDuration = performance.now() - loadStartedAt;
|
|
664
536
|
if (!data) {
|
|
@@ -997,11 +869,11 @@ var MAX_API_REQUEST_BYTES = 1024 * 1024;
|
|
|
997
869
|
function findWebDistPath() {
|
|
998
870
|
const __dirname2 = dirname(fileURLToPath(import.meta.url));
|
|
999
871
|
const packagedPath = resolve(__dirname2, "web");
|
|
1000
|
-
if (
|
|
872
|
+
if (existsSync(packagedPath)) {
|
|
1001
873
|
return packagedPath;
|
|
1002
874
|
}
|
|
1003
875
|
const devPath = resolve(__dirname2, "../../../apps/web/dist");
|
|
1004
|
-
if (
|
|
876
|
+
if (existsSync(devPath)) {
|
|
1005
877
|
return devPath;
|
|
1006
878
|
}
|
|
1007
879
|
return null;
|
|
@@ -1073,6 +945,7 @@ async function createServer(port, store, options = {}) {
|
|
|
1073
945
|
onError: (c) => c.json({ error: "Request body too large" }, 413)
|
|
1074
946
|
})
|
|
1075
947
|
);
|
|
948
|
+
app.use("/api/*", compress());
|
|
1076
949
|
const routeOptions = {
|
|
1077
950
|
defaultSessionFrom: options.defaultSessionFrom,
|
|
1078
951
|
defaultSessionTo: options.defaultSessionTo,
|
|
@@ -1140,11 +1013,11 @@ async function createServer(port, store, options = {}) {
|
|
|
1140
1013
|
}
|
|
1141
1014
|
|
|
1142
1015
|
// src/live-scan.ts
|
|
1143
|
-
import { existsSync as
|
|
1016
|
+
import { existsSync as existsSync4 } from "fs";
|
|
1144
1017
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
1145
1018
|
|
|
1146
1019
|
// src/search-index-job-runner.ts
|
|
1147
|
-
import { existsSync as
|
|
1020
|
+
import { existsSync as existsSync2 } from "fs";
|
|
1148
1021
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
1149
1022
|
import { Worker } from "worker_threads";
|
|
1150
1023
|
|
|
@@ -1418,7 +1291,7 @@ var SearchIndexJobRunner = class {
|
|
|
1418
1291
|
}
|
|
1419
1292
|
workerUrl() {
|
|
1420
1293
|
const workerUrl = new URL("./search-index-worker.js", import.meta.url);
|
|
1421
|
-
if (workerUrl.protocol === "file:" && !
|
|
1294
|
+
if (workerUrl.protocol === "file:" && !existsSync2(fileURLToPath2(workerUrl))) return null;
|
|
1422
1295
|
return workerUrl;
|
|
1423
1296
|
}
|
|
1424
1297
|
};
|
|
@@ -1612,13 +1485,15 @@ var MAX_ADAPTIVE_REFRESH_DELAY_MS = 3e4;
|
|
|
1612
1485
|
var ADAPTIVE_REFRESH_DELAY_MULTIPLIER = 4;
|
|
1613
1486
|
var SEARCH_INDEX_BULK_PENDING_PATH_THRESHOLD = 100;
|
|
1614
1487
|
var BACKFILL_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
1615
|
-
function buildRefreshDiff(agentName, previousSessions, nextSessions, candidateChangedIds = []) {
|
|
1488
|
+
function buildRefreshDiff(agentName, previousSessions, nextSessions, candidateChangedIds = [], signatureCache) {
|
|
1616
1489
|
const { changes, removedSessionIds, counts } = computeSessionDiff(
|
|
1617
1490
|
previousSessions,
|
|
1618
1491
|
nextSessions,
|
|
1619
1492
|
candidateChangedIds,
|
|
1620
|
-
sessionSignature
|
|
1493
|
+
sessionSignature,
|
|
1494
|
+
signatureCache
|
|
1621
1495
|
);
|
|
1496
|
+
for (const removedId of removedSessionIds) signatureCache?.delete(removedId);
|
|
1622
1497
|
if (counts.new === 0 && counts.updated === 0 && counts.removed === 0) {
|
|
1623
1498
|
return { event: null, changedSessions: changes, removedSessionIds };
|
|
1624
1499
|
}
|
|
@@ -1872,7 +1747,8 @@ var AgentSyncEngine = class {
|
|
|
1872
1747
|
agentName,
|
|
1873
1748
|
previousSessions,
|
|
1874
1749
|
nextSessions,
|
|
1875
|
-
strategyResult.preciseChangedIds ?? []
|
|
1750
|
+
strategyResult.preciseChangedIds ?? [],
|
|
1751
|
+
state.signatureCache
|
|
1876
1752
|
);
|
|
1877
1753
|
const diffDuration = performance.now() - diffStartedAt;
|
|
1878
1754
|
const searchIndexOptions = pendingPathCount >= SEARCH_INDEX_BULK_PENDING_PATH_THRESHOLD ? { isBulk: true } : void 0;
|
|
@@ -1984,7 +1860,9 @@ var AgentSyncEngine = class {
|
|
|
1984
1860
|
const preciseChangedIds = checkResult.changedIds ?? null;
|
|
1985
1861
|
const scanStartedAt = performance.now();
|
|
1986
1862
|
const sessions = attachMissingProjectIdentities(
|
|
1987
|
-
await Promise.resolve(
|
|
1863
|
+
await Promise.resolve(
|
|
1864
|
+
agent.incrementalScan(baseline, checkResult.changedIds ?? [], checkResult.refs)
|
|
1865
|
+
)
|
|
1988
1866
|
);
|
|
1989
1867
|
return this.refreshStrategyResult(sessions, {
|
|
1990
1868
|
preciseChangedIds,
|
|
@@ -2155,7 +2033,8 @@ var AgentSyncEngine = class {
|
|
|
2155
2033
|
hasPendingRerun: false,
|
|
2156
2034
|
lastRefreshAt: 0,
|
|
2157
2035
|
lastRefreshDurationMs: 0,
|
|
2158
|
-
pendingPathCount: 0
|
|
2036
|
+
pendingPathCount: 0,
|
|
2037
|
+
signatureCache: /* @__PURE__ */ new Map()
|
|
2159
2038
|
};
|
|
2160
2039
|
this.refreshStates.set(agentName, state);
|
|
2161
2040
|
return state;
|
|
@@ -2227,19 +2106,19 @@ var AgentSyncEngine = class {
|
|
|
2227
2106
|
};
|
|
2228
2107
|
|
|
2229
2108
|
// src/session-watcher.ts
|
|
2230
|
-
import { existsSync as
|
|
2231
|
-
import { dirname as dirname2, isAbsolute, join
|
|
2109
|
+
import { existsSync as existsSync3, readdirSync, statSync, watch } from "fs";
|
|
2110
|
+
import { dirname as dirname2, isAbsolute, join, relative, resolve as resolve2 } from "path";
|
|
2232
2111
|
var WRITE_STABILITY_THRESHOLD_MS = 250;
|
|
2233
2112
|
var WRITE_STABILITY_POLL_MS = 100;
|
|
2234
2113
|
function toAbsolutePath(path) {
|
|
2235
2114
|
return isAbsolute(path) ? path : resolve2(path);
|
|
2236
2115
|
}
|
|
2237
2116
|
function closestWatchablePath(targetPath) {
|
|
2238
|
-
if (!isAbsolute(targetPath) && !
|
|
2117
|
+
if (!isAbsolute(targetPath) && !existsSync3(targetPath)) {
|
|
2239
2118
|
return null;
|
|
2240
2119
|
}
|
|
2241
2120
|
let current = toAbsolutePath(targetPath);
|
|
2242
|
-
while (!
|
|
2121
|
+
while (!existsSync3(current)) {
|
|
2243
2122
|
const parent = dirname2(current);
|
|
2244
2123
|
if (parent === current) {
|
|
2245
2124
|
return null;
|
|
@@ -2249,7 +2128,7 @@ function closestWatchablePath(targetPath) {
|
|
|
2249
2128
|
return current;
|
|
2250
2129
|
}
|
|
2251
2130
|
function getWatchRoot(path) {
|
|
2252
|
-
const stat =
|
|
2131
|
+
const stat = statSync(path);
|
|
2253
2132
|
return stat.isDirectory() ? path : dirname2(path);
|
|
2254
2133
|
}
|
|
2255
2134
|
function isRecursiveWatchSupported(platform = process.platform, nodeVersion = process.versions.node) {
|
|
@@ -2286,7 +2165,7 @@ function resolveWatchEventPath(watchPath, filename) {
|
|
|
2286
2165
|
if (!filenameText) {
|
|
2287
2166
|
return watchPath;
|
|
2288
2167
|
}
|
|
2289
|
-
return isAbsolute(filenameText) ? filenameText :
|
|
2168
|
+
return isAbsolute(filenameText) ? filenameText : join(watchPath, filenameText);
|
|
2290
2169
|
}
|
|
2291
2170
|
function resolveAgentWatchTargets(agentName) {
|
|
2292
2171
|
const roots = resolveProviderRoots();
|
|
@@ -2294,39 +2173,39 @@ function resolveAgentWatchTargets(agentName) {
|
|
|
2294
2173
|
switch (agentName) {
|
|
2295
2174
|
case "claudecode":
|
|
2296
2175
|
return [
|
|
2297
|
-
{ root: roots.claudeRoot, path:
|
|
2176
|
+
{ root: roots.claudeRoot, path: join(roots.claudeRoot, "projects") },
|
|
2298
2177
|
{ path: "data/claudecode" }
|
|
2299
2178
|
];
|
|
2300
2179
|
case "codex":
|
|
2301
2180
|
return [
|
|
2302
|
-
{ path:
|
|
2303
|
-
{ path:
|
|
2181
|
+
{ path: join(roots.codexRoot, "sessions") },
|
|
2182
|
+
{ path: join(roots.codexRoot, "session_index.jsonl") }
|
|
2304
2183
|
];
|
|
2305
2184
|
case "pi":
|
|
2306
2185
|
return [
|
|
2307
|
-
{ root: roots.piRoot, path:
|
|
2186
|
+
{ root: roots.piRoot, path: join(roots.piRoot, "agent", "sessions") },
|
|
2308
2187
|
{ root: "data/pi", path: "data/pi" }
|
|
2309
2188
|
];
|
|
2310
2189
|
case "cursor":
|
|
2311
2190
|
return cursorDataPath ? [
|
|
2312
2191
|
{
|
|
2313
2192
|
root: cursorDataPath,
|
|
2314
|
-
path:
|
|
2193
|
+
path: join(cursorDataPath, "globalStorage", "state.vscdb")
|
|
2315
2194
|
},
|
|
2316
|
-
{ root: cursorDataPath, path:
|
|
2195
|
+
{ root: cursorDataPath, path: join(cursorDataPath, "workspaceStorage") }
|
|
2317
2196
|
] : [];
|
|
2318
2197
|
case "kimi":
|
|
2319
2198
|
return [
|
|
2320
|
-
{ root: roots.kimiRoot, path:
|
|
2199
|
+
{ root: roots.kimiRoot, path: join(roots.kimiRoot, "sessions") },
|
|
2321
2200
|
{ path: "data/kimi" }
|
|
2322
2201
|
];
|
|
2323
2202
|
case "opencode":
|
|
2324
2203
|
return [
|
|
2325
|
-
{ root: roots.opencodeRoot, path:
|
|
2204
|
+
{ root: roots.opencodeRoot, path: join(roots.opencodeRoot, "opencode.db") },
|
|
2326
2205
|
{ root: "data/opencode", path: "data/opencode/opencode.db" }
|
|
2327
2206
|
];
|
|
2328
2207
|
case "zcode":
|
|
2329
|
-
return roots.zcodeRoot ? [{ root: roots.zcodeRoot, path:
|
|
2208
|
+
return roots.zcodeRoot ? [{ root: roots.zcodeRoot, path: join(roots.zcodeRoot, "cli", "db", "db.sqlite") }] : [];
|
|
2330
2209
|
default:
|
|
2331
2210
|
return [];
|
|
2332
2211
|
}
|
|
@@ -2437,9 +2316,9 @@ var SessionWatcher = class {
|
|
|
2437
2316
|
const dirPath = pending.pop();
|
|
2438
2317
|
this.watchFallbackDirectory(dirPath, scopes);
|
|
2439
2318
|
try {
|
|
2440
|
-
for (const entry of
|
|
2319
|
+
for (const entry of readdirSync(dirPath, { withFileTypes: true })) {
|
|
2441
2320
|
if (entry.isDirectory()) {
|
|
2442
|
-
pending.push(
|
|
2321
|
+
pending.push(join(dirPath, entry.name));
|
|
2443
2322
|
}
|
|
2444
2323
|
}
|
|
2445
2324
|
} catch (error) {
|
|
@@ -2462,7 +2341,7 @@ var SessionWatcher = class {
|
|
|
2462
2341
|
watchNewDirectories(watchPath, filename, scopes) {
|
|
2463
2342
|
const path = resolveWatchEventPath(watchPath, filename);
|
|
2464
2343
|
try {
|
|
2465
|
-
if (
|
|
2344
|
+
if (statSync(path).isDirectory()) {
|
|
2466
2345
|
this.watchDirectoryTree(path, scopes);
|
|
2467
2346
|
}
|
|
2468
2347
|
} catch {
|
|
@@ -2510,7 +2389,7 @@ var SessionWatcher = class {
|
|
|
2510
2389
|
let size;
|
|
2511
2390
|
let mtimeMs;
|
|
2512
2391
|
try {
|
|
2513
|
-
const stat =
|
|
2392
|
+
const stat = statSync(path);
|
|
2514
2393
|
size = stat.size;
|
|
2515
2394
|
mtimeMs = stat.mtimeMs;
|
|
2516
2395
|
} catch {
|
|
@@ -2791,7 +2670,7 @@ var LiveScanStore = class {
|
|
|
2791
2670
|
}
|
|
2792
2671
|
getSmartTagWorkerUrl() {
|
|
2793
2672
|
const workerUrl = new URL("./smart-tag-worker.js", import.meta.url);
|
|
2794
|
-
if (workerUrl.protocol === "file:" && !
|
|
2673
|
+
if (workerUrl.protocol === "file:" && !existsSync4(fileURLToPath3(workerUrl))) return null;
|
|
2795
2674
|
return workerUrl;
|
|
2796
2675
|
}
|
|
2797
2676
|
applyScanResult(result) {
|
|
@@ -2845,29 +2724,32 @@ function printScanResults(agents) {
|
|
|
2845
2724
|
consola.log("");
|
|
2846
2725
|
}
|
|
2847
2726
|
|
|
2848
|
-
// src/
|
|
2849
|
-
var DEFAULT_PORT = 4521;
|
|
2850
|
-
var DEFAULT_PORT_FALLBACK_ATTEMPTS = 20;
|
|
2851
|
-
function parsePort(value) {
|
|
2852
|
-
const port = parseInt(value ?? "", 10);
|
|
2853
|
-
return Number.isNaN(port) ? DEFAULT_PORT : port;
|
|
2854
|
-
}
|
|
2855
|
-
function hasExplicitPortArg(argv) {
|
|
2856
|
-
return argv.some((arg, index) => {
|
|
2857
|
-
if (arg === "--port" || arg === "-p") return index < argv.length - 1;
|
|
2858
|
-
return arg.startsWith("--port=") || /^-p\d+$/.test(arg);
|
|
2859
|
-
});
|
|
2860
|
-
}
|
|
2861
|
-
|
|
2862
|
-
// src/index.ts
|
|
2727
|
+
// src/runtime-plan.ts
|
|
2863
2728
|
function parseSessionUri(uri) {
|
|
2864
2729
|
const match = uri.match(/^([a-z]+):\/\/(.+)$/i);
|
|
2865
2730
|
if (!match) return null;
|
|
2866
2731
|
return { agent: match[1], sessionId: match[2] };
|
|
2867
2732
|
}
|
|
2868
|
-
function
|
|
2733
|
+
function buildCliRuntimePlan(input, environment) {
|
|
2734
|
+
const listWindow = resolveTimeWindow({
|
|
2735
|
+
mode: "cli",
|
|
2736
|
+
from: input.from,
|
|
2737
|
+
to: input.to,
|
|
2738
|
+
days: input.days,
|
|
2739
|
+
now: environment.now
|
|
2740
|
+
});
|
|
2741
|
+
const cwd = input.cwd === "." ? environment.currentWorkingDirectory : input.cwd;
|
|
2742
|
+
const agents = input.targetSession ? [input.targetSession.agent] : input.agent ? input.agent.split(",").map((agent) => agent.trim()) : void 0;
|
|
2743
|
+
return {
|
|
2744
|
+
listWindow,
|
|
2745
|
+
scanOptions: { agents, cwd, useCache: input.useCache },
|
|
2746
|
+
startupScanOptions: input.targetSession || input.jsonOnly ? {} : { from: listWindow.from, to: listWindow.to }
|
|
2747
|
+
};
|
|
2748
|
+
}
|
|
2749
|
+
function resolveStartupUrl(startupUrl, targetSession) {
|
|
2750
|
+
if (!targetSession) return startupUrl;
|
|
2869
2751
|
const url = new URL(startupUrl);
|
|
2870
|
-
url.pathname =
|
|
2752
|
+
url.pathname = `/${targetSession.agent.toLowerCase()}/${targetSession.sessionId}`;
|
|
2871
2753
|
return url.toString();
|
|
2872
2754
|
}
|
|
2873
2755
|
function redactStartupUrl(startupUrl) {
|
|
@@ -2877,6 +2759,22 @@ function redactStartupUrl(startupUrl) {
|
|
|
2877
2759
|
}
|
|
2878
2760
|
return url.toString();
|
|
2879
2761
|
}
|
|
2762
|
+
|
|
2763
|
+
// src/ports.ts
|
|
2764
|
+
var DEFAULT_PORT = 4521;
|
|
2765
|
+
var DEFAULT_PORT_FALLBACK_ATTEMPTS = 20;
|
|
2766
|
+
function parsePort(value) {
|
|
2767
|
+
const port = parseInt(value ?? "", 10);
|
|
2768
|
+
return Number.isNaN(port) ? DEFAULT_PORT : port;
|
|
2769
|
+
}
|
|
2770
|
+
function hasExplicitPortArg(argv) {
|
|
2771
|
+
return argv.some((arg, index) => {
|
|
2772
|
+
if (arg === "--port" || arg === "-p") return index < argv.length - 1;
|
|
2773
|
+
return arg.startsWith("--port=") || /^-p\d+$/.test(arg);
|
|
2774
|
+
});
|
|
2775
|
+
}
|
|
2776
|
+
|
|
2777
|
+
// src/index.ts
|
|
2880
2778
|
var main = defineCommand({
|
|
2881
2779
|
meta: {
|
|
2882
2780
|
name: "codesesh",
|
|
@@ -2985,7 +2883,7 @@ var main = defineCommand({
|
|
|
2985
2883
|
log_path: appLogger.getLogPath()
|
|
2986
2884
|
});
|
|
2987
2885
|
if (clearCache) {
|
|
2988
|
-
const { clearCache: clear } = await import("./dist-
|
|
2886
|
+
const { clearCache: clear } = await import("./dist-AIDCOQZO.js");
|
|
2989
2887
|
clear();
|
|
2990
2888
|
appLogger.info("cache.clear");
|
|
2991
2889
|
console.log("Cache cleared.");
|
|
@@ -2999,26 +2897,20 @@ var main = defineCommand({
|
|
|
2999
2897
|
process.exit(1);
|
|
3000
2898
|
}
|
|
3001
2899
|
}
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
}
|
|
3016
|
-
const scanOptions = {
|
|
3017
|
-
agents: targetSession ? [targetSession.agent] : args.agent ? args.agent.split(",").map((a) => a.trim()) : void 0,
|
|
3018
|
-
cwd: cwdFilter,
|
|
3019
|
-
useCache
|
|
3020
|
-
};
|
|
3021
|
-
const startupScanOptions = targetSession || jsonOnly ? {} : { from: listDefaultFrom, to: listDefaultTo };
|
|
2900
|
+
const { listWindow, scanOptions, startupScanOptions } = buildCliRuntimePlan(
|
|
2901
|
+
{
|
|
2902
|
+
agent: args.agent,
|
|
2903
|
+
cwd: args.cwd,
|
|
2904
|
+
from: args.from,
|
|
2905
|
+
to: args.to,
|
|
2906
|
+
days: args.days,
|
|
2907
|
+
jsonOnly,
|
|
2908
|
+
targetSession,
|
|
2909
|
+
useCache
|
|
2910
|
+
},
|
|
2911
|
+
{ currentWorkingDirectory: process.cwd() }
|
|
2912
|
+
);
|
|
2913
|
+
const { from: listDefaultFrom, to: listDefaultTo, days: listDefaultDays } = listWindow;
|
|
3022
2914
|
const store = new LiveScanStore({
|
|
3023
2915
|
watchEnabled: !jsonOnly,
|
|
3024
2916
|
scanOptions,
|
|
@@ -3108,7 +3000,7 @@ var main = defineCommand({
|
|
|
3108
3000
|
});
|
|
3109
3001
|
if (!noOpen) {
|
|
3110
3002
|
const open = (await import("open")).default;
|
|
3111
|
-
const targetUrl =
|
|
3003
|
+
const targetUrl = resolveStartupUrl(url, targetSession);
|
|
3112
3004
|
appLogger.info("browser.open", { url: redactStartupUrl(targetUrl) });
|
|
3113
3005
|
await open(targetUrl);
|
|
3114
3006
|
}
|