@ctxo/lang-csharp 0.7.0-alpha.0 → 0.7.1
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.
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +13 -4
package/dist/index.d.ts
CHANGED
|
@@ -100,7 +100,7 @@ declare class CSharpCompositeAdapter implements ILanguageAdapter {
|
|
|
100
100
|
getTier(): 'full' | 'syntax' | 'unavailable';
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
type Language = Parameters<InstanceType<typeof Parser>['setLanguage']>[0];
|
|
103
|
+
type Language = Parameters<InstanceType<typeof Parser>['setLanguage']>[0] | object;
|
|
104
104
|
|
|
105
105
|
declare abstract class TreeSitterAdapter implements ILanguageAdapter {
|
|
106
106
|
abstract readonly extensions: readonly string[];
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/roslyn/roslyn-adapter.ts","../src/logger.ts","../src/roslyn/solution-discovery.ts","../src/roslyn/roslyn-process.ts","../src/csharp-adapter.ts","../src/tree-sitter-adapter.ts","../src/composite-adapter.ts","../src/index.ts"],"sourcesContent":["import { relative, dirname, resolve } from 'node:path';\nimport type { SymbolNode, GraphEdge, ComplexityMetrics, SymbolKind, ILanguageAdapter } from '@ctxo/plugin-api';\nimport { createLogger } from '../logger.js';\nimport { detectDotnetSdk, discoverSolution, findCtxoRoslynProject } from './solution-discovery.js';\nimport { runBatchIndex, RoslynKeepAlive, type RoslynBatchResult, type RoslynFileResult } from './roslyn-process.js';\n\nconst log = createLogger('ctxo:roslyn');\n\nexport class RoslynAdapter implements ILanguageAdapter {\n readonly extensions = ['.cs'] as const;\n readonly tier = 'full' as const;\n\n private roslynProjectDir: string | null = null;\n private solutionPath: string | null = null;\n private rootDir: string | null = null;\n private cache = new Map<string, RoslynFileResult>();\n private keepAlive: RoslynKeepAlive | null = null;\n private initialized = false;\n\n isSupported(filePath: string): boolean {\n return filePath.endsWith('.cs');\n }\n\n isReady(): boolean {\n return this.initialized && this.roslynProjectDir !== null && this.solutionPath !== null;\n }\n\n async initialize(rootDir: string): Promise<void> {\n // 1. Check dotnet SDK\n const sdk = detectDotnetSdk();\n if (!sdk.available) {\n log.info(`Roslyn adapter unavailable: .NET SDK ${sdk.version ? `${sdk.version} (< 8.0)` : 'not found'}`);\n return;\n }\n\n // 2. Find ctxo-roslyn project\n this.roslynProjectDir = findCtxoRoslynProject();\n if (!this.roslynProjectDir) {\n log.info('Roslyn adapter unavailable: ctxo-roslyn project not found');\n return;\n }\n\n // 3. Discover solution\n this.solutionPath = discoverSolution(rootDir);\n if (!this.solutionPath) {\n log.info('Roslyn adapter unavailable: no .sln or .csproj found');\n return;\n }\n\n this.rootDir = rootDir;\n log.info(`Roslyn adapter ready: SDK ${sdk.version}, solution ${this.solutionPath}`);\n this.initialized = true;\n }\n\n /**\n * Run batch analysis for all .cs files in the solution.\n * Call this once before extractSymbols/extractEdges for best performance.\n */\n async batchIndex(): Promise<RoslynBatchResult | null> {\n if (!this.isReady()) return null;\n\n const result = await runBatchIndex(this.roslynProjectDir!, this.solutionPath!);\n\n // Build path mapping: solution-relative -> project-root-relative for ALL files\n // .NET outputs \"CFTCoreService/Base.cs\" (relative to solution dir)\n // IndexCommand expects \"src/CFTCoreService/Base.cs\" (relative to project root)\n const solutionDir = dirname(this.solutionPath!);\n const pathMap = new Map<string, string>();\n for (const file of result.files) {\n const absolutePath = resolve(solutionDir, file.file);\n const projectRelative = relative(this.rootDir!, absolutePath).replace(/\\\\/g, '/');\n pathMap.set(file.file, projectRelative);\n }\n\n // Rewrite all paths using the complete mapping\n this.cache.clear();\n for (const file of result.files) {\n const projectRelative = pathMap.get(file.file)!;\n const rewritten = rewriteAllPaths(file, projectRelative, pathMap);\n this.cache.set(projectRelative, rewritten);\n }\n\n log.info(`Roslyn batch index: ${result.totalFiles} files in ${result.elapsed}`);\n return result;\n }\n\n async extractSymbols(filePath: string, _source: string): Promise<SymbolNode[]> {\n const cached = this.cache.get(filePath);\n if (!cached) return [];\n\n return cached.symbols.map(s => ({\n symbolId: s.symbolId,\n name: s.name,\n kind: s.kind as SymbolKind,\n startLine: s.startLine,\n endLine: s.endLine,\n ...(s.startOffset != null ? { startOffset: s.startOffset } : {}),\n ...(s.endOffset != null ? { endOffset: s.endOffset } : {}),\n }));\n }\n\n async extractEdges(filePath: string, _source: string): Promise<GraphEdge[]> {\n const cached = this.cache.get(filePath);\n if (!cached) return [];\n\n // Filter out edges with invalid symbol ID format (must be file::name::kind with non-empty segments)\n const VALID_SYMBOL_ID = /^.+::.+::.+$/;\n return cached.edges\n .filter(e => VALID_SYMBOL_ID.test(e.from) && VALID_SYMBOL_ID.test(e.to))\n .map(e => ({\n from: e.from,\n to: e.to,\n kind: e.kind as GraphEdge['kind'],\n }));\n }\n\n async extractComplexity(filePath: string, _source: string): Promise<ComplexityMetrics[]> {\n const cached = this.cache.get(filePath);\n if (!cached) return [];\n\n return cached.complexity.map(c => ({\n symbolId: c.symbolId,\n cyclomatic: c.cyclomatic,\n }));\n }\n\n /**\n * Start keep-alive process for watch mode.\n */\n async startKeepAlive(): Promise<boolean> {\n if (!this.isReady()) return false;\n\n this.keepAlive = new RoslynKeepAlive(this.roslynProjectDir!, this.solutionPath!);\n return await this.keepAlive.start();\n }\n\n /**\n * Incremental re-analysis of a single file (keep-alive mode).\n */\n async reindexFile(relativePath: string): Promise<RoslynFileResult | null> {\n if (!this.keepAlive?.isAlive()) return null;\n\n const result = await this.keepAlive.analyzeFile(relativePath);\n if (result) {\n this.cache.set(relativePath, result);\n }\n return result;\n }\n\n async dispose(): Promise<void> {\n if (this.keepAlive) {\n await this.keepAlive.shutdown();\n this.keepAlive = null;\n }\n this.cache.clear();\n this.initialized = false;\n }\n}\n\n/**\n * Rewrite ALL file paths in symbols/edges using the complete path mapping.\n * Handles cross-file edge targets (e.g., ChatSync -> BaseSyncJob) correctly.\n */\nfunction rewriteAllPaths(\n file: RoslynFileResult,\n newFilePath: string,\n pathMap: Map<string, string>,\n): RoslynFileResult {\n // Rewrite a symbolId or path string: find any solution-relative path prefix and replace it\n const rewrite = (s: string): string => {\n for (const [oldPath, newPath] of pathMap) {\n if (s.includes(oldPath)) {\n return s.replaceAll(oldPath, newPath);\n }\n }\n return s;\n };\n\n return {\n ...file,\n file: newFilePath,\n symbols: file.symbols.map(s => ({\n ...s,\n symbolId: rewrite(s.symbolId),\n })),\n edges: file.edges.map(e => ({\n ...e,\n from: rewrite(e.from),\n to: rewrite(e.to),\n })),\n complexity: file.complexity.map(c => ({\n ...c,\n symbolId: rewrite(c.symbolId),\n })),\n };\n}\n","/**\n * Minimal namespaced logger. Mirrors the shape of cli's `createLogger` so\n * adapter code extracted from the monorepo continues to work unchanged.\n * Emits to stderr only (stdio transport requires stdout kept clean).\n */\ntype LogFn = (message: string, ...args: unknown[]) => void;\n\nexport interface Logger {\n debug: LogFn;\n info: LogFn;\n warn: LogFn;\n error: LogFn;\n}\n\nfunction enabledFor(namespace: string): boolean {\n const env = process.env['DEBUG'];\n if (!env) return false;\n const patterns = env.split(',').map((p) => p.trim()).filter(Boolean);\n for (const pattern of patterns) {\n if (pattern === '*' || pattern === namespace) return true;\n if (pattern.endsWith('*') && namespace.startsWith(pattern.slice(0, -1))) return true;\n }\n return false;\n}\n\nfunction emit(namespace: string, level: string, message: string, args: unknown[]): void {\n const line = `[${namespace}] ${message}${args.length ? ' ' + args.map(String).join(' ') : ''}`;\n if (level === 'error') process.stderr.write(line + '\\n');\n else if (level === 'warn') process.stderr.write(line + '\\n');\n else if (enabledFor(namespace)) process.stderr.write(line + '\\n');\n}\n\nexport function createLogger(namespace: string): Logger {\n return {\n debug: (msg, ...args) => emit(namespace, 'debug', msg, args),\n info: (msg, ...args) => emit(namespace, 'info', msg, args),\n warn: (msg, ...args) => emit(namespace, 'warn', msg, args),\n error: (msg, ...args) => emit(namespace, 'error', msg, args),\n };\n}\n","import { execFileSync } from 'node:child_process';\nimport { existsSync, readdirSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { createLogger } from '../logger.js';\n\nconst log = createLogger('ctxo:roslyn');\n\nconst IGNORE_DIRS = new Set(['bin', 'obj', 'node_modules', '.git', '.ctxo', 'packages']);\n\nfunction findPackageRoot(startDir: string): string | null {\n let dir = startDir;\n for (let i = 0; i < 10; i++) {\n if (existsSync(join(dir, 'package.json'))) return dir;\n const parent = join(dir, '..');\n if (parent === dir) break;\n dir = parent;\n }\n return null;\n}\n\nfunction findMonorepoRoot(startDir: string): string | null {\n let dir = startDir;\n for (let i = 0; i < 12; i++) {\n if (existsSync(join(dir, 'pnpm-workspace.yaml'))) return dir;\n const parent = join(dir, '..');\n if (parent === dir) break;\n dir = parent;\n }\n return null;\n}\n\nexport function detectDotnetSdk(): { available: boolean; version?: string } {\n try {\n const version = execFileSync('dotnet', ['--version'], { encoding: 'utf-8', timeout: 10_000 }).trim();\n const major = parseInt(version.split('.')[0]!, 10);\n if (major < 8) {\n log.info(`dotnet SDK ${version} found but < 8.0 required`);\n return { available: false, version };\n }\n return { available: true, version };\n } catch {\n return { available: false };\n }\n}\n\nexport function discoverSolution(rootDir: string): string | null {\n // 1. .sln in root\n const rootSlns = findFiles(rootDir, '.sln', 0);\n if (rootSlns.length === 1) return rootSlns[0]!;\n if (rootSlns.length > 1) {\n log.info(`Multiple .sln in root, picking first: ${rootSlns[0]}`);\n return rootSlns[0]!;\n }\n\n // 2. .sln recursive (shallowest first)\n const allSlns = findFiles(rootDir, '.sln', 3);\n if (allSlns.length > 0) {\n allSlns.sort((a, b) => a.split('/').length - b.split('/').length);\n return allSlns[0]!;\n }\n\n // 3. .csproj fallback\n const csprojFiles = findFiles(rootDir, '.csproj', 3);\n if (csprojFiles.length > 0) {\n log.info(`No .sln found, using .csproj: ${csprojFiles[0]}`);\n return csprojFiles[0]!;\n }\n\n return null;\n}\n\nfunction findFiles(dir: string, ext: string, maxDepth: number, currentDepth = 0): string[] {\n const results: string[] = [];\n if (currentDepth > maxDepth) return results;\n\n try {\n const entries = readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isFile() && entry.name.endsWith(ext)) {\n results.push(join(dir, entry.name));\n } else if (entry.isDirectory() && !IGNORE_DIRS.has(entry.name)) {\n results.push(...findFiles(join(dir, entry.name), ext, maxDepth, currentDepth + 1));\n }\n }\n } catch {\n // permission denied, etc.\n }\n\n return results;\n}\n\nexport function findCtxoRoslynProject(): string | null {\n // Look for the ctxo-roslyn project relative to this package\n // tsup bundles all code into dist/*.js, so import.meta.dirname = dist/\n // We need to find the package root by walking up from import.meta.dirname\n const pkgRoot = findPackageRoot(import.meta.dirname);\n const monorepoRoot = findMonorepoRoot(import.meta.dirname);\n const candidates = [\n // Plugin package root — tools/ctxo-roslyn ships inside @ctxo/lang-csharp\n ...(pkgRoot ? [join(pkgRoot, 'tools/ctxo-roslyn')] : []),\n // Monorepo dev: packages/lang-csharp/tools/ctxo-roslyn\n ...(monorepoRoot ? [join(monorepoRoot, 'packages/lang-csharp/tools/ctxo-roslyn')] : []),\n // Bundled dist: dist/roslyn -> ../tools (tsup preserves relative layout)\n join(import.meta.dirname, '../tools/ctxo-roslyn'),\n // Unbundled src layout: src/roslyn -> ../../tools\n join(import.meta.dirname, '../../tools/ctxo-roslyn'),\n // Consumer node_modules installs\n join(process.cwd(), 'node_modules/@ctxo/lang-csharp/tools/ctxo-roslyn'),\n // Legacy paths kept for migration window\n join(process.cwd(), 'node_modules/@ctxo/cli/tools/ctxo-roslyn'),\n join(process.cwd(), 'node_modules/ctxo-mcp/tools/ctxo-roslyn'),\n ];\n\n for (const candidate of candidates) {\n const csproj = join(candidate, 'ctxo-roslyn.csproj');\n if (existsSync(csproj)) return candidate;\n }\n\n return null;\n}\n","import { spawn, type ChildProcess } from 'node:child_process';\nimport { createLogger } from '../logger.js';\n\nconst log = createLogger('ctxo:roslyn');\n\nexport interface RoslynFileResult {\n type: 'file';\n file: string;\n symbols: RoslynSymbol[];\n edges: RoslynEdge[];\n complexity: RoslynComplexity[];\n}\n\nexport interface RoslynSymbol {\n symbolId: string;\n name: string;\n kind: string;\n startLine: number;\n endLine: number;\n startOffset?: number;\n endOffset?: number;\n}\n\nexport interface RoslynEdge {\n from: string;\n to: string;\n kind: string;\n}\n\nexport interface RoslynComplexity {\n symbolId: string;\n cyclomatic: number;\n cognitive: number;\n}\n\nexport interface RoslynProjectGraph {\n type: 'projectGraph';\n projects: Array<{ name: string; path: string }>;\n edges: Array<{ from: string; to: string; kind: string }>;\n}\n\nexport interface RoslynBatchResult {\n files: RoslynFileResult[];\n projectGraph: RoslynProjectGraph | null;\n totalFiles: number;\n elapsed: string;\n}\n\n/**\n * Run ctxo-roslyn in one-shot batch mode.\n * Spawns `dotnet run`, reads JSONL from stdout, returns parsed results.\n */\nexport async function runBatchIndex(\n projectDir: string,\n solutionPath: string,\n timeoutMs = 120_000,\n): Promise<RoslynBatchResult> {\n return new Promise((resolve) => {\n const proc = spawn('dotnet', ['run', '--project', projectDir, '--', solutionPath], {\n stdio: ['ignore', 'pipe', 'pipe'],\n timeout: timeoutMs,\n });\n\n const files: RoslynFileResult[] = [];\n let projectGraph: RoslynProjectGraph | null = null;\n let totalFiles = 0;\n let elapsed = '';\n let stderr = '';\n\n let buffer = '';\n proc.stdout.on('data', (chunk: Buffer) => {\n buffer += chunk.toString();\n let newlineIdx: number;\n while ((newlineIdx = buffer.indexOf('\\n')) !== -1) {\n const line = buffer.slice(0, newlineIdx).trim();\n buffer = buffer.slice(newlineIdx + 1);\n if (!line) continue;\n\n try {\n const obj = JSON.parse(line);\n switch (obj.type) {\n case 'file':\n files.push(obj as RoslynFileResult);\n break;\n case 'projectGraph':\n projectGraph = obj as RoslynProjectGraph;\n break;\n case 'progress':\n log.info(obj.message);\n break;\n case 'done':\n totalFiles = obj.totalFiles ?? 0;\n elapsed = obj.elapsed ?? '';\n break;\n }\n } catch {\n log.error(`Failed to parse JSONL line: ${line.slice(0, 100)}`);\n }\n }\n });\n\n proc.stderr.on('data', (chunk: Buffer) => {\n stderr += chunk.toString();\n });\n\n proc.on('close', (code) => {\n if (code !== 0) {\n log.error(`ctxo-roslyn exited with code ${code}: ${stderr.trim()}`);\n resolve({ files: [], projectGraph: null, totalFiles: 0, elapsed: '' });\n return;\n }\n resolve({ files, projectGraph, totalFiles, elapsed });\n });\n\n proc.on('error', (err) => {\n log.error(`ctxo-roslyn spawn error: ${err.message}`);\n resolve({ files: [], projectGraph: null, totalFiles: 0, elapsed: '' });\n });\n });\n}\n\n/**\n * Keep-alive Roslyn process for watch mode.\n * Stays alive, accepts file paths via stdin, returns results via stdout.\n */\nexport class RoslynKeepAlive {\n private proc: ChildProcess | null = null;\n private buffer = '';\n private pending: Map<string, (result: RoslynFileResult | null) => void> = new Map();\n private projectDir: string;\n private solutionPath: string;\n private timeoutMs: number;\n private inactivityTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(projectDir: string, solutionPath: string, timeoutMs = 300_000) {\n this.projectDir = projectDir;\n this.solutionPath = solutionPath;\n this.timeoutMs = timeoutMs;\n }\n\n async start(): Promise<boolean> {\n return new Promise((resolve) => {\n this.proc = spawn('dotnet', ['run', '--project', this.projectDir, '--', this.solutionPath, '--keep-alive'], {\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n this.proc.stdout!.on('data', (chunk: Buffer) => {\n this.buffer += chunk.toString();\n let newlineIdx: number;\n while ((newlineIdx = this.buffer.indexOf('\\n')) !== -1) {\n const line = this.buffer.slice(0, newlineIdx).trim();\n this.buffer = this.buffer.slice(newlineIdx + 1);\n if (!line) continue;\n\n try {\n const obj = JSON.parse(line);\n if (obj.type === 'ready') {\n log.info(`Roslyn keep-alive ready: ${obj.projectCount} projects, ${obj.fileCount} files`);\n resolve(true);\n } else if (obj.type === 'file') {\n const result = obj as RoslynFileResult;\n const callback = this.pending.get(result.file);\n if (callback) {\n this.pending.delete(result.file);\n callback(result);\n }\n } else if (obj.type === 'progress') {\n log.info(obj.message);\n }\n } catch {\n log.error(`Keep-alive parse error: ${line.slice(0, 100)}`);\n }\n }\n });\n\n this.proc.stderr!.on('data', (chunk: Buffer) => {\n log.error(`Roslyn stderr: ${chunk.toString().trim()}`);\n });\n\n this.proc.on('close', (code) => {\n log.info(`Roslyn keep-alive exited (code ${code})`);\n this.proc = null;\n // Reject any pending requests\n for (const callback of this.pending.values()) callback(null);\n this.pending.clear();\n });\n\n this.proc.on('error', (err) => {\n log.error(`Roslyn keep-alive error: ${err.message}`);\n resolve(false);\n });\n\n this.resetInactivityTimer();\n });\n }\n\n async analyzeFile(relativePath: string): Promise<RoslynFileResult | null> {\n if (!this.proc || !this.proc.stdin!.writable) {\n return null;\n }\n\n this.resetInactivityTimer();\n\n return new Promise((resolve) => {\n this.pending.set(relativePath, resolve);\n this.proc!.stdin!.write(JSON.stringify({ file: relativePath }) + '\\n');\n\n // Per-request timeout\n setTimeout(() => {\n if (this.pending.has(relativePath)) {\n this.pending.delete(relativePath);\n log.error(`Roslyn keep-alive timeout for ${relativePath}`);\n resolve(null);\n }\n }, 30_000);\n });\n }\n\n isAlive(): boolean {\n return this.proc !== null && !this.proc.killed;\n }\n\n async shutdown(): Promise<void> {\n if (this.inactivityTimer) clearTimeout(this.inactivityTimer);\n if (this.proc) {\n this.proc.stdin!.end();\n this.proc.kill();\n this.proc = null;\n }\n }\n\n private resetInactivityTimer(): void {\n if (this.inactivityTimer) clearTimeout(this.inactivityTimer);\n this.inactivityTimer = setTimeout(() => {\n log.info(`Roslyn keep-alive shutting down after ${this.timeoutMs / 1000}s inactivity`);\n this.shutdown();\n }, this.timeoutMs);\n }\n}\n","import CSharpLanguage from 'tree-sitter-c-sharp';\nimport type { SyntaxNode } from 'tree-sitter';\nimport { TreeSitterAdapter } from './tree-sitter-adapter.js';\nimport type { SymbolNode, GraphEdge, ComplexityMetrics, SymbolKind } from '@ctxo/plugin-api';\n\nconst CSHARP_BRANCH_TYPES = [\n 'if_statement', 'for_statement', 'foreach_statement',\n 'while_statement', 'do_statement', 'switch_section',\n 'catch_clause', 'conditional_expression',\n];\n\nexport class CSharpAdapter extends TreeSitterAdapter {\n readonly extensions = ['.cs'] as const;\n\n constructor() {\n super(CSharpLanguage);\n }\n\n async extractSymbols(filePath: string, source: string): Promise<SymbolNode[]> {\n try {\n const tree = this.parse(source);\n const symbols: SymbolNode[] = [];\n this.visitSymbols(tree.rootNode, filePath, '', symbols);\n return symbols;\n } catch (err) {\n console.error(`[ctxo:csharp] Symbol extraction failed for ${filePath}: ${(err as Error).message}`);\n return [];\n }\n }\n\n async extractEdges(filePath: string, source: string): Promise<GraphEdge[]> {\n try {\n const tree = this.parse(source);\n const edges: GraphEdge[] = [];\n const symbols = await this.extractSymbols(filePath, source);\n const firstSymbol = symbols.length > 0 ? symbols[0]!.symbolId : undefined;\n if (!firstSymbol) return edges;\n\n this.visitEdges(tree.rootNode, filePath, firstSymbol, '', edges);\n return edges;\n } catch (err) {\n console.error(`[ctxo:csharp] Edge extraction failed for ${filePath}: ${(err as Error).message}`);\n return [];\n }\n }\n\n async extractComplexity(filePath: string, source: string): Promise<ComplexityMetrics[]> {\n try {\n const tree = this.parse(source);\n const metrics: ComplexityMetrics[] = [];\n this.visitComplexity(tree.rootNode, filePath, '', metrics);\n return metrics;\n } catch (err) {\n console.error(`[ctxo:csharp] Complexity extraction failed for ${filePath}: ${(err as Error).message}`);\n return [];\n }\n }\n\n // ── Symbol visitor ──────────────────────────────────────────\n\n private visitSymbols(\n node: SyntaxNode,\n filePath: string,\n namespace: string,\n symbols: SymbolNode[],\n ): void {\n if (node.type === 'namespace_declaration') {\n const name = node.childForFieldName('name')?.text ?? '';\n const ns = namespace ? `${namespace}.${name}` : name;\n for (let i = 0; i < node.childCount; i++) {\n this.visitSymbols(node.child(i)!, filePath, ns, symbols);\n }\n return;\n }\n\n if (node.type === 'declaration_list') {\n for (let i = 0; i < node.childCount; i++) {\n this.visitSymbols(node.child(i)!, filePath, namespace, symbols);\n }\n return;\n }\n\n const typeMapping: Record<string, SymbolKind> = {\n class_declaration: 'class',\n struct_declaration: 'class',\n record_declaration: 'class',\n interface_declaration: 'interface',\n enum_declaration: 'type',\n };\n\n const kind = typeMapping[node.type];\n if (kind) {\n if (!this.isPublic(node)) return;\n const name = node.childForFieldName('name')?.text;\n if (!name) return;\n\n const qualifiedName = namespace ? `${namespace}.${name}` : name;\n const range = this.nodeToLineRange(node);\n symbols.push({\n symbolId: this.buildSymbolId(filePath, qualifiedName, kind),\n name: qualifiedName,\n kind,\n ...range,\n });\n\n // Extract methods inside the class/struct/record\n if (kind === 'class') {\n this.extractMethodSymbols(node, filePath, qualifiedName, symbols);\n }\n return;\n }\n\n // Recurse into compilation_unit and other containers\n for (let i = 0; i < node.childCount; i++) {\n this.visitSymbols(node.child(i)!, filePath, namespace, symbols);\n }\n }\n\n private extractMethodSymbols(\n classNode: SyntaxNode,\n filePath: string,\n className: string,\n symbols: SymbolNode[],\n ): void {\n const declList = classNode.children.find(c => c.type === 'declaration_list');\n if (!declList) return;\n\n for (let i = 0; i < declList.childCount; i++) {\n const child = declList.child(i)!;\n if (child.type !== 'method_declaration' && child.type !== 'constructor_declaration') continue;\n if (!this.isPublic(child)) continue;\n\n const name = child.childForFieldName('name')?.text;\n if (!name) continue;\n\n const paramCount = this.countParameters(child);\n const qualifiedName = `${className}.${name}(${paramCount})`;\n const range = this.nodeToLineRange(child);\n symbols.push({\n symbolId: this.buildSymbolId(filePath, qualifiedName, 'method'),\n name: qualifiedName,\n kind: 'method',\n ...range,\n });\n }\n }\n\n // ── Edge visitor ────────────────────────────────────────────\n\n private visitEdges(\n node: SyntaxNode,\n filePath: string,\n fromSymbol: string,\n namespace: string,\n edges: GraphEdge[],\n ): void {\n if (node.type === 'using_directive') {\n const nameNode = node.children.find(c => c.type === 'identifier' || c.type === 'qualified_name');\n if (nameNode) {\n edges.push({\n from: fromSymbol,\n to: `${nameNode.text}::${nameNode.text.split('.').pop()}::variable`,\n kind: 'imports',\n });\n }\n return;\n }\n\n if (node.type === 'namespace_declaration') {\n const name = node.childForFieldName('name')?.text ?? '';\n const ns = namespace ? `${namespace}.${name}` : name;\n for (let i = 0; i < node.childCount; i++) {\n this.visitEdges(node.child(i)!, filePath, fromSymbol, ns, edges);\n }\n return;\n }\n\n if (node.type === 'class_declaration' || node.type === 'struct_declaration') {\n if (!this.isPublic(node)) return;\n const name = node.childForFieldName('name')?.text;\n if (!name) return;\n\n const qualifiedName = namespace ? `${namespace}.${name}` : name;\n const classSymbolId = this.buildSymbolId(filePath, qualifiedName, 'class');\n\n // Check base_list for extends/implements\n const baseList = node.children.find(c => c.type === 'base_list');\n if (baseList) {\n for (let i = 0; i < baseList.childCount; i++) {\n const child = baseList.child(i)!;\n if (child.type === 'identifier' || child.type === 'qualified_name') {\n const baseName = child.text;\n // Heuristic: I-prefix = interface → implements, otherwise extends\n const edgeKind = baseName.match(/^I[A-Z]/) ? 'implements' : 'extends';\n const targetKind = edgeKind === 'implements' ? 'interface' : 'class';\n edges.push({\n from: classSymbolId,\n to: this.resolveBaseType(baseName, namespace, targetKind),\n kind: edgeKind,\n });\n }\n }\n }\n }\n\n for (let i = 0; i < node.childCount; i++) {\n this.visitEdges(node.child(i)!, filePath, fromSymbol, namespace, edges);\n }\n }\n\n // ── Complexity visitor ──────────────────────────────────────\n\n private visitComplexity(\n node: SyntaxNode,\n filePath: string,\n namespace: string,\n metrics: ComplexityMetrics[],\n ): void {\n if (node.type === 'namespace_declaration') {\n const name = node.childForFieldName('name')?.text ?? '';\n const ns = namespace ? `${namespace}.${name}` : name;\n for (let i = 0; i < node.childCount; i++) {\n this.visitComplexity(node.child(i)!, filePath, ns, metrics);\n }\n return;\n }\n\n const typeMapping: Record<string, true> = {\n class_declaration: true,\n struct_declaration: true,\n record_declaration: true,\n };\n\n if (typeMapping[node.type]) {\n if (!this.isPublic(node)) return;\n const className = node.childForFieldName('name')?.text;\n if (!className) return;\n\n const qualifiedClass = namespace ? `${namespace}.${className}` : className;\n const declList = node.children.find(c => c.type === 'declaration_list');\n if (!declList) return;\n\n for (let i = 0; i < declList.childCount; i++) {\n const child = declList.child(i)!;\n if (child.type !== 'method_declaration') continue;\n if (!this.isPublic(child)) continue;\n\n const methodName = child.childForFieldName('name')?.text;\n if (!methodName) continue;\n\n const paramCount = this.countParameters(child);\n metrics.push({\n symbolId: this.buildSymbolId(filePath, `${qualifiedClass}.${methodName}(${paramCount})`, 'method'),\n cyclomatic: this.countCyclomaticComplexity(child, CSHARP_BRANCH_TYPES),\n });\n }\n return;\n }\n\n for (let i = 0; i < node.childCount; i++) {\n this.visitComplexity(node.child(i)!, filePath, namespace, metrics);\n }\n }\n\n // ── Helpers ─────────────────────────────────────────────────\n\n private countParameters(methodNode: SyntaxNode): number {\n const paramList = methodNode.childForFieldName('parameters');\n if (!paramList) return 0;\n let count = 0;\n for (let i = 0; i < paramList.childCount; i++) {\n if (paramList.child(i)!.type === 'parameter') count++;\n }\n return count;\n }\n\n private isPublic(node: SyntaxNode): boolean {\n for (let i = 0; i < node.childCount; i++) {\n const child = node.child(i)!;\n if (child.type === 'modifier' && child.text === 'public') return true;\n }\n return false;\n }\n\n private resolveBaseType(baseName: string, namespace: string, defaultKind: SymbolKind): string {\n // Check symbol registry first\n const prefix = namespace ? `${namespace}.${baseName}` : baseName;\n for (const [id] of this.symbolRegistry) {\n if (id.includes(`::${prefix}::`)) return id;\n if (id.includes(`::${baseName}::`)) return id;\n }\n // Fallback: assume same namespace\n const qualifiedName = namespace ? `${namespace}.${baseName}` : baseName;\n return `${qualifiedName}::${baseName}::${defaultKind}`;\n }\n}\n","import Parser from 'tree-sitter';\nimport type { Tree, SyntaxNode } from 'tree-sitter';\ntype Language = Parameters<InstanceType<typeof Parser>['setLanguage']>[0];\nimport { extname } from 'node:path';\nimport type { SymbolNode, GraphEdge, ComplexityMetrics, SymbolKind, ILanguageAdapter } from '@ctxo/plugin-api';\n\nexport abstract class TreeSitterAdapter implements ILanguageAdapter {\n abstract readonly extensions: readonly string[];\n readonly tier = 'syntax' as const;\n\n protected parser: Parser;\n protected symbolRegistry = new Map<string, SymbolKind>();\n\n constructor(language: Language) {\n this.parser = new Parser();\n this.parser.setLanguage(language);\n }\n\n isSupported(filePath: string): boolean {\n const ext = extname(filePath).toLowerCase();\n return (this.extensions as readonly string[]).includes(ext);\n }\n\n setSymbolRegistry(registry: Map<string, SymbolKind>): void {\n this.symbolRegistry = registry;\n }\n\n protected parse(source: string): Tree {\n return this.parser.parse(source);\n }\n\n protected buildSymbolId(filePath: string, name: string, kind: SymbolKind): string {\n return `${filePath}::${name}::${kind}`;\n }\n\n protected nodeToLineRange(node: SyntaxNode): {\n startLine: number;\n endLine: number;\n startOffset: number;\n endOffset: number;\n } {\n return {\n startLine: node.startPosition.row,\n endLine: node.endPosition.row,\n startOffset: node.startIndex,\n endOffset: node.endIndex,\n };\n }\n\n protected countCyclomaticComplexity(node: SyntaxNode, branchTypes: string[]): number {\n let complexity = 1;\n const visit = (n: SyntaxNode) => {\n if (branchTypes.includes(n.type)) {\n complexity++;\n }\n for (let i = 0; i < n.childCount; i++) {\n visit(n.child(i)!);\n }\n };\n visit(node);\n return complexity;\n }\n\n abstract extractSymbols(filePath: string, source: string): Promise<SymbolNode[]>;\n abstract extractEdges(filePath: string, source: string): Promise<GraphEdge[]>;\n abstract extractComplexity(filePath: string, source: string): Promise<ComplexityMetrics[]>;\n}\n","import type { SymbolNode, GraphEdge, ComplexityMetrics, SymbolKind, ILanguageAdapter } from '@ctxo/plugin-api';\nimport { RoslynAdapter } from './roslyn/roslyn-adapter.js';\nimport { CSharpAdapter } from './csharp-adapter.js';\nimport { createLogger } from './logger.js';\n\nconst log = createLogger('ctxo:lang-csharp');\n\n/**\n * Chooses between the full-tier Roslyn launcher and the syntax-tier tree-sitter\n * adapter at initialize() time. Forwards extract*() calls to the active delegate\n * and exposes the Roslyn delegate (when active) for cli optimizations such as\n * watch-mode keep-alive and batch index pre-warm.\n */\nexport class CSharpCompositeAdapter implements ILanguageAdapter {\n private delegate: ILanguageAdapter | null = null;\n private roslyn: RoslynAdapter | null = null;\n private treeSitter: CSharpAdapter | null = null;\n\n async initialize(rootDir: string): Promise<void> {\n try {\n const roslyn = new RoslynAdapter();\n await roslyn.initialize(rootDir);\n if (roslyn.isReady()) {\n this.roslyn = roslyn;\n this.delegate = roslyn;\n log.info('C# plugin: Roslyn full-tier active');\n return;\n }\n // Roslyn constructed but not ready — dispose and fall through\n await roslyn.dispose();\n } catch (err) {\n log.warn(`Roslyn unavailable: ${(err as Error).message}`);\n }\n\n try {\n this.treeSitter = new CSharpAdapter();\n this.delegate = this.treeSitter;\n log.info('C# plugin: tree-sitter syntax-tier active (install .NET 8+ SDK for full tier)');\n } catch (err) {\n log.warn(`tree-sitter fallback unavailable: ${(err as Error).message}`);\n }\n }\n\n async dispose(): Promise<void> {\n if (this.roslyn) await this.roslyn.dispose();\n }\n\n extractSymbols(filePath: string, source: string): Promise<SymbolNode[]> {\n return this.delegate ? this.delegate.extractSymbols(filePath, source) : Promise.resolve([]);\n }\n\n extractEdges(filePath: string, source: string): Promise<GraphEdge[]> {\n return this.delegate ? this.delegate.extractEdges(filePath, source) : Promise.resolve([]);\n }\n\n extractComplexity(filePath: string, source: string): Promise<ComplexityMetrics[]> {\n return this.delegate ? this.delegate.extractComplexity(filePath, source) : Promise.resolve([]);\n }\n\n isSupported(filePath: string): boolean {\n return filePath.toLowerCase().endsWith('.cs');\n }\n\n setSymbolRegistry(registry: Map<string, SymbolKind>): void {\n this.delegate?.setSymbolRegistry?.(registry);\n }\n\n /** Exposed for cli watch/index optimizations. Null when running in syntax tier. */\n getRoslynDelegate(): RoslynAdapter | null {\n return this.roslyn;\n }\n\n /** Current active tier after initialize() resolves. */\n getTier(): 'full' | 'syntax' | 'unavailable' {\n if (this.roslyn) return 'full';\n if (this.treeSitter) return 'syntax';\n return 'unavailable';\n }\n}\n","import type { CtxoLanguagePlugin, PluginContext, ILanguageAdapter } from '@ctxo/plugin-api';\nimport { CSharpCompositeAdapter } from './composite-adapter.js';\n\nexport { CSharpCompositeAdapter } from './composite-adapter.js';\nexport { CSharpAdapter } from './csharp-adapter.js';\nexport { RoslynAdapter } from './roslyn/roslyn-adapter.js';\nexport { TreeSitterAdapter } from './tree-sitter-adapter.js';\n\nconst VERSION = '0.7.0-alpha.0';\n\nexport const plugin: CtxoLanguagePlugin = {\n apiVersion: '1',\n id: 'csharp',\n name: 'C# (Roslyn full tier, tree-sitter fallback)',\n version: VERSION,\n extensions: ['.cs'],\n // Plugin advertises full-tier capability; the composite adapter downgrades to\n // syntax at runtime when .NET SDK 8+ is unavailable.\n tier: 'full',\n createAdapter(_ctx: PluginContext): ILanguageAdapter {\n return new CSharpCompositeAdapter();\n },\n};\n\nexport default plugin;\n"],"mappings":";AAAA,SAAS,UAAU,SAAS,eAAe;;;ACc3C,SAAS,WAAW,WAA4B;AAC9C,QAAM,MAAM,QAAQ,IAAI,OAAO;AAC/B,MAAI,CAAC,IAAK,QAAO;AACjB,QAAM,WAAW,IAAI,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,OAAO;AACnE,aAAW,WAAW,UAAU;AAC9B,QAAI,YAAY,OAAO,YAAY,UAAW,QAAO;AACrD,QAAI,QAAQ,SAAS,GAAG,KAAK,UAAU,WAAW,QAAQ,MAAM,GAAG,EAAE,CAAC,EAAG,QAAO;AAAA,EAClF;AACA,SAAO;AACT;AAEA,SAAS,KAAK,WAAmB,OAAe,SAAiB,MAAuB;AACtF,QAAM,OAAO,IAAI,SAAS,KAAK,OAAO,GAAG,KAAK,SAAS,MAAM,KAAK,IAAI,MAAM,EAAE,KAAK,GAAG,IAAI,EAAE;AAC5F,MAAI,UAAU,QAAS,SAAQ,OAAO,MAAM,OAAO,IAAI;AAAA,WAC9C,UAAU,OAAQ,SAAQ,OAAO,MAAM,OAAO,IAAI;AAAA,WAClD,WAAW,SAAS,EAAG,SAAQ,OAAO,MAAM,OAAO,IAAI;AAClE;AAEO,SAAS,aAAa,WAA2B;AACtD,SAAO;AAAA,IACL,OAAO,CAAC,QAAQ,SAAS,KAAK,WAAW,SAAS,KAAK,IAAI;AAAA,IAC3D,MAAM,CAAC,QAAQ,SAAS,KAAK,WAAW,QAAQ,KAAK,IAAI;AAAA,IACzD,MAAM,CAAC,QAAQ,SAAS,KAAK,WAAW,QAAQ,KAAK,IAAI;AAAA,IACzD,OAAO,CAAC,QAAQ,SAAS,KAAK,WAAW,SAAS,KAAK,IAAI;AAAA,EAC7D;AACF;;;ACvCA,SAAS,oBAAoB;AAC7B,SAAS,YAAY,mBAAmB;AACxC,SAAS,YAAY;AAGrB,IAAM,MAAM,aAAa,aAAa;AAEtC,IAAM,cAAc,oBAAI,IAAI,CAAC,OAAO,OAAO,gBAAgB,QAAQ,SAAS,UAAU,CAAC;AAEvF,SAAS,gBAAgB,UAAiC;AACxD,MAAI,MAAM;AACV,WAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,QAAI,WAAW,KAAK,KAAK,cAAc,CAAC,EAAG,QAAO;AAClD,UAAM,SAAS,KAAK,KAAK,IAAI;AAC7B,QAAI,WAAW,IAAK;AACpB,UAAM;AAAA,EACR;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,UAAiC;AACzD,MAAI,MAAM;AACV,WAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,QAAI,WAAW,KAAK,KAAK,qBAAqB,CAAC,EAAG,QAAO;AACzD,UAAM,SAAS,KAAK,KAAK,IAAI;AAC7B,QAAI,WAAW,IAAK;AACpB,UAAM;AAAA,EACR;AACA,SAAO;AACT;AAEO,SAAS,kBAA4D;AAC1E,MAAI;AACF,UAAM,UAAU,aAAa,UAAU,CAAC,WAAW,GAAG,EAAE,UAAU,SAAS,SAAS,IAAO,CAAC,EAAE,KAAK;AACnG,UAAM,QAAQ,SAAS,QAAQ,MAAM,GAAG,EAAE,CAAC,GAAI,EAAE;AACjD,QAAI,QAAQ,GAAG;AACb,UAAI,KAAK,cAAc,OAAO,2BAA2B;AACzD,aAAO,EAAE,WAAW,OAAO,QAAQ;AAAA,IACrC;AACA,WAAO,EAAE,WAAW,MAAM,QAAQ;AAAA,EACpC,QAAQ;AACN,WAAO,EAAE,WAAW,MAAM;AAAA,EAC5B;AACF;AAEO,SAAS,iBAAiB,SAAgC;AAE/D,QAAM,WAAW,UAAU,SAAS,QAAQ,CAAC;AAC7C,MAAI,SAAS,WAAW,EAAG,QAAO,SAAS,CAAC;AAC5C,MAAI,SAAS,SAAS,GAAG;AACvB,QAAI,KAAK,yCAAyC,SAAS,CAAC,CAAC,EAAE;AAC/D,WAAO,SAAS,CAAC;AAAA,EACnB;AAGA,QAAM,UAAU,UAAU,SAAS,QAAQ,CAAC;AAC5C,MAAI,QAAQ,SAAS,GAAG;AACtB,YAAQ,KAAK,CAAC,GAAG,MAAM,EAAE,MAAM,GAAG,EAAE,SAAS,EAAE,MAAM,GAAG,EAAE,MAAM;AAChE,WAAO,QAAQ,CAAC;AAAA,EAClB;AAGA,QAAM,cAAc,UAAU,SAAS,WAAW,CAAC;AACnD,MAAI,YAAY,SAAS,GAAG;AAC1B,QAAI,KAAK,iCAAiC,YAAY,CAAC,CAAC,EAAE;AAC1D,WAAO,YAAY,CAAC;AAAA,EACtB;AAEA,SAAO;AACT;AAEA,SAAS,UAAU,KAAa,KAAa,UAAkB,eAAe,GAAa;AACzF,QAAM,UAAoB,CAAC;AAC3B,MAAI,eAAe,SAAU,QAAO;AAEpC,MAAI;AACF,UAAM,UAAU,YAAY,KAAK,EAAE,eAAe,KAAK,CAAC;AACxD,eAAW,SAAS,SAAS;AAC3B,UAAI,MAAM,OAAO,KAAK,MAAM,KAAK,SAAS,GAAG,GAAG;AAC9C,gBAAQ,KAAK,KAAK,KAAK,MAAM,IAAI,CAAC;AAAA,MACpC,WAAW,MAAM,YAAY,KAAK,CAAC,YAAY,IAAI,MAAM,IAAI,GAAG;AAC9D,gBAAQ,KAAK,GAAG,UAAU,KAAK,KAAK,MAAM,IAAI,GAAG,KAAK,UAAU,eAAe,CAAC,CAAC;AAAA,MACnF;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAER;AAEA,SAAO;AACT;AAEO,SAAS,wBAAuC;AAIrD,QAAM,UAAU,gBAAgB,YAAY,OAAO;AACnD,QAAM,eAAe,iBAAiB,YAAY,OAAO;AACzD,QAAM,aAAa;AAAA;AAAA,IAEjB,GAAI,UAAU,CAAC,KAAK,SAAS,mBAAmB,CAAC,IAAI,CAAC;AAAA;AAAA,IAEtD,GAAI,eAAe,CAAC,KAAK,cAAc,wCAAwC,CAAC,IAAI,CAAC;AAAA;AAAA,IAErF,KAAK,YAAY,SAAS,sBAAsB;AAAA;AAAA,IAEhD,KAAK,YAAY,SAAS,yBAAyB;AAAA;AAAA,IAEnD,KAAK,QAAQ,IAAI,GAAG,kDAAkD;AAAA;AAAA,IAEtE,KAAK,QAAQ,IAAI,GAAG,0CAA0C;AAAA,IAC9D,KAAK,QAAQ,IAAI,GAAG,yCAAyC;AAAA,EAC/D;AAEA,aAAW,aAAa,YAAY;AAClC,UAAM,SAAS,KAAK,WAAW,oBAAoB;AACnD,QAAI,WAAW,MAAM,EAAG,QAAO;AAAA,EACjC;AAEA,SAAO;AACT;;;ACvHA,SAAS,aAAgC;AAGzC,IAAMA,OAAM,aAAa,aAAa;AAiDtC,eAAsB,cACpB,YACA,cACA,YAAY,MACgB;AAC5B,SAAO,IAAI,QAAQ,CAACC,aAAY;AAC9B,UAAM,OAAO,MAAM,UAAU,CAAC,OAAO,aAAa,YAAY,MAAM,YAAY,GAAG;AAAA,MACjF,OAAO,CAAC,UAAU,QAAQ,MAAM;AAAA,MAChC,SAAS;AAAA,IACX,CAAC;AAED,UAAM,QAA4B,CAAC;AACnC,QAAI,eAA0C;AAC9C,QAAI,aAAa;AACjB,QAAI,UAAU;AACd,QAAI,SAAS;AAEb,QAAI,SAAS;AACb,SAAK,OAAO,GAAG,QAAQ,CAAC,UAAkB;AACxC,gBAAU,MAAM,SAAS;AACzB,UAAI;AACJ,cAAQ,aAAa,OAAO,QAAQ,IAAI,OAAO,IAAI;AACjD,cAAM,OAAO,OAAO,MAAM,GAAG,UAAU,EAAE,KAAK;AAC9C,iBAAS,OAAO,MAAM,aAAa,CAAC;AACpC,YAAI,CAAC,KAAM;AAEX,YAAI;AACF,gBAAM,MAAM,KAAK,MAAM,IAAI;AAC3B,kBAAQ,IAAI,MAAM;AAAA,YAChB,KAAK;AACH,oBAAM,KAAK,GAAuB;AAClC;AAAA,YACF,KAAK;AACH,6BAAe;AACf;AAAA,YACF,KAAK;AACH,cAAAD,KAAI,KAAK,IAAI,OAAO;AACpB;AAAA,YACF,KAAK;AACH,2BAAa,IAAI,cAAc;AAC/B,wBAAU,IAAI,WAAW;AACzB;AAAA,UACJ;AAAA,QACF,QAAQ;AACN,UAAAA,KAAI,MAAM,+BAA+B,KAAK,MAAM,GAAG,GAAG,CAAC,EAAE;AAAA,QAC/D;AAAA,MACF;AAAA,IACF,CAAC;AAED,SAAK,OAAO,GAAG,QAAQ,CAAC,UAAkB;AACxC,gBAAU,MAAM,SAAS;AAAA,IAC3B,CAAC;AAED,SAAK,GAAG,SAAS,CAAC,SAAS;AACzB,UAAI,SAAS,GAAG;AACd,QAAAA,KAAI,MAAM,gCAAgC,IAAI,KAAK,OAAO,KAAK,CAAC,EAAE;AAClE,QAAAC,SAAQ,EAAE,OAAO,CAAC,GAAG,cAAc,MAAM,YAAY,GAAG,SAAS,GAAG,CAAC;AACrE;AAAA,MACF;AACA,MAAAA,SAAQ,EAAE,OAAO,cAAc,YAAY,QAAQ,CAAC;AAAA,IACtD,CAAC;AAED,SAAK,GAAG,SAAS,CAAC,QAAQ;AACxB,MAAAD,KAAI,MAAM,4BAA4B,IAAI,OAAO,EAAE;AACnD,MAAAC,SAAQ,EAAE,OAAO,CAAC,GAAG,cAAc,MAAM,YAAY,GAAG,SAAS,GAAG,CAAC;AAAA,IACvE,CAAC;AAAA,EACH,CAAC;AACH;AAMO,IAAM,kBAAN,MAAsB;AAAA,EACnB,OAA4B;AAAA,EAC5B,SAAS;AAAA,EACT,UAAkE,oBAAI,IAAI;AAAA,EAC1E;AAAA,EACA;AAAA,EACA;AAAA,EACA,kBAAwD;AAAA,EAEhE,YAAY,YAAoB,cAAsB,YAAY,KAAS;AACzE,SAAK,aAAa;AAClB,SAAK,eAAe;AACpB,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,MAAM,QAA0B;AAC9B,WAAO,IAAI,QAAQ,CAACA,aAAY;AAC9B,WAAK,OAAO,MAAM,UAAU,CAAC,OAAO,aAAa,KAAK,YAAY,MAAM,KAAK,cAAc,cAAc,GAAG;AAAA,QAC1G,OAAO,CAAC,QAAQ,QAAQ,MAAM;AAAA,MAChC,CAAC;AAED,WAAK,KAAK,OAAQ,GAAG,QAAQ,CAAC,UAAkB;AAC9C,aAAK,UAAU,MAAM,SAAS;AAC9B,YAAI;AACJ,gBAAQ,aAAa,KAAK,OAAO,QAAQ,IAAI,OAAO,IAAI;AACtD,gBAAM,OAAO,KAAK,OAAO,MAAM,GAAG,UAAU,EAAE,KAAK;AACnD,eAAK,SAAS,KAAK,OAAO,MAAM,aAAa,CAAC;AAC9C,cAAI,CAAC,KAAM;AAEX,cAAI;AACF,kBAAM,MAAM,KAAK,MAAM,IAAI;AAC3B,gBAAI,IAAI,SAAS,SAAS;AACxB,cAAAD,KAAI,KAAK,4BAA4B,IAAI,YAAY,cAAc,IAAI,SAAS,QAAQ;AACxF,cAAAC,SAAQ,IAAI;AAAA,YACd,WAAW,IAAI,SAAS,QAAQ;AAC9B,oBAAM,SAAS;AACf,oBAAM,WAAW,KAAK,QAAQ,IAAI,OAAO,IAAI;AAC7C,kBAAI,UAAU;AACZ,qBAAK,QAAQ,OAAO,OAAO,IAAI;AAC/B,yBAAS,MAAM;AAAA,cACjB;AAAA,YACF,WAAW,IAAI,SAAS,YAAY;AAClC,cAAAD,KAAI,KAAK,IAAI,OAAO;AAAA,YACtB;AAAA,UACF,QAAQ;AACN,YAAAA,KAAI,MAAM,2BAA2B,KAAK,MAAM,GAAG,GAAG,CAAC,EAAE;AAAA,UAC3D;AAAA,QACF;AAAA,MACF,CAAC;AAED,WAAK,KAAK,OAAQ,GAAG,QAAQ,CAAC,UAAkB;AAC9C,QAAAA,KAAI,MAAM,kBAAkB,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE;AAAA,MACvD,CAAC;AAED,WAAK,KAAK,GAAG,SAAS,CAAC,SAAS;AAC9B,QAAAA,KAAI,KAAK,kCAAkC,IAAI,GAAG;AAClD,aAAK,OAAO;AAEZ,mBAAW,YAAY,KAAK,QAAQ,OAAO,EAAG,UAAS,IAAI;AAC3D,aAAK,QAAQ,MAAM;AAAA,MACrB,CAAC;AAED,WAAK,KAAK,GAAG,SAAS,CAAC,QAAQ;AAC7B,QAAAA,KAAI,MAAM,4BAA4B,IAAI,OAAO,EAAE;AACnD,QAAAC,SAAQ,KAAK;AAAA,MACf,CAAC;AAED,WAAK,qBAAqB;AAAA,IAC5B,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,YAAY,cAAwD;AACxE,QAAI,CAAC,KAAK,QAAQ,CAAC,KAAK,KAAK,MAAO,UAAU;AAC5C,aAAO;AAAA,IACT;AAEA,SAAK,qBAAqB;AAE1B,WAAO,IAAI,QAAQ,CAACA,aAAY;AAC9B,WAAK,QAAQ,IAAI,cAAcA,QAAO;AACtC,WAAK,KAAM,MAAO,MAAM,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC,IAAI,IAAI;AAGrE,iBAAW,MAAM;AACf,YAAI,KAAK,QAAQ,IAAI,YAAY,GAAG;AAClC,eAAK,QAAQ,OAAO,YAAY;AAChC,UAAAD,KAAI,MAAM,iCAAiC,YAAY,EAAE;AACzD,UAAAC,SAAQ,IAAI;AAAA,QACd;AAAA,MACF,GAAG,GAAM;AAAA,IACX,CAAC;AAAA,EACH;AAAA,EAEA,UAAmB;AACjB,WAAO,KAAK,SAAS,QAAQ,CAAC,KAAK,KAAK;AAAA,EAC1C;AAAA,EAEA,MAAM,WAA0B;AAC9B,QAAI,KAAK,gBAAiB,cAAa,KAAK,eAAe;AAC3D,QAAI,KAAK,MAAM;AACb,WAAK,KAAK,MAAO,IAAI;AACrB,WAAK,KAAK,KAAK;AACf,WAAK,OAAO;AAAA,IACd;AAAA,EACF;AAAA,EAEQ,uBAA6B;AACnC,QAAI,KAAK,gBAAiB,cAAa,KAAK,eAAe;AAC3D,SAAK,kBAAkB,WAAW,MAAM;AACtC,MAAAD,KAAI,KAAK,yCAAyC,KAAK,YAAY,GAAI,cAAc;AACrF,WAAK,SAAS;AAAA,IAChB,GAAG,KAAK,SAAS;AAAA,EACnB;AACF;;;AHxOA,IAAME,OAAM,aAAa,aAAa;AAE/B,IAAM,gBAAN,MAAgD;AAAA,EAC5C,aAAa,CAAC,KAAK;AAAA,EACnB,OAAO;AAAA,EAER,mBAAkC;AAAA,EAClC,eAA8B;AAAA,EAC9B,UAAyB;AAAA,EACzB,QAAQ,oBAAI,IAA8B;AAAA,EAC1C,YAAoC;AAAA,EACpC,cAAc;AAAA,EAEtB,YAAY,UAA2B;AACrC,WAAO,SAAS,SAAS,KAAK;AAAA,EAChC;AAAA,EAEA,UAAmB;AACjB,WAAO,KAAK,eAAe,KAAK,qBAAqB,QAAQ,KAAK,iBAAiB;AAAA,EACrF;AAAA,EAEA,MAAM,WAAW,SAAgC;AAE/C,UAAM,MAAM,gBAAgB;AAC5B,QAAI,CAAC,IAAI,WAAW;AAClB,MAAAA,KAAI,KAAK,wCAAwC,IAAI,UAAU,GAAG,IAAI,OAAO,aAAa,WAAW,EAAE;AACvG;AAAA,IACF;AAGA,SAAK,mBAAmB,sBAAsB;AAC9C,QAAI,CAAC,KAAK,kBAAkB;AAC1B,MAAAA,KAAI,KAAK,2DAA2D;AACpE;AAAA,IACF;AAGA,SAAK,eAAe,iBAAiB,OAAO;AAC5C,QAAI,CAAC,KAAK,cAAc;AACtB,MAAAA,KAAI,KAAK,sDAAsD;AAC/D;AAAA,IACF;AAEA,SAAK,UAAU;AACf,IAAAA,KAAI,KAAK,6BAA6B,IAAI,OAAO,cAAc,KAAK,YAAY,EAAE;AAClF,SAAK,cAAc;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,aAAgD;AACpD,QAAI,CAAC,KAAK,QAAQ,EAAG,QAAO;AAE5B,UAAM,SAAS,MAAM,cAAc,KAAK,kBAAmB,KAAK,YAAa;AAK7E,UAAM,cAAc,QAAQ,KAAK,YAAa;AAC9C,UAAM,UAAU,oBAAI,IAAoB;AACxC,eAAW,QAAQ,OAAO,OAAO;AAC/B,YAAM,eAAe,QAAQ,aAAa,KAAK,IAAI;AACnD,YAAM,kBAAkB,SAAS,KAAK,SAAU,YAAY,EAAE,QAAQ,OAAO,GAAG;AAChF,cAAQ,IAAI,KAAK,MAAM,eAAe;AAAA,IACxC;AAGA,SAAK,MAAM,MAAM;AACjB,eAAW,QAAQ,OAAO,OAAO;AAC/B,YAAM,kBAAkB,QAAQ,IAAI,KAAK,IAAI;AAC7C,YAAM,YAAY,gBAAgB,MAAM,iBAAiB,OAAO;AAChE,WAAK,MAAM,IAAI,iBAAiB,SAAS;AAAA,IAC3C;AAEA,IAAAA,KAAI,KAAK,uBAAuB,OAAO,UAAU,aAAa,OAAO,OAAO,EAAE;AAC9E,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,eAAe,UAAkB,SAAwC;AAC7E,UAAM,SAAS,KAAK,MAAM,IAAI,QAAQ;AACtC,QAAI,CAAC,OAAQ,QAAO,CAAC;AAErB,WAAO,OAAO,QAAQ,IAAI,QAAM;AAAA,MAC9B,UAAU,EAAE;AAAA,MACZ,MAAM,EAAE;AAAA,MACR,MAAM,EAAE;AAAA,MACR,WAAW,EAAE;AAAA,MACb,SAAS,EAAE;AAAA,MACX,GAAI,EAAE,eAAe,OAAO,EAAE,aAAa,EAAE,YAAY,IAAI,CAAC;AAAA,MAC9D,GAAI,EAAE,aAAa,OAAO,EAAE,WAAW,EAAE,UAAU,IAAI,CAAC;AAAA,IAC1D,EAAE;AAAA,EACJ;AAAA,EAEA,MAAM,aAAa,UAAkB,SAAuC;AAC1E,UAAM,SAAS,KAAK,MAAM,IAAI,QAAQ;AACtC,QAAI,CAAC,OAAQ,QAAO,CAAC;AAGrB,UAAM,kBAAkB;AACxB,WAAO,OAAO,MACX,OAAO,OAAK,gBAAgB,KAAK,EAAE,IAAI,KAAK,gBAAgB,KAAK,EAAE,EAAE,CAAC,EACtE,IAAI,QAAM;AAAA,MACT,MAAM,EAAE;AAAA,MACR,IAAI,EAAE;AAAA,MACN,MAAM,EAAE;AAAA,IACV,EAAE;AAAA,EACN;AAAA,EAEA,MAAM,kBAAkB,UAAkB,SAA+C;AACvF,UAAM,SAAS,KAAK,MAAM,IAAI,QAAQ;AACtC,QAAI,CAAC,OAAQ,QAAO,CAAC;AAErB,WAAO,OAAO,WAAW,IAAI,QAAM;AAAA,MACjC,UAAU,EAAE;AAAA,MACZ,YAAY,EAAE;AAAA,IAChB,EAAE;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,iBAAmC;AACvC,QAAI,CAAC,KAAK,QAAQ,EAAG,QAAO;AAE5B,SAAK,YAAY,IAAI,gBAAgB,KAAK,kBAAmB,KAAK,YAAa;AAC/E,WAAO,MAAM,KAAK,UAAU,MAAM;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAAY,cAAwD;AACxE,QAAI,CAAC,KAAK,WAAW,QAAQ,EAAG,QAAO;AAEvC,UAAM,SAAS,MAAM,KAAK,UAAU,YAAY,YAAY;AAC5D,QAAI,QAAQ;AACV,WAAK,MAAM,IAAI,cAAc,MAAM;AAAA,IACrC;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,UAAyB;AAC7B,QAAI,KAAK,WAAW;AAClB,YAAM,KAAK,UAAU,SAAS;AAC9B,WAAK,YAAY;AAAA,IACnB;AACA,SAAK,MAAM,MAAM;AACjB,SAAK,cAAc;AAAA,EACrB;AACF;AAMA,SAAS,gBACP,MACA,aACA,SACkB;AAElB,QAAM,UAAU,CAAC,MAAsB;AACrC,eAAW,CAAC,SAAS,OAAO,KAAK,SAAS;AACxC,UAAI,EAAE,SAAS,OAAO,GAAG;AACvB,eAAO,EAAE,WAAW,SAAS,OAAO;AAAA,MACtC;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,MAAM;AAAA,IACN,SAAS,KAAK,QAAQ,IAAI,QAAM;AAAA,MAC9B,GAAG;AAAA,MACH,UAAU,QAAQ,EAAE,QAAQ;AAAA,IAC9B,EAAE;AAAA,IACF,OAAO,KAAK,MAAM,IAAI,QAAM;AAAA,MAC1B,GAAG;AAAA,MACH,MAAM,QAAQ,EAAE,IAAI;AAAA,MACpB,IAAI,QAAQ,EAAE,EAAE;AAAA,IAClB,EAAE;AAAA,IACF,YAAY,KAAK,WAAW,IAAI,QAAM;AAAA,MACpC,GAAG;AAAA,MACH,UAAU,QAAQ,EAAE,QAAQ;AAAA,IAC9B,EAAE;AAAA,EACJ;AACF;;;AInMA,OAAO,oBAAoB;;;ACA3B,OAAO,YAAY;AAGnB,SAAS,eAAe;AAGjB,IAAe,oBAAf,MAA6D;AAAA,EAEzD,OAAO;AAAA,EAEN;AAAA,EACA,iBAAiB,oBAAI,IAAwB;AAAA,EAEvD,YAAY,UAAoB;AAC9B,SAAK,SAAS,IAAI,OAAO;AACzB,SAAK,OAAO,YAAY,QAAQ;AAAA,EAClC;AAAA,EAEA,YAAY,UAA2B;AACrC,UAAM,MAAM,QAAQ,QAAQ,EAAE,YAAY;AAC1C,WAAQ,KAAK,WAAiC,SAAS,GAAG;AAAA,EAC5D;AAAA,EAEA,kBAAkB,UAAyC;AACzD,SAAK,iBAAiB;AAAA,EACxB;AAAA,EAEU,MAAM,QAAsB;AACpC,WAAO,KAAK,OAAO,MAAM,MAAM;AAAA,EACjC;AAAA,EAEU,cAAc,UAAkB,MAAc,MAA0B;AAChF,WAAO,GAAG,QAAQ,KAAK,IAAI,KAAK,IAAI;AAAA,EACtC;AAAA,EAEU,gBAAgB,MAKxB;AACA,WAAO;AAAA,MACL,WAAW,KAAK,cAAc;AAAA,MAC9B,SAAS,KAAK,YAAY;AAAA,MAC1B,aAAa,KAAK;AAAA,MAClB,WAAW,KAAK;AAAA,IAClB;AAAA,EACF;AAAA,EAEU,0BAA0B,MAAkB,aAA+B;AACnF,QAAI,aAAa;AACjB,UAAM,QAAQ,CAAC,MAAkB;AAC/B,UAAI,YAAY,SAAS,EAAE,IAAI,GAAG;AAChC;AAAA,MACF;AACA,eAAS,IAAI,GAAG,IAAI,EAAE,YAAY,KAAK;AACrC,cAAM,EAAE,MAAM,CAAC,CAAE;AAAA,MACnB;AAAA,IACF;AACA,UAAM,IAAI;AACV,WAAO;AAAA,EACT;AAKF;;;AD7DA,IAAM,sBAAsB;AAAA,EAC1B;AAAA,EAAgB;AAAA,EAAiB;AAAA,EACjC;AAAA,EAAmB;AAAA,EAAgB;AAAA,EACnC;AAAA,EAAgB;AAClB;AAEO,IAAM,gBAAN,cAA4B,kBAAkB;AAAA,EAC1C,aAAa,CAAC,KAAK;AAAA,EAE5B,cAAc;AACZ,UAAM,cAAc;AAAA,EACtB;AAAA,EAEA,MAAM,eAAe,UAAkB,QAAuC;AAC5E,QAAI;AACF,YAAM,OAAO,KAAK,MAAM,MAAM;AAC9B,YAAM,UAAwB,CAAC;AAC/B,WAAK,aAAa,KAAK,UAAU,UAAU,IAAI,OAAO;AACtD,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,cAAQ,MAAM,8CAA8C,QAAQ,KAAM,IAAc,OAAO,EAAE;AACjG,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAAA,EAEA,MAAM,aAAa,UAAkB,QAAsC;AACzE,QAAI;AACF,YAAM,OAAO,KAAK,MAAM,MAAM;AAC9B,YAAM,QAAqB,CAAC;AAC5B,YAAM,UAAU,MAAM,KAAK,eAAe,UAAU,MAAM;AAC1D,YAAM,cAAc,QAAQ,SAAS,IAAI,QAAQ,CAAC,EAAG,WAAW;AAChE,UAAI,CAAC,YAAa,QAAO;AAEzB,WAAK,WAAW,KAAK,UAAU,UAAU,aAAa,IAAI,KAAK;AAC/D,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,cAAQ,MAAM,4CAA4C,QAAQ,KAAM,IAAc,OAAO,EAAE;AAC/F,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAAA,EAEA,MAAM,kBAAkB,UAAkB,QAA8C;AACtF,QAAI;AACF,YAAM,OAAO,KAAK,MAAM,MAAM;AAC9B,YAAM,UAA+B,CAAC;AACtC,WAAK,gBAAgB,KAAK,UAAU,UAAU,IAAI,OAAO;AACzD,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,cAAQ,MAAM,kDAAkD,QAAQ,KAAM,IAAc,OAAO,EAAE;AACrG,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAAA;AAAA,EAIQ,aACN,MACA,UACA,WACA,SACM;AACN,QAAI,KAAK,SAAS,yBAAyB;AACzC,YAAM,OAAO,KAAK,kBAAkB,MAAM,GAAG,QAAQ;AACrD,YAAM,KAAK,YAAY,GAAG,SAAS,IAAI,IAAI,KAAK;AAChD,eAAS,IAAI,GAAG,IAAI,KAAK,YAAY,KAAK;AACxC,aAAK,aAAa,KAAK,MAAM,CAAC,GAAI,UAAU,IAAI,OAAO;AAAA,MACzD;AACA;AAAA,IACF;AAEA,QAAI,KAAK,SAAS,oBAAoB;AACpC,eAAS,IAAI,GAAG,IAAI,KAAK,YAAY,KAAK;AACxC,aAAK,aAAa,KAAK,MAAM,CAAC,GAAI,UAAU,WAAW,OAAO;AAAA,MAChE;AACA;AAAA,IACF;AAEA,UAAM,cAA0C;AAAA,MAC9C,mBAAmB;AAAA,MACnB,oBAAoB;AAAA,MACpB,oBAAoB;AAAA,MACpB,uBAAuB;AAAA,MACvB,kBAAkB;AAAA,IACpB;AAEA,UAAM,OAAO,YAAY,KAAK,IAAI;AAClC,QAAI,MAAM;AACR,UAAI,CAAC,KAAK,SAAS,IAAI,EAAG;AAC1B,YAAM,OAAO,KAAK,kBAAkB,MAAM,GAAG;AAC7C,UAAI,CAAC,KAAM;AAEX,YAAM,gBAAgB,YAAY,GAAG,SAAS,IAAI,IAAI,KAAK;AAC3D,YAAM,QAAQ,KAAK,gBAAgB,IAAI;AACvC,cAAQ,KAAK;AAAA,QACX,UAAU,KAAK,cAAc,UAAU,eAAe,IAAI;AAAA,QAC1D,MAAM;AAAA,QACN;AAAA,QACA,GAAG;AAAA,MACL,CAAC;AAGD,UAAI,SAAS,SAAS;AACpB,aAAK,qBAAqB,MAAM,UAAU,eAAe,OAAO;AAAA,MAClE;AACA;AAAA,IACF;AAGA,aAAS,IAAI,GAAG,IAAI,KAAK,YAAY,KAAK;AACxC,WAAK,aAAa,KAAK,MAAM,CAAC,GAAI,UAAU,WAAW,OAAO;AAAA,IAChE;AAAA,EACF;AAAA,EAEQ,qBACN,WACA,UACA,WACA,SACM;AACN,UAAM,WAAW,UAAU,SAAS,KAAK,OAAK,EAAE,SAAS,kBAAkB;AAC3E,QAAI,CAAC,SAAU;AAEf,aAAS,IAAI,GAAG,IAAI,SAAS,YAAY,KAAK;AAC5C,YAAM,QAAQ,SAAS,MAAM,CAAC;AAC9B,UAAI,MAAM,SAAS,wBAAwB,MAAM,SAAS,0BAA2B;AACrF,UAAI,CAAC,KAAK,SAAS,KAAK,EAAG;AAE3B,YAAM,OAAO,MAAM,kBAAkB,MAAM,GAAG;AAC9C,UAAI,CAAC,KAAM;AAEX,YAAM,aAAa,KAAK,gBAAgB,KAAK;AAC7C,YAAM,gBAAgB,GAAG,SAAS,IAAI,IAAI,IAAI,UAAU;AACxD,YAAM,QAAQ,KAAK,gBAAgB,KAAK;AACxC,cAAQ,KAAK;AAAA,QACX,UAAU,KAAK,cAAc,UAAU,eAAe,QAAQ;AAAA,QAC9D,MAAM;AAAA,QACN,MAAM;AAAA,QACN,GAAG;AAAA,MACL,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA,EAIQ,WACN,MACA,UACA,YACA,WACA,OACM;AACN,QAAI,KAAK,SAAS,mBAAmB;AACnC,YAAM,WAAW,KAAK,SAAS,KAAK,OAAK,EAAE,SAAS,gBAAgB,EAAE,SAAS,gBAAgB;AAC/F,UAAI,UAAU;AACZ,cAAM,KAAK;AAAA,UACT,MAAM;AAAA,UACN,IAAI,GAAG,SAAS,IAAI,KAAK,SAAS,KAAK,MAAM,GAAG,EAAE,IAAI,CAAC;AAAA,UACvD,MAAM;AAAA,QACR,CAAC;AAAA,MACH;AACA;AAAA,IACF;AAEA,QAAI,KAAK,SAAS,yBAAyB;AACzC,YAAM,OAAO,KAAK,kBAAkB,MAAM,GAAG,QAAQ;AACrD,YAAM,KAAK,YAAY,GAAG,SAAS,IAAI,IAAI,KAAK;AAChD,eAAS,IAAI,GAAG,IAAI,KAAK,YAAY,KAAK;AACxC,aAAK,WAAW,KAAK,MAAM,CAAC,GAAI,UAAU,YAAY,IAAI,KAAK;AAAA,MACjE;AACA;AAAA,IACF;AAEA,QAAI,KAAK,SAAS,uBAAuB,KAAK,SAAS,sBAAsB;AAC3E,UAAI,CAAC,KAAK,SAAS,IAAI,EAAG;AAC1B,YAAM,OAAO,KAAK,kBAAkB,MAAM,GAAG;AAC7C,UAAI,CAAC,KAAM;AAEX,YAAM,gBAAgB,YAAY,GAAG,SAAS,IAAI,IAAI,KAAK;AAC3D,YAAM,gBAAgB,KAAK,cAAc,UAAU,eAAe,OAAO;AAGzE,YAAM,WAAW,KAAK,SAAS,KAAK,OAAK,EAAE,SAAS,WAAW;AAC/D,UAAI,UAAU;AACZ,iBAAS,IAAI,GAAG,IAAI,SAAS,YAAY,KAAK;AAC5C,gBAAM,QAAQ,SAAS,MAAM,CAAC;AAC9B,cAAI,MAAM,SAAS,gBAAgB,MAAM,SAAS,kBAAkB;AAClE,kBAAM,WAAW,MAAM;AAEvB,kBAAM,WAAW,SAAS,MAAM,SAAS,IAAI,eAAe;AAC5D,kBAAM,aAAa,aAAa,eAAe,cAAc;AAC7D,kBAAM,KAAK;AAAA,cACT,MAAM;AAAA,cACN,IAAI,KAAK,gBAAgB,UAAU,WAAW,UAAU;AAAA,cACxD,MAAM;AAAA,YACR,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,aAAS,IAAI,GAAG,IAAI,KAAK,YAAY,KAAK;AACxC,WAAK,WAAW,KAAK,MAAM,CAAC,GAAI,UAAU,YAAY,WAAW,KAAK;AAAA,IACxE;AAAA,EACF;AAAA;AAAA,EAIQ,gBACN,MACA,UACA,WACA,SACM;AACN,QAAI,KAAK,SAAS,yBAAyB;AACzC,YAAM,OAAO,KAAK,kBAAkB,MAAM,GAAG,QAAQ;AACrD,YAAM,KAAK,YAAY,GAAG,SAAS,IAAI,IAAI,KAAK;AAChD,eAAS,IAAI,GAAG,IAAI,KAAK,YAAY,KAAK;AACxC,aAAK,gBAAgB,KAAK,MAAM,CAAC,GAAI,UAAU,IAAI,OAAO;AAAA,MAC5D;AACA;AAAA,IACF;AAEA,UAAM,cAAoC;AAAA,MACxC,mBAAmB;AAAA,MACnB,oBAAoB;AAAA,MACpB,oBAAoB;AAAA,IACtB;AAEA,QAAI,YAAY,KAAK,IAAI,GAAG;AAC1B,UAAI,CAAC,KAAK,SAAS,IAAI,EAAG;AAC1B,YAAM,YAAY,KAAK,kBAAkB,MAAM,GAAG;AAClD,UAAI,CAAC,UAAW;AAEhB,YAAM,iBAAiB,YAAY,GAAG,SAAS,IAAI,SAAS,KAAK;AACjE,YAAM,WAAW,KAAK,SAAS,KAAK,OAAK,EAAE,SAAS,kBAAkB;AACtE,UAAI,CAAC,SAAU;AAEf,eAAS,IAAI,GAAG,IAAI,SAAS,YAAY,KAAK;AAC5C,cAAM,QAAQ,SAAS,MAAM,CAAC;AAC9B,YAAI,MAAM,SAAS,qBAAsB;AACzC,YAAI,CAAC,KAAK,SAAS,KAAK,EAAG;AAE3B,cAAM,aAAa,MAAM,kBAAkB,MAAM,GAAG;AACpD,YAAI,CAAC,WAAY;AAEjB,cAAM,aAAa,KAAK,gBAAgB,KAAK;AAC7C,gBAAQ,KAAK;AAAA,UACX,UAAU,KAAK,cAAc,UAAU,GAAG,cAAc,IAAI,UAAU,IAAI,UAAU,KAAK,QAAQ;AAAA,UACjG,YAAY,KAAK,0BAA0B,OAAO,mBAAmB;AAAA,QACvE,CAAC;AAAA,MACH;AACA;AAAA,IACF;AAEA,aAAS,IAAI,GAAG,IAAI,KAAK,YAAY,KAAK;AACxC,WAAK,gBAAgB,KAAK,MAAM,CAAC,GAAI,UAAU,WAAW,OAAO;AAAA,IACnE;AAAA,EACF;AAAA;AAAA,EAIQ,gBAAgB,YAAgC;AACtD,UAAM,YAAY,WAAW,kBAAkB,YAAY;AAC3D,QAAI,CAAC,UAAW,QAAO;AACvB,QAAI,QAAQ;AACZ,aAAS,IAAI,GAAG,IAAI,UAAU,YAAY,KAAK;AAC7C,UAAI,UAAU,MAAM,CAAC,EAAG,SAAS,YAAa;AAAA,IAChD;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,SAAS,MAA2B;AAC1C,aAAS,IAAI,GAAG,IAAI,KAAK,YAAY,KAAK;AACxC,YAAM,QAAQ,KAAK,MAAM,CAAC;AAC1B,UAAI,MAAM,SAAS,cAAc,MAAM,SAAS,SAAU,QAAO;AAAA,IACnE;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,gBAAgB,UAAkB,WAAmB,aAAiC;AAE5F,UAAM,SAAS,YAAY,GAAG,SAAS,IAAI,QAAQ,KAAK;AACxD,eAAW,CAAC,EAAE,KAAK,KAAK,gBAAgB;AACtC,UAAI,GAAG,SAAS,KAAK,MAAM,IAAI,EAAG,QAAO;AACzC,UAAI,GAAG,SAAS,KAAK,QAAQ,IAAI,EAAG,QAAO;AAAA,IAC7C;AAEA,UAAM,gBAAgB,YAAY,GAAG,SAAS,IAAI,QAAQ,KAAK;AAC/D,WAAO,GAAG,aAAa,KAAK,QAAQ,KAAK,WAAW;AAAA,EACtD;AACF;;;AElSA,IAAMC,OAAM,aAAa,kBAAkB;AAQpC,IAAM,yBAAN,MAAyD;AAAA,EACtD,WAAoC;AAAA,EACpC,SAA+B;AAAA,EAC/B,aAAmC;AAAA,EAE3C,MAAM,WAAW,SAAgC;AAC/C,QAAI;AACF,YAAM,SAAS,IAAI,cAAc;AACjC,YAAM,OAAO,WAAW,OAAO;AAC/B,UAAI,OAAO,QAAQ,GAAG;AACpB,aAAK,SAAS;AACd,aAAK,WAAW;AAChB,QAAAA,KAAI,KAAK,oCAAoC;AAC7C;AAAA,MACF;AAEA,YAAM,OAAO,QAAQ;AAAA,IACvB,SAAS,KAAK;AACZ,MAAAA,KAAI,KAAK,uBAAwB,IAAc,OAAO,EAAE;AAAA,IAC1D;AAEA,QAAI;AACF,WAAK,aAAa,IAAI,cAAc;AACpC,WAAK,WAAW,KAAK;AACrB,MAAAA,KAAI,KAAK,+EAA+E;AAAA,IAC1F,SAAS,KAAK;AACZ,MAAAA,KAAI,KAAK,qCAAsC,IAAc,OAAO,EAAE;AAAA,IACxE;AAAA,EACF;AAAA,EAEA,MAAM,UAAyB;AAC7B,QAAI,KAAK,OAAQ,OAAM,KAAK,OAAO,QAAQ;AAAA,EAC7C;AAAA,EAEA,eAAe,UAAkB,QAAuC;AACtE,WAAO,KAAK,WAAW,KAAK,SAAS,eAAe,UAAU,MAAM,IAAI,QAAQ,QAAQ,CAAC,CAAC;AAAA,EAC5F;AAAA,EAEA,aAAa,UAAkB,QAAsC;AACnE,WAAO,KAAK,WAAW,KAAK,SAAS,aAAa,UAAU,MAAM,IAAI,QAAQ,QAAQ,CAAC,CAAC;AAAA,EAC1F;AAAA,EAEA,kBAAkB,UAAkB,QAA8C;AAChF,WAAO,KAAK,WAAW,KAAK,SAAS,kBAAkB,UAAU,MAAM,IAAI,QAAQ,QAAQ,CAAC,CAAC;AAAA,EAC/F;AAAA,EAEA,YAAY,UAA2B;AACrC,WAAO,SAAS,YAAY,EAAE,SAAS,KAAK;AAAA,EAC9C;AAAA,EAEA,kBAAkB,UAAyC;AACzD,SAAK,UAAU,oBAAoB,QAAQ;AAAA,EAC7C;AAAA;AAAA,EAGA,oBAA0C;AACxC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,UAA6C;AAC3C,QAAI,KAAK,OAAQ,QAAO;AACxB,QAAI,KAAK,WAAY,QAAO;AAC5B,WAAO;AAAA,EACT;AACF;;;ACtEA,IAAM,UAAU;AAET,IAAM,SAA6B;AAAA,EACxC,YAAY;AAAA,EACZ,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,SAAS;AAAA,EACT,YAAY,CAAC,KAAK;AAAA;AAAA;AAAA,EAGlB,MAAM;AAAA,EACN,cAAc,MAAuC;AACnD,WAAO,IAAI,uBAAuB;AAAA,EACpC;AACF;AAEA,IAAO,gBAAQ;","names":["log","resolve","log","log"]}
|
|
1
|
+
{"version":3,"sources":["../src/roslyn/roslyn-adapter.ts","../src/logger.ts","../src/roslyn/solution-discovery.ts","../src/roslyn/roslyn-process.ts","../src/csharp-adapter.ts","../src/tree-sitter-adapter.ts","../src/composite-adapter.ts","../src/index.ts"],"sourcesContent":["import { relative, dirname, resolve } from 'node:path';\nimport type { SymbolNode, GraphEdge, ComplexityMetrics, SymbolKind, ILanguageAdapter } from '@ctxo/plugin-api';\nimport { createLogger } from '../logger.js';\nimport { detectDotnetSdk, discoverSolution, findCtxoRoslynProject } from './solution-discovery.js';\nimport { runBatchIndex, RoslynKeepAlive, type RoslynBatchResult, type RoslynFileResult } from './roslyn-process.js';\n\nconst log = createLogger('ctxo:roslyn');\n\nexport class RoslynAdapter implements ILanguageAdapter {\n readonly extensions = ['.cs'] as const;\n readonly tier = 'full' as const;\n\n private roslynProjectDir: string | null = null;\n private solutionPath: string | null = null;\n private rootDir: string | null = null;\n private cache = new Map<string, RoslynFileResult>();\n private keepAlive: RoslynKeepAlive | null = null;\n private initialized = false;\n\n isSupported(filePath: string): boolean {\n return filePath.endsWith('.cs');\n }\n\n isReady(): boolean {\n return this.initialized && this.roslynProjectDir !== null && this.solutionPath !== null;\n }\n\n async initialize(rootDir: string): Promise<void> {\n // 1. Check dotnet SDK\n const sdk = detectDotnetSdk();\n if (!sdk.available) {\n log.info(`Roslyn adapter unavailable: .NET SDK ${sdk.version ? `${sdk.version} (< 8.0)` : 'not found'}`);\n return;\n }\n\n // 2. Find ctxo-roslyn project\n this.roslynProjectDir = findCtxoRoslynProject();\n if (!this.roslynProjectDir) {\n log.info('Roslyn adapter unavailable: ctxo-roslyn project not found');\n return;\n }\n\n // 3. Discover solution\n this.solutionPath = discoverSolution(rootDir);\n if (!this.solutionPath) {\n log.info('Roslyn adapter unavailable: no .sln or .csproj found');\n return;\n }\n\n this.rootDir = rootDir;\n log.info(`Roslyn adapter ready: SDK ${sdk.version}, solution ${this.solutionPath}`);\n this.initialized = true;\n }\n\n /**\n * Run batch analysis for all .cs files in the solution.\n * Call this once before extractSymbols/extractEdges for best performance.\n */\n async batchIndex(): Promise<RoslynBatchResult | null> {\n if (!this.isReady()) return null;\n\n const result = await runBatchIndex(this.roslynProjectDir!, this.solutionPath!);\n\n // Build path mapping: solution-relative -> project-root-relative for ALL files\n // .NET outputs \"CFTCoreService/Base.cs\" (relative to solution dir)\n // IndexCommand expects \"src/CFTCoreService/Base.cs\" (relative to project root)\n const solutionDir = dirname(this.solutionPath!);\n const pathMap = new Map<string, string>();\n for (const file of result.files) {\n const absolutePath = resolve(solutionDir, file.file);\n const projectRelative = relative(this.rootDir!, absolutePath).replace(/\\\\/g, '/');\n pathMap.set(file.file, projectRelative);\n }\n\n // Rewrite all paths using the complete mapping\n this.cache.clear();\n for (const file of result.files) {\n const projectRelative = pathMap.get(file.file)!;\n const rewritten = rewriteAllPaths(file, projectRelative, pathMap);\n this.cache.set(projectRelative, rewritten);\n }\n\n log.info(`Roslyn batch index: ${result.totalFiles} files in ${result.elapsed}`);\n return result;\n }\n\n async extractSymbols(filePath: string, _source: string): Promise<SymbolNode[]> {\n const cached = this.cache.get(filePath);\n if (!cached) return [];\n\n return cached.symbols.map(s => ({\n symbolId: s.symbolId,\n name: s.name,\n kind: s.kind as SymbolKind,\n startLine: s.startLine,\n endLine: s.endLine,\n ...(s.startOffset != null ? { startOffset: s.startOffset } : {}),\n ...(s.endOffset != null ? { endOffset: s.endOffset } : {}),\n }));\n }\n\n async extractEdges(filePath: string, _source: string): Promise<GraphEdge[]> {\n const cached = this.cache.get(filePath);\n if (!cached) return [];\n\n // Filter out edges with invalid symbol ID format (must be file::name::kind with non-empty segments)\n const VALID_SYMBOL_ID = /^.+::.+::.+$/;\n return cached.edges\n .filter(e => VALID_SYMBOL_ID.test(e.from) && VALID_SYMBOL_ID.test(e.to))\n .map(e => ({\n from: e.from,\n to: e.to,\n kind: e.kind as GraphEdge['kind'],\n }));\n }\n\n async extractComplexity(filePath: string, _source: string): Promise<ComplexityMetrics[]> {\n const cached = this.cache.get(filePath);\n if (!cached) return [];\n\n return cached.complexity.map(c => ({\n symbolId: c.symbolId,\n cyclomatic: c.cyclomatic,\n }));\n }\n\n /**\n * Start keep-alive process for watch mode.\n */\n async startKeepAlive(): Promise<boolean> {\n if (!this.isReady()) return false;\n\n this.keepAlive = new RoslynKeepAlive(this.roslynProjectDir!, this.solutionPath!);\n return await this.keepAlive.start();\n }\n\n /**\n * Incremental re-analysis of a single file (keep-alive mode).\n */\n async reindexFile(relativePath: string): Promise<RoslynFileResult | null> {\n if (!this.keepAlive?.isAlive()) return null;\n\n const result = await this.keepAlive.analyzeFile(relativePath);\n if (result) {\n this.cache.set(relativePath, result);\n }\n return result;\n }\n\n async dispose(): Promise<void> {\n if (this.keepAlive) {\n await this.keepAlive.shutdown();\n this.keepAlive = null;\n }\n this.cache.clear();\n this.initialized = false;\n }\n}\n\n/**\n * Rewrite ALL file paths in symbols/edges using the complete path mapping.\n * Handles cross-file edge targets (e.g., ChatSync -> BaseSyncJob) correctly.\n */\nfunction rewriteAllPaths(\n file: RoslynFileResult,\n newFilePath: string,\n pathMap: Map<string, string>,\n): RoslynFileResult {\n // Rewrite a symbolId or path string: find any solution-relative path prefix and replace it\n const rewrite = (s: string): string => {\n for (const [oldPath, newPath] of pathMap) {\n if (s.includes(oldPath)) {\n return s.replaceAll(oldPath, newPath);\n }\n }\n return s;\n };\n\n return {\n ...file,\n file: newFilePath,\n symbols: file.symbols.map(s => ({\n ...s,\n symbolId: rewrite(s.symbolId),\n })),\n edges: file.edges.map(e => ({\n ...e,\n from: rewrite(e.from),\n to: rewrite(e.to),\n })),\n complexity: file.complexity.map(c => ({\n ...c,\n symbolId: rewrite(c.symbolId),\n })),\n };\n}\n","/**\n * Minimal namespaced logger. Mirrors the shape of cli's `createLogger` so\n * adapter code extracted from the monorepo continues to work unchanged.\n * Emits to stderr only (stdio transport requires stdout kept clean).\n */\ntype LogFn = (message: string, ...args: unknown[]) => void;\n\nexport interface Logger {\n debug: LogFn;\n info: LogFn;\n warn: LogFn;\n error: LogFn;\n}\n\nfunction enabledFor(namespace: string): boolean {\n const env = process.env['DEBUG'];\n if (!env) return false;\n const patterns = env.split(',').map((p) => p.trim()).filter(Boolean);\n for (const pattern of patterns) {\n if (pattern === '*' || pattern === namespace) return true;\n if (pattern.endsWith('*') && namespace.startsWith(pattern.slice(0, -1))) return true;\n }\n return false;\n}\n\nfunction emit(namespace: string, level: string, message: string, args: unknown[]): void {\n const line = `[${namespace}] ${message}${args.length ? ' ' + args.map(String).join(' ') : ''}`;\n if (level === 'error') process.stderr.write(line + '\\n');\n else if (level === 'warn') process.stderr.write(line + '\\n');\n else if (enabledFor(namespace)) process.stderr.write(line + '\\n');\n}\n\nexport function createLogger(namespace: string): Logger {\n return {\n debug: (msg, ...args) => emit(namespace, 'debug', msg, args),\n info: (msg, ...args) => emit(namespace, 'info', msg, args),\n warn: (msg, ...args) => emit(namespace, 'warn', msg, args),\n error: (msg, ...args) => emit(namespace, 'error', msg, args),\n };\n}\n","import { execFileSync } from 'node:child_process';\nimport { existsSync, readdirSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { createLogger } from '../logger.js';\n\nconst log = createLogger('ctxo:roslyn');\n\nconst IGNORE_DIRS = new Set(['bin', 'obj', 'node_modules', '.git', '.ctxo', 'packages']);\n\nfunction findPackageRoot(startDir: string): string | null {\n let dir = startDir;\n for (let i = 0; i < 10; i++) {\n if (existsSync(join(dir, 'package.json'))) return dir;\n const parent = join(dir, '..');\n if (parent === dir) break;\n dir = parent;\n }\n return null;\n}\n\nfunction findMonorepoRoot(startDir: string): string | null {\n let dir = startDir;\n for (let i = 0; i < 12; i++) {\n if (existsSync(join(dir, 'pnpm-workspace.yaml'))) return dir;\n const parent = join(dir, '..');\n if (parent === dir) break;\n dir = parent;\n }\n return null;\n}\n\nexport function detectDotnetSdk(): { available: boolean; version?: string } {\n try {\n const version = execFileSync('dotnet', ['--version'], { encoding: 'utf-8', timeout: 10_000 }).trim();\n const major = parseInt(version.split('.')[0]!, 10);\n if (major < 8) {\n log.info(`dotnet SDK ${version} found but < 8.0 required`);\n return { available: false, version };\n }\n return { available: true, version };\n } catch {\n return { available: false };\n }\n}\n\nexport function discoverSolution(rootDir: string): string | null {\n // 1. .sln in root\n const rootSlns = findFiles(rootDir, '.sln', 0);\n if (rootSlns.length === 1) return rootSlns[0]!;\n if (rootSlns.length > 1) {\n log.info(`Multiple .sln in root, picking first: ${rootSlns[0]}`);\n return rootSlns[0]!;\n }\n\n // 2. .sln recursive (shallowest first)\n const allSlns = findFiles(rootDir, '.sln', 3);\n if (allSlns.length > 0) {\n allSlns.sort((a, b) => a.split('/').length - b.split('/').length);\n return allSlns[0]!;\n }\n\n // 3. .csproj fallback\n const csprojFiles = findFiles(rootDir, '.csproj', 3);\n if (csprojFiles.length > 0) {\n log.info(`No .sln found, using .csproj: ${csprojFiles[0]}`);\n return csprojFiles[0]!;\n }\n\n return null;\n}\n\nfunction findFiles(dir: string, ext: string, maxDepth: number, currentDepth = 0): string[] {\n const results: string[] = [];\n if (currentDepth > maxDepth) return results;\n\n try {\n const entries = readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isFile() && entry.name.endsWith(ext)) {\n results.push(join(dir, entry.name));\n } else if (entry.isDirectory() && !IGNORE_DIRS.has(entry.name)) {\n results.push(...findFiles(join(dir, entry.name), ext, maxDepth, currentDepth + 1));\n }\n }\n } catch {\n // permission denied, etc.\n }\n\n return results;\n}\n\nexport function findCtxoRoslynProject(): string | null {\n // Look for the ctxo-roslyn project relative to this package\n // tsup bundles all code into dist/*.js, so import.meta.dirname = dist/\n // We need to find the package root by walking up from import.meta.dirname\n const pkgRoot = findPackageRoot(import.meta.dirname);\n const monorepoRoot = findMonorepoRoot(import.meta.dirname);\n const candidates = [\n // Plugin package root — tools/ctxo-roslyn ships inside @ctxo/lang-csharp\n ...(pkgRoot ? [join(pkgRoot, 'tools/ctxo-roslyn')] : []),\n // Monorepo dev: packages/lang-csharp/tools/ctxo-roslyn\n ...(monorepoRoot ? [join(monorepoRoot, 'packages/lang-csharp/tools/ctxo-roslyn')] : []),\n // Bundled dist: dist/roslyn -> ../tools (tsup preserves relative layout)\n join(import.meta.dirname, '../tools/ctxo-roslyn'),\n // Unbundled src layout: src/roslyn -> ../../tools\n join(import.meta.dirname, '../../tools/ctxo-roslyn'),\n // Consumer node_modules installs\n join(process.cwd(), 'node_modules/@ctxo/lang-csharp/tools/ctxo-roslyn'),\n // Legacy paths kept for migration window\n join(process.cwd(), 'node_modules/@ctxo/cli/tools/ctxo-roslyn'),\n join(process.cwd(), 'node_modules/ctxo-mcp/tools/ctxo-roslyn'),\n ];\n\n for (const candidate of candidates) {\n const csproj = join(candidate, 'ctxo-roslyn.csproj');\n if (existsSync(csproj)) return candidate;\n }\n\n return null;\n}\n","import { spawn, type ChildProcess } from 'node:child_process';\nimport { createLogger } from '../logger.js';\n\nconst log = createLogger('ctxo:roslyn');\n\nexport interface RoslynFileResult {\n type: 'file';\n file: string;\n symbols: RoslynSymbol[];\n edges: RoslynEdge[];\n complexity: RoslynComplexity[];\n}\n\nexport interface RoslynSymbol {\n symbolId: string;\n name: string;\n kind: string;\n startLine: number;\n endLine: number;\n startOffset?: number;\n endOffset?: number;\n}\n\nexport interface RoslynEdge {\n from: string;\n to: string;\n kind: string;\n}\n\nexport interface RoslynComplexity {\n symbolId: string;\n cyclomatic: number;\n cognitive: number;\n}\n\nexport interface RoslynProjectGraph {\n type: 'projectGraph';\n projects: Array<{ name: string; path: string }>;\n edges: Array<{ from: string; to: string; kind: string }>;\n}\n\nexport interface RoslynBatchResult {\n files: RoslynFileResult[];\n projectGraph: RoslynProjectGraph | null;\n totalFiles: number;\n elapsed: string;\n}\n\n/**\n * Run ctxo-roslyn in one-shot batch mode.\n * Spawns `dotnet run`, reads JSONL from stdout, returns parsed results.\n */\nexport async function runBatchIndex(\n projectDir: string,\n solutionPath: string,\n timeoutMs = 120_000,\n): Promise<RoslynBatchResult> {\n return new Promise((resolve) => {\n const proc = spawn('dotnet', ['run', '--project', projectDir, '--', solutionPath], {\n stdio: ['ignore', 'pipe', 'pipe'],\n timeout: timeoutMs,\n });\n\n const files: RoslynFileResult[] = [];\n let projectGraph: RoslynProjectGraph | null = null;\n let totalFiles = 0;\n let elapsed = '';\n let stderr = '';\n\n let buffer = '';\n proc.stdout.on('data', (chunk: Buffer) => {\n buffer += chunk.toString();\n let newlineIdx: number;\n while ((newlineIdx = buffer.indexOf('\\n')) !== -1) {\n const line = buffer.slice(0, newlineIdx).trim();\n buffer = buffer.slice(newlineIdx + 1);\n if (!line) continue;\n\n try {\n const obj = JSON.parse(line);\n switch (obj.type) {\n case 'file':\n files.push(obj as RoslynFileResult);\n break;\n case 'projectGraph':\n projectGraph = obj as RoslynProjectGraph;\n break;\n case 'progress':\n log.info(obj.message);\n break;\n case 'done':\n totalFiles = obj.totalFiles ?? 0;\n elapsed = obj.elapsed ?? '';\n break;\n }\n } catch {\n log.error(`Failed to parse JSONL line: ${line.slice(0, 100)}`);\n }\n }\n });\n\n proc.stderr.on('data', (chunk: Buffer) => {\n stderr += chunk.toString();\n });\n\n proc.on('close', (code) => {\n if (code !== 0) {\n log.error(`ctxo-roslyn exited with code ${code}: ${stderr.trim()}`);\n resolve({ files: [], projectGraph: null, totalFiles: 0, elapsed: '' });\n return;\n }\n resolve({ files, projectGraph, totalFiles, elapsed });\n });\n\n proc.on('error', (err) => {\n log.error(`ctxo-roslyn spawn error: ${err.message}`);\n resolve({ files: [], projectGraph: null, totalFiles: 0, elapsed: '' });\n });\n });\n}\n\n/**\n * Keep-alive Roslyn process for watch mode.\n * Stays alive, accepts file paths via stdin, returns results via stdout.\n */\nexport class RoslynKeepAlive {\n private proc: ChildProcess | null = null;\n private buffer = '';\n private pending: Map<string, (result: RoslynFileResult | null) => void> = new Map();\n private projectDir: string;\n private solutionPath: string;\n private timeoutMs: number;\n private inactivityTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(projectDir: string, solutionPath: string, timeoutMs = 300_000) {\n this.projectDir = projectDir;\n this.solutionPath = solutionPath;\n this.timeoutMs = timeoutMs;\n }\n\n async start(): Promise<boolean> {\n return new Promise((resolve) => {\n this.proc = spawn('dotnet', ['run', '--project', this.projectDir, '--', this.solutionPath, '--keep-alive'], {\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n this.proc.stdout!.on('data', (chunk: Buffer) => {\n this.buffer += chunk.toString();\n let newlineIdx: number;\n while ((newlineIdx = this.buffer.indexOf('\\n')) !== -1) {\n const line = this.buffer.slice(0, newlineIdx).trim();\n this.buffer = this.buffer.slice(newlineIdx + 1);\n if (!line) continue;\n\n try {\n const obj = JSON.parse(line);\n if (obj.type === 'ready') {\n log.info(`Roslyn keep-alive ready: ${obj.projectCount} projects, ${obj.fileCount} files`);\n resolve(true);\n } else if (obj.type === 'file') {\n const result = obj as RoslynFileResult;\n const callback = this.pending.get(result.file);\n if (callback) {\n this.pending.delete(result.file);\n callback(result);\n }\n } else if (obj.type === 'progress') {\n log.info(obj.message);\n }\n } catch {\n log.error(`Keep-alive parse error: ${line.slice(0, 100)}`);\n }\n }\n });\n\n this.proc.stderr!.on('data', (chunk: Buffer) => {\n log.error(`Roslyn stderr: ${chunk.toString().trim()}`);\n });\n\n this.proc.on('close', (code) => {\n log.info(`Roslyn keep-alive exited (code ${code})`);\n this.proc = null;\n // Reject any pending requests\n for (const callback of this.pending.values()) callback(null);\n this.pending.clear();\n });\n\n this.proc.on('error', (err) => {\n log.error(`Roslyn keep-alive error: ${err.message}`);\n resolve(false);\n });\n\n this.resetInactivityTimer();\n });\n }\n\n async analyzeFile(relativePath: string): Promise<RoslynFileResult | null> {\n if (!this.proc || !this.proc.stdin!.writable) {\n return null;\n }\n\n this.resetInactivityTimer();\n\n return new Promise((resolve) => {\n this.pending.set(relativePath, resolve);\n this.proc!.stdin!.write(JSON.stringify({ file: relativePath }) + '\\n');\n\n // Per-request timeout\n setTimeout(() => {\n if (this.pending.has(relativePath)) {\n this.pending.delete(relativePath);\n log.error(`Roslyn keep-alive timeout for ${relativePath}`);\n resolve(null);\n }\n }, 30_000);\n });\n }\n\n isAlive(): boolean {\n return this.proc !== null && !this.proc.killed;\n }\n\n async shutdown(): Promise<void> {\n if (this.inactivityTimer) clearTimeout(this.inactivityTimer);\n if (this.proc) {\n this.proc.stdin!.end();\n this.proc.kill();\n this.proc = null;\n }\n }\n\n private resetInactivityTimer(): void {\n if (this.inactivityTimer) clearTimeout(this.inactivityTimer);\n this.inactivityTimer = setTimeout(() => {\n log.info(`Roslyn keep-alive shutting down after ${this.timeoutMs / 1000}s inactivity`);\n this.shutdown();\n }, this.timeoutMs);\n }\n}\n","import CSharpLanguage from 'tree-sitter-c-sharp';\nimport type { SyntaxNode } from 'tree-sitter';\nimport { TreeSitterAdapter } from './tree-sitter-adapter.js';\nimport type { SymbolNode, GraphEdge, ComplexityMetrics, SymbolKind } from '@ctxo/plugin-api';\n\nconst CSHARP_BRANCH_TYPES = [\n 'if_statement', 'for_statement', 'foreach_statement',\n 'while_statement', 'do_statement', 'switch_section',\n 'catch_clause', 'conditional_expression',\n];\n\nexport class CSharpAdapter extends TreeSitterAdapter {\n readonly extensions = ['.cs'] as const;\n\n constructor() {\n super(CSharpLanguage);\n }\n\n async extractSymbols(filePath: string, source: string): Promise<SymbolNode[]> {\n try {\n const tree = this.parse(source);\n const symbols: SymbolNode[] = [];\n this.visitSymbols(tree.rootNode, filePath, '', symbols);\n return symbols;\n } catch (err) {\n console.error(`[ctxo:csharp] Symbol extraction failed for ${filePath}: ${(err as Error).message}`);\n return [];\n }\n }\n\n async extractEdges(filePath: string, source: string): Promise<GraphEdge[]> {\n try {\n const tree = this.parse(source);\n const edges: GraphEdge[] = [];\n const symbols = await this.extractSymbols(filePath, source);\n const firstSymbol = symbols.length > 0 ? symbols[0]!.symbolId : undefined;\n if (!firstSymbol) return edges;\n\n this.visitEdges(tree.rootNode, filePath, firstSymbol, '', edges);\n return edges;\n } catch (err) {\n console.error(`[ctxo:csharp] Edge extraction failed for ${filePath}: ${(err as Error).message}`);\n return [];\n }\n }\n\n async extractComplexity(filePath: string, source: string): Promise<ComplexityMetrics[]> {\n try {\n const tree = this.parse(source);\n const metrics: ComplexityMetrics[] = [];\n this.visitComplexity(tree.rootNode, filePath, '', metrics);\n return metrics;\n } catch (err) {\n console.error(`[ctxo:csharp] Complexity extraction failed for ${filePath}: ${(err as Error).message}`);\n return [];\n }\n }\n\n // ── Symbol visitor ──────────────────────────────────────────\n\n private visitSymbols(\n node: SyntaxNode,\n filePath: string,\n namespace: string,\n symbols: SymbolNode[],\n ): void {\n if (node.type === 'namespace_declaration') {\n const name = node.childForFieldName('name')?.text ?? '';\n const ns = namespace ? `${namespace}.${name}` : name;\n for (let i = 0; i < node.childCount; i++) {\n this.visitSymbols(node.child(i)!, filePath, ns, symbols);\n }\n return;\n }\n\n if (node.type === 'declaration_list') {\n for (let i = 0; i < node.childCount; i++) {\n this.visitSymbols(node.child(i)!, filePath, namespace, symbols);\n }\n return;\n }\n\n const typeMapping: Record<string, SymbolKind> = {\n class_declaration: 'class',\n struct_declaration: 'class',\n record_declaration: 'class',\n interface_declaration: 'interface',\n enum_declaration: 'type',\n };\n\n const kind = typeMapping[node.type];\n if (kind) {\n if (!this.isPublic(node)) return;\n const name = node.childForFieldName('name')?.text;\n if (!name) return;\n\n const qualifiedName = namespace ? `${namespace}.${name}` : name;\n const range = this.nodeToLineRange(node);\n symbols.push({\n symbolId: this.buildSymbolId(filePath, qualifiedName, kind),\n name: qualifiedName,\n kind,\n ...range,\n });\n\n // Extract methods inside the class/struct/record\n if (kind === 'class') {\n this.extractMethodSymbols(node, filePath, qualifiedName, symbols);\n }\n return;\n }\n\n // Recurse into compilation_unit and other containers\n for (let i = 0; i < node.childCount; i++) {\n this.visitSymbols(node.child(i)!, filePath, namespace, symbols);\n }\n }\n\n private extractMethodSymbols(\n classNode: SyntaxNode,\n filePath: string,\n className: string,\n symbols: SymbolNode[],\n ): void {\n const declList = classNode.children.find(c => c.type === 'declaration_list');\n if (!declList) return;\n\n for (let i = 0; i < declList.childCount; i++) {\n const child = declList.child(i)!;\n if (child.type !== 'method_declaration' && child.type !== 'constructor_declaration') continue;\n if (!this.isPublic(child)) continue;\n\n const name = child.childForFieldName('name')?.text;\n if (!name) continue;\n\n const paramCount = this.countParameters(child);\n const qualifiedName = `${className}.${name}(${paramCount})`;\n const range = this.nodeToLineRange(child);\n symbols.push({\n symbolId: this.buildSymbolId(filePath, qualifiedName, 'method'),\n name: qualifiedName,\n kind: 'method',\n ...range,\n });\n }\n }\n\n // ── Edge visitor ────────────────────────────────────────────\n\n private visitEdges(\n node: SyntaxNode,\n filePath: string,\n fromSymbol: string,\n namespace: string,\n edges: GraphEdge[],\n ): void {\n if (node.type === 'using_directive') {\n const nameNode = node.children.find(c => c.type === 'identifier' || c.type === 'qualified_name');\n if (nameNode) {\n edges.push({\n from: fromSymbol,\n to: `${nameNode.text}::${nameNode.text.split('.').pop()}::variable`,\n kind: 'imports',\n });\n }\n return;\n }\n\n if (node.type === 'namespace_declaration') {\n const name = node.childForFieldName('name')?.text ?? '';\n const ns = namespace ? `${namespace}.${name}` : name;\n for (let i = 0; i < node.childCount; i++) {\n this.visitEdges(node.child(i)!, filePath, fromSymbol, ns, edges);\n }\n return;\n }\n\n if (node.type === 'class_declaration' || node.type === 'struct_declaration') {\n if (!this.isPublic(node)) return;\n const name = node.childForFieldName('name')?.text;\n if (!name) return;\n\n const qualifiedName = namespace ? `${namespace}.${name}` : name;\n const classSymbolId = this.buildSymbolId(filePath, qualifiedName, 'class');\n\n // Check base_list for extends/implements\n const baseList = node.children.find(c => c.type === 'base_list');\n if (baseList) {\n for (let i = 0; i < baseList.childCount; i++) {\n const child = baseList.child(i)!;\n if (child.type === 'identifier' || child.type === 'qualified_name') {\n const baseName = child.text;\n // Heuristic: I-prefix = interface → implements, otherwise extends\n const edgeKind = baseName.match(/^I[A-Z]/) ? 'implements' : 'extends';\n const targetKind = edgeKind === 'implements' ? 'interface' : 'class';\n edges.push({\n from: classSymbolId,\n to: this.resolveBaseType(baseName, namespace, targetKind),\n kind: edgeKind,\n });\n }\n }\n }\n }\n\n for (let i = 0; i < node.childCount; i++) {\n this.visitEdges(node.child(i)!, filePath, fromSymbol, namespace, edges);\n }\n }\n\n // ── Complexity visitor ──────────────────────────────────────\n\n private visitComplexity(\n node: SyntaxNode,\n filePath: string,\n namespace: string,\n metrics: ComplexityMetrics[],\n ): void {\n if (node.type === 'namespace_declaration') {\n const name = node.childForFieldName('name')?.text ?? '';\n const ns = namespace ? `${namespace}.${name}` : name;\n for (let i = 0; i < node.childCount; i++) {\n this.visitComplexity(node.child(i)!, filePath, ns, metrics);\n }\n return;\n }\n\n const typeMapping: Record<string, true> = {\n class_declaration: true,\n struct_declaration: true,\n record_declaration: true,\n };\n\n if (typeMapping[node.type]) {\n if (!this.isPublic(node)) return;\n const className = node.childForFieldName('name')?.text;\n if (!className) return;\n\n const qualifiedClass = namespace ? `${namespace}.${className}` : className;\n const declList = node.children.find(c => c.type === 'declaration_list');\n if (!declList) return;\n\n for (let i = 0; i < declList.childCount; i++) {\n const child = declList.child(i)!;\n if (child.type !== 'method_declaration') continue;\n if (!this.isPublic(child)) continue;\n\n const methodName = child.childForFieldName('name')?.text;\n if (!methodName) continue;\n\n const paramCount = this.countParameters(child);\n metrics.push({\n symbolId: this.buildSymbolId(filePath, `${qualifiedClass}.${methodName}(${paramCount})`, 'method'),\n cyclomatic: this.countCyclomaticComplexity(child, CSHARP_BRANCH_TYPES),\n });\n }\n return;\n }\n\n for (let i = 0; i < node.childCount; i++) {\n this.visitComplexity(node.child(i)!, filePath, namespace, metrics);\n }\n }\n\n // ── Helpers ─────────────────────────────────────────────────\n\n private countParameters(methodNode: SyntaxNode): number {\n const paramList = methodNode.childForFieldName('parameters');\n if (!paramList) return 0;\n let count = 0;\n for (let i = 0; i < paramList.childCount; i++) {\n if (paramList.child(i)!.type === 'parameter') count++;\n }\n return count;\n }\n\n private isPublic(node: SyntaxNode): boolean {\n for (let i = 0; i < node.childCount; i++) {\n const child = node.child(i)!;\n if (child.type === 'modifier' && child.text === 'public') return true;\n }\n return false;\n }\n\n private resolveBaseType(baseName: string, namespace: string, defaultKind: SymbolKind): string {\n // Check symbol registry first\n const prefix = namespace ? `${namespace}.${baseName}` : baseName;\n for (const [id] of this.symbolRegistry) {\n if (id.includes(`::${prefix}::`)) return id;\n if (id.includes(`::${baseName}::`)) return id;\n }\n // Fallback: assume same namespace\n const qualifiedName = namespace ? `${namespace}.${baseName}` : baseName;\n return `${qualifiedName}::${baseName}::${defaultKind}`;\n }\n}\n","import Parser from 'tree-sitter';\nimport type { Tree, SyntaxNode } from 'tree-sitter';\n// Grammars (tree-sitter-c-sharp etc.) ship their own Language type which can\n// drift against tree-sitter's parameter type across major versions. Accept any\n// structurally compatible value and hand it to the parser as the runtime API\n// expects (the parser does its own validation).\ntype Language = Parameters<InstanceType<typeof Parser>['setLanguage']>[0] | object;\nimport { extname } from 'node:path';\nimport type { SymbolNode, GraphEdge, ComplexityMetrics, SymbolKind, ILanguageAdapter } from '@ctxo/plugin-api';\n\nexport abstract class TreeSitterAdapter implements ILanguageAdapter {\n abstract readonly extensions: readonly string[];\n readonly tier = 'syntax' as const;\n\n protected parser: Parser;\n protected symbolRegistry = new Map<string, SymbolKind>();\n\n constructor(language: Language) {\n this.parser = new Parser();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.parser.setLanguage(language as any);\n }\n\n isSupported(filePath: string): boolean {\n const ext = extname(filePath).toLowerCase();\n return (this.extensions as readonly string[]).includes(ext);\n }\n\n setSymbolRegistry(registry: Map<string, SymbolKind>): void {\n this.symbolRegistry = registry;\n }\n\n protected parse(source: string): Tree {\n return this.parser.parse(source);\n }\n\n protected buildSymbolId(filePath: string, name: string, kind: SymbolKind): string {\n return `${filePath}::${name}::${kind}`;\n }\n\n protected nodeToLineRange(node: SyntaxNode): {\n startLine: number;\n endLine: number;\n startOffset: number;\n endOffset: number;\n } {\n return {\n startLine: node.startPosition.row,\n endLine: node.endPosition.row,\n startOffset: node.startIndex,\n endOffset: node.endIndex,\n };\n }\n\n protected countCyclomaticComplexity(node: SyntaxNode, branchTypes: string[]): number {\n let complexity = 1;\n const visit = (n: SyntaxNode) => {\n if (branchTypes.includes(n.type)) {\n complexity++;\n }\n for (let i = 0; i < n.childCount; i++) {\n visit(n.child(i)!);\n }\n };\n visit(node);\n return complexity;\n }\n\n abstract extractSymbols(filePath: string, source: string): Promise<SymbolNode[]>;\n abstract extractEdges(filePath: string, source: string): Promise<GraphEdge[]>;\n abstract extractComplexity(filePath: string, source: string): Promise<ComplexityMetrics[]>;\n}\n","import type { SymbolNode, GraphEdge, ComplexityMetrics, SymbolKind, ILanguageAdapter } from '@ctxo/plugin-api';\nimport { RoslynAdapter } from './roslyn/roslyn-adapter.js';\nimport { CSharpAdapter } from './csharp-adapter.js';\nimport { createLogger } from './logger.js';\n\nconst log = createLogger('ctxo:lang-csharp');\n\n/**\n * Chooses between the full-tier Roslyn launcher and the syntax-tier tree-sitter\n * adapter at initialize() time. Forwards extract*() calls to the active delegate\n * and exposes the Roslyn delegate (when active) for cli optimizations such as\n * watch-mode keep-alive and batch index pre-warm.\n */\nexport class CSharpCompositeAdapter implements ILanguageAdapter {\n private delegate: ILanguageAdapter | null = null;\n private roslyn: RoslynAdapter | null = null;\n private treeSitter: CSharpAdapter | null = null;\n\n async initialize(rootDir: string): Promise<void> {\n try {\n const roslyn = new RoslynAdapter();\n await roslyn.initialize(rootDir);\n if (roslyn.isReady()) {\n this.roslyn = roslyn;\n this.delegate = roslyn;\n log.info('C# plugin: Roslyn full-tier active');\n return;\n }\n // Roslyn constructed but not ready — dispose and fall through\n await roslyn.dispose();\n } catch (err) {\n log.warn(`Roslyn unavailable: ${(err as Error).message}`);\n }\n\n try {\n this.treeSitter = new CSharpAdapter();\n this.delegate = this.treeSitter;\n log.info('C# plugin: tree-sitter syntax-tier active (install .NET 8+ SDK for full tier)');\n } catch (err) {\n log.warn(`tree-sitter fallback unavailable: ${(err as Error).message}`);\n }\n }\n\n async dispose(): Promise<void> {\n if (this.roslyn) await this.roslyn.dispose();\n }\n\n extractSymbols(filePath: string, source: string): Promise<SymbolNode[]> {\n return this.delegate ? this.delegate.extractSymbols(filePath, source) : Promise.resolve([]);\n }\n\n extractEdges(filePath: string, source: string): Promise<GraphEdge[]> {\n return this.delegate ? this.delegate.extractEdges(filePath, source) : Promise.resolve([]);\n }\n\n extractComplexity(filePath: string, source: string): Promise<ComplexityMetrics[]> {\n return this.delegate ? this.delegate.extractComplexity(filePath, source) : Promise.resolve([]);\n }\n\n isSupported(filePath: string): boolean {\n return filePath.toLowerCase().endsWith('.cs');\n }\n\n setSymbolRegistry(registry: Map<string, SymbolKind>): void {\n this.delegate?.setSymbolRegistry?.(registry);\n }\n\n /** Exposed for cli watch/index optimizations. Null when running in syntax tier. */\n getRoslynDelegate(): RoslynAdapter | null {\n return this.roslyn;\n }\n\n /** Current active tier after initialize() resolves. */\n getTier(): 'full' | 'syntax' | 'unavailable' {\n if (this.roslyn) return 'full';\n if (this.treeSitter) return 'syntax';\n return 'unavailable';\n }\n}\n","import type { CtxoLanguagePlugin, PluginContext, ILanguageAdapter } from '@ctxo/plugin-api';\nimport { CSharpCompositeAdapter } from './composite-adapter.js';\n\nexport { CSharpCompositeAdapter } from './composite-adapter.js';\nexport { CSharpAdapter } from './csharp-adapter.js';\nexport { RoslynAdapter } from './roslyn/roslyn-adapter.js';\nexport { TreeSitterAdapter } from './tree-sitter-adapter.js';\n\nconst VERSION = '0.7.0-alpha.0';\n\nexport const plugin: CtxoLanguagePlugin = {\n apiVersion: '1',\n id: 'csharp',\n name: 'C# (Roslyn full tier, tree-sitter fallback)',\n version: VERSION,\n extensions: ['.cs'],\n // Plugin advertises full-tier capability; the composite adapter downgrades to\n // syntax at runtime when .NET SDK 8+ is unavailable.\n tier: 'full',\n createAdapter(_ctx: PluginContext): ILanguageAdapter {\n return new CSharpCompositeAdapter();\n },\n};\n\nexport default plugin;\n"],"mappings":"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","names":["log","resolve","log","log"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ctxo/lang-csharp",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.1",
|
|
4
4
|
"description": "Ctxo C# language plugin (Roslyn full tier, tree-sitter syntax fallback)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -33,19 +33,28 @@
|
|
|
33
33
|
"author": "Alper Hankendi",
|
|
34
34
|
"license": "MIT",
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"tree-sitter": "^0.
|
|
36
|
+
"tree-sitter": "^0.25.0",
|
|
37
37
|
"tree-sitter-c-sharp": "^0.23.1"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
|
-
"@ctxo/plugin-api": "^0.7.0
|
|
40
|
+
"@ctxo/plugin-api": "^0.7.0"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/node": "^22.15.3",
|
|
44
44
|
"tsup": "^8.4.0",
|
|
45
45
|
"typescript": "^5.8.3",
|
|
46
46
|
"vitest": "^3.1.3",
|
|
47
|
-
"@ctxo/plugin-api": "0.7.0
|
|
47
|
+
"@ctxo/plugin-api": "0.7.0"
|
|
48
48
|
},
|
|
49
|
+
"repository": {
|
|
50
|
+
"type": "git",
|
|
51
|
+
"url": "git+https://github.com/alperhankendi/Ctxo.git",
|
|
52
|
+
"directory": "packages/lang-csharp"
|
|
53
|
+
},
|
|
54
|
+
"bugs": {
|
|
55
|
+
"url": "https://github.com/alperhankendi/Ctxo/issues"
|
|
56
|
+
},
|
|
57
|
+
"homepage": "https://github.com/alperhankendi/Ctxo#readme",
|
|
49
58
|
"scripts": {
|
|
50
59
|
"build": "tsup",
|
|
51
60
|
"typecheck": "tsc --noEmit",
|