@mcampa/ai-context-cli 0.0.1-beta.05e8984

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,236 @@
1
+ import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
2
+ import { existsSync, mkdirSync, writeFileSync, rmSync } from "fs";
3
+ import { join } from "path";
4
+ import { findConfigFile, loadConfig } from "./config-loader.js";
5
+ // Test directory for temporary files
6
+ const TEST_DIR = join(process.cwd(), ".test-temp");
7
+ // Counter for unique file names to avoid ESM import caching
8
+ let testCounter = 0;
9
+ function getUniqueConfigPath(ext = "js") {
10
+ testCounter++;
11
+ return join(TEST_DIR, `test-config-${testCounter}.${ext}`);
12
+ }
13
+ describe("config-loader", () => {
14
+ beforeEach(() => {
15
+ // Create test directory
16
+ if (!existsSync(TEST_DIR)) {
17
+ mkdirSync(TEST_DIR, { recursive: true });
18
+ }
19
+ });
20
+ afterEach(() => {
21
+ // Clean up test directory
22
+ if (existsSync(TEST_DIR)) {
23
+ rmSync(TEST_DIR, { recursive: true, force: true });
24
+ }
25
+ vi.restoreAllMocks();
26
+ });
27
+ describe("findConfigFile", () => {
28
+ it("should return null when no config file exists", () => {
29
+ const result = findConfigFile(TEST_DIR);
30
+ expect(result).toBeNull();
31
+ });
32
+ it("should find ai-context.config.ts", () => {
33
+ const configPath = join(TEST_DIR, "ai-context.config.ts");
34
+ writeFileSync(configPath, "export default {};");
35
+ const result = findConfigFile(TEST_DIR);
36
+ expect(result).toBe(configPath);
37
+ });
38
+ it("should find ai-context.config.js", () => {
39
+ const configPath = join(TEST_DIR, "ai-context.config.js");
40
+ writeFileSync(configPath, "export default {};");
41
+ const result = findConfigFile(TEST_DIR);
42
+ expect(result).toBe(configPath);
43
+ });
44
+ it("should prefer .ts over .js", () => {
45
+ const tsConfigPath = join(TEST_DIR, "ai-context.config.ts");
46
+ const jsConfigPath = join(TEST_DIR, "ai-context.config.js");
47
+ writeFileSync(tsConfigPath, "export default {};");
48
+ writeFileSync(jsConfigPath, "export default {};");
49
+ const result = findConfigFile(TEST_DIR);
50
+ expect(result).toBe(tsConfigPath);
51
+ });
52
+ });
53
+ describe("loadConfig", () => {
54
+ it("should throw error when no config file found", async () => {
55
+ const originalCwd = process.cwd();
56
+ process.chdir(TEST_DIR);
57
+ try {
58
+ await expect(loadConfig()).rejects.toThrow("No config file found");
59
+ }
60
+ finally {
61
+ process.chdir(originalCwd);
62
+ }
63
+ });
64
+ it("should throw error when specified config file not found", async () => {
65
+ await expect(loadConfig("/nonexistent/config.ts")).rejects.toThrow("Config file not found");
66
+ });
67
+ it("should load and validate a valid JavaScript config", async () => {
68
+ const configPath = getUniqueConfigPath("js");
69
+ const configContent = `
70
+ export default {
71
+ name: "test-project",
72
+ embeddingConfig: {
73
+ apiKey: "test-key",
74
+ model: "text-embedding-3-small",
75
+ },
76
+ vectorDatabaseConfig: {
77
+ address: "localhost:19530",
78
+ },
79
+ };
80
+ `;
81
+ writeFileSync(configPath, configContent);
82
+ const config = await loadConfig(configPath);
83
+ expect(config.name).toBe("test-project");
84
+ expect(config.embeddingConfig?.apiKey).toBe("test-key");
85
+ expect(config.embeddingConfig?.model).toBe("text-embedding-3-small");
86
+ expect(config.vectorDatabaseConfig?.address).toBe("localhost:19530");
87
+ });
88
+ it("should throw error for missing embeddingConfig", async () => {
89
+ const configPath = getUniqueConfigPath("js");
90
+ const configContent = `
91
+ export default {
92
+ vectorDatabaseConfig: {
93
+ address: "localhost:19530",
94
+ },
95
+ };
96
+ `;
97
+ writeFileSync(configPath, configContent);
98
+ await expect(loadConfig(configPath)).rejects.toThrow("Missing required field: embeddingConfig");
99
+ });
100
+ it("should throw error for missing embeddingConfig.apiKey", async () => {
101
+ const configPath = getUniqueConfigPath("js");
102
+ const configContent = `
103
+ export default {
104
+ embeddingConfig: {
105
+ model: "text-embedding-3-small",
106
+ },
107
+ vectorDatabaseConfig: {
108
+ address: "localhost:19530",
109
+ },
110
+ };
111
+ `;
112
+ writeFileSync(configPath, configContent);
113
+ await expect(loadConfig(configPath)).rejects.toThrow("Missing required field: embeddingConfig.apiKey");
114
+ });
115
+ it("should throw error for missing embeddingConfig.model", async () => {
116
+ const configPath = getUniqueConfigPath("js");
117
+ const configContent = `
118
+ export default {
119
+ embeddingConfig: {
120
+ apiKey: "test-key",
121
+ },
122
+ vectorDatabaseConfig: {
123
+ address: "localhost:19530",
124
+ },
125
+ };
126
+ `;
127
+ writeFileSync(configPath, configContent);
128
+ await expect(loadConfig(configPath)).rejects.toThrow("Missing required field: embeddingConfig.model");
129
+ });
130
+ it("should throw error for missing vectorDatabaseConfig", async () => {
131
+ const configPath = getUniqueConfigPath("js");
132
+ const configContent = `
133
+ export default {
134
+ embeddingConfig: {
135
+ apiKey: "test-key",
136
+ model: "text-embedding-3-small",
137
+ },
138
+ };
139
+ `;
140
+ writeFileSync(configPath, configContent);
141
+ await expect(loadConfig(configPath)).rejects.toThrow("Missing required field: vectorDatabaseConfig");
142
+ });
143
+ it("should throw error when vectorDatabaseConfig has neither address nor token", async () => {
144
+ const configPath = getUniqueConfigPath("js");
145
+ const configContent = `
146
+ export default {
147
+ embeddingConfig: {
148
+ apiKey: "test-key",
149
+ model: "text-embedding-3-small",
150
+ },
151
+ vectorDatabaseConfig: {
152
+ ssl: true,
153
+ },
154
+ };
155
+ `;
156
+ writeFileSync(configPath, configContent);
157
+ await expect(loadConfig(configPath)).rejects.toThrow("vectorDatabaseConfig requires either 'address' or 'token' to be set");
158
+ });
159
+ it("should accept config with token instead of address", async () => {
160
+ const configPath = getUniqueConfigPath("js");
161
+ const configContent = `
162
+ export default {
163
+ embeddingConfig: {
164
+ apiKey: "test-key",
165
+ model: "text-embedding-3-small",
166
+ },
167
+ vectorDatabaseConfig: {
168
+ token: "zilliz-token",
169
+ },
170
+ };
171
+ `;
172
+ writeFileSync(configPath, configContent);
173
+ const config = await loadConfig(configPath);
174
+ expect(config.vectorDatabaseConfig?.token).toBe("zilliz-token");
175
+ });
176
+ it("should throw error for invalid supportedExtensions type", async () => {
177
+ const configPath = getUniqueConfigPath("js");
178
+ const configContent = `
179
+ export default {
180
+ embeddingConfig: {
181
+ apiKey: "test-key",
182
+ model: "text-embedding-3-small",
183
+ },
184
+ vectorDatabaseConfig: {
185
+ address: "localhost:19530",
186
+ },
187
+ supportedExtensions: "not-an-array",
188
+ };
189
+ `;
190
+ writeFileSync(configPath, configContent);
191
+ await expect(loadConfig(configPath)).rejects.toThrow("supportedExtensions must be an array of strings");
192
+ });
193
+ it("should throw error for non-string values in supportedExtensions", async () => {
194
+ const configPath = getUniqueConfigPath("js");
195
+ const configContent = `
196
+ export default {
197
+ embeddingConfig: {
198
+ apiKey: "test-key",
199
+ model: "text-embedding-3-small",
200
+ },
201
+ vectorDatabaseConfig: {
202
+ address: "localhost:19530",
203
+ },
204
+ supportedExtensions: [".ts", 123],
205
+ };
206
+ `;
207
+ writeFileSync(configPath, configContent);
208
+ await expect(loadConfig(configPath)).rejects.toThrow("supportedExtensions contains non-string value");
209
+ });
210
+ it("should accept valid optional arrays", async () => {
211
+ const configPath = getUniqueConfigPath("js");
212
+ const configContent = `
213
+ export default {
214
+ embeddingConfig: {
215
+ apiKey: "test-key",
216
+ model: "text-embedding-3-small",
217
+ },
218
+ vectorDatabaseConfig: {
219
+ address: "localhost:19530",
220
+ },
221
+ supportedExtensions: [".ts", ".js"],
222
+ ignorePatterns: ["node_modules/**"],
223
+ customExtensions: [".vue"],
224
+ customIgnorePatterns: ["*.test.ts"],
225
+ };
226
+ `;
227
+ writeFileSync(configPath, configContent);
228
+ const config = await loadConfig(configPath);
229
+ expect(config.supportedExtensions).toEqual([".ts", ".js"]);
230
+ expect(config.ignorePatterns).toEqual(["node_modules/**"]);
231
+ expect(config.customExtensions).toEqual([".vue"]);
232
+ expect(config.customIgnorePatterns).toEqual(["*.test.ts"]);
233
+ });
234
+ });
235
+ });
236
+ //# sourceMappingURL=config-loader.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-loader.test.js","sourceRoot":"","sources":["../src/config-loader.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export type { ContextConfig, OpenAIEmbeddingConfig, MilvusConfig, CLIOptions, IndexResult, } from "./types.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,YAAY,EACV,aAAa,EACb,qBAAqB,EACrB,YAAY,EACZ,UAAU,EACV,WAAW,GACZ,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,59 @@
1
+ import { Command } from "commander";
2
+ import { readFileSync } from "fs";
3
+ import { fileURLToPath } from "url";
4
+ import { dirname, join } from "path";
5
+ import { loadConfig } from "./config-loader.js";
6
+ import { runIndex } from "./indexer.js";
7
+ // Read version from package.json to keep it in sync
8
+ const __filename = fileURLToPath(import.meta.url);
9
+ const __dirname = dirname(__filename);
10
+ const packageJson = JSON.parse(readFileSync(join(__dirname, "..", "package.json"), "utf-8"));
11
+ const VERSION = packageJson.version;
12
+ const program = new Command();
13
+ program
14
+ .name("ai-context-index")
15
+ .description("Index your codebase for AI-powered semantic search")
16
+ .version(VERSION)
17
+ .option("-c, --config <path>", "Path to config file (default: ai-context.config.ts/js)")
18
+ .option("-f, --force", "Force reindex even if collection already exists")
19
+ .action(async (options) => {
20
+ try {
21
+ console.log("");
22
+ console.log("╔════════════════════════════════════════════════════════════╗");
23
+ console.log("║ AI Context CLI - Codebase Indexer ║");
24
+ console.log("╚════════════════════════════════════════════════════════════╝");
25
+ console.log("");
26
+ // Load and validate config
27
+ const config = await loadConfig(options.config);
28
+ // Run the indexing operation
29
+ await runIndex(config, options.force);
30
+ process.exit(0);
31
+ }
32
+ catch (error) {
33
+ console.error("");
34
+ console.error("❌ Error:", error instanceof Error ? error.message : String(error));
35
+ console.error("");
36
+ if (error instanceof Error && error.stack && process.env.DEBUG) {
37
+ console.error("Stack trace:");
38
+ console.error(error.stack);
39
+ console.error("");
40
+ }
41
+ process.exit(1);
42
+ }
43
+ });
44
+ // Handle uncaught errors
45
+ process.on("uncaughtException", (error) => {
46
+ console.error("");
47
+ console.error("❌ Uncaught error:", error.message);
48
+ if (process.env.DEBUG) {
49
+ console.error(error.stack);
50
+ }
51
+ process.exit(1);
52
+ });
53
+ process.on("unhandledRejection", (reason) => {
54
+ console.error("");
55
+ console.error("❌ Unhandled rejection:", reason);
56
+ process.exit(1);
57
+ });
58
+ program.parse();
59
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { ContextConfig, IndexResult } from "./types.js";
2
+ /**
3
+ * Run the indexing operation with the provided configuration
4
+ * @param config Validated configuration object
5
+ * @param forceReindex Whether to force reindex even if collection exists
6
+ * @returns Index result with statistics
7
+ */
8
+ export declare function runIndex(config: ContextConfig, forceReindex?: boolean): Promise<IndexResult>;
9
+ //# sourceMappingURL=indexer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexer.d.ts","sourceRoot":"","sources":["../src/indexer.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AA2B7D;;;;;GAKG;AACH,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,aAAa,EACrB,YAAY,GAAE,OAAe,GAC5B,OAAO,CAAC,WAAW,CAAC,CAmFtB"}
@@ -0,0 +1,97 @@
1
+ import { Context, MilvusVectorDatabase, OpenAIEmbedding, } from "@mcampa/ai-context-core";
2
+ /**
3
+ * Format a progress bar string
4
+ */
5
+ function formatProgressBar(percentage, width = 30) {
6
+ const filled = Math.round((percentage / 100) * width);
7
+ const empty = width - filled;
8
+ return `[${"█".repeat(filled)}${"░".repeat(empty)}]`;
9
+ }
10
+ /**
11
+ * Format duration in human-readable format
12
+ */
13
+ function formatDuration(ms) {
14
+ if (ms < 1000) {
15
+ return `${ms}ms`;
16
+ }
17
+ const seconds = Math.floor(ms / 1000);
18
+ if (seconds < 60) {
19
+ return `${seconds}s`;
20
+ }
21
+ const minutes = Math.floor(seconds / 60);
22
+ const remainingSeconds = seconds % 60;
23
+ return `${minutes}m ${remainingSeconds}s`;
24
+ }
25
+ /**
26
+ * Run the indexing operation with the provided configuration
27
+ * @param config Validated configuration object
28
+ * @param forceReindex Whether to force reindex even if collection exists
29
+ * @returns Index result with statistics
30
+ */
31
+ export async function runIndex(config, forceReindex = false) {
32
+ const startTime = Date.now();
33
+ const cwd = process.cwd();
34
+ console.log("\n🚀 Starting codebase indexing...\n");
35
+ console.log(`📁 Target directory: ${cwd}`);
36
+ console.log(`📛 Context name: ${config.name || "my-context"}`);
37
+ if (forceReindex) {
38
+ console.log(`⚡ Force reindex: enabled`);
39
+ }
40
+ console.log("");
41
+ // Initialize embedding provider
42
+ console.log("🔧 Initializing OpenAI embedding provider...");
43
+ const embedding = new OpenAIEmbedding({
44
+ apiKey: config.embeddingConfig.apiKey,
45
+ model: config.embeddingConfig.model,
46
+ baseURL: config.embeddingConfig.baseURL,
47
+ });
48
+ console.log(` Model: ${config.embeddingConfig.model}`);
49
+ // Initialize vector database
50
+ console.log("🔧 Initializing Milvus vector database...");
51
+ const vectorDatabase = new MilvusVectorDatabase({
52
+ address: config.vectorDatabaseConfig.address,
53
+ token: config.vectorDatabaseConfig.token,
54
+ username: config.vectorDatabaseConfig.username,
55
+ password: config.vectorDatabaseConfig.password,
56
+ ssl: config.vectorDatabaseConfig.ssl,
57
+ });
58
+ // Create context instance
59
+ console.log("🔧 Creating context instance...\n");
60
+ const context = new Context({
61
+ name: config.name,
62
+ embedding,
63
+ vectorDatabase,
64
+ supportedExtensions: config.supportedExtensions,
65
+ ignorePatterns: config.ignorePatterns,
66
+ customExtensions: config.customExtensions,
67
+ customIgnorePatterns: config.customIgnorePatterns,
68
+ });
69
+ // Track last progress update to avoid console spam
70
+ let lastProgressLine = "";
71
+ // Index the codebase
72
+ const stats = await context.indexCodebase(cwd, (progress) => {
73
+ const progressLine = `${formatProgressBar(progress.percentage)} ${progress.percentage}% - ${progress.phase}`;
74
+ // Only update if the line changed (to reduce console noise)
75
+ if (progressLine !== lastProgressLine) {
76
+ // Clear previous line and write new one
77
+ process.stdout.write(`\r${progressLine.padEnd(80)}`);
78
+ lastProgressLine = progressLine;
79
+ }
80
+ }, forceReindex);
81
+ // Clear the progress line and print summary
82
+ process.stdout.write("\r" + " ".repeat(80) + "\r");
83
+ const duration = Date.now() - startTime;
84
+ console.log("\n✅ Indexing completed successfully!\n");
85
+ console.log("📊 Summary:");
86
+ console.log(` Files indexed: ${stats.indexedFiles}`);
87
+ console.log(` Total chunks: ${stats.totalChunks}`);
88
+ console.log(` Status: ${stats.status}`);
89
+ console.log(` Duration: ${formatDuration(duration)}`);
90
+ console.log("");
91
+ if (stats.status === "limit_reached") {
92
+ console.log("⚠️ Warning: Chunk limit was reached. Some files may not have been fully indexed.");
93
+ console.log("");
94
+ }
95
+ return stats;
96
+ }
97
+ //# sourceMappingURL=indexer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexer.js","sourceRoot":"","sources":["../src/indexer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=indexer.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexer.test.d.ts","sourceRoot":"","sources":["../src/indexer.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,160 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
2
+ // Create hoisted mock functions
3
+ const { mockIndexCodebase, mockContext, mockOpenAIEmbedding, mockMilvusVectorDatabase, } = vi.hoisted(() => {
4
+ const mockIndexCodebase = vi.fn();
5
+ const mockContext = vi.fn(() => ({
6
+ indexCodebase: mockIndexCodebase,
7
+ }));
8
+ const mockOpenAIEmbedding = vi.fn(() => ({}));
9
+ const mockMilvusVectorDatabase = vi.fn(() => ({}));
10
+ return {
11
+ mockIndexCodebase,
12
+ mockContext,
13
+ mockOpenAIEmbedding,
14
+ mockMilvusVectorDatabase,
15
+ };
16
+ });
17
+ // Mock the core package
18
+ vi.mock("@mcampa/ai-context-core", () => ({
19
+ Context: mockContext,
20
+ OpenAIEmbedding: mockOpenAIEmbedding,
21
+ MilvusVectorDatabase: mockMilvusVectorDatabase,
22
+ }));
23
+ // Import after mocking
24
+ import { runIndex } from "./indexer.js";
25
+ describe("indexer", () => {
26
+ const validConfig = {
27
+ name: "test-project",
28
+ embeddingConfig: {
29
+ apiKey: "test-api-key",
30
+ model: "text-embedding-3-small",
31
+ },
32
+ vectorDatabaseConfig: {
33
+ address: "localhost:19530",
34
+ },
35
+ };
36
+ beforeEach(() => {
37
+ vi.clearAllMocks();
38
+ // Default mock implementation
39
+ mockIndexCodebase.mockResolvedValue({
40
+ indexedFiles: 10,
41
+ totalChunks: 50,
42
+ status: "completed",
43
+ });
44
+ // Suppress console output during tests
45
+ vi.spyOn(console, "log").mockImplementation(() => { });
46
+ vi.spyOn(process.stdout, "write").mockImplementation(() => true);
47
+ });
48
+ afterEach(() => {
49
+ vi.restoreAllMocks();
50
+ });
51
+ describe("runIndex", () => {
52
+ it("should initialize OpenAIEmbedding with config", async () => {
53
+ await runIndex(validConfig);
54
+ expect(mockOpenAIEmbedding).toHaveBeenCalledWith({
55
+ apiKey: "test-api-key",
56
+ model: "text-embedding-3-small",
57
+ baseURL: undefined,
58
+ });
59
+ });
60
+ it("should initialize OpenAIEmbedding with baseURL when provided", async () => {
61
+ const configWithBaseURL = {
62
+ ...validConfig,
63
+ embeddingConfig: {
64
+ ...validConfig.embeddingConfig,
65
+ baseURL: "https://custom.api.com",
66
+ },
67
+ };
68
+ await runIndex(configWithBaseURL);
69
+ expect(mockOpenAIEmbedding).toHaveBeenCalledWith({
70
+ apiKey: "test-api-key",
71
+ model: "text-embedding-3-small",
72
+ baseURL: "https://custom.api.com",
73
+ });
74
+ });
75
+ it("should initialize MilvusVectorDatabase with config", async () => {
76
+ await runIndex(validConfig);
77
+ expect(mockMilvusVectorDatabase).toHaveBeenCalledWith({
78
+ address: "localhost:19530",
79
+ token: undefined,
80
+ username: undefined,
81
+ password: undefined,
82
+ ssl: undefined,
83
+ });
84
+ });
85
+ it("should initialize MilvusVectorDatabase with all options", async () => {
86
+ const fullConfig = {
87
+ ...validConfig,
88
+ vectorDatabaseConfig: {
89
+ address: "localhost:19530",
90
+ token: "my-token",
91
+ username: "user",
92
+ password: "pass",
93
+ ssl: true,
94
+ },
95
+ };
96
+ await runIndex(fullConfig);
97
+ expect(mockMilvusVectorDatabase).toHaveBeenCalledWith({
98
+ address: "localhost:19530",
99
+ token: "my-token",
100
+ username: "user",
101
+ password: "pass",
102
+ ssl: true,
103
+ });
104
+ });
105
+ it("should create Context with all config options", async () => {
106
+ const fullConfig = {
107
+ name: "my-project",
108
+ embeddingConfig: {
109
+ apiKey: "test-key",
110
+ model: "text-embedding-3-small",
111
+ },
112
+ vectorDatabaseConfig: {
113
+ address: "localhost:19530",
114
+ },
115
+ supportedExtensions: [".ts", ".js"],
116
+ ignorePatterns: ["node_modules/**"],
117
+ customExtensions: [".vue"],
118
+ customIgnorePatterns: ["*.test.ts"],
119
+ };
120
+ await runIndex(fullConfig);
121
+ expect(mockContext).toHaveBeenCalledWith(expect.objectContaining({
122
+ name: "my-project",
123
+ supportedExtensions: [".ts", ".js"],
124
+ ignorePatterns: ["node_modules/**"],
125
+ customExtensions: [".vue"],
126
+ customIgnorePatterns: ["*.test.ts"],
127
+ }));
128
+ });
129
+ it("should return indexing statistics", async () => {
130
+ const result = await runIndex(validConfig);
131
+ expect(result).toEqual({
132
+ indexedFiles: 10,
133
+ totalChunks: 50,
134
+ status: "completed",
135
+ });
136
+ });
137
+ it("should pass forceReindex flag to indexCodebase", async () => {
138
+ await runIndex(validConfig, true);
139
+ expect(mockIndexCodebase).toHaveBeenCalledWith(expect.any(String), expect.any(Function), true);
140
+ });
141
+ it("should call indexCodebase with progress callback", async () => {
142
+ await runIndex(validConfig);
143
+ expect(mockIndexCodebase).toHaveBeenCalledWith(expect.any(String), expect.any(Function), false);
144
+ });
145
+ it("should handle limit_reached status", async () => {
146
+ mockIndexCodebase.mockResolvedValue({
147
+ indexedFiles: 100,
148
+ totalChunks: 450000,
149
+ status: "limit_reached",
150
+ });
151
+ const result = await runIndex(validConfig);
152
+ expect(result.status).toBe("limit_reached");
153
+ });
154
+ it("should use process.cwd() as the indexing path", async () => {
155
+ await runIndex(validConfig);
156
+ expect(mockIndexCodebase).toHaveBeenCalledWith(process.cwd(), expect.any(Function), false);
157
+ });
158
+ });
159
+ });
160
+ //# sourceMappingURL=indexer.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexer.test.js","sourceRoot":"","sources":["../src/indexer.test.ts"],"names":[],"mappings":"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"}