diff --git a/lib/storage.ts b/lib/storage.ts index 28d1b439..1440ff57 100644 --- a/lib/storage.ts +++ b/lib/storage.ts @@ -43,6 +43,10 @@ import { migrateV1ToV3, type RateLimitStateV3, } from "./storage/migrations.js"; +import { + getStoragePathState, + setStoragePathState, +} from "./storage/path-state.js"; import { findProjectRoot, getConfigDir, @@ -345,31 +349,6 @@ async function ensureGitignore(storagePath: string): Promise { } } -type StoragePathState = { - currentStoragePath: string | null; - currentLegacyProjectStoragePath: string | null; - currentLegacyWorktreeStoragePath: string | null; - currentProjectRoot: string | null; -}; - -let currentStorageState: StoragePathState = { - currentStoragePath: null, - currentLegacyProjectStoragePath: null, - currentLegacyWorktreeStoragePath: null, - currentProjectRoot: null, -}; - -const storagePathStateContext = new AsyncLocalStorage(); - -function getStoragePathState(): StoragePathState { - return storagePathStateContext.getStore() ?? currentStorageState; -} - -function setStoragePathState(state: StoragePathState): void { - currentStorageState = state; - storagePathStateContext.enterWith(state); -} - export function setStorageBackupEnabled(enabled: boolean): void { storageBackupEnabled = enabled; } diff --git a/lib/storage/path-state.ts b/lib/storage/path-state.ts new file mode 100644 index 00000000..d0ebb8f4 --- /dev/null +++ b/lib/storage/path-state.ts @@ -0,0 +1,30 @@ +import { AsyncLocalStorage } from "node:async_hooks"; + +export type StoragePathState = { + currentStoragePath: string | null; + currentLegacyProjectStoragePath: string | null; + currentLegacyWorktreeStoragePath: string | null; + currentProjectRoot: string | null; +}; + +const storagePathStateContext = new AsyncLocalStorage(); + +let currentStorageState: StoragePathState = { + currentStoragePath: null, + currentLegacyProjectStoragePath: null, + currentLegacyWorktreeStoragePath: null, + currentProjectRoot: null, +}; + +export function getStoragePathState(): StoragePathState { + // Keep the last synchronously assigned state as a fallback until enterWith() + // has propagated through the current async chain. This is intentionally a + // best-effort bridge for immediate reads; callers should still set state + // before spawning child work and treat AsyncLocalStorage as the source of truth. + return storagePathStateContext.getStore() ?? currentStorageState; +} + +export function setStoragePathState(state: StoragePathState): void { + currentStorageState = state; + storagePathStateContext.enterWith(state); +}