@@ -31,7 +31,7 @@ describe("memory manager self-heal missing identity with FTS-only chunks", () =>
3131 let caseId = 0 ;
3232 let workspaceDir = "" ;
3333 let indexPath = "" ;
34- let manager : MemoryIndexManager | null = null ;
34+ let managers : MemoryIndexManager [ ] = [ ] ;
3535
3636 function indexIdentityStatus ( memoryManager : MemoryIndexManager ) : string | undefined {
3737 const identity = memoryManager . status ( ) . custom ?. indexIdentity as
@@ -54,10 +54,10 @@ describe("memory manager self-heal missing identity with FTS-only chunks", () =>
5454 } ) ;
5555
5656 afterEach ( async ( ) => {
57- if ( manager ) {
58- await manager . close ( ) ;
59- manager = null ;
57+ for ( const activeManager of managers . toReversed ( ) ) {
58+ await activeManager . close ( ) ;
6059 }
60+ managers = [ ] ;
6161 await closeAllMemorySearchManagers ( ) ;
6262 vi . unstubAllEnvs ( ) ;
6363 } ) ;
@@ -70,7 +70,11 @@ describe("memory manager self-heal missing identity with FTS-only chunks", () =>
7070 } ) ;
7171
7272 async function createManager (
73- params : { provider ?: string ; vectorEnabled ?: boolean } = { } ,
73+ params : {
74+ provider ?: string ;
75+ vectorEnabled ?: boolean ;
76+ purpose ?: "default" | "status" | "cli" ;
77+ } = { } ,
7478 ) : Promise < MemoryIndexManager > {
7579 const store =
7680 params . vectorEnabled === undefined
@@ -92,12 +96,17 @@ describe("memory manager self-heal missing identity with FTS-only chunks", () =>
9296 list : [ { id : "main" , default : true } ] ,
9397 } ,
9498 } as OpenClawConfig ;
95- const result = await getMemorySearchManager ( { cfg, agentId : "main" } ) ;
99+ const result = await getMemorySearchManager ( {
100+ cfg,
101+ agentId : "main" ,
102+ purpose : params . purpose ,
103+ } ) ;
96104 if ( ! result . manager ) {
97105 throw new Error ( result . error ?? "manager missing" ) ;
98106 }
99- manager = result . manager as unknown as MemoryIndexManager ;
100- return manager ;
107+ const activeManager = result . manager as unknown as MemoryIndexManager ;
108+ managers . push ( activeManager ) ;
109+ return activeManager ;
101110 }
102111
103112 async function seedChunksWithNoMeta ( model = "fts-only" ) : Promise < void > {
@@ -159,4 +168,30 @@ describe("memory manager self-heal missing identity with FTS-only chunks", () =>
159168 expect ( statusAfter . chunks ) . toBe ( 1 ) ;
160169 expect ( statusAfter . dirty ) . toBe ( true ) ;
161170 } ) ;
171+
172+ it ( "observes a separate CLI reindex without reopening the live gateway manager" , async ( ) => {
173+ const liveManager = await createManager ( { provider : "none" , vectorEnabled : false } ) ;
174+ await liveManager . sync ( { reason : "test" , force : true } ) ;
175+ (
176+ liveManager as unknown as {
177+ db : { exec : ( sql : string ) => void } ;
178+ }
179+ ) . db . exec ( `DELETE FROM memory_index_meta WHERE key = 'memory_index_meta_v1'` ) ;
180+ expect ( indexIdentityStatus ( liveManager ) ) . toBe ( "missing" ) ;
181+
182+ await fs . writeFile (
183+ path . join ( workspaceDir , "MEMORY.md" ) ,
184+ "Beta topic\n\nKeep this repaired note." ,
185+ ) ;
186+ const cliManager = await createManager ( {
187+ provider : "none" ,
188+ vectorEnabled : false ,
189+ purpose : "cli" ,
190+ } ) ;
191+ await cliManager . sync ( { reason : "cli" , force : true } ) ;
192+
193+ expect ( indexIdentityStatus ( liveManager ) ) . toBe ( "valid" ) ;
194+ const results = await liveManager . search ( "beta repaired" ) ;
195+ expect ( results . some ( ( result ) => result . snippet . includes ( "Beta topic" ) ) ) . toBe ( true ) ;
196+ } ) ;
162197} ) ;
0 commit comments