Merge pull request #55 from proxikal/fix/perf-regression-agent-configs-and-search-stat

fix: resolve performance regression in transcript loading and session search
This commit is contained in:
matt 2026-02-22 19:32:13 +09:00 committed by GitHub
commit 94a6599acc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 31 additions and 14 deletions

View file

@ -43,11 +43,25 @@ export class LocalFileSystemProvider implements FileSystemProvider {
async readdir(dirPath: string): Promise<FsDirent[]> {
const entries = await fs.promises.readdir(dirPath, { withFileTypes: true });
return entries.map((entry) => ({
name: entry.name,
isFile: () => entry.isFile(),
isDirectory: () => entry.isDirectory(),
}));
// Stat all entries concurrently to populate mtimeMs, used by SessionSearcher's
// mtime-based cache invalidation. Failures are silently ignored (mtimeMs stays undefined).
return Promise.all(
entries.map(async (entry) => {
let mtimeMs: number | undefined;
try {
const stat = await fs.promises.stat(`${dirPath}/${entry.name}`);
mtimeMs = stat.mtimeMs;
} catch {
// ignore
}
return {
name: entry.name,
mtimeMs,
isFile: () => entry.isFile(),
isDirectory: () => entry.isDirectory(),
};
})
);
}
createReadStream(filePath: string, opts?: ReadStreamOptions): fs.ReadStream {

View file

@ -197,16 +197,19 @@ export const createSessionDetailSlice: StateCreator<AppState, [], [], SessionDet
let claudeMdStats: Map<string, ClaudeMdStats> | null = null;
let contextStats: Map<string, ContextStats> | null = null;
let phaseInfo: ContextPhaseInfo | null = null;
// Fetch agent configs from .claude/agents/ (only when project changes)
// Fetch agent configs from .claude/agents/ (only when project changes).
// Fire-and-forget: don't block transcript rendering — color badges update async.
if (connectionMode !== 'ssh' && projectRoot && projectRoot !== agentConfigsCachedForProject) {
try {
const configs = await api.readAgentConfigs(projectRoot);
if (requestGeneration !== sessionDetailFetchGeneration) return;
agentConfigsCachedForProject = projectRoot;
set({ agentConfigs: configs });
} catch (err) {
logger.error('Failed to read agent configs:', err);
}
agentConfigsCachedForProject = projectRoot; // Optimistic set to prevent duplicate fetches
api
.readAgentConfigs(projectRoot)
.then((configs) => {
set({ agentConfigs: configs });
})
.catch((err) => {
logger.error('Failed to read agent configs:', err);
agentConfigsCachedForProject = ''; // Reset so it retries next time
});
}
if (connectionMode !== 'ssh' && conversation?.items) {