From b241012a31bfccd4b38947b095b3b64154b42259 Mon Sep 17 00:00:00 2001 From: ndycode Date: Sat, 21 Mar 2026 12:10:06 +0800 Subject: [PATCH 1/2] refactor: extract storage path state --- lib/storage.ts | 29 ++++------------------------- lib/storage/path-state.ts | 26 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 25 deletions(-) create mode 100644 lib/storage/path-state.ts 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..6c708d2c --- /dev/null +++ b/lib/storage/path-state.ts @@ -0,0 +1,26 @@ +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 { + return storagePathStateContext.getStore() ?? currentStorageState; +} + +export function setStoragePathState(state: StoragePathState): void { + currentStorageState = state; + storagePathStateContext.enterWith(state); +} From f3604f58d140f993683ebf303e2c578da78c0810 Mon Sep 17 00:00:00 2001 From: ndycode Date: Sat, 21 Mar 2026 12:48:49 +0800 Subject: [PATCH 2/2] docs: clarify storage path fallback semantics --- lib/storage/path-state.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/storage/path-state.ts b/lib/storage/path-state.ts index 6c708d2c..d0ebb8f4 100644 --- a/lib/storage/path-state.ts +++ b/lib/storage/path-state.ts @@ -17,6 +17,10 @@ let currentStorageState: StoragePathState = { }; 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; }