go c c# java python ts js rust now supported

This commit is contained in:
abhigyanpatwari 2026-01-23 19:11:24 +05:30
parent 1b5a3bbc1b
commit 46330fa301
21 changed files with 468 additions and 50 deletions

View file

@ -57,6 +57,7 @@
"@types/react-syntax-highlighter": "^15.5.13",
"@vercel/node": "^5.5.16",
"@vitejs/plugin-react": "^5.1.0",
"tree-sitter-wasms": "^0.1.13",
"typescript": "^5.4.5",
"vite": "^5.2.0",
"vite-plugin-static-copy": "^3.1.4"
@ -9154,6 +9155,16 @@
"dev": true,
"license": "MIT"
},
"node_modules/tree-sitter-wasms": {
"version": "0.1.13",
"resolved": "https://registry.npmjs.org/tree-sitter-wasms/-/tree-sitter-wasms-0.1.13.tgz",
"integrity": "sha512-wT+cR6DwaIz80/vho3AvSF0N4txuNx/5bcRKoXouOfClpxh/qqrF4URNLQXbbt8MaAxeksZcZd1j8gcGjc+QxQ==",
"dev": true,
"license": "Unlicense",
"dependencies": {
"tree-sitter-wasms": "^0.1.11"
}
},
"node_modules/trim-lines": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz",

View file

