@@ -4,7 +4,12 @@ import path from 'path';
44import os from 'os' ;
55import { CodebaseIndexer } from '../src/core/indexer.js' ;
66import { readManifest } from '../src/core/manifest.js' ;
7- import { CODEBASE_CONTEXT_DIRNAME , MANIFEST_FILENAME , KEYWORD_INDEX_FILENAME } from '../src/constants/codebase-context.js' ;
7+ import {
8+ CODEBASE_CONTEXT_DIRNAME ,
9+ MANIFEST_FILENAME ,
10+ KEYWORD_INDEX_FILENAME ,
11+ INDEXING_STATS_FILENAME
12+ } from '../src/constants/codebase-context.js' ;
813
914describe ( 'Incremental Indexing' , ( ) => {
1015 let tempDir : string ;
@@ -68,35 +73,41 @@ describe('Incremental Indexing', () => {
6873
6974 it ( 'should preserve indexedFiles and totalChunks in short-circuit (nothing changed)' , async ( ) => {
7075 // Use files substantial enough to produce chunks
71- await fs . writeFile ( path . join ( tempDir , 'service.ts' ) , [
72- 'import { Injectable } from "@angular/core";' ,
73- '' ,
74- '@Injectable({ providedIn: "root" })' ,
75- 'export class UserService {' ,
76- ' private users: string[] = [];' ,
77- '' ,
78- ' getUsers(): string[] {' ,
79- ' return this.users;' ,
80- ' }' ,
81- '' ,
82- ' addUser(name: string): void {' ,
83- ' this.users.push(name);' ,
84- ' }' ,
85- '}'
86- ] . join ( '\n' ) ) ;
87- await fs . writeFile ( path . join ( tempDir , 'utils.ts' ) , [
88- 'export function formatDate(date: Date): string {' ,
89- ' return date.toISOString().split("T")[0];' ,
90- '}' ,
91- '' ,
92- 'export function capitalize(str: string): string {' ,
93- ' return str.charAt(0).toUpperCase() + str.slice(1);' ,
94- '}' ,
95- '' ,
96- 'export function range(n: number): number[] {' ,
97- ' return Array.from({ length: n }, (_, i) => i);' ,
98- '}'
99- ] . join ( '\n' ) ) ;
76+ await fs . writeFile (
77+ path . join ( tempDir , 'service.ts' ) ,
78+ [
79+ 'import { Injectable } from "@angular/core";' ,
80+ '' ,
81+ '@Injectable({ providedIn: "root" })' ,
82+ 'export class UserService {' ,
83+ ' private users: string[] = [];' ,
84+ '' ,
85+ ' getUsers(): string[] {' ,
86+ ' return this.users;' ,
87+ ' }' ,
88+ '' ,
89+ ' addUser(name: string): void {' ,
90+ ' this.users.push(name);' ,
91+ ' }' ,
92+ '}'
93+ ] . join ( '\n' )
94+ ) ;
95+ await fs . writeFile (
96+ path . join ( tempDir , 'utils.ts' ) ,
97+ [
98+ 'export function formatDate(date: Date): string {' ,
99+ ' return date.toISOString().split("T")[0];' ,
100+ '}' ,
101+ '' ,
102+ 'export function capitalize(str: string): string {' ,
103+ ' return str.charAt(0).toUpperCase() + str.slice(1);' ,
104+ '}' ,
105+ '' ,
106+ 'export function range(n: number): number[] {' ,
107+ ' return Array.from({ length: n }, (_, i) => i);' ,
108+ '}'
109+ ] . join ( '\n' )
110+ ) ;
100111
101112 // Full index first
102113 const indexer1 = new CodebaseIndexer ( {
@@ -119,6 +130,43 @@ describe('Incremental Indexing', () => {
119130 expect ( incStats . totalFiles ) . toBe ( fullStats . totalFiles ) ;
120131 } ) ;
121132
133+ it ( 'should prefer persisted stats over keyword index in no-op incremental runs' , async ( ) => {
134+ await fs . writeFile ( path . join ( tempDir , 'index.ts' ) , 'export const x = 1;' ) ;
135+
136+ const fullIndexer = new CodebaseIndexer ( {
137+ rootPath : tempDir ,
138+ config : { skipEmbedding : true }
139+ } ) ;
140+ await fullIndexer . index ( ) ;
141+
142+ const contextDir = path . join ( tempDir , CODEBASE_CONTEXT_DIRNAME ) ;
143+ await fs . writeFile (
144+ path . join ( contextDir , INDEXING_STATS_FILENAME ) ,
145+ JSON . stringify (
146+ {
147+ indexedFiles : 77 ,
148+ totalChunks : 1234 ,
149+ totalFiles : 88 ,
150+ generatedAt : new Date ( ) . toISOString ( )
151+ } ,
152+ null ,
153+ 2
154+ )
155+ ) ;
156+ await fs . writeFile ( path . join ( contextDir , KEYWORD_INDEX_FILENAME ) , JSON . stringify ( [ ] ) ) ;
157+
158+ const incIndexer = new CodebaseIndexer ( {
159+ rootPath : tempDir ,
160+ config : { skipEmbedding : true } ,
161+ incrementalOnly : true
162+ } ) ;
163+ const stats = await incIndexer . index ( ) ;
164+
165+ expect ( stats . indexedFiles ) . toBe ( 77 ) ;
166+ expect ( stats . totalChunks ) . toBe ( 1234 ) ;
167+ expect ( stats . totalFiles ) . toBe ( 1 ) ;
168+ } ) ;
169+
122170 it ( 'should detect changed files in incremental mode' , async ( ) => {
123171 await fs . writeFile ( path . join ( tempDir , 'index.ts' ) , 'export const x = 1;' ) ;
124172
@@ -155,7 +203,10 @@ describe('Incremental Indexing', () => {
155203 await indexer1 . index ( ) ;
156204
157205 // Add a new file
158- await fs . writeFile ( path . join ( tempDir , 'utils.ts' ) , 'export function add(a: number, b: number) { return a + b; }' ) ;
206+ await fs . writeFile (
207+ path . join ( tempDir , 'utils.ts' ) ,
208+ 'export function add(a: number, b: number) { return a + b; }'
209+ ) ;
159210
160211 // Incremental index
161212 const indexer2 = new CodebaseIndexer ( {
0 commit comments