@pixelbyte-software/pixcode 1.54.8 → 1.54.9

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.
@@ -67,9 +67,10 @@ import sessionManager from './sessionManager.js';
67
67
  import { applyCustomSessionNames } from './database/db.js';
68
68
 
69
69
  const FILE_COUNT_LIMIT = 20000;
70
- const FILE_COUNT_CACHE_TTL_MS = 5 * 60 * 1000;
71
- const FILE_COUNT_CACHE_MAX_ENTRIES = 300;
70
+ const FILE_COUNT_CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes — was already set, kept
72
71
  const FILE_COUNT_SCAN_MAX_MS = 2500;
72
+ // Bump cache entry limit so active projects don't get evicted quickly
73
+ const FILE_COUNT_CACHE_MAX_ENTRIES = 500;
73
74
  const CODEX_SESSION_INDEX_TTL_MS = 60 * 1000;
74
75
  const CODEX_SESSION_INDEX_MAX_FILES = 1200;
75
76
  const CODEX_SESSION_INDEX_MAX_DIRS = 2500;
@@ -77,6 +78,7 @@ const CLAUDE_JSONL_LINE_MAX_CHARS = 1024 * 1024;
77
78
  const GEMINI_QWEN_PROJECT_ENTRY_CACHE_TTL_MS = 60 * 1000;
78
79
  const CLI_CHAT_FILE_READ_MAX_BYTES = 2 * 1024 * 1024;
79
80
  const CLI_CHAT_FILES_PER_PROJECT_LIMIT = 150;
81
+ const JSONL_PARSE_MAX_SESSIONS = 200; // stop parsing a file once we have enough session data
80
82
  const FILE_COUNT_IGNORED_DIRECTORIES = new Set([
81
83
  '.cache',
82
84
  '.git',
@@ -920,22 +922,24 @@ async function getSessions(projectName, limit = 5, offset = 0) {
920
922
  return { sessions: [], hasMore: false, total: 0 };
921
923
  }
922
924
 
923
- // Sort files by modification time (newest first)
924
- const filesWithStats = await Promise.all(
925
- jsonlFiles.map(async (file) => {
925
+ // Sort files by modification time (newest first) — limit early to avoid stat'ing all files
926
+ const neededSessionsCount = Math.min(limit + offset, 50); // never need more than 50 visible
927
+ const filesToProcess = Math.min(jsonlFiles.length, Math.max(5, Math.ceil(neededSessionsCount * 1.5)));
928
+ const newestFiles = await Promise.all(
929
+ jsonlFiles.slice(0, filesToProcess).map(async (file) => {
926
930
  const filePath = path.join(projectDir, file);
927
931
  const stats = await fs.stat(filePath);
928
932
  return { file, mtime: stats.mtime };
929
933
  })
930
934
  );
931
- filesWithStats.sort((a, b) => b.mtime - a.mtime);
935
+ newestFiles.sort((a, b) => b.mtime - a.mtime);
932
936
 
933
937
  const allSessions = new Map();
934
938
  const sessionFirstUserMessageIds = new Map();
935
939
 
936
940
  // Collect all sessions and entries from all files
937
941
  let filesScanned = 0;
938
- for (const { file } of filesWithStats) {
942
+ for (const { file } of newestFiles) {
939
943
  filesScanned++;
940
944
  const jsonlFile = path.join(projectDir, file);
941
945
  const result = await parseJsonlSessions(jsonlFile);
@@ -1043,7 +1047,13 @@ async function parseJsonlSessions(filePath) {
1043
1047
  crlfDelay: Infinity
1044
1048
  });
1045
1049
 
1050
+ let linesRead = 0;
1046
1051
  for await (const line of rl) {
1052
+ // Stop early if we already have enough sessions to satisfy typical UI requests.
1053
+ // Full scan still happens for small files; huge files are bounded.
1054
+ if (++linesRead > 5000 && sessions.size >= JSONL_PARSE_MAX_SESSIONS) {
1055
+ break;
1056
+ }
1047
1057
  if (line.trim()) {
1048
1058
  if (line.length > CLAUDE_JSONL_LINE_MAX_CHARS) {
1049
1059
  continue;