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/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
- loadCachedSessionData,
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-NBCLV4CX.js";
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 as existsSync2 } from "fs";
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
- return executeSessionSearch(
323
- "",
324
- { ...search.options, limit: Math.max(scanResult.sessions.length, 1) },
325
- scanResult
326
- ).flatMap((result) => {
327
- const alias = aliases.get(getSessionAliasKey(result.agentName, result.session.id));
328
- if (!alias || !alias.toLowerCase().includes(needle)) return [];
329
- return [
330
- {
331
- agentName: result.agentName,
332
- session: withDisplayTitle(result.session, result.agentName, aliases),
333
- snippet: `Alias \xB7 ${result.session.directory}`,
334
- matchType: "title"
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 cachedData = loadCachedSessionData(agentName, sessionId);
529
+ const cachedEntry = loadCachedSessionDataEntry(agentName, sessionId);
530
+ const cachedData = cachedEntry?.data ?? null;
660
531
  const cachedMessageCount = cachedData?.stats.message_count ?? 0;
661
- const cacheHasExpectedMessages = cachedData !== null && (cachedData.messages.length > 0 || cachedMessageCount === 0);
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 (existsSync2(packagedPath)) {
872
+ if (existsSync(packagedPath)) {
1001
873
  return packagedPath;
1002
874
  }
1003
875
  const devPath = resolve(__dirname2, "../../../apps/web/dist");
1004
- if (existsSync2(devPath)) {
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 existsSync5 } from "fs";
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 existsSync3 } from "fs";
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:" && !existsSync3(fileURLToPath2(workerUrl))) return null;
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(agent.incrementalScan(baseline, checkResult.changedIds ?? []))
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 existsSync4, readdirSync as readdirSync2, statSync as statSync2, watch } from "fs";
2231
- import { dirname as dirname2, isAbsolute, join as join2, relative, resolve as resolve2 } from "path";
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) && !existsSync4(targetPath)) {
2117
+ if (!isAbsolute(targetPath) && !existsSync3(targetPath)) {
2239
2118
  return null;
2240
2119
  }
2241
2120
  let current = toAbsolutePath(targetPath);
2242
- while (!existsSync4(current)) {
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 = statSync2(path);
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 : join2(watchPath, 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: join2(roots.claudeRoot, "projects") },
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: join2(roots.codexRoot, "sessions") },
2303
- { path: join2(roots.codexRoot, "session_index.jsonl") }
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: join2(roots.piRoot, "agent", "sessions") },
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: join2(cursorDataPath, "globalStorage", "state.vscdb")
2193
+ path: join(cursorDataPath, "globalStorage", "state.vscdb")
2315
2194
  },
2316
- { root: cursorDataPath, path: join2(cursorDataPath, "workspaceStorage") }
2195
+ { root: cursorDataPath, path: join(cursorDataPath, "workspaceStorage") }
2317
2196
  ] : [];
2318
2197
  case "kimi":
2319
2198
  return [
2320
- { root: roots.kimiRoot, path: join2(roots.kimiRoot, "sessions") },
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: join2(roots.opencodeRoot, "opencode.db") },
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: join2(roots.zcodeRoot, "cli", "db", "db.sqlite") }] : [];
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 readdirSync2(dirPath, { withFileTypes: true })) {
2319
+ for (const entry of readdirSync(dirPath, { withFileTypes: true })) {
2441
2320
  if (entry.isDirectory()) {
2442
- pending.push(join2(dirPath, entry.name));
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 (statSync2(path).isDirectory()) {
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 = statSync2(path);
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:" && !existsSync5(fileURLToPath3(workerUrl))) return null;
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/ports.ts
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 appendStartupPath(startupUrl, path) {
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 = path;
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-5356XOFP.js");
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
- let cwdFilter = args.cwd;
3003
- if (cwdFilter === ".") {
3004
- cwdFilter = process.cwd();
3005
- }
3006
- const {
3007
- from: listDefaultFrom,
3008
- to: listDefaultTo,
3009
- days: listDefaultDays
3010
- } = resolveTimeWindow({
3011
- mode: "cli",
3012
- from: args.from,
3013
- to: args.to,
3014
- days: args.days
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 = targetSession ? appendStartupPath(url, `/${targetSession.agent.toLowerCase()}/${targetSession.sessionId}`) : url;
3003
+ const targetUrl = resolveStartupUrl(url, targetSession);
3112
3004
  appLogger.info("browser.open", { url: redactStartupUrl(targetUrl) });
3113
3005
  await open(targetUrl);
3114
3006
  }