perf: overhaul session loading, caching, and runtime isolation (#2360)

Improve OpenChamber responsiveness under large session workloads while fixing
cache, synchronization, and persistence correctness across runtimes, projects,
directories, and worktrees.

- prioritize selected and visible sessions during bootstrap and defer
  non-critical enrichment work
- reduce redundant message loading, event processing, store publication, and
  hidden sidebar work
- prevent stale session and message requests from overwriting newer
  authoritative state
- preserve existing data when authoritative fetches fail instead of treating
  failures as successful empty responses
- scope session materialization, messages, drafts, queues, todos, pins,
  permissions, folders, tabs, Git state, and pull request data by runtime and
  directory identity
- harden runtime switching, reconnect, cleanup, mutation reconciliation, and
  persisted-state ordering
- preserve live subagent Task linkage when metadata arrives after an older
  message request or while streaming parts are suspended
- coalesce overlapping tail refreshes without losing newer refresh demand
- improve cold-session loading by moving deferrable work out of the critical
  bootstrap path
- isolate URL authentication, mobile credentials, native secrets, and other
  runtime-owned state across endpoint changes
- bound long-lived caches and remove avoidable allocations from event and
  rendering hot paths
- limit virtualization to archive collections where it improves rendering
  without disrupting active sidebar layout
- stabilize session folders, pin ordering, expanded state, and persisted
  sidebar behavior
- open skill files through the same secure editor and outside-workspace grant
  flow used by file navigation, including worktree sessions
- expand regression coverage for stale completions, runtime collisions,
  reconnect behavior, persistence races, authoritative empty results, and
  subagent refresh ordering
- document the updated synchronization, cache ownership, performance, and
  runtime-isolation invariants
This commit is contained in:
Bohdan Triapitsyn
2026-07-21 20:52:20 +03:00
committed by GitHub
parent 485efc7117
commit 85400459e9
197 changed files with 10835 additions and 3400 deletions
+53 -8
View File
@@ -21,6 +21,7 @@ import { runtimeFetch } from "@/lib/runtime-fetch";
import { markStartupTrace, measureStartupTrace } from "@/lib/startupTrace";
import { normalizePath } from "@/lib/pathNormalization";
import { getSyncConfig, subscribeToSyncConfigChanges } from "@/sync/sync-refs";
import { getRuntimeKey } from "@/lib/runtime-switch";
const MODELS_DEV_API_URL = "https://models.dev/api.json";
const MODELS_DEV_PROXY_URL = "/api/openchamber/models-metadata";
@@ -717,18 +718,57 @@ const resolveInitialDirectoryKey = (): string => {
// We cache resolved mappings to localStorage so subsequent launches resolve the
// project synchronously at init time. worktree→project is effectively immutable,
// so a cached entry is safe to trust.
const WORKTREE_PROJECT_MAP_KEY = 'oc.worktreeProjectMap';
let _worktreeProjectMap: Record<string, string> | null = null;
const WORKTREE_PROJECT_MAP_KEY = 'oc.worktreeProjectMap.v2';
const LEGACY_WORKTREE_PROJECT_MAP_KEY = 'oc.worktreeProjectMap';
const MAX_WORKTREE_PROJECT_RUNTIME_MAPS = 8;
type WorktreeProjectMapEnvelope = {
version: 2;
legacyClaimed: boolean;
runtimes: Record<string, { updatedAt: number; entries: Record<string, string> }>;
};
const _worktreeProjectMaps = new Map<string, Record<string, string>>();
const readWorktreeProjectEnvelope = (): WorktreeProjectMapEnvelope => {
try {
const raw = typeof localStorage !== 'undefined' ? localStorage.getItem(WORKTREE_PROJECT_MAP_KEY) : null;
if (!raw) return { version: 2, legacyClaimed: false, runtimes: {} };
const parsed = JSON.parse(raw) as Partial<WorktreeProjectMapEnvelope>;
if (parsed.version !== 2 || !parsed.runtimes || typeof parsed.runtimes !== 'object') {
return { version: 2, legacyClaimed: false, runtimes: {} };
}
return { version: 2, legacyClaimed: parsed.legacyClaimed === true, runtimes: parsed.runtimes };
} catch {
return { version: 2, legacyClaimed: false, runtimes: {} };
}
};
const writeWorktreeProjectEnvelope = (envelope: WorktreeProjectMapEnvelope): void => {
const runtimes = Object.fromEntries(
Object.entries(envelope.runtimes)
.sort(([, left], [, right]) => right.updatedAt - left.updatedAt)
.slice(0, MAX_WORKTREE_PROJECT_RUNTIME_MAPS),
);
localStorage.setItem(WORKTREE_PROJECT_MAP_KEY, JSON.stringify({ ...envelope, runtimes }));
};
const getWorktreeProjectMap = (): Record<string, string> => {
if (_worktreeProjectMap === null) {
const runtimeKey = getRuntimeKey() || 'default';
const existing = _worktreeProjectMaps.get(runtimeKey);
if (existing) return existing;
const envelope = readWorktreeProjectEnvelope();
let map = envelope.runtimes[runtimeKey]?.entries ?? null;
if (!map && !envelope.legacyClaimed) {
try {
const raw = typeof localStorage !== 'undefined' ? localStorage.getItem(WORKTREE_PROJECT_MAP_KEY) : null;
_worktreeProjectMap = raw ? (JSON.parse(raw) as Record<string, string>) : {};
const raw = typeof localStorage !== 'undefined' ? localStorage.getItem(LEGACY_WORKTREE_PROJECT_MAP_KEY) : null;
map = raw ? (JSON.parse(raw) as Record<string, string>) : {};
envelope.legacyClaimed = true;
envelope.runtimes[runtimeKey] = { updatedAt: Date.now(), entries: map };
writeWorktreeProjectEnvelope(envelope);
localStorage.removeItem(LEGACY_WORKTREE_PROJECT_MAP_KEY);
} catch {
_worktreeProjectMap = {};
map = {};
}
}
return _worktreeProjectMap;
const result = map ?? {};
_worktreeProjectMaps.set(runtimeKey, result);
return result;
};
const rememberWorktreeProject = (worktree: string, project: string): void => {
if (!worktree || !project || worktree === project) return;
@@ -736,7 +776,12 @@ const rememberWorktreeProject = (worktree: string, project: string): void => {
if (map[worktree] === project) return;
map[worktree] = project;
try {
localStorage.setItem(WORKTREE_PROJECT_MAP_KEY, JSON.stringify(map));
const runtimeKey = getRuntimeKey() || 'default';
const envelope = readWorktreeProjectEnvelope();
envelope.legacyClaimed = true;
envelope.runtimes[runtimeKey] = { updatedAt: Date.now(), entries: map };
writeWorktreeProjectEnvelope(envelope);
localStorage.removeItem(LEGACY_WORKTREE_PROJECT_MAP_KEY);
} catch {
// localStorage quota exceeded — ignore; live resolution still works.
}