mirror of
https://github.com/zilliztech/claude-context.git
synced 2025-10-06 01:10:02 +03:00
refactor: rename class name from indexer to context
Signed-off-by: ChengZi <chen.zhang@zilliz.com>
This commit is contained in:
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@@ -2,9 +2,9 @@ name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master, main, refactor_name ]
|
||||
branches: [ master, main, refactor_class_name ]
|
||||
pull_request:
|
||||
branches: [ master, main, refactor_name ]
|
||||
branches: [ master, main, refactor_class_name ]
|
||||
|
||||
jobs:
|
||||
lint_and_build:
|
||||
|
||||
10
README.md
10
README.md
@@ -374,7 +374,7 @@ While MCP is the recommended way to use Code Context with AI assistants, you can
|
||||
The `@zilliz/code-context-core` package provides the fundamental functionality for code indexing and semantic search.
|
||||
|
||||
```typescript
|
||||
import { CodeIndexer, MilvusVectorDatabase, OpenAIEmbedding } from '@zilliz/code-context-core';
|
||||
import { CodeContext, MilvusVectorDatabase, OpenAIEmbedding } from '@zilliz/code-context-core';
|
||||
|
||||
// Initialize embedding provider
|
||||
const embedding = new OpenAIEmbedding({
|
||||
@@ -388,20 +388,20 @@ const vectorDatabase = new MilvusVectorDatabase({
|
||||
token: process.env.MILVUS_TOKEN || 'your-zilliz-cloud-api-key'
|
||||
});
|
||||
|
||||
// Create indexer instance
|
||||
const indexer = new CodeIndexer({
|
||||
// Create context instance
|
||||
const context = new CodeContext({
|
||||
embedding,
|
||||
vectorDatabase
|
||||
});
|
||||
|
||||
// Index your codebase with progress tracking
|
||||
const stats = await indexer.indexCodebase('./your-project', (progress) => {
|
||||
const stats = await context.indexCodebase('./your-project', (progress) => {
|
||||
console.log(`${progress.phase} - ${progress.percentage}%`);
|
||||
});
|
||||
console.log(`Indexed ${stats.indexedFiles} files, ${stats.totalChunks} chunks`);
|
||||
|
||||
// Perform semantic search
|
||||
const results = await indexer.semanticSearch('./your-project', 'vector database operations', 5);
|
||||
const results = await context.semanticSearch('./your-project', 'vector database operations', 5);
|
||||
results.forEach(result => {
|
||||
console.log(`File: ${result.relativePath}:${result.startLine}-${result.endLine}`);
|
||||
console.log(`Score: ${(result.score * 100).toFixed(2)}%`);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { CodeIndexer, MilvusVectorDatabase, MilvusRestfulVectorDatabase, AstCodeSplitter, LangChainCodeSplitter } from '@zilliz/code-context-core';
|
||||
import { CodeContext, MilvusVectorDatabase, MilvusRestfulVectorDatabase, AstCodeSplitter, LangChainCodeSplitter } from '@zilliz/code-context-core';
|
||||
import * as path from 'path';
|
||||
|
||||
// Try to load .env file
|
||||
@@ -9,7 +9,7 @@ try {
|
||||
}
|
||||
|
||||
async function main() {
|
||||
console.log('🚀 CodeIndexer Real Usage Example');
|
||||
console.log('🚀 CodeContext Real Usage Example');
|
||||
console.log('===============================');
|
||||
|
||||
try {
|
||||
@@ -39,14 +39,14 @@ async function main() {
|
||||
});
|
||||
}
|
||||
|
||||
// 2. Create CodeIndexer instance
|
||||
// 2. Create CodeContext instance
|
||||
let codeSplitter;
|
||||
if (splitterType === 'langchain') {
|
||||
codeSplitter = new LangChainCodeSplitter(1000, 200);
|
||||
} else {
|
||||
codeSplitter = new AstCodeSplitter(2500, 300);
|
||||
}
|
||||
const indexer = new CodeIndexer({
|
||||
const context = new CodeContext({
|
||||
vectorDatabase,
|
||||
codeSplitter,
|
||||
supportedExtensions: ['.ts', '.js', '.py', '.java', '.cpp', '.go', '.rs']
|
||||
@@ -57,14 +57,14 @@ async function main() {
|
||||
const codebasePath = path.join(__dirname, '../..'); // Index entire project
|
||||
|
||||
// Check if index already exists
|
||||
const hasExistingIndex = await indexer.hasIndex(codebasePath);
|
||||
const hasExistingIndex = await context.hasIndex(codebasePath);
|
||||
if (hasExistingIndex) {
|
||||
console.log('🗑️ Existing index found, clearing it first...');
|
||||
await indexer.clearIndex(codebasePath);
|
||||
await context.clearIndex(codebasePath);
|
||||
}
|
||||
|
||||
// Index with progress tracking
|
||||
const indexStats = await indexer.indexCodebase(codebasePath);
|
||||
const indexStats = await context.indexCodebase(codebasePath);
|
||||
|
||||
// 4. Show indexing statistics
|
||||
console.log(`\n📊 Indexing stats: ${indexStats.indexedFiles} files, ${indexStats.totalChunks} code chunks`);
|
||||
@@ -81,7 +81,7 @@ async function main() {
|
||||
|
||||
for (const query of queries) {
|
||||
console.log(`\n🔎 Search: "${query}"`);
|
||||
const results = await indexer.semanticSearch(codebasePath, query, 3, 0.3);
|
||||
const results = await context.semanticSearch(codebasePath, query, 3, 0.3);
|
||||
|
||||
if (results.length > 0) {
|
||||
results.forEach((result, index) => {
|
||||
|
||||
@@ -27,7 +27,7 @@ pnpm dev:core
|
||||
|
||||
## Project Structure
|
||||
|
||||
- `src/indexer.ts` - Main CodeIndexer class
|
||||
- `src/context.ts` - Main CodeContext class
|
||||
- `src/embedding/` - Embedding providers (OpenAI, VoyageAI, Ollama)
|
||||
- `src/vectordb/` - Vector database implementations (Milvus)
|
||||
- `src/splitter/` - Code splitting logic
|
||||
|
||||
@@ -45,7 +45,7 @@ MILVUS_TOKEN=your-zilliz-cloud-api-key
|
||||
|
||||
```typescript
|
||||
import {
|
||||
CodeIndexer,
|
||||
CodeContext,
|
||||
OpenAIEmbedding,
|
||||
MilvusVectorDatabase
|
||||
} from '@zilliz/code-context-core';
|
||||
@@ -62,21 +62,21 @@ const vectorDatabase = new MilvusVectorDatabase({
|
||||
token: process.env.MILVUS_TOKEN || ''
|
||||
});
|
||||
|
||||
// Create indexer instance
|
||||
const indexer = new CodeIndexer({
|
||||
// Create context instance
|
||||
const context = new CodeContext({
|
||||
embedding,
|
||||
vectorDatabase
|
||||
});
|
||||
|
||||
// Index a codebase
|
||||
const stats = await indexer.indexCodebase('./my-project', (progress) => {
|
||||
const stats = await context.indexCodebase('./my-project', (progress) => {
|
||||
console.log(`${progress.phase} - ${progress.percentage}%`);
|
||||
});
|
||||
|
||||
console.log(`Indexed ${stats.indexedFiles} files with ${stats.totalChunks} chunks`);
|
||||
|
||||
// Search the codebase
|
||||
const results = await indexer.semanticSearch(
|
||||
const results = await context.semanticSearch(
|
||||
'./my-project',
|
||||
'function that handles user authentication',
|
||||
5
|
||||
@@ -115,10 +115,10 @@ results.forEach(result => {
|
||||
|
||||
## Configuration
|
||||
|
||||
### CodeIndexerConfig
|
||||
### CodeContextConfig
|
||||
|
||||
```typescript
|
||||
interface CodeIndexerConfig {
|
||||
interface CodeContextConfig {
|
||||
embedding?: Embedding; // Embedding provider
|
||||
vectorDatabase?: VectorDatabase; // Vector database instance (required)
|
||||
codeSplitter?: Splitter; // Code splitting strategy
|
||||
@@ -148,7 +148,7 @@ interface CodeIndexerConfig {
|
||||
|
||||
## API Reference
|
||||
|
||||
### CodeIndexer
|
||||
### CodeContext
|
||||
|
||||
#### Methods
|
||||
|
||||
@@ -180,7 +180,7 @@ interface SemanticSearchResult {
|
||||
### Using VoyageAI Embeddings
|
||||
|
||||
```typescript
|
||||
import { CodeIndexer, MilvusVectorDatabase, VoyageAIEmbedding } from '@zilliz/code-context-core';
|
||||
import { CodeContext, MilvusVectorDatabase, VoyageAIEmbedding } from '@zilliz/code-context-core';
|
||||
|
||||
// Initialize with VoyageAI embedding provider
|
||||
const embedding = new VoyageAIEmbedding({
|
||||
@@ -193,7 +193,7 @@ const vectorDatabase = new MilvusVectorDatabase({
|
||||
token: process.env.MILVUS_TOKEN || ''
|
||||
});
|
||||
|
||||
const indexer = new CodeIndexer({
|
||||
const context = new CodeContext({
|
||||
embedding,
|
||||
vectorDatabase
|
||||
});
|
||||
@@ -202,7 +202,7 @@ const indexer = new CodeIndexer({
|
||||
### Custom File Filtering
|
||||
|
||||
```typescript
|
||||
const indexer = new CodeIndexer({
|
||||
const context = new CodeContext({
|
||||
embedding,
|
||||
vectorDatabase,
|
||||
supportedExtensions: ['.ts', '.js', '.py', '.java'],
|
||||
@@ -257,13 +257,13 @@ The file synchronization system uses a **Merkle tree-based approach** combined w
|
||||
|
||||
## Contributing
|
||||
|
||||
This package is part of the CodeIndexer monorepo. Please see:
|
||||
This package is part of the CodeContext monorepo. Please see:
|
||||
- [Main Contributing Guide](../../CONTRIBUTING.md) - General contribution guidelines
|
||||
- [Core Package Contributing](CONTRIBUTING.md) - Specific development guide for this package
|
||||
|
||||
## Related Packages
|
||||
|
||||
- **[@code-indexer/mcp](../mcp)** - MCP server that uses this core engine
|
||||
- **[@code-context/mcp](../mcp)** - MCP server that uses this core engine
|
||||
- **[VSCode Extension](../vscode-extension)** - VSCode extension built on this core
|
||||
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ const DEFAULT_IGNORE_PATTERNS = [
|
||||
'*.map', // source map files
|
||||
];
|
||||
|
||||
export interface CodeIndexerConfig {
|
||||
export interface CodeContextConfig {
|
||||
embedding?: Embedding;
|
||||
vectorDatabase?: VectorDatabase;
|
||||
codeSplitter?: Splitter;
|
||||
@@ -87,7 +87,7 @@ export interface CodeIndexerConfig {
|
||||
ignorePatterns?: string[];
|
||||
}
|
||||
|
||||
export class CodeIndexer {
|
||||
export class CodeContext {
|
||||
private embedding: Embedding;
|
||||
private vectorDatabase: VectorDatabase;
|
||||
private codeSplitter: Splitter;
|
||||
@@ -95,7 +95,7 @@ export class CodeIndexer {
|
||||
private ignorePatterns: string[];
|
||||
private synchronizers = new Map<string, FileSynchronizer>();
|
||||
|
||||
constructor(config: CodeIndexerConfig = {}) {
|
||||
constructor(config: CodeContextConfig = {}) {
|
||||
// Initialize services
|
||||
this.embedding = config.embedding || new OpenAIEmbedding({
|
||||
apiKey: process.env.OPENAI_API_KEY || 'your-openai-api-key',
|
||||
@@ -2,5 +2,5 @@ export * from './splitter';
|
||||
export * from './embedding';
|
||||
export * from './vectordb';
|
||||
export * from './types';
|
||||
export * from './indexer';
|
||||
export * from './context';
|
||||
export * from './sync/synchronizer';
|
||||
@@ -21,7 +21,7 @@ export class FileSynchronizer {
|
||||
|
||||
private getSnapshotPath(codebasePath: string): string {
|
||||
const homeDir = os.homedir();
|
||||
const merkleDir = path.join(homeDir, '.codeindexer', 'merkle');
|
||||
const merkleDir = path.join(homeDir, '.codecontext', 'merkle');
|
||||
|
||||
const normalizedPath = path.resolve(codebasePath);
|
||||
const hash = crypto.createHash('md5').update(normalizedPath).digest('hex');
|
||||
@@ -287,7 +287,7 @@ export class FileSynchronizer {
|
||||
*/
|
||||
static async deleteSnapshot(codebasePath: string): Promise<void> {
|
||||
const homeDir = os.homedir();
|
||||
const merkleDir = path.join(homeDir, '.codeindexer', 'merkle');
|
||||
const merkleDir = path.join(homeDir, '.codecontext', 'merkle');
|
||||
const normalizedPath = path.resolve(codebasePath);
|
||||
const hash = crypto.createHash('md5').update(normalizedPath).digest('hex');
|
||||
const snapshotPath = path.join(merkleDir, `${hash}.json`);
|
||||
|
||||
@@ -86,7 +86,7 @@ export class MilvusVectorDatabase implements VectorDatabase {
|
||||
|
||||
const createCollectionParams = {
|
||||
collection_name: collectionName,
|
||||
description: description || `Code indexer collection: ${collectionName}`,
|
||||
description: description || `Code context collection: ${collectionName}`,
|
||||
fields: schema,
|
||||
};
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
ListToolsRequestSchema,
|
||||
CallToolRequestSchema
|
||||
} from "@modelcontextprotocol/sdk/types.js";
|
||||
import { CodeIndexer, SemanticSearchResult } from "@zilliz/code-context-core";
|
||||
import { CodeContext, SemanticSearchResult } from "@zilliz/code-context-core";
|
||||
import { OpenAIEmbedding, VoyageAIEmbedding, GeminiEmbedding, OllamaEmbedding } from "@zilliz/code-context-core";
|
||||
import { MilvusVectorDatabase } from "@zilliz/code-context-core";
|
||||
import * as path from "path";
|
||||
@@ -63,7 +63,7 @@ function getEmbeddingModelForProvider(provider: string): string {
|
||||
}
|
||||
|
||||
// Helper function to create embedding instance based on provider
|
||||
function createEmbeddingInstance(config: CodeIndexerMcpConfig): OpenAIEmbedding | VoyageAIEmbedding | GeminiEmbedding | OllamaEmbedding {
|
||||
function createEmbeddingInstance(config: CodeContextMcpConfig): OpenAIEmbedding | VoyageAIEmbedding | GeminiEmbedding | OllamaEmbedding {
|
||||
console.log(`[EMBEDDING] Creating ${config.embeddingProvider} embedding instance...`);
|
||||
|
||||
switch (config.embeddingProvider) {
|
||||
@@ -123,7 +123,7 @@ function createEmbeddingInstance(config: CodeIndexerMcpConfig): OpenAIEmbedding
|
||||
}
|
||||
}
|
||||
|
||||
interface CodeIndexerMcpConfig {
|
||||
interface CodeContextMcpConfig {
|
||||
name: string;
|
||||
version: string;
|
||||
// Embedding provider configuration
|
||||
@@ -147,9 +147,9 @@ interface CodebaseSnapshot {
|
||||
lastUpdated: string;
|
||||
}
|
||||
|
||||
class CodeIndexerMcpServer {
|
||||
class CodeContextMcpServer {
|
||||
private server: Server;
|
||||
private codeIndexer: CodeIndexer;
|
||||
private codeContext: CodeContext;
|
||||
private activeCodebasePath: string | null = null;
|
||||
private indexedCodebases: string[] = [];
|
||||
private indexingStats: { indexedFiles: number; totalChunks: number } | null = null;
|
||||
@@ -157,13 +157,13 @@ class CodeIndexerMcpServer {
|
||||
private snapshotFilePath: string;
|
||||
private currentWorkspace: string;
|
||||
|
||||
constructor(config: CodeIndexerMcpConfig) {
|
||||
constructor(config: CodeContextMcpConfig) {
|
||||
// Get current workspace
|
||||
this.currentWorkspace = process.cwd();
|
||||
console.log(`[WORKSPACE] Current workspace: ${this.currentWorkspace}`);
|
||||
|
||||
// Initialize snapshot file path
|
||||
this.snapshotFilePath = path.join(os.homedir(), '.code-indexer-mcp', 'codebase-snapshot.json');
|
||||
this.snapshotFilePath = path.join(os.homedir(), '.code-context-mcp', 'codebase-snapshot.json');
|
||||
|
||||
// Initialize MCP server
|
||||
this.server = new Server(
|
||||
@@ -178,7 +178,7 @@ class CodeIndexerMcpServer {
|
||||
}
|
||||
);
|
||||
|
||||
// Initialize code indexer with proper configuration
|
||||
// Initialize code context with proper configuration
|
||||
console.log(`[EMBEDDING] Initializing embedding provider: ${config.embeddingProvider}`);
|
||||
console.log(`[EMBEDDING] Using model: ${config.embeddingModel}`);
|
||||
|
||||
@@ -208,7 +208,7 @@ class CodeIndexerMcpServer {
|
||||
...(config.milvusToken && { token: config.milvusToken })
|
||||
});
|
||||
|
||||
this.codeIndexer = new CodeIndexer({
|
||||
this.codeContext = new CodeContext({
|
||||
embedding,
|
||||
vectorDatabase
|
||||
});
|
||||
@@ -419,11 +419,11 @@ class CodeIndexerMcpServer {
|
||||
|
||||
// Clear index if force is true
|
||||
if (forceReindex) {
|
||||
await this.codeIndexer.clearIndex(absolutePath);
|
||||
await this.codeContext.clearIndex(absolutePath);
|
||||
}
|
||||
|
||||
// Use the existing CodeIndexer instance for indexing.
|
||||
let indexerForThisTask = this.codeIndexer;
|
||||
// Use the existing CodeContext instance for indexing.
|
||||
let contextForThisTask = this.codeContext;
|
||||
|
||||
if (splitterType !== 'ast') {
|
||||
console.warn(`[INDEX] Non-AST splitter '${splitterType}' requested; falling back to AST splitter`);
|
||||
@@ -431,30 +431,30 @@ class CodeIndexerMcpServer {
|
||||
|
||||
// Initialize file synchronizer with proper ignore patterns
|
||||
const { FileSynchronizer } = await import("@zilliz/code-context-core");
|
||||
const ignorePatterns = this.codeIndexer['ignorePatterns'] || [];
|
||||
const ignorePatterns = this.codeContext['ignorePatterns'] || [];
|
||||
console.log(`[INDEX] Using ignore patterns: ${ignorePatterns.join(', ')}`);
|
||||
const synchronizer = new FileSynchronizer(absolutePath, ignorePatterns);
|
||||
await synchronizer.initialize();
|
||||
// Store synchronizer in the indexer's internal map using the same collection name generation logic
|
||||
// Store synchronizer in the context's internal map using the same collection name generation logic
|
||||
const normalizedPath = path.resolve(absolutePath);
|
||||
const hash = crypto.createHash('md5').update(normalizedPath).digest('hex');
|
||||
const collectionName = `code_chunks_${hash.substring(0, 8)}`;
|
||||
|
||||
// Store synchronizer in both indexers if using a custom one
|
||||
this.codeIndexer['synchronizers'].set(collectionName, synchronizer);
|
||||
if (indexerForThisTask !== this.codeIndexer) {
|
||||
indexerForThisTask['synchronizers'].set(collectionName, synchronizer);
|
||||
// Store synchronizer in both contexts if using a custom one
|
||||
this.codeContext['synchronizers'].set(collectionName, synchronizer);
|
||||
if (contextForThisTask !== this.codeContext) {
|
||||
contextForThisTask['synchronizers'].set(collectionName, synchronizer);
|
||||
}
|
||||
|
||||
console.log(`[INDEX] Starting indexing with ${splitterType} splitter for: ${absolutePath}`);
|
||||
|
||||
// Log embedding provider information before indexing
|
||||
const embeddingProvider = this.codeIndexer['embedding'];
|
||||
const embeddingProvider = this.codeContext['embedding'];
|
||||
console.log(`[INDEX] 🧠 Using embedding provider: ${embeddingProvider.getProvider()} with dimension: ${embeddingProvider.getDimension()}`);
|
||||
|
||||
// Start indexing with the appropriate indexer
|
||||
// Start indexing with the appropriate context
|
||||
console.log(`[INDEX] 🚀 Beginning codebase indexing process...`);
|
||||
const stats = await indexerForThisTask.indexCodebase(absolutePath);
|
||||
const stats = await contextForThisTask.indexCodebase(absolutePath);
|
||||
console.log(`[INDEX] ✅ Indexing completed successfully! Files: ${stats.indexedFiles}, Chunks: ${stats.totalChunks}`);
|
||||
|
||||
// Store current codebase path and stats
|
||||
@@ -533,8 +533,8 @@ class CodeIndexerMcpServer {
|
||||
}
|
||||
|
||||
try {
|
||||
console.log(`[SYNC-DEBUG] Calling codeIndexer.reindexByChange() for '${codebasePath}'`);
|
||||
const stats = await this.codeIndexer.reindexByChange(codebasePath);
|
||||
console.log(`[SYNC-DEBUG] Calling codeContext.reindexByChange() for '${codebasePath}'`);
|
||||
const stats = await this.codeContext.reindexByChange(codebasePath);
|
||||
const codebaseElapsed = Date.now() - codebaseStartTime;
|
||||
|
||||
console.log(`[SYNC-DEBUG] Reindex stats for '${codebasePath}':`, stats);
|
||||
@@ -628,12 +628,12 @@ class CodeIndexerMcpServer {
|
||||
console.log(`[SEARCH] Query: "${query}"`);
|
||||
|
||||
// Log embedding provider information before search
|
||||
const embeddingProvider = this.codeIndexer['embedding'];
|
||||
const embeddingProvider = this.codeContext['embedding'];
|
||||
console.log(`[SEARCH] 🧠 Using embedding provider: ${embeddingProvider.getProvider()} for semantic search`);
|
||||
console.log(`[SEARCH] 🔍 Generating embeddings for query using ${embeddingProvider.getProvider()}...`);
|
||||
|
||||
// Search in the specified codebase
|
||||
const searchResults = await this.codeIndexer.semanticSearch(
|
||||
const searchResults = await this.codeContext.semanticSearch(
|
||||
absolutePath,
|
||||
query,
|
||||
Math.min(resultLimit, 50),
|
||||
@@ -734,7 +734,7 @@ class CodeIndexerMcpServer {
|
||||
console.log(`[CLEAR] Clearing codebase: ${absolutePath}`);
|
||||
|
||||
try {
|
||||
await this.codeIndexer.clearIndex(absolutePath);
|
||||
await this.codeContext.clearIndex(absolutePath);
|
||||
console.log(`[CLEAR] Successfully cleared index for: ${absolutePath}`);
|
||||
} catch (error: any) {
|
||||
const errorMsg = `Failed to clear ${absolutePath}: ${error.message}`;
|
||||
@@ -818,7 +818,7 @@ class CodeIndexerMcpServer {
|
||||
|
||||
async start() {
|
||||
console.log('[SYNC-DEBUG] MCP server start() method called');
|
||||
console.log('Starting CodeIndexer MCP server...');
|
||||
console.log('Starting CodeContext MCP server...');
|
||||
|
||||
const transport = new StdioServerTransport();
|
||||
console.log('[SYNC-DEBUG] StdioServerTransport created, attempting server connection...');
|
||||
@@ -866,7 +866,7 @@ async function main() {
|
||||
const args = process.argv.slice(2);
|
||||
|
||||
const embeddingProvider = (process.env.EMBEDDING_PROVIDER?.toLowerCase() === 'ollama' ? 'ollama' : 'openai') as 'openai' | 'ollama';
|
||||
// Debug: Print all environment variables related to CodeIndexer
|
||||
// Debug: Print all environment variables related to CodeContext
|
||||
console.log(`[DEBUG] 🔍 Environment Variables Debug:`);
|
||||
console.log(`[DEBUG] EMBEDDING_PROVIDER: ${process.env.EMBEDDING_PROVIDER || 'NOT SET'}`);
|
||||
console.log(`[DEBUG] EMBEDDING_MODEL: ${process.env.EMBEDDING_MODEL || 'NOT SET'}`);
|
||||
@@ -876,8 +876,8 @@ async function main() {
|
||||
console.log(`[DEBUG] MILVUS_ADDRESS: ${process.env.MILVUS_ADDRESS || 'NOT SET'}`);
|
||||
console.log(`[DEBUG] NODE_ENV: ${process.env.NODE_ENV || 'NOT SET'}`);
|
||||
|
||||
const config: CodeIndexerMcpConfig = {
|
||||
name: process.env.MCP_SERVER_NAME || "CodeIndexer MCP Server",
|
||||
const config: CodeContextMcpConfig = {
|
||||
name: process.env.MCP_SERVER_NAME || "CodeContext MCP Server",
|
||||
version: process.env.MCP_SERVER_VERSION || "1.0.0",
|
||||
// Embedding provider configuration
|
||||
embeddingProvider: (process.env.EMBEDDING_PROVIDER as 'OpenAI' | 'VoyageAI' | 'Gemini' | 'Ollama') || 'OpenAI',
|
||||
@@ -898,9 +898,9 @@ async function main() {
|
||||
// Show help if requested
|
||||
if (args.includes('--help') || args.includes('-h')) {
|
||||
console.log(`
|
||||
CodeIndexer MCP Server
|
||||
CodeContext MCP Server
|
||||
|
||||
Usage: npx @code-indexer/mcp@latest [options]
|
||||
Usage: npx @zilliz/code-context-mcp@latest [options]
|
||||
|
||||
Options:
|
||||
--help, -h Show this help message
|
||||
@@ -929,22 +929,22 @@ Environment Variables:
|
||||
|
||||
Examples:
|
||||
# Start MCP server with OpenAI (default)
|
||||
OPENAI_API_KEY=sk-xxx npx @code-indexer/mcp@latest
|
||||
OPENAI_API_KEY=sk-xxx npx @zilliz/code-context-mcp@latest
|
||||
|
||||
# Start MCP server with VoyageAI
|
||||
EMBEDDING_PROVIDER=VoyageAI VOYAGEAI_API_KEY=pa-xxx npx @code-indexer/mcp@latest
|
||||
EMBEDDING_PROVIDER=VoyageAI VOYAGEAI_API_KEY=pa-xxx npx @zilliz/code-context-mcp@latest
|
||||
|
||||
# Start MCP server with Gemini
|
||||
EMBEDDING_PROVIDER=Gemini GEMINI_API_KEY=xxx npx @code-indexer/mcp@latest
|
||||
EMBEDDING_PROVIDER=Gemini GEMINI_API_KEY=xxx npx @zilliz/code-context-mcp@latest
|
||||
|
||||
# Start MCP server with Ollama
|
||||
EMBEDDING_PROVIDER=Ollama EMBEDDING_MODEL=nomic-embed-text npx @code-indexer/mcp@latest
|
||||
EMBEDDING_PROVIDER=Ollama EMBEDDING_MODEL=nomic-embed-text npx @zilliz/code-context-mcp@latest
|
||||
`);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
// Log configuration summary before starting server
|
||||
console.log(`[MCP] 🚀 Starting CodeIndexer MCP Server`);
|
||||
console.log(`[MCP] 🚀 Starting CodeContext MCP Server`);
|
||||
console.log(`[MCP] Configuration Summary:`);
|
||||
console.log(`[MCP] Server: ${config.name} v${config.version}`);
|
||||
console.log(`[MCP] Embedding Provider: ${config.embeddingProvider}`);
|
||||
@@ -973,7 +973,7 @@ Examples:
|
||||
|
||||
console.log(`[MCP] 🔧 Initializing server components...`);
|
||||
|
||||
const server = new CodeIndexerMcpServer(config);
|
||||
const server = new CodeContextMcpServer(config);
|
||||
await server.start();
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
[](https://marketplace.visualstudio.com/items?itemName=zilliz.semanticcodesearch)
|
||||
|
||||
A code indexing and semantic search VSCode extension powered by Code Context.
|
||||
A code indexing and semantic search VSCode extension powered by [Code Context](https://github.com/zilliztech/code-context).
|
||||
|
||||
> 📖 **New to Code Context?** Check out the [main project README](../../README.md) for an overview and setup instructions.
|
||||
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
import * as vscode from 'vscode';
|
||||
import { CodeIndexer } from '@zilliz/code-context-core';
|
||||
import { CodeContext } from '@zilliz/code-context-core';
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
import * as crypto from 'crypto';
|
||||
|
||||
export class IndexCommand {
|
||||
private codeIndexer: CodeIndexer;
|
||||
private codeContext: CodeContext;
|
||||
|
||||
constructor(codeIndexer: CodeIndexer) {
|
||||
this.codeIndexer = codeIndexer;
|
||||
constructor(codeContext: CodeContext) {
|
||||
this.codeContext = codeContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the CodeIndexer instance (used when configuration changes)
|
||||
* Update the CodeContext instance (used when configuration changes)
|
||||
*/
|
||||
updateCodeIndexer(codeIndexer: CodeIndexer): void {
|
||||
this.codeIndexer = codeIndexer;
|
||||
updateCodeContext(codeContext: CodeContext): void {
|
||||
this.codeContext = codeContext;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -30,12 +30,12 @@ export class IndexCommand {
|
||||
if (fs.existsSync(gitignorePath)) {
|
||||
console.log(`📄 Found .gitignore file at: ${gitignorePath}`);
|
||||
|
||||
// Use the static method from CodeIndexer to read ignore patterns
|
||||
const ignorePatterns = await CodeIndexer.getIgnorePatternsFromFile(gitignorePath);
|
||||
// Use the static method from CodeContext to read ignore patterns
|
||||
const ignorePatterns = await CodeContext.getIgnorePatternsFromFile(gitignorePath);
|
||||
|
||||
if (ignorePatterns.length > 0) {
|
||||
// Update the CodeIndexer instance with new patterns
|
||||
this.codeIndexer.updateIgnorePatterns(ignorePatterns);
|
||||
// Update the CodeContext instance with new patterns
|
||||
this.codeContext.updateIgnorePatterns(ignorePatterns);
|
||||
console.log(`🚫 Loaded ${ignorePatterns.length} ignore patterns from .gitignore`);
|
||||
|
||||
vscode.window.showInformationMessage(
|
||||
@@ -46,13 +46,13 @@ export class IndexCommand {
|
||||
}
|
||||
} else {
|
||||
console.log('📄 No .gitignore file found, using default ignore patterns only');
|
||||
// No need to update patterns - CodeIndexer will use defaults
|
||||
// No need to update patterns - CodeContext will use defaults
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(`⚠️ Failed to load .gitignore patterns: ${error}`);
|
||||
vscode.window.showWarningMessage(`⚠️ Failed to load .gitignore: ${error}`);
|
||||
// Continue with default patterns on error
|
||||
this.codeIndexer.updateIgnorePatterns([]);
|
||||
this.codeContext.updateIgnorePatterns([]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ export class IndexCommand {
|
||||
await this.loadGitignorePatterns(selectedFolder.uri.fsPath);
|
||||
|
||||
// Clear existing index first
|
||||
await this.codeIndexer.clearIndex(
|
||||
await this.codeContext.clearIndex(
|
||||
selectedFolder.uri.fsPath,
|
||||
(progressInfo) => {
|
||||
// Clear index progress is usually fast, just show the message
|
||||
@@ -119,16 +119,16 @@ export class IndexCommand {
|
||||
// Initialize file synchronizer
|
||||
progress.report({ increment: 0, message: 'Initializing file synchronizer...' });
|
||||
const { FileSynchronizer } = await import("@zilliz/code-context-core");
|
||||
const synchronizer = new FileSynchronizer(selectedFolder.uri.fsPath, this.codeIndexer['ignorePatterns'] || []);
|
||||
const synchronizer = new FileSynchronizer(selectedFolder.uri.fsPath, this.codeContext['ignorePatterns'] || []);
|
||||
await synchronizer.initialize();
|
||||
// Store synchronizer in the indexer's internal map using the same collection name generation logic
|
||||
// Store synchronizer in the context's internal map using the same collection name generation logic
|
||||
const normalizedPath = path.resolve(selectedFolder.uri.fsPath);
|
||||
const hash = crypto.createHash('md5').update(normalizedPath).digest('hex');
|
||||
const collectionName = `code_chunks_${hash.substring(0, 8)}`;
|
||||
this.codeIndexer['synchronizers'].set(collectionName, synchronizer);
|
||||
this.codeContext['synchronizers'].set(collectionName, synchronizer);
|
||||
|
||||
// Start indexing with progress callback
|
||||
indexStats = await this.codeIndexer.indexCodebase(
|
||||
indexStats = await this.codeContext.indexCodebase(
|
||||
selectedFolder.uri.fsPath,
|
||||
(progressInfo) => {
|
||||
// Calculate increment from last reported percentage
|
||||
@@ -178,7 +178,7 @@ export class IndexCommand {
|
||||
title: 'Clearing Index',
|
||||
cancellable: false
|
||||
}, async (progress) => {
|
||||
await this.codeIndexer.clearIndex(
|
||||
await this.codeContext.clearIndex(
|
||||
workspaceFolders[0].uri.fsPath,
|
||||
(progressInfo) => {
|
||||
progress.report({
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import * as vscode from 'vscode';
|
||||
import { CodeIndexer, SearchQuery, SemanticSearchResult } from '@zilliz/code-context-core';
|
||||
import { CodeContext, SearchQuery, SemanticSearchResult } from '@zilliz/code-context-core';
|
||||
import * as path from 'path';
|
||||
|
||||
export class SearchCommand {
|
||||
private codeIndexer: CodeIndexer;
|
||||
private codeContext: CodeContext;
|
||||
|
||||
constructor(codeIndexer: CodeIndexer) {
|
||||
this.codeIndexer = codeIndexer;
|
||||
constructor(codeContext: CodeContext) {
|
||||
this.codeContext = codeContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the CodeIndexer instance (used when configuration changes)
|
||||
* Update the CodeContext instance (used when configuration changes)
|
||||
*/
|
||||
updateCodeIndexer(codeIndexer: CodeIndexer): void {
|
||||
this.codeIndexer = codeIndexer;
|
||||
updateCodeContext(codeContext: CodeContext): void {
|
||||
this.codeContext = codeContext;
|
||||
}
|
||||
|
||||
async execute(preSelectedText?: string): Promise<void> {
|
||||
@@ -59,7 +59,7 @@ export class SearchCommand {
|
||||
limit: 20
|
||||
};
|
||||
|
||||
const results = await this.codeIndexer.semanticSearch(
|
||||
const results = await this.codeContext.semanticSearch(
|
||||
codebasePath,
|
||||
query.term,
|
||||
query.limit || 20,
|
||||
@@ -136,7 +136,7 @@ export class SearchCommand {
|
||||
const codebasePath = workspaceFolders[0].uri.fsPath;
|
||||
|
||||
// Use the semantic search service
|
||||
return await this.codeIndexer.semanticSearch(
|
||||
return await this.codeContext.semanticSearch(
|
||||
codebasePath,
|
||||
searchTerm,
|
||||
limit,
|
||||
@@ -148,7 +148,7 @@ export class SearchCommand {
|
||||
* Check if index exists for the given codebase path
|
||||
*/
|
||||
async hasIndex(codebasePath: string): Promise<boolean> {
|
||||
return await this.codeIndexer.hasIndex(codebasePath);
|
||||
return await this.codeContext.hasIndex(codebasePath);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
import * as vscode from 'vscode';
|
||||
import { CodeIndexer } from '@zilliz/code-context-core';
|
||||
import { CodeContext } from '@zilliz/code-context-core';
|
||||
import * as fs from 'fs';
|
||||
|
||||
export class SyncCommand {
|
||||
private codeIndexer: CodeIndexer;
|
||||
private codeContext: CodeContext;
|
||||
private isSyncing: boolean = false;
|
||||
|
||||
constructor(codeIndexer: CodeIndexer) {
|
||||
this.codeIndexer = codeIndexer;
|
||||
constructor(codeContext: CodeContext) {
|
||||
this.codeContext = codeContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the CodeIndexer instance (used when configuration changes)
|
||||
* Update the CodeContext instance (used when configuration changes)
|
||||
*/
|
||||
updateCodeIndexer(codeIndexer: CodeIndexer): void {
|
||||
this.codeIndexer = codeIndexer;
|
||||
updateCodeContext(codeContext: CodeContext): void {
|
||||
this.codeContext = codeContext;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -57,7 +57,7 @@ export class SyncCommand {
|
||||
progress.report({ increment: 0, message: 'Checking for file changes...' });
|
||||
|
||||
try {
|
||||
syncStats = await this.codeIndexer.reindexByChange(
|
||||
syncStats = await this.codeContext.reindexByChange(
|
||||
codebasePath,
|
||||
(progressInfo) => {
|
||||
const increment = progressInfo.percentage;
|
||||
@@ -148,7 +148,7 @@ export class SyncCommand {
|
||||
this.isSyncing = true;
|
||||
|
||||
try {
|
||||
const syncStats = await this.codeIndexer.reindexByChange(codebasePath);
|
||||
const syncStats = await this.codeContext.reindexByChange(codebasePath);
|
||||
|
||||
const totalChanges = syncStats.added + syncStats.removed + syncStats.modified;
|
||||
|
||||
|
||||
@@ -5,29 +5,29 @@ import { SearchCommand } from './commands/searchCommand';
|
||||
import { IndexCommand } from './commands/indexCommand';
|
||||
import { SyncCommand } from './commands/syncCommand';
|
||||
import { ConfigManager } from './config/configManager';
|
||||
import { CodeIndexer, OpenAIEmbedding, VoyageAIEmbedding, GeminiEmbedding, MilvusRestfulVectorDatabase, AstCodeSplitter, LangChainCodeSplitter, SplitterType } from '@zilliz/code-context-core';
|
||||
import { CodeContext, OpenAIEmbedding, VoyageAIEmbedding, GeminiEmbedding, MilvusRestfulVectorDatabase, AstCodeSplitter, LangChainCodeSplitter, SplitterType } from '@zilliz/code-context-core';
|
||||
|
||||
let semanticSearchProvider: SemanticSearchViewProvider;
|
||||
let searchCommand: SearchCommand;
|
||||
let indexCommand: IndexCommand;
|
||||
let syncCommand: SyncCommand;
|
||||
let configManager: ConfigManager;
|
||||
let codeIndexer: CodeIndexer;
|
||||
let codeContext: CodeContext;
|
||||
let autoSyncDisposable: vscode.Disposable | null = null;
|
||||
|
||||
export async function activate(context: vscode.ExtensionContext) {
|
||||
console.log('CodeIndexer extension is now active!');
|
||||
console.log('CodeContext extension is now active!');
|
||||
|
||||
// Initialize config manager
|
||||
configManager = new ConfigManager(context);
|
||||
|
||||
// Initialize shared codeIndexer instance with embedding configuration
|
||||
codeIndexer = createCodeIndexerWithConfig(configManager);
|
||||
// Initialize shared codeContext instance with embedding configuration
|
||||
codeContext = createCodeContextWithConfig(configManager);
|
||||
|
||||
// Initialize providers and commands
|
||||
searchCommand = new SearchCommand(codeIndexer);
|
||||
indexCommand = new IndexCommand(codeIndexer);
|
||||
syncCommand = new SyncCommand(codeIndexer);
|
||||
searchCommand = new SearchCommand(codeContext);
|
||||
indexCommand = new IndexCommand(codeContext);
|
||||
syncCommand = new SyncCommand(codeContext);
|
||||
semanticSearchProvider = new SemanticSearchViewProvider(context.extensionUri, searchCommand, indexCommand, syncCommand, configManager);
|
||||
|
||||
// Register command handlers
|
||||
@@ -45,8 +45,8 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||
event.affectsConfiguration('semanticCodeSearch.milvus') ||
|
||||
event.affectsConfiguration('semanticCodeSearch.splitter') ||
|
||||
event.affectsConfiguration('semanticCodeSearch.autoSync')) {
|
||||
console.log('CodeIndexer configuration changed, reloading...');
|
||||
reloadCodeIndexerConfiguration();
|
||||
console.log('CodeContext configuration changed, reloading...');
|
||||
reloadCodeContextConfiguration();
|
||||
}
|
||||
}),
|
||||
|
||||
@@ -59,7 +59,7 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||
}),
|
||||
vscode.commands.registerCommand('semanticCodeSearch.indexCodebase', () => indexCommand.execute()),
|
||||
vscode.commands.registerCommand('semanticCodeSearch.clearIndex', () => indexCommand.clearIndex()),
|
||||
vscode.commands.registerCommand('semanticCodeSearch.reloadConfiguration', () => reloadCodeIndexerConfiguration())
|
||||
vscode.commands.registerCommand('semanticCodeSearch.reloadConfiguration', () => reloadCodeContextConfiguration())
|
||||
];
|
||||
|
||||
context.subscriptions.push(...disposables);
|
||||
@@ -72,7 +72,7 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||
|
||||
// Show status bar item
|
||||
const statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 100);
|
||||
statusBarItem.text = `$(search) CodeIndexer`;
|
||||
statusBarItem.text = `$(search) CodeContext`;
|
||||
statusBarItem.tooltip = 'Click to open semantic search';
|
||||
statusBarItem.command = 'semanticCodeSearch.semanticSearch';
|
||||
statusBarItem.show();
|
||||
@@ -117,7 +117,7 @@ function setupAutoSync() {
|
||||
}
|
||||
}
|
||||
|
||||
function createCodeIndexerWithConfig(configManager: ConfigManager): CodeIndexer {
|
||||
function createCodeContextWithConfig(configManager: ConfigManager): CodeContext {
|
||||
const embeddingConfig = configManager.getEmbeddingProviderConfig();
|
||||
const milvusConfig = configManager.getMilvusFullConfig();
|
||||
const splitterConfig = configManager.getSplitterConfig();
|
||||
@@ -126,13 +126,13 @@ function createCodeIndexerWithConfig(configManager: ConfigManager): CodeIndexer
|
||||
let embedding;
|
||||
let vectorDatabase;
|
||||
|
||||
const codeIndexerConfig: any = {};
|
||||
const codeContextConfig: any = {};
|
||||
|
||||
// Create embedding instance
|
||||
if (embeddingConfig) {
|
||||
embedding = ConfigManager.createEmbeddingInstance(embeddingConfig.provider, embeddingConfig.config);
|
||||
console.log(`Embedding initialized with ${embeddingConfig.provider} (model: ${embeddingConfig.config.model})`);
|
||||
codeIndexerConfig.embedding = embedding;
|
||||
codeContextConfig.embedding = embedding;
|
||||
} else {
|
||||
console.log('No embedding configuration found');
|
||||
}
|
||||
@@ -141,14 +141,14 @@ function createCodeIndexerWithConfig(configManager: ConfigManager): CodeIndexer
|
||||
if (milvusConfig) {
|
||||
vectorDatabase = new MilvusRestfulVectorDatabase(milvusConfig);
|
||||
console.log(`Vector database initialized with Milvus REST API (address: ${milvusConfig.address})`);
|
||||
codeIndexerConfig.vectorDatabase = vectorDatabase;
|
||||
codeContextConfig.vectorDatabase = vectorDatabase;
|
||||
} else {
|
||||
vectorDatabase = new MilvusRestfulVectorDatabase({
|
||||
address: process.env.MILVUS_ADDRESS || 'http://localhost:19530',
|
||||
token: process.env.MILVUS_TOKEN || ''
|
||||
});
|
||||
console.log('No Milvus configuration found, using default REST API configuration');
|
||||
codeIndexerConfig.vectorDatabase = vectorDatabase;
|
||||
codeContextConfig.vectorDatabase = vectorDatabase;
|
||||
}
|
||||
|
||||
// Create splitter instance
|
||||
@@ -165,23 +165,23 @@ function createCodeIndexerWithConfig(configManager: ConfigManager): CodeIndexer
|
||||
splitterConfig.chunkOverlap ?? 300
|
||||
);
|
||||
}
|
||||
codeIndexerConfig.codeSplitter = codeSplitter;
|
||||
codeContextConfig.codeSplitter = codeSplitter;
|
||||
console.log(`Splitter configured: ${splitterConfig.type} (chunkSize: ${splitterConfig.chunkSize}, overlap: ${splitterConfig.chunkOverlap})`);
|
||||
} else {
|
||||
codeSplitter = new AstCodeSplitter(2500, 300);
|
||||
codeIndexerConfig.codeSplitter = codeSplitter;
|
||||
codeContextConfig.codeSplitter = codeSplitter;
|
||||
console.log('No splitter configuration found, using default AST splitter (chunkSize: 2500, overlap: 300)');
|
||||
}
|
||||
return new CodeIndexer(codeIndexerConfig);
|
||||
return new CodeContext(codeContextConfig);
|
||||
} catch (error) {
|
||||
console.error('Failed to create CodeIndexer with user config:', error);
|
||||
vscode.window.showErrorMessage(`Failed to initialize CodeIndexer: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
||||
console.error('Failed to create CodeContext with user config:', error);
|
||||
vscode.window.showErrorMessage(`Failed to initialize CodeContext: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
function reloadCodeIndexerConfiguration() {
|
||||
console.log('Reloading CodeIndexer configuration...');
|
||||
function reloadCodeContextConfiguration() {
|
||||
console.log('Reloading CodeContext configuration...');
|
||||
|
||||
const embeddingConfig = configManager.getEmbeddingProviderConfig();
|
||||
const milvusConfig = configManager.getMilvusFullConfig();
|
||||
@@ -191,14 +191,14 @@ function reloadCodeIndexerConfiguration() {
|
||||
// Update embedding if configuration exists
|
||||
if (embeddingConfig) {
|
||||
const embedding = ConfigManager.createEmbeddingInstance(embeddingConfig.provider, embeddingConfig.config);
|
||||
codeIndexer.updateEmbedding(embedding);
|
||||
codeContext.updateEmbedding(embedding);
|
||||
console.log(`Embedding updated with ${embeddingConfig.provider} (model: ${embeddingConfig.config.model})`);
|
||||
}
|
||||
|
||||
// Update vector database if configuration exists
|
||||
if (milvusConfig) {
|
||||
const vectorDatabase = new MilvusRestfulVectorDatabase(milvusConfig);
|
||||
codeIndexer.updateVectorDatabase(vectorDatabase);
|
||||
codeContext.updateVectorDatabase(vectorDatabase);
|
||||
console.log(`Vector database updated with Milvus REST API (address: ${milvusConfig.address})`);
|
||||
}
|
||||
|
||||
@@ -216,32 +216,32 @@ function reloadCodeIndexerConfiguration() {
|
||||
splitterConfig.chunkOverlap ?? 300
|
||||
);
|
||||
}
|
||||
codeIndexer.updateSplitter(newSplitter);
|
||||
codeContext.updateSplitter(newSplitter);
|
||||
console.log(`Splitter updated: ${splitterConfig.type} (chunkSize: ${splitterConfig.chunkSize}, overlap: ${splitterConfig.chunkOverlap})`);
|
||||
} else {
|
||||
const defaultSplitter = new AstCodeSplitter(2500, 300);
|
||||
codeIndexer.updateSplitter(defaultSplitter);
|
||||
codeContext.updateSplitter(defaultSplitter);
|
||||
console.log('No splitter configuration found, using default AST splitter (chunkSize: 2500, overlap: 300)');
|
||||
}
|
||||
|
||||
// Update command instances with new codeIndexer
|
||||
searchCommand.updateCodeIndexer(codeIndexer);
|
||||
indexCommand.updateCodeIndexer(codeIndexer);
|
||||
syncCommand.updateCodeIndexer(codeIndexer);
|
||||
// Update command instances with new codeContext
|
||||
searchCommand.updateCodeContext(codeContext);
|
||||
indexCommand.updateCodeContext(codeContext);
|
||||
syncCommand.updateCodeContext(codeContext);
|
||||
|
||||
// Restart auto-sync if it was enabled
|
||||
setupAutoSync();
|
||||
|
||||
console.log('CodeIndexer configuration reloaded successfully');
|
||||
console.log('CodeContext configuration reloaded successfully');
|
||||
vscode.window.showInformationMessage('Configuration reloaded successfully!');
|
||||
} catch (error) {
|
||||
console.error('Failed to reload CodeIndexer configuration:', error);
|
||||
console.error('Failed to reload CodeContext configuration:', error);
|
||||
vscode.window.showErrorMessage(`Failed to reload configuration: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
||||
}
|
||||
}
|
||||
|
||||
export function deactivate() {
|
||||
console.log('CodeIndexer extension is now deactivated');
|
||||
console.log('CodeContext extension is now deactivated');
|
||||
|
||||
// Stop auto-sync if running
|
||||
if (autoSyncDisposable) {
|
||||
|
||||
@@ -259,7 +259,7 @@ export class SemanticSearchViewProvider implements vscode.WebviewViewProvider {
|
||||
// Add a small delay to ensure configuration is fully saved
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
|
||||
// Notify extension to recreate CodeIndexer with new config
|
||||
// Notify extension to recreate CodeContext with new config
|
||||
vscode.commands.executeCommand('semanticCodeSearch.reloadConfiguration');
|
||||
|
||||
webview.postMessage({
|
||||
@@ -268,7 +268,7 @@ export class SemanticSearchViewProvider implements vscode.WebviewViewProvider {
|
||||
message: 'Configuration saved successfully!'
|
||||
});
|
||||
|
||||
vscode.window.showInformationMessage('CodeIndexer configuration saved successfully!');
|
||||
vscode.window.showInformationMessage('CodeContext configuration saved successfully!');
|
||||
} catch (error) {
|
||||
webview.postMessage({
|
||||
command: 'saveResult',
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
<div class="header-section">
|
||||
<div class="title-section">
|
||||
<h3>🔍 Semantic Code Search</h3>
|
||||
<p class="subtitle">built by CodeIndexer</p>
|
||||
<p class="subtitle">built by <a href="https://github.com/zilliztech/code-context"
|
||||
target="_blank">Code Context</a></p>
|
||||
</div>
|
||||
<button id="settingsButton" class="settings-button" title="Settings">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
|
||||
@@ -47,7 +47,7 @@ from ts_executor import TypeScriptExecutor
|
||||
executor = TypeScriptExecutor()
|
||||
result = executor.call_method(
|
||||
'./test_codecontext.ts',
|
||||
'testCodeIndexerEndToEnd',
|
||||
'testCodeContextEndToEnd',
|
||||
{
|
||||
'openaiApiKey': 'sk-your-key',
|
||||
'milvusAddress': 'localhost:19530',
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
import { CodeIndexer } from '../packages/core/src/indexer';
|
||||
import { CodeContext } from '../packages/core/src/context';
|
||||
import { OpenAIEmbedding } from '../packages/core/src/embedding/openai-embedding';
|
||||
import { MilvusVectorDatabase } from '../packages/core/src/vectordb/milvus-vectordb';
|
||||
import { AstCodeSplitter } from '../packages/core/src/splitter/ast-splitter';
|
||||
|
||||
/**
|
||||
* CodeIndexer End-to-End Test - Complete Workflow
|
||||
* Includes: Configure Embedding → Configure Vector Database → Create Indexer → Index Codebase → Semantic Search
|
||||
* CodeContext End-to-End Test - Complete Workflow
|
||||
* Includes: Configure Embedding → Configure Vector Database → Create Context → Index Codebase → Semantic Search
|
||||
*/
|
||||
export async function testCodeIndexerEndToEnd(config: {
|
||||
export async function testCodeContextEndToEnd(config: {
|
||||
openaiApiKey: string;
|
||||
milvusAddress: string;
|
||||
codebasePath: string;
|
||||
searchQuery: string;
|
||||
}) {
|
||||
try {
|
||||
console.log('🚀 Starting CodeIndexer end-to-end test...');
|
||||
console.log('🚀 Starting CodeContext end-to-end test...');
|
||||
|
||||
// 1. Create embedding instance
|
||||
console.log('📝 Creating OpenAI embedding instance...');
|
||||
@@ -29,10 +29,10 @@ export async function testCodeIndexerEndToEnd(config: {
|
||||
address: config.milvusAddress
|
||||
});
|
||||
|
||||
// 3. Create CodeIndexer instance
|
||||
console.log('🔧 Creating CodeIndexer instance...');
|
||||
// 3. Create CodeContext instance
|
||||
console.log('🔧 Creating CodeContext instance...');
|
||||
const codeSplitter = new AstCodeSplitter(1000, 200);
|
||||
const indexer = new CodeIndexer({
|
||||
const context = new CodeContext({
|
||||
embedding: embedding,
|
||||
vectorDatabase: vectorDB,
|
||||
codeSplitter: codeSplitter
|
||||
@@ -40,14 +40,14 @@ export async function testCodeIndexerEndToEnd(config: {
|
||||
|
||||
// 4. Check if index already exists
|
||||
console.log('🔍 Checking existing index...');
|
||||
const hasIndex = await indexer.hasIndex(config.codebasePath);
|
||||
const hasIndex = await context.hasIndex(config.codebasePath);
|
||||
console.log(`Existing index status: ${hasIndex}`);
|
||||
|
||||
// 5. Index codebase
|
||||
let indexStats;
|
||||
if (!hasIndex) {
|
||||
console.log('📚 Starting codebase indexing...');
|
||||
indexStats = await indexer.indexCodebase(config.codebasePath, (progress) => {
|
||||
indexStats = await context.indexCodebase(config.codebasePath, (progress) => {
|
||||
console.log(`Indexing progress: ${progress.phase} - ${progress.percentage}%`);
|
||||
});
|
||||
console.log('✅ Indexing completed');
|
||||
@@ -58,7 +58,7 @@ export async function testCodeIndexerEndToEnd(config: {
|
||||
|
||||
// 6. Execute semantic search
|
||||
console.log('🔎 Executing semantic search...');
|
||||
const searchResults = await indexer.semanticSearch(
|
||||
const searchResults = await context.semanticSearch(
|
||||
config.codebasePath,
|
||||
config.searchQuery,
|
||||
5, // topK
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
CodeIndexer End-to-End Test
|
||||
Use TypeScriptExecutor to call complete CodeIndexer workflow
|
||||
CodeContext End-to-End Test
|
||||
Use TypeScriptExecutor to call complete CodeContext workflow
|
||||
"""
|
||||
|
||||
import os
|
||||
@@ -14,18 +14,20 @@ sys.path.append(str(Path(__file__).parent))
|
||||
from ts_executor import TypeScriptExecutor
|
||||
|
||||
|
||||
def run_codeindexer_endtoend_test():
|
||||
"""Run CodeIndexer end-to-end test"""
|
||||
def run_codecontext_endtoend_test():
|
||||
"""Run CodeContext end-to-end test"""
|
||||
|
||||
# Configuration parameters
|
||||
config = {
|
||||
"openaiApiKey": os.environ.get("OPENAI_API_KEY", "your-openai-api-key"),
|
||||
"milvusAddress": os.environ.get("MILVUS_ADDRESS", "localhost:19530"),
|
||||
"codebasePath": "../packages/core/src", # Index core source code
|
||||
"codebasePath": str(
|
||||
Path(__file__).parent.parent / "packages" / "core" / "src"
|
||||
), # Index core source code
|
||||
"searchQuery": "embedding creation and vector database configuration",
|
||||
}
|
||||
|
||||
print("🚀 Starting CodeIndexer end-to-end test")
|
||||
print("🚀 Starting CodeContext end-to-end test")
|
||||
print(f"📊 Configuration:")
|
||||
print(f" - Codebase path: {config['codebasePath']}")
|
||||
print(f" - Vector database: {config['milvusAddress']}")
|
||||
@@ -40,7 +42,7 @@ def run_codeindexer_endtoend_test():
|
||||
|
||||
# Call end-to-end test
|
||||
result = executor.call_method(
|
||||
"./test_codecontext.ts", "testCodeIndexerEndToEnd", config
|
||||
"./test_codecontext.ts", "testCodeContextEndToEnd", config
|
||||
)
|
||||
|
||||
# Output results
|
||||
@@ -102,19 +104,19 @@ def run_codeindexer_endtoend_test():
|
||||
def main():
|
||||
"""Main function"""
|
||||
print("=" * 60)
|
||||
print("🧪 CodeIndexer End-to-End Test")
|
||||
print("🧪 CodeContext End-to-End Test")
|
||||
print("=" * 60)
|
||||
print()
|
||||
|
||||
success = run_codeindexer_endtoend_test()
|
||||
success = run_codecontext_endtoend_test()
|
||||
|
||||
print()
|
||||
print("=" * 60)
|
||||
if success:
|
||||
print("🎉 Test completed! CodeIndexer end-to-end workflow runs successfully!")
|
||||
print("🎉 Test completed! CodeContext end-to-end workflow runs successfully!")
|
||||
print()
|
||||
print("💡 This proves:")
|
||||
print(" ✅ Can call TypeScript CodeIndexer from Python")
|
||||
print(" ✅ Can call TypeScript CodeContext from Python")
|
||||
print(" ✅ Supports complete indexing and search workflow")
|
||||
print(" ✅ Supports complex configuration and parameter passing")
|
||||
print(" ✅ Can get detailed execution results and statistics")
|
||||
|
||||
@@ -61,39 +61,64 @@ class TypeScriptExecutor:
|
||||
f.write(wrapper_code)
|
||||
|
||||
# Execute TypeScript code using ts-node
|
||||
result = subprocess.run(
|
||||
# Use subprocess.Popen to capture output in real-time
|
||||
process = subprocess.Popen(
|
||||
["npx", "ts-node", temp_file],
|
||||
capture_output=True,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
text=True,
|
||||
check=True,
|
||||
cwd=self.working_dir,
|
||||
bufsize=1, # Line buffering
|
||||
universal_newlines=True,
|
||||
)
|
||||
|
||||
# Parse results
|
||||
if result.stdout.strip():
|
||||
# Try to extract JSON part from output
|
||||
import re
|
||||
stdout_lines = []
|
||||
stderr_lines = []
|
||||
|
||||
output = result.stdout.strip()
|
||||
# Find the last complete JSON object - improved regex
|
||||
json_match = re.search(
|
||||
r"\{.*\}(?=\s*$)", output, re.DOTALL | re.MULTILINE
|
||||
)
|
||||
if json_match:
|
||||
# Read output line by line and display console.log in real-time
|
||||
while True:
|
||||
output = process.stdout.readline()
|
||||
if output == "" and process.poll() is not None:
|
||||
break
|
||||
if output:
|
||||
line = output.strip()
|
||||
stdout_lines.append(line)
|
||||
|
||||
# Try to parse as JSON to see if it's the final result
|
||||
try:
|
||||
return json.loads(json_match.group())
|
||||
json.loads(line)
|
||||
# If it parses as JSON, it might be the final result, don't print it yet
|
||||
except json.JSONDecodeError:
|
||||
pass
|
||||
# If no JSON found, try direct parsing
|
||||
# If it's not JSON, it's likely a console.log, so print it
|
||||
print(line)
|
||||
|
||||
# Get any remaining stderr
|
||||
stderr_output = process.stderr.read()
|
||||
if stderr_output:
|
||||
stderr_lines.append(stderr_output.strip())
|
||||
|
||||
return_code = process.poll()
|
||||
|
||||
if return_code != 0:
|
||||
error_msg = "\n".join(stderr_lines) if stderr_lines else "Unknown error"
|
||||
raise RuntimeError(f"TypeScript execution failed: {error_msg}")
|
||||
|
||||
# Parse results from the last line that looks like JSON
|
||||
for line in reversed(stdout_lines):
|
||||
if line.strip():
|
||||
try:
|
||||
return json.loads(output)
|
||||
# Try to parse as JSON
|
||||
return json.loads(line)
|
||||
except json.JSONDecodeError:
|
||||
return output # Return raw output
|
||||
else:
|
||||
continue
|
||||
|
||||
# If no JSON found, return the last non-empty line
|
||||
for line in reversed(stdout_lines):
|
||||
if line.strip():
|
||||
return line
|
||||
|
||||
return None
|
||||
|
||||
except subprocess.CalledProcessError as e:
|
||||
raise RuntimeError(f"TypeScript execution failed: {e.stderr}")
|
||||
except Exception as e:
|
||||
raise RuntimeError(f"Execution error: {str(e)}")
|
||||
finally:
|
||||
|
||||
Reference in New Issue
Block a user