@ -58,6 +58,7 @@
"@types/react-syntax-highlighter": "^15.5.13",
"@vercel/node": "^5.5.16",
"@vitejs/plugin-react": "^5.1.0",
"tree-sitter-wasms": "^0.1.13",
"typescript": "^5.4.5",
"vite": "^5.2.0",
"vite-plugin-static-copy": "^3.1.4"

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -81,6 +81,8 @@ const AppContent = () => {
console.log('📥 App.handleFileSelect - param received:', enableSmartClustering, 'provider exists:', !!getActiveProviderConfig());
const projectName = file.name.replace('.zip', '');
setProjectName(projectName);
// Set initial progress BEFORE entering loading mode to prevent black screen
setProgress({ phase: 'extracting', percent: 0, message: 'Starting...', detail: 'Preparing to extract files' });
setViewMode('loading');
try {
@ -136,6 +138,8 @@ const AppContent = () => {
const projectName = firstPath.split('/')[0].replace(/-\d+$/, '') || 'repository';
setProjectName(projectName);
// Set initial progress BEFORE entering loading mode to prevent black screen
setProgress({ phase: 'extracting', percent: 0, message: 'Starting...', detail: 'Preparing to process files' });
setViewMode('loading');
try {

View file

@ -25,10 +25,7 @@ export const DropZone = ({ onFileSelect, onGitClone }: DropZoneProps) => {
useEffect(() => {
const config = getActiveProviderConfig();
setHasLLMProvider(!!config);
// Auto-enable if provider is available
if (config) {
setEnableSmartClustering(true);
}
// Keep smart clustering OFF by default, user must opt-in
}, []);
const handleDragOver = useCallback((e: DragEvent<HTMLDivElement>) => {

View file

@ -2,12 +2,12 @@ export enum SupportedLanguages {
JavaScript = 'javascript',
TypeScript = 'typescript',
Python = 'python',
// Java = 'java',
// C = 'c',
// CPlusPlus = 'cpp',
// CSharp = 'csharp',
// Go = 'go',
// Rust = 'rust',
Java = 'java',
C = 'c',
CPlusPlus = 'cpp',
CSharp = 'csharp',
Go = 'go',
Rust = 'rust',
// PHP = 'php',
// Ruby = 'ruby',
// Swift = 'swift',

View file

@ -23,6 +23,17 @@ const FUNCTION_NODE_TYPES = new Set([
// Common async variants
'async_function_declaration',
'async_arrow_function',
// Java
'method_declaration',
'constructor_declaration',
// C/C++
// 'function_definition' already included above
// Go
// 'method_declaration' already included from Java
// C#
'local_function_statement',
// Rust
'function_item',
]);
/**

View file

@ -117,6 +117,33 @@ export const processHeritage = async (
});
}
}
// IMPLEMENTS (Rust): impl Trait for Struct
if (captureMap['heritage.trait'] && captureMap['heritage.class']) {
const structName = captureMap['heritage.class'].text;
const traitName = captureMap['heritage.trait'].text;
// Resolve struct and trait IDs
const structId = symbolTable.lookupExact(file.path, structName) ||
symbolTable.lookupFuzzy(structName)[0]?.nodeId ||
generateId('Struct', `${file.path}:${structName}`);
const traitId = symbolTable.lookupFuzzy(traitName)[0]?.nodeId ||
generateId('Trait', `${traitName}`);
if (structId && traitId) {
const relId = generateId('IMPLEMENTS', `${structId}->${traitId}`);
graph.addRelationship({
id: relId,
sourceId: structId,
targetId: traitId,
type: 'IMPLEMENTS',
confidence: 1.0,
reason: 'trait-impl',
});
}
}
});
// Cleanup

View file

@ -35,8 +35,24 @@ const resolveImportPath = (
const basePath = currentDir.join('/');
// 3. Try extensions (prioritize .tsx for React projects)
const extensions = ['', '.tsx', '.ts', '.jsx', '.js', '/index.tsx', '/index.ts', '/index.jsx', '/index.js'];
// 3. Try extensions for all supported languages
const extensions = [
'',
// TypeScript/JavaScript
'.tsx', '.ts', '.jsx', '.js', '/index.tsx', '/index.ts', '/index.jsx', '/index.js',
// Python
'.py', '/__init__.py',
// Java
'.java',
// C/C++
'.c', '.h', '.cpp', '.hpp', '.cc', '.cxx', '.hxx', '.hh',
// C#
'.cs',
// Go
'.go',
// Rust
'.rs', '/mod.rs'
];
for (const ext of extensions) {
const candidate = basePath + ext;

View file

@ -81,10 +81,37 @@ export const processParsing = async (
let nodeLabel = 'CodeElement';
// Core types
if (captureMap['definition.function']) nodeLabel = 'Function';
else if (captureMap['definition.class']) nodeLabel = 'Class';
else if (captureMap['definition.interface']) nodeLabel = 'Interface';
else if (captureMap['definition.method']) nodeLabel = 'Method';
// Struct types (C, C++, Go, Rust, C#)
else if (captureMap['definition.struct']) nodeLabel = 'Struct';
// Enum types
else if (captureMap['definition.enum']) nodeLabel = 'Enum';
// Namespace/Module (C++, C#, Rust)
else if (captureMap['definition.namespace']) nodeLabel = 'Namespace';
else if (captureMap['definition.module']) nodeLabel = 'Module';
// Rust-specific
else if (captureMap['definition.trait']) nodeLabel = 'Trait';
else if (captureMap['definition.impl']) nodeLabel = 'Impl';
else if (captureMap['definition.type']) nodeLabel = 'TypeAlias';
else if (captureMap['definition.const']) nodeLabel = 'Const';
else if (captureMap['definition.static']) nodeLabel = 'Static';
// C-specific
else if (captureMap['definition.typedef']) nodeLabel = 'Typedef';
else if (captureMap['definition.macro']) nodeLabel = 'Macro';
else if (captureMap['definition.union']) nodeLabel = 'Union';
// C#-specific
else if (captureMap['definition.property']) nodeLabel = 'Property';
else if (captureMap['definition.record']) nodeLabel = 'Record';
else if (captureMap['definition.delegate']) nodeLabel = 'Delegate';
// Java-specific
else if (captureMap['definition.annotation']) nodeLabel = 'Annotation';
else if (captureMap['definition.constructor']) nodeLabel = 'Constructor';
// C++ template
else if (captureMap['definition.template']) nodeLabel = 'Template';
const nodeId = generateId(nodeLabel, `${file.path}:${nodeName}`);

View file

@ -148,9 +148,184 @@ export const PYTHON_QUERIES = `
(identifier) @heritage.extends)) @heritage
`;
// Java queries - works with tree-sitter-java
export const JAVA_QUERIES = `
; Classes, Interfaces, Enums, Annotations
(class_declaration name: (identifier) @name) @definition.class
(interface_declaration name: (identifier) @name) @definition.interface
(enum_declaration name: (identifier) @name) @definition.enum
(annotation_type_declaration name: (identifier) @name) @definition.annotation
; Methods & Constructors
(method_declaration name: (identifier) @name) @definition.method
(constructor_declaration name: (identifier) @name) @definition.constructor
; Imports
(import_declaration (scoped_identifier) @import.source) @import
; Calls
(method_invocation name: (identifier) @call.name) @call
(method_invocation object: (_) name: (identifier) @call.name) @call
; Heritage - extends class
(class_declaration name: (identifier) @heritage.class
(superclass (type_identifier) @heritage.extends)) @heritage
; Heritage - implements interfaces
(class_declaration name: (identifier) @heritage.class
(super_interfaces (type_list (type_identifier) @heritage.implements))) @heritage.impl
`;
// C queries - works with tree-sitter-c
export const C_QUERIES = `
; Functions
(function_definition declarator: (function_declarator declarator: (identifier) @name)) @definition.function
(declaration declarator: (function_declarator declarator: (identifier) @name)) @definition.function
; Structs, Unions, Enums, Typedefs
(struct_specifier name: (type_identifier) @name) @definition.struct
(union_specifier name: (type_identifier) @name) @definition.union
(enum_specifier name: (type_identifier) @name) @definition.enum
(type_definition declarator: (type_identifier) @name) @definition.typedef
; Macros
(preproc_function_def name: (identifier) @name) @definition.macro
(preproc_def name: (identifier) @name) @definition.macro
; Includes
(preproc_include path: (_) @import.source) @import
; Calls
(call_expression function: (identifier) @call.name) @call
(call_expression function: (field_expression field: (field_identifier) @call.name)) @call
`;
// Go queries - works with tree-sitter-go
export const GO_QUERIES = `
; Functions & Methods
(function_declaration name: (identifier) @name) @definition.function
(method_declaration name: (field_identifier) @name) @definition.method
; Types
(type_declaration (type_spec name: (type_identifier) @name type: (struct_type))) @definition.struct
(type_declaration (type_spec name: (type_identifier) @name type: (interface_type))) @definition.interface
(type_declaration (type_spec name: (type_identifier) @name)) @definition.type
; Imports
(import_declaration (import_spec path: (interpreted_string_literal) @import.source)) @import
(import_declaration (import_spec_list (import_spec path: (interpreted_string_literal) @import.source))) @import
; Calls
(call_expression function: (identifier) @call.name) @call
(call_expression function: (selector_expression field: (field_identifier) @call.name)) @call
`;
// C++ queries - works with tree-sitter-cpp
export const CPP_QUERIES = `
; Classes, Structs, Namespaces
(class_specifier name: (type_identifier) @name) @definition.class
(struct_specifier name: (type_identifier) @name) @definition.struct
(namespace_definition name: (namespace_identifier) @name) @definition.namespace
(enum_specifier name: (type_identifier) @name) @definition.enum
; Functions & Methods
(function_definition declarator: (function_declarator declarator: (identifier) @name)) @definition.function
(function_definition declarator: (function_declarator declarator: (qualified_identifier name: (identifier) @name))) @definition.method
; Templates
(template_declaration (class_specifier name: (type_identifier) @name)) @definition.template
(template_declaration (function_definition declarator: (function_declarator declarator: (identifier) @name))) @definition.template
; Includes
(preproc_include path: (_) @import.source) @import
; Calls
(call_expression function: (identifier) @call.name) @call
(call_expression function: (field_expression field: (field_identifier) @call.name)) @call
(call_expression function: (qualified_identifier name: (identifier) @call.name)) @call
(call_expression function: (template_function name: (identifier) @call.name)) @call
; Heritage
(class_specifier name: (type_identifier) @heritage.class
(base_class_clause (type_identifier) @heritage.extends)) @heritage
(class_specifier name: (type_identifier) @heritage.class
(base_class_clause (access_specifier) (type_identifier) @heritage.extends)) @heritage
`;
// C# queries - works with tree-sitter-c-sharp
export const CSHARP_QUERIES = `
; Types
(class_declaration name: (identifier) @name) @definition.class
(interface_declaration name: (identifier) @name) @definition.interface
(struct_declaration name: (identifier) @name) @definition.struct
(enum_declaration name: (identifier) @name) @definition.enum
(record_declaration name: (identifier) @name) @definition.record
(delegate_declaration name: (identifier) @name) @definition.delegate
; Namespaces
(namespace_declaration name: (identifier) @name) @definition.namespace
(namespace_declaration name: (qualified_name) @name) @definition.namespace
; Methods & Properties
(method_declaration name: (identifier) @name) @definition.method
(local_function_statement name: (identifier) @name) @definition.function
(constructor_declaration name: (identifier) @name) @definition.constructor
(property_declaration name: (identifier) @name) @definition.property
; Using
(using_directive (qualified_name) @import.source) @import
(using_directive (identifier) @import.source) @import
; Calls
(invocation_expression function: (identifier) @call.name) @call
(invocation_expression function: (member_access_expression name: (identifier) @call.name)) @call
; Heritage
(class_declaration name: (identifier) @heritage.class
(base_list (simple_base_type (identifier) @heritage.extends))) @heritage
(class_declaration name: (identifier) @heritage.class
(base_list (simple_base_type (generic_name (identifier) @heritage.extends)))) @heritage
`;
// Rust queries - works with tree-sitter-rust
export const RUST_QUERIES = `
; Functions & Items
(function_item name: (identifier) @name) @definition.function
(struct_item name: (type_identifier) @name) @definition.struct
(enum_item name: (type_identifier) @name) @definition.enum
(trait_item name: (type_identifier) @name) @definition.trait
(impl_item type: (type_identifier) @name) @definition.impl
(mod_item name: (identifier) @name) @definition.module
; Type aliases, const, static, macros
(type_item name: (type_identifier) @name) @definition.type
(const_item name: (identifier) @name) @definition.const
(static_item name: (identifier) @name) @definition.static
(macro_definition name: (identifier) @name) @definition.macro
; Use statements
(use_declaration argument: (_) @import.source) @import
; Calls
(call_expression function: (identifier) @call.name) @call
(call_expression function: (field_expression field: (field_identifier) @call.name)) @call
(call_expression function: (scoped_identifier name: (identifier) @call.name)) @call
(call_expression function: (generic_function function: (identifier) @call.name)) @call
; Heritage (trait implementation)
(impl_item trait: (type_identifier) @heritage.trait type: (type_identifier) @heritage.class) @heritage
(impl_item trait: (generic_type type: (type_identifier) @heritage.trait) type: (type_identifier) @heritage.class) @heritage
`;
export const LANGUAGE_QUERIES: Record<SupportedLanguages, string> = {
[SupportedLanguages.TypeScript]: TYPESCRIPT_QUERIES,
[SupportedLanguages.JavaScript]: JAVASCRIPT_QUERIES,
[SupportedLanguages.Python]: PYTHON_QUERIES,
[SupportedLanguages.Java]: JAVA_QUERIES,
[SupportedLanguages.C]: C_QUERIES,
[SupportedLanguages.Go]: GO_QUERIES,
[SupportedLanguages.CPlusPlus]: CPP_QUERIES,
[SupportedLanguages.CSharp]: CSHARP_QUERIES,
[SupportedLanguages.Rust]: RUST_QUERIES,
};

View file

@ -4,11 +4,27 @@ import { SupportedLanguages } from '../../config/supported-languages';
* Map file extension to SupportedLanguage enum
*/
export const getLanguageFromFilename = (filename: string): SupportedLanguages | null => {
// TypeScript (including TSX)
if (filename.endsWith('.tsx')) return SupportedLanguages.TypeScript;
if (filename.endsWith('.ts')) return SupportedLanguages.TypeScript;
// JavaScript (including JSX)
if (filename.endsWith('.jsx')) return SupportedLanguages.JavaScript;
if (filename.endsWith('.js')) return SupportedLanguages.JavaScript;
// Python
if (filename.endsWith('.py')) return SupportedLanguages.Python;
// Java
if (filename.endsWith('.java')) return SupportedLanguages.Java;
// C (source and headers)
if (filename.endsWith('.c') || filename.endsWith('.h')) return SupportedLanguages.C;
// C++ (all common extensions)
if (filename.endsWith('.cpp') || filename.endsWith('.cc') || filename.endsWith('.cxx') ||
filename.endsWith('.hpp') || filename.endsWith('.hxx') || filename.endsWith('.hh')) return SupportedLanguages.CPlusPlus;
// C#
if (filename.endsWith('.cs')) return SupportedLanguages.CSharp;
// Go
if (filename.endsWith('.go')) return SupportedLanguages.Go;
// Rust
if (filename.endsWith('.rs')) return SupportedLanguages.Rust;
return null;
};

View file

@ -137,8 +137,14 @@ export const loadGraphToKuzu = async (
return nodeId.split(':')[0];
};
const fromLabel = getNodeLabel(fromId);
const toLabel = getNodeLabel(toId);
// Reserved Cypher keywords need backtick escaping
const RESERVED_LABELS = ['Macro', 'Enum', 'Union', 'Const', 'Module', 'Struct'];
const escapeLabel = (label: string): string => {
return RESERVED_LABELS.includes(label) ? `\`${label}\`` : label;
};
const fromLabel = escapeLabel(getNodeLabel(fromId));
const toLabel = escapeLabel(getNodeLabel(toId));
// INSERT with explicit node matching (including confidence and reason)
const insertQuery = `
@ -148,21 +154,24 @@ export const loadGraphToKuzu = async (
`;
await conn.query(insertQuery);
insertedRels++;
} catch {
} catch (err) {
// Skip failed insertions (nodes might not exist, or relation pair not allowed by schema)
skippedRels++;
if (import.meta.env.DEV) {
const match = line.match(/"([^"]*)","([^"]*)","([^"]*)",([0-9.]+),"([^"]*)"/);
if (match) {
const [, fromId, toId, relType] = match;
const getNodeLabel = (nodeId: string): string => {
if (nodeId.startsWith('comm_')) return 'Community';
return nodeId.split(':')[0];
};
const fromLabel = getNodeLabel(fromId);
const toLabel = getNodeLabel(toId);
const key = `${relType}:${fromLabel}->` + toLabel;
skippedRelStats.set(key, (skippedRelStats.get(key) || 0) + 1);
const match = line.match(/"([^"]*)","([^"]*)","([^"]*)",([0-9.]+),"([^"]*)"/);
if (match) {
const [, fromId, toId, relType] = match;
const getNodeLabel = (nodeId: string): string => {
if (nodeId.startsWith('comm_')) return 'Community';
return nodeId.split(':')[0];
};
const fromLabel = getNodeLabel(fromId);
const toLabel = getNodeLabel(toId);
const key = `${relType}:${fromLabel}->` + toLabel;
skippedRelStats.set(key, (skippedRelStats.get(key) || 0) + 1);
// Log each skipped relation
if (import.meta.env.DEV) {
console.warn(`⚠️ Skipped: ${key} | "${fromId}" → "${toId}" | ${err instanceof Error ? err.message : String(err)}`);
}
}
}

View file

@ -12,7 +12,12 @@
// ============================================================================
// NODE TABLE NAMES
// ============================================================================
export const NODE_TABLES = ['File', 'Folder', 'Function', 'Class', 'Interface', 'Method', 'CodeElement', 'Community'] as const;
export const NODE_TABLES = [
'File', 'Folder', 'Function', 'Class', 'Interface', 'Method', 'CodeElement', 'Community',
// Multi-language support
'Struct', 'Enum', 'Macro', 'Typedef', 'Union', 'Namespace', 'Trait', 'Impl',
'TypeAlias', 'Const', 'Static', 'Property', 'Record', 'Delegate', 'Annotation', 'Constructor', 'Template', 'Module'
] as const;
export type NodeTableName = typeof NODE_TABLES[number];
// ============================================================================
@ -122,6 +127,41 @@ CREATE NODE TABLE Community (
PRIMARY KEY (id)
)`;
// ============================================================================
// MULTI-LANGUAGE NODE TABLE SCHEMAS
// ============================================================================
// Generic code element with startLine/endLine for C, C++, Rust, Go, Java, C#
const CODE_ELEMENT_BASE = (name: string) => `
CREATE NODE TABLE \`${name}\` (
id STRING,
name STRING,
filePath STRING,
startLine INT64,
endLine INT64,
content STRING,
PRIMARY KEY (id)
)`;
export const STRUCT_SCHEMA = CODE_ELEMENT_BASE('Struct');
export const ENUM_SCHEMA = CODE_ELEMENT_BASE('Enum');
export const MACRO_SCHEMA = CODE_ELEMENT_BASE('Macro');
export const TYPEDEF_SCHEMA = CODE_ELEMENT_BASE('Typedef');
export const UNION_SCHEMA = CODE_ELEMENT_BASE('Union');
export const NAMESPACE_SCHEMA = CODE_ELEMENT_BASE('Namespace');
export const TRAIT_SCHEMA = CODE_ELEMENT_BASE('Trait');
export const IMPL_SCHEMA = CODE_ELEMENT_BASE('Impl');
export const TYPE_ALIAS_SCHEMA = CODE_ELEMENT_BASE('TypeAlias');
export const CONST_SCHEMA = CODE_ELEMENT_BASE('Const');
export const STATIC_SCHEMA = CODE_ELEMENT_BASE('Static');
export const PROPERTY_SCHEMA = CODE_ELEMENT_BASE('Property');
export const RECORD_SCHEMA = CODE_ELEMENT_BASE('Record');
export const DELEGATE_SCHEMA = CODE_ELEMENT_BASE('Delegate');
export const ANNOTATION_SCHEMA = CODE_ELEMENT_BASE('Annotation');
export const CONSTRUCTOR_SCHEMA = CODE_ELEMENT_BASE('Constructor');
export const TEMPLATE_SCHEMA = CODE_ELEMENT_BASE('Template');
export const MODULE_SCHEMA = CODE_ELEMENT_BASE('Module');
// ============================================================================
// RELATION TABLE SCHEMA
// Single table with 'type' property - connects all node tables
@ -136,23 +176,79 @@ CREATE REL TABLE ${REL_TABLE_NAME} (
FROM File TO Interface,
FROM File TO Method,
FROM File TO CodeElement,
FROM File TO \`Struct\`,
FROM File TO \`Enum\`,
FROM File TO \`Macro\`,
FROM File TO Typedef,
FROM File TO \`Union\`,
FROM File TO Namespace,
FROM File TO Trait,
FROM File TO Impl,
FROM File TO TypeAlias,
FROM File TO \`Const\`,
FROM File TO Static,
FROM File TO Property,
FROM File TO Record,
FROM File TO Delegate,
FROM File TO Annotation,
FROM File TO Constructor,
FROM File TO Template,
FROM File TO \`Module\`,
FROM Folder TO Folder,
FROM Folder TO File,
FROM Function TO Function,
FROM Function TO Method,
FROM Function TO Class,
FROM Function TO Community,
FROM Function TO \`Macro\`,
FROM Function TO \`Struct\`,
FROM Function TO Template,
FROM Function TO \`Enum\`,
FROM Function TO Namespace,
FROM Function TO TypeAlias,
FROM Class TO Method,
FROM Class TO Function,
FROM Class TO Class,
FROM Class TO Interface,
FROM Class TO Community,
FROM Class TO Template,
FROM Method TO Function,
FROM Method TO Method,
FROM Method TO Class,
FROM Method TO Community,
FROM Method TO Template,
FROM Method TO \`Struct\`,
FROM Template TO Template,
FROM Template TO Function,
FROM Template TO Method,
FROM Template TO Class,
FROM Template TO \`Struct\`,
FROM CodeElement TO Community,
FROM Interface TO Community,
FROM \`Struct\` TO Community,
FROM \`Struct\` TO Trait,
FROM \`Struct\` TO Function,
FROM \`Struct\` TO Method,
FROM \`Enum\` TO Community,
FROM \`Macro\` TO Community,
FROM Typedef TO Community,
FROM \`Union\` TO Community,
FROM Namespace TO Community,
FROM Trait TO Community,
FROM Impl TO Community,
FROM Impl TO Trait,
FROM TypeAlias TO Community,
FROM \`Const\` TO Community,
FROM Static TO Community,
FROM Property TO Community,
FROM Record TO Community,
FROM Delegate TO Community,
FROM Annotation TO Community,
FROM Constructor TO Community,
FROM Constructor TO Interface,
FROM Constructor TO Class,
FROM Template TO Community,
FROM \`Module\` TO Community,
type STRING,
confidence DOUBLE,
reason STRING
@ -192,6 +288,25 @@ export const NODE_SCHEMA_QUERIES = [
METHOD_SCHEMA,
CODE_ELEMENT_SCHEMA,
COMMUNITY_SCHEMA,
// Multi-language support
STRUCT_SCHEMA,
ENUM_SCHEMA,
MACRO_SCHEMA,
TYPEDEF_SCHEMA,
UNION_SCHEMA,
NAMESPACE_SCHEMA,
TRAIT_SCHEMA,
IMPL_SCHEMA,
TYPE_ALIAS_SCHEMA,
CONST_SCHEMA,
STATIC_SCHEMA,
PROPERTY_SCHEMA,
RECORD_SCHEMA,
DELEGATE_SCHEMA,
ANNOTATION_SCHEMA,
CONSTRUCTOR_SCHEMA,
TEMPLATE_SCHEMA,
MODULE_SCHEMA,
];
export const REL_SCHEMA_QUERIES = [

View file

@ -33,6 +33,12 @@ const getWasmPath = (language: SupportedLanguages, filePath?: string): string =>
[SupportedLanguages.JavaScript]: '/wasm/javascript/tree-sitter-javascript.wasm',
[SupportedLanguages.TypeScript]: '/wasm/typescript/tree-sitter-typescript.wasm',
[SupportedLanguages.Python]: '/wasm/python/tree-sitter-python.wasm',
[SupportedLanguages.Java]: '/wasm/java/tree-sitter-java.wasm',
[SupportedLanguages.C]: '/wasm/c/tree-sitter-c.wasm',
[SupportedLanguages.CPlusPlus]: '/wasm/cpp/tree-sitter-cpp.wasm',
[SupportedLanguages.CSharp]: '/wasm/csharp/tree-sitter-csharp.wasm',
[SupportedLanguages.Go]: '/wasm/go/tree-sitter-go.wasm',
[SupportedLanguages.Rust]: '/wasm/rust/tree-sitter-rust.wasm',
};
return languageFileMap[language];
@ -40,18 +46,27 @@ const getWasmPath = (language: SupportedLanguages, filePath?: string): string =>
export const loadLanguage = async (language: SupportedLanguages, filePath?: string): Promise<void> => {
if (!parser) await loadParser();
const wasmPath = getWasmPath(language, filePath);
// Use wasmPath as cache key to differentiate ts vs tsx
if (languageCache.has(wasmPath)) {
parser!.setLanguage(languageCache.get(wasmPath)!);
return;
}
if (!wasmPath) throw new Error(`Unsupported language: ${language}`);
if (!wasmPath) {
console.error(`❌ [Parser] No WASM path configured for language: ${language}`);
throw new Error(`Unsupported language: ${language}`);
}
const loadedLanguage = await Parser.Language.load(wasmPath);
languageCache.set(wasmPath, loadedLanguage);
parser!.setLanguage(loadedLanguage);
try {
const loadedLanguage = await Parser.Language.load(wasmPath);
languageCache.set(wasmPath, loadedLanguage);
parser!.setLanguage(loadedLanguage);
} catch (error: unknown) {
const errorMessage = error instanceof Error ? error.message : String(error);
console.error(`❌ [Parser] Failed to load WASM grammar for ${language}`);
console.error(` WASM Path: ${wasmPath}`);
console.error(` Error: ${errorMessage}`);
throw new Error(`Failed to load grammar for ${language}: ${errorMessage}`);
}
}

View file

@ -17,25 +17,22 @@ const initFS = () => {
return fsName;
};
// Use public proxy in development, a custom proxy in production
const USE_OWN_PROXY = !import.meta.env.DEV;
// Hosted proxy URL - use this for localhost to avoid local proxy issues
const HOSTED_PROXY_URL = 'https://gitnexus.vercel.app/api/proxy';
/**
* Custom HTTP client that uses a query-param based proxy in production
* isomorphic-git's default corsProxy appends URL as path, which doesn't work
* well with Vercel's file-based routing.
* Custom HTTP client that uses a query-param based proxy
* - In development (localhost): uses the hosted Vercel proxy for reliability
* - In production: uses the local /api/proxy endpoint
*/
const createProxiedHttp = (): typeof http => {
if (!USE_OWN_PROXY) {
// In dev, use the public proxy via isomorphic-git's built-in corsProxy option
return http;
}
// In production, wrap the HTTP client to use the custom proxy
const isDev = typeof window !== 'undefined' && window.location.hostname === 'localhost';
return {
request: async (config) => {
// Rewrite the URL to go through the proxy
const proxyUrl = `/api/proxy?url=${encodeURIComponent(config.url)}`;
// Use hosted proxy for localhost, local proxy for production
const proxyBase = isDev ? HOSTED_PROXY_URL : '/api/proxy';
const proxyUrl = `${proxyBase}?url=${encodeURIComponent(config.url)}`;
// Call the original http.request with the proxied URL
return http.request({
@ -100,9 +97,6 @@ export const cloneRepository = async (
http: httpClient,
dir,
url: repoUrl,
// Only use corsProxy in dev mode (with public proxy)
...(import.meta.env.DEV ? { corsProxy: 'https://cors.isomorphic-git.org' } : {}),
singleBranch: true,
depth: 1,
// Auth callback for private repos (PAT stays client-side)
onAuth: token ? () => ({ username: token, password: 'x-oauth-basic' }) : undefined